mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-12-27 02:11:53 +00:00
96d4a3ecf7
Due to historical reasons, the code is in subfolder "1". With SVN removal, we place the code back and remove the annoying "1" folder.
279 lines
7.8 KiB
JavaScript
279 lines
7.8 KiB
JavaScript
// Custom reveal.js integration
|
|
(function(){
|
|
var isEnabled = true;
|
|
|
|
document.querySelector( '.reveal' ).addEventListener( 'mousedown', function( event ) {
|
|
var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : 'alt' ) + 'Key';
|
|
|
|
var zoomPadding = 20;
|
|
var revealScale = Reveal.getScale();
|
|
|
|
if( event[ modifier ] && isEnabled ) {
|
|
event.preventDefault();
|
|
|
|
var bounds = event.target.getBoundingClientRect();
|
|
|
|
zoom.to({
|
|
x: ( bounds.left * revealScale ) - zoomPadding,
|
|
y: ( bounds.top * revealScale ) - zoomPadding,
|
|
width: ( bounds.width * revealScale ) + ( zoomPadding * 2 ),
|
|
height: ( bounds.height * revealScale ) + ( zoomPadding * 2 ),
|
|
pan: false
|
|
});
|
|
}
|
|
} );
|
|
|
|
Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } );
|
|
Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } );
|
|
})();
|
|
|
|
/*!
|
|
* zoom.js 0.3 (modified for use with reveal.js)
|
|
* http://lab.hakim.se/zoom-js
|
|
* MIT licensed
|
|
*
|
|
* Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
|
|
*/
|
|
var zoom = (function(){
|
|
|
|
// The current zoom level (scale)
|
|
var level = 1;
|
|
|
|
// The current mouse position, used for panning
|
|
var mouseX = 0,
|
|
mouseY = 0;
|
|
|
|
// Timeout before pan is activated
|
|
var panEngageTimeout = -1,
|
|
panUpdateInterval = -1;
|
|
|
|
// Check for transform support so that we can fallback otherwise
|
|
var supportsTransforms = 'WebkitTransform' in document.body.style ||
|
|
'MozTransform' in document.body.style ||
|
|
'msTransform' in document.body.style ||
|
|
'OTransform' in document.body.style ||
|
|
'transform' in document.body.style;
|
|
|
|
if( supportsTransforms ) {
|
|
// The easing that will be applied when we zoom in/out
|
|
document.body.style.transition = 'transform 0.8s ease';
|
|
document.body.style.OTransition = '-o-transform 0.8s ease';
|
|
document.body.style.msTransition = '-ms-transform 0.8s ease';
|
|
document.body.style.MozTransition = '-moz-transform 0.8s ease';
|
|
document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
|
|
}
|
|
|
|
// Zoom out if the user hits escape
|
|
document.addEventListener( 'keyup', function( event ) {
|
|
if( level !== 1 && event.keyCode === 27 ) {
|
|
zoom.out();
|
|
}
|
|
} );
|
|
|
|
// Monitor mouse movement for panning
|
|
document.addEventListener( 'mousemove', function( event ) {
|
|
if( level !== 1 ) {
|
|
mouseX = event.clientX;
|
|
mouseY = event.clientY;
|
|
}
|
|
} );
|
|
|
|
/**
|
|
* Applies the CSS required to zoom in, prefers the use of CSS3
|
|
* transforms but falls back on zoom for IE.
|
|
*
|
|
* @param {Object} rect
|
|
* @param {Number} scale
|
|
*/
|
|
function magnify( rect, scale ) {
|
|
|
|
var scrollOffset = getScrollOffset();
|
|
|
|
// Ensure a width/height is set
|
|
rect.width = rect.width || 1;
|
|
rect.height = rect.height || 1;
|
|
|
|
// Center the rect within the zoomed viewport
|
|
rect.x -= ( window.innerWidth - ( rect.width * scale ) ) / 2;
|
|
rect.y -= ( window.innerHeight - ( rect.height * scale ) ) / 2;
|
|
|
|
if( supportsTransforms ) {
|
|
// Reset
|
|
if( scale === 1 ) {
|
|
document.body.style.transform = '';
|
|
document.body.style.OTransform = '';
|
|
document.body.style.msTransform = '';
|
|
document.body.style.MozTransform = '';
|
|
document.body.style.WebkitTransform = '';
|
|
}
|
|
// Scale
|
|
else {
|
|
var origin = scrollOffset.x +'px '+ scrollOffset.y +'px',
|
|
transform = 'translate('+ -rect.x +'px,'+ -rect.y +'px) scale('+ scale +')';
|
|
|
|
document.body.style.transformOrigin = origin;
|
|
document.body.style.OTransformOrigin = origin;
|
|
document.body.style.msTransformOrigin = origin;
|
|
document.body.style.MozTransformOrigin = origin;
|
|
document.body.style.WebkitTransformOrigin = origin;
|
|
|
|
document.body.style.transform = transform;
|
|
document.body.style.OTransform = transform;
|
|
document.body.style.msTransform = transform;
|
|
document.body.style.MozTransform = transform;
|
|
document.body.style.WebkitTransform = transform;
|
|
}
|
|
}
|
|
else {
|
|
// Reset
|
|
if( scale === 1 ) {
|
|
document.body.style.position = '';
|
|
document.body.style.left = '';
|
|
document.body.style.top = '';
|
|
document.body.style.width = '';
|
|
document.body.style.height = '';
|
|
document.body.style.zoom = '';
|
|
}
|
|
// Scale
|
|
else {
|
|
document.body.style.position = 'relative';
|
|
document.body.style.left = ( - ( scrollOffset.x + rect.x ) / scale ) + 'px';
|
|
document.body.style.top = ( - ( scrollOffset.y + rect.y ) / scale ) + 'px';
|
|
document.body.style.width = ( scale * 100 ) + '%';
|
|
document.body.style.height = ( scale * 100 ) + '%';
|
|
document.body.style.zoom = scale;
|
|
}
|
|
}
|
|
|
|
level = scale;
|
|
|
|
if( document.documentElement.classList ) {
|
|
if( level !== 1 ) {
|
|
document.documentElement.classList.add( 'zoomed' );
|
|
}
|
|
else {
|
|
document.documentElement.classList.remove( 'zoomed' );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Pan the document when the mosue cursor approaches the edges
|
|
* of the window.
|
|
*/
|
|
function pan() {
|
|
var range = 0.12,
|
|
rangeX = window.innerWidth * range,
|
|
rangeY = window.innerHeight * range,
|
|
scrollOffset = getScrollOffset();
|
|
|
|
// Up
|
|
if( mouseY < rangeY ) {
|
|
window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
|
|
}
|
|
// Down
|
|
else if( mouseY > window.innerHeight - rangeY ) {
|
|
window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
|
|
}
|
|
|
|
// Left
|
|
if( mouseX < rangeX ) {
|
|
window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
|
|
}
|
|
// Right
|
|
else if( mouseX > window.innerWidth - rangeX ) {
|
|
window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
|
|
}
|
|
}
|
|
|
|
function getScrollOffset() {
|
|
return {
|
|
x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
|
|
y: window.scrollY !== undefined ? window.scrollY : window.pageYOffset
|
|
}
|
|
}
|
|
|
|
return {
|
|
/**
|
|
* Zooms in on either a rectangle or HTML element.
|
|
*
|
|
* @param {Object} options
|
|
* - element: HTML element to zoom in on
|
|
* OR
|
|
* - x/y: coordinates in non-transformed space to zoom in on
|
|
* - width/height: the portion of the screen to zoom in on
|
|
* - scale: can be used instead of width/height to explicitly set scale
|
|
*/
|
|
to: function( options ) {
|
|
|
|
// Due to an implementation limitation we can't zoom in
|
|
// to another element without zooming out first
|
|
if( level !== 1 ) {
|
|
zoom.out();
|
|
}
|
|
else {
|
|
options.x = options.x || 0;
|
|
options.y = options.y || 0;
|
|
|
|
// If an element is set, that takes precedence
|
|
if( !!options.element ) {
|
|
// Space around the zoomed in element to leave on screen
|
|
var padding = 20;
|
|
var bounds = options.element.getBoundingClientRect();
|
|
|
|
options.x = bounds.left - padding;
|
|
options.y = bounds.top - padding;
|
|
options.width = bounds.width + ( padding * 2 );
|
|
options.height = bounds.height + ( padding * 2 );
|
|
}
|
|
|
|
// If width/height values are set, calculate scale from those values
|
|
if( options.width !== undefined && options.height !== undefined ) {
|
|
options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
|
|
}
|
|
|
|
if( options.scale > 1 ) {
|
|
options.x *= options.scale;
|
|
options.y *= options.scale;
|
|
|
|
magnify( options, options.scale );
|
|
|
|
if( options.pan !== false ) {
|
|
|
|
// Wait with engaging panning as it may conflict with the
|
|
// zoom transition
|
|
panEngageTimeout = setTimeout( function() {
|
|
panUpdateInterval = setInterval( pan, 1000 / 60 );
|
|
}, 800 );
|
|
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Resets the document zoom state to its default.
|
|
*/
|
|
out: function() {
|
|
clearTimeout( panEngageTimeout );
|
|
clearInterval( panUpdateInterval );
|
|
|
|
magnify( { x: 0, y: 0 }, 1 );
|
|
|
|
level = 1;
|
|
},
|
|
|
|
// Alias
|
|
magnify: function( options ) { this.to( options ) },
|
|
reset: function() { this.out() },
|
|
|
|
zoomLevel: function() {
|
|
return level;
|
|
}
|
|
}
|
|
|
|
})();
|
|
|
|
|
|
|