Ignore rally_conf.json
[functest-xtesting.git] / docs / com / plugin / zoom-js / zoom.js
1 // Custom reveal.js integration
2 (function(){
3         var isEnabled = true;
4
5         document.querySelector( '.reveal .slides' ).addEventListener( 'mousedown', function( event ) {
6                 var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : 'alt' ) + 'Key';
7
8                 var zoomPadding = 20;
9                 var revealScale = Reveal.getScale();
10
11                 if( event[ modifier ] && isEnabled ) {
12                         event.preventDefault();
13
14                         var bounds = event.target.getBoundingClientRect();
15
16                         zoom.to({
17                                 x: ( bounds.left * revealScale ) - zoomPadding,
18                                 y: ( bounds.top * revealScale ) - zoomPadding,
19                                 width: ( bounds.width * revealScale ) + ( zoomPadding * 2 ),
20                                 height: ( bounds.height * revealScale ) + ( zoomPadding * 2 ),
21                                 pan: false
22                         });
23                 }
24         } );
25
26         Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } );
27         Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } );
28 })();
29
30 /*!
31  * zoom.js 0.3 (modified for use with reveal.js)
32  * http://lab.hakim.se/zoom-js
33  * MIT licensed
34  *
35  * Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
36  */
37 var zoom = (function(){
38
39         // The current zoom level (scale)
40         var level = 1;
41
42         // The current mouse position, used for panning
43         var mouseX = 0,
44                 mouseY = 0;
45
46         // Timeout before pan is activated
47         var panEngageTimeout = -1,
48                 panUpdateInterval = -1;
49
50         // Check for transform support so that we can fallback otherwise
51         var supportsTransforms =        'WebkitTransform' in document.body.style ||
52                                                                 'MozTransform' in document.body.style ||
53                                                                 'msTransform' in document.body.style ||
54                                                                 'OTransform' in document.body.style ||
55                                                                 'transform' in document.body.style;
56
57         if( supportsTransforms ) {
58                 // The easing that will be applied when we zoom in/out
59                 document.body.style.transition = 'transform 0.8s ease';
60                 document.body.style.OTransition = '-o-transform 0.8s ease';
61                 document.body.style.msTransition = '-ms-transform 0.8s ease';
62                 document.body.style.MozTransition = '-moz-transform 0.8s ease';
63                 document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
64         }
65
66         // Zoom out if the user hits escape
67         document.addEventListener( 'keyup', function( event ) {
68                 if( level !== 1 && event.keyCode === 27 ) {
69                         zoom.out();
70                 }
71         } );
72
73         // Monitor mouse movement for panning
74         document.addEventListener( 'mousemove', function( event ) {
75                 if( level !== 1 ) {
76                         mouseX = event.clientX;
77                         mouseY = event.clientY;
78                 }
79         } );
80
81         /**
82          * Applies the CSS required to zoom in, prefers the use of CSS3
83          * transforms but falls back on zoom for IE.
84          *
85          * @param {Object} rect
86          * @param {Number} scale
87          */
88         function magnify( rect, scale ) {
89
90                 var scrollOffset = getScrollOffset();
91
92                 // Ensure a width/height is set
93                 rect.width = rect.width || 1;
94                 rect.height = rect.height || 1;
95
96                 // Center the rect within the zoomed viewport
97                 rect.x -= ( window.innerWidth - ( rect.width * scale ) ) / 2;
98                 rect.y -= ( window.innerHeight - ( rect.height * scale ) ) / 2;
99
100                 if( supportsTransforms ) {
101                         // Reset
102                         if( scale === 1 ) {
103                                 document.body.style.transform = '';
104                                 document.body.style.OTransform = '';
105                                 document.body.style.msTransform = '';
106                                 document.body.style.MozTransform = '';
107                                 document.body.style.WebkitTransform = '';
108                         }
109                         // Scale
110                         else {
111                                 var origin = scrollOffset.x +'px '+ scrollOffset.y +'px',
112                                         transform = 'translate('+ -rect.x +'px,'+ -rect.y +'px) scale('+ scale +')';
113
114                                 document.body.style.transformOrigin = origin;
115                                 document.body.style.OTransformOrigin = origin;
116                                 document.body.style.msTransformOrigin = origin;
117                                 document.body.style.MozTransformOrigin = origin;
118                                 document.body.style.WebkitTransformOrigin = origin;
119
120                                 document.body.style.transform = transform;
121                                 document.body.style.OTransform = transform;
122                                 document.body.style.msTransform = transform;
123                                 document.body.style.MozTransform = transform;
124                                 document.body.style.WebkitTransform = transform;
125                         }
126                 }
127                 else {
128                         // Reset
129                         if( scale === 1 ) {
130                                 document.body.style.position = '';
131                                 document.body.style.left = '';
132                                 document.body.style.top = '';
133                                 document.body.style.width = '';
134                                 document.body.style.height = '';
135                                 document.body.style.zoom = '';
136                         }
137                         // Scale
138                         else {
139                                 document.body.style.position = 'relative';
140                                 document.body.style.left = ( - ( scrollOffset.x + rect.x ) / scale ) + 'px';
141                                 document.body.style.top = ( - ( scrollOffset.y + rect.y ) / scale ) + 'px';
142                                 document.body.style.width = ( scale * 100 ) + '%';
143                                 document.body.style.height = ( scale * 100 ) + '%';
144                                 document.body.style.zoom = scale;
145                         }
146                 }
147
148                 level = scale;
149
150                 if( document.documentElement.classList ) {
151                         if( level !== 1 ) {
152                                 document.documentElement.classList.add( 'zoomed' );
153                         }
154                         else {
155                                 document.documentElement.classList.remove( 'zoomed' );
156                         }
157                 }
158         }
159
160         /**
161          * Pan the document when the mosue cursor approaches the edges
162          * of the window.
163          */
164         function pan() {
165                 var range = 0.12,
166                         rangeX = window.innerWidth * range,
167                         rangeY = window.innerHeight * range,
168                         scrollOffset = getScrollOffset();
169
170                 // Up
171                 if( mouseY < rangeY ) {
172                         window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
173                 }
174                 // Down
175                 else if( mouseY > window.innerHeight - rangeY ) {
176                         window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
177                 }
178
179                 // Left
180                 if( mouseX < rangeX ) {
181                         window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
182                 }
183                 // Right
184                 else if( mouseX > window.innerWidth - rangeX ) {
185                         window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
186                 }
187         }
188
189         function getScrollOffset() {
190                 return {
191                         x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
192                         y: window.scrollY !== undefined ? window.scrollY : window.pageYOffset
193                 }
194         }
195
196         return {
197                 /**
198                  * Zooms in on either a rectangle or HTML element.
199                  *
200                  * @param {Object} options
201                  *   - element: HTML element to zoom in on
202                  *   OR
203                  *   - x/y: coordinates in non-transformed space to zoom in on
204                  *   - width/height: the portion of the screen to zoom in on
205                  *   - scale: can be used instead of width/height to explicitly set scale
206                  */
207                 to: function( options ) {
208
209                         // Due to an implementation limitation we can't zoom in
210                         // to another element without zooming out first
211                         if( level !== 1 ) {
212                                 zoom.out();
213                         }
214                         else {
215                                 options.x = options.x || 0;
216                                 options.y = options.y || 0;
217
218                                 // If an element is set, that takes precedence
219                                 if( !!options.element ) {
220                                         // Space around the zoomed in element to leave on screen
221                                         var padding = 20;
222                                         var bounds = options.element.getBoundingClientRect();
223
224                                         options.x = bounds.left - padding;
225                                         options.y = bounds.top - padding;
226                                         options.width = bounds.width + ( padding * 2 );
227                                         options.height = bounds.height + ( padding * 2 );
228                                 }
229
230                                 // If width/height values are set, calculate scale from those values
231                                 if( options.width !== undefined && options.height !== undefined ) {
232                                         options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
233                                 }
234
235                                 if( options.scale > 1 ) {
236                                         options.x *= options.scale;
237                                         options.y *= options.scale;
238
239                                         magnify( options, options.scale );
240
241                                         if( options.pan !== false ) {
242
243                                                 // Wait with engaging panning as it may conflict with the
244                                                 // zoom transition
245                                                 panEngageTimeout = setTimeout( function() {
246                                                         panUpdateInterval = setInterval( pan, 1000 / 60 );
247                                                 }, 800 );
248
249                                         }
250                                 }
251                         }
252                 },
253
254                 /**
255                  * Resets the document zoom state to its default.
256                  */
257                 out: function() {
258                         clearTimeout( panEngageTimeout );
259                         clearInterval( panUpdateInterval );
260
261                         magnify( { x: 0, y: 0 }, 1 );
262
263                         level = 1;
264                 },
265
266                 // Alias
267                 magnify: function( options ) { this.to( options ) },
268                 reset: function() { this.out() },
269
270                 zoomLevel: function() {
271                         return level;
272                 }
273         }
274
275 })();
276
277
278