Skip to content

Commit 680e17e

Browse files
committed
initial commit
0 parents  commit 680e17e

File tree

3 files changed

+782
-0
lines changed

3 files changed

+782
-0
lines changed
+339
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
/**
2+
* impress.js
3+
*
4+
* impress.js is a presentation tool based on the power of CSS3 transforms and transitions
5+
* in modern browsers and inspired by the idea behind prezi.com.
6+
*
7+
* MIT Licensed.
8+
*
9+
* Copyright 2011 Bartek Szopka (@bartaz)
10+
*/
11+
12+
(function ( document, window ) {
13+
14+
// HELPER FUNCTIONS
15+
16+
var pfx = (function () {
17+
18+
var style = document.createElement('dummy').style,
19+
prefixes = 'Webkit Moz O ms Khtml'.split(' '),
20+
memory = {};
21+
22+
return function ( prop ) {
23+
if ( typeof memory[ prop ] === "undefined" ) {
24+
25+
var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1),
26+
props = (prop + ' ' + prefixes.join(ucProp + ' ') + ucProp).split(' ');
27+
28+
memory[ prop ] = null;
29+
for ( var i in props ) {
30+
if ( style[ props[i] ] !== undefined ) {
31+
memory[ prop ] = props[i];
32+
break;
33+
}
34+
}
35+
36+
}
37+
38+
return memory[ prop ];
39+
}
40+
41+
})();
42+
43+
var arrayify = function ( a ) {
44+
return [].slice.call( a );
45+
};
46+
47+
var css = function ( el, props ) {
48+
var key, pkey;
49+
for ( key in props ) {
50+
if ( props.hasOwnProperty(key) ) {
51+
pkey = pfx(key);
52+
if ( pkey != null ) {
53+
el.style[pkey] = props[key];
54+
}
55+
}
56+
}
57+
return el;
58+
}
59+
60+
var byId = function ( id ) {
61+
return document.getElementById(id);
62+
}
63+
64+
var $ = function ( selector, context ) {
65+
context = context || document;
66+
return context.querySelector(selector);
67+
};
68+
69+
var $$ = function ( selector, context ) {
70+
context = context || document;
71+
return arrayify( context.querySelectorAll(selector) );
72+
};
73+
74+
var translate = function ( t ) {
75+
return " translate3d(" + t.x + "px," + t.y + "px," + t.z + "px) ";
76+
};
77+
78+
var rotate = function ( r, revert ) {
79+
var rX = " rotateX(" + r.x + "deg) ",
80+
rY = " rotateY(" + r.y + "deg) ",
81+
rZ = " rotateZ(" + r.z + "deg) ";
82+
83+
return revert ? rZ+rY+rX : rX+rY+rZ;
84+
};
85+
86+
var scale = function ( s ) {
87+
return " scale(" + s + ") ";
88+
}
89+
90+
// CHECK SUPPORT
91+
92+
var ua = navigator.userAgent.toLowerCase();
93+
var impressSupported = ( pfx("perspective") != null ) &&
94+
( ua.search(/(iphone)|(ipod)|(ipad)|(android)/) == -1 );
95+
96+
// DOM ELEMENTS
97+
98+
var impress = byId("impress");
99+
100+
if (!impressSupported) {
101+
impress.className = "impress-not-supported";
102+
return;
103+
} else {
104+
impress.className = "";
105+
}
106+
107+
var canvas = document.createElement("div");
108+
canvas.className = "canvas";
109+
110+
arrayify( impress.childNodes ).forEach(function ( el ) {
111+
canvas.appendChild( el );
112+
});
113+
impress.appendChild(canvas);
114+
115+
var steps = $$(".step", impress);
116+
117+
// SETUP
118+
// set initial values and defaults
119+
120+
document.documentElement.style.height = "100%";
121+
122+
css(document.body, {
123+
height: "100%",
124+
overflow: "hidden"
125+
});
126+
127+
var props = {
128+
position: "absolute",
129+
transformOrigin: "top left",
130+
transition: "all 0s ease-in-out",
131+
transformStyle: "preserve-3d"
132+
}
133+
134+
css(impress, props);
135+
css(impress, {
136+
top: "50%",
137+
left: "50%",
138+
perspective: "1000px"
139+
});
140+
css(canvas, props);
141+
142+
var current = {
143+
translate: { x: 0, y: 0, z: 0 },
144+
rotate: { x: 0, y: 0, z: 0 },
145+
scale: 1
146+
};
147+
148+
steps.forEach(function ( el, idx ) {
149+
var data = el.dataset,
150+
step = {
151+
translate: {
152+
x: data.x || 0,
153+
y: data.y || 0,
154+
z: data.z || 0
155+
},
156+
rotate: {
157+
x: data.rotateX || 0,
158+
y: data.rotateY || 0,
159+
z: data.rotateZ || data.rotate || 0
160+
},
161+
scale: data.scale || 1
162+
};
163+
164+
el.stepData = step;
165+
166+
if ( !el.id ) {
167+
el.id = "step-" + (idx + 1);
168+
}
169+
170+
css(el, {
171+
position: "absolute",
172+
transform: "translate(-50%,-50%)" +
173+
translate(step.translate) +
174+
rotate(step.rotate) +
175+
scale(step.scale),
176+
transformStyle: "preserve-3d"
177+
});
178+
179+
});
180+
181+
// making given step active
182+
183+
var active = null;
184+
var hashTimeout = null;
185+
186+
var select = function ( el ) {
187+
if ( !el || !el.stepData || el == active) {
188+
// selected element is not defined as step or is already active
189+
return false;
190+
}
191+
192+
// Sometimes it's possible to trigger focus on first link with some keyboard action.
193+
// Browser in such a case tries to scroll the page to make this element visible
194+
// (even that body overflow is set to hidden) and it breaks our careful positioning.
195+
//
196+
// So, as a lousy (and lazy) workaround we will make the page scroll back to the top
197+
// whenever slide is selected
198+
//
199+
// If you are reading this and know any better way to handle it, I'll be glad to hear about it!
200+
window.scrollTo(0, 0);
201+
202+
var step = el.stepData;
203+
204+
if ( active ) {
205+
active.classList.remove("active");
206+
}
207+
el.classList.add("active");
208+
209+
impress.className = "step-" + el.id;
210+
211+
// `#/step-id` is used instead of `#step-id` to prevent default browser
212+
// scrolling to element in hash
213+
//
214+
// and it has to be set after animation finishes, because in chrome it
215+
// causes transtion being laggy
216+
window.clearTimeout( hashTimeout );
217+
hashTimeout = window.setTimeout(function () {
218+
window.location.hash = "#/" + el.id;
219+
}, 1000);
220+
221+
var target = {
222+
rotate: {
223+
x: -parseInt(step.rotate.x, 10),
224+
y: -parseInt(step.rotate.y, 10),
225+
z: -parseInt(step.rotate.z, 10)
226+
},
227+
translate: {
228+
x: -step.translate.x,
229+
y: -step.translate.y,
230+
z: -step.translate.z
231+
},
232+
scale: 1 / parseFloat(step.scale)
233+
};
234+
235+
// check if the transition is zooming in or not
236+
var zoomin = target.scale >= current.scale;
237+
238+
// if presentation starts (nothing is active yet)
239+
// don't animate (set duration to 0)
240+
var duration = (active) ? "1s" : "0";
241+
242+
css(impress, {
243+
// to keep the perspective look similar for different scales
244+
// we need to 'scale' the perspective, too
245+
perspective: step.scale * 1000 + "px",
246+
transform: scale(target.scale),
247+
transitionDuration: duration,
248+
transitionDelay: (zoomin ? "500ms" : "0ms")
249+
});
250+
251+
css(canvas, {
252+
transform: rotate(target.rotate, true) + translate(target.translate),
253+
transitionDuration: duration,
254+
transitionDelay: (zoomin ? "0ms" : "500ms")
255+
});
256+
257+
current = target;
258+
active = el;
259+
260+
return el;
261+
};
262+
263+
var selectPrev = function () {
264+
var prev = steps.indexOf( active ) - 1;
265+
prev = prev >= 0 ? steps[ prev ] : steps[ steps.length-1 ];
266+
267+
return select(prev);
268+
};
269+
270+
var selectNext = function () {
271+
var next = steps.indexOf( active ) + 1;
272+
next = next < steps.length ? steps[ next ] : steps[ 0 ];
273+
274+
return select(next);
275+
};
276+
277+
// EVENTS
278+
279+
document.addEventListener("keydown", function ( event ) {
280+
if ( event.keyCode == 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
281+
switch( event.keyCode ) {
282+
case 33: ; // pg up
283+
case 37: ; // left
284+
case 38: // up
285+
selectPrev();
286+
break;
287+
case 9: ; // tab
288+
case 32: ; // space
289+
case 34: ; // pg down
290+
case 39: ; // right
291+
case 40: // down
292+
selectNext();
293+
break;
294+
}
295+
296+
event.preventDefault();
297+
}
298+
}, false);
299+
300+
document.addEventListener("click", function ( event ) {
301+
// event delegation with "bubbling"
302+
// check if event target (or any of its parents is a link or a step)
303+
var target = event.target;
304+
while ( (target.tagName != "A") &&
305+
(!target.stepData) &&
306+
(target != document.body) ) {
307+
target = target.parentNode;
308+
}
309+
310+
if ( target.tagName == "A" ) {
311+
var href = target.getAttribute("href");
312+
313+
// if it's a link to presentation step, target this step
314+
if ( href && href[0] == '#' ) {
315+
target = byId( href.slice(1) );
316+
}
317+
}
318+
319+
if ( select(target) ) {
320+
event.preventDefault();
321+
}
322+
}, false);
323+
324+
var getElementFromUrl = function () {
325+
// get id from url # by removing `#` or `#/` from the beginning,
326+
// so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work
327+
return byId( window.location.hash.replace(/^#\/?/,"") );
328+
}
329+
330+
window.addEventListener("hashchange", function () {
331+
select( getElementFromUrl() );
332+
}, false);
333+
334+
// START
335+
// by selecting step defined in url or first step of the presentation
336+
select(getElementFromUrl() || steps[0]);
337+
338+
})(document, window);
339+

0 commit comments

Comments
 (0)