/remote-apps-atlascamp-eu/js/impress.js

https://bitbucket.org/jkodumal/rmanalan.bitbucket.org · JavaScript · 324 lines · 222 code · 65 blank · 37 comment · 45 complexity · 774a78490ad893cca086687d44020ade MD5 · raw file

  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. (function ( document, window ) {
  12. // HELPER FUNCTIONS
  13. var pfx = (function () {
  14. var style = document.createElement('dummy').style,
  15. prefixes = 'Webkit Moz O ms Khtml'.split(' '),
  16. memory = {};
  17. return function ( prop ) {
  18. if ( typeof memory[ prop ] === "undefined" ) {
  19. var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1),
  20. props = (prop + ' ' + prefixes.join(ucProp + ' ') + ucProp).split(' ');
  21. memory[ prop ] = null;
  22. for ( var i in props ) {
  23. if ( style[ props[i] ] !== undefined ) {
  24. memory[ prop ] = props[i];
  25. break;
  26. }
  27. }
  28. }
  29. return memory[ prop ];
  30. }
  31. })();
  32. var arrayify = function ( a ) {
  33. return [].slice.call( a );
  34. };
  35. var css = function ( el, props ) {
  36. var key, pkey;
  37. for ( key in props ) {
  38. if ( props.hasOwnProperty(key) ) {
  39. pkey = pfx(key);
  40. if ( pkey != null ) {
  41. el.style[pkey] = props[key];
  42. }
  43. }
  44. }
  45. return el;
  46. }
  47. var byId = function ( id ) {
  48. return document.getElementById(id);
  49. }
  50. var $ = function ( selector, context ) {
  51. context = context || document;
  52. return context.querySelector(selector);
  53. };
  54. var $$ = function ( selector, context ) {
  55. context = context || document;
  56. return arrayify( context.querySelectorAll(selector) );
  57. };
  58. var translate = function ( t ) {
  59. return " translate3d(" + t.x + "px," + t.y + "px," + t.z + "px) ";
  60. };
  61. var rotate = function ( r, revert ) {
  62. var rX = " rotateX(" + r.x + "deg) ",
  63. rY = " rotateY(" + r.y + "deg) ",
  64. rZ = " rotateZ(" + r.z + "deg) ";
  65. return revert ? rZ+rY+rX : rX+rY+rZ;
  66. };
  67. var scale = function ( s ) {
  68. return " scaleX(" + s.x + ") scaleY(" + s.y + ") scaleZ(" + s.z + ") ";
  69. }
  70. // CHECK SUPPORT
  71. var ua = navigator.userAgent.toLowerCase();
  72. var impressSupported = ( pfx("perspective") != null ) &&
  73. ( ua.search(/(iphone)|(ipod)|(ipad)|(android)/) == -1 );
  74. // DOM ELEMENTS
  75. var impress = byId("impress");
  76. if (!impressSupported) {
  77. impress.className = "impress-not-supported";
  78. return;
  79. } else {
  80. impress.className = "";
  81. }
  82. var canvas = document.createElement("div");
  83. canvas.className = "canvas";
  84. arrayify( impress.childNodes ).forEach(function ( el ) {
  85. canvas.appendChild( el );
  86. });
  87. impress.appendChild(canvas);
  88. var steps = $$(".step", impress);
  89. // SETUP
  90. // set initial values and defaults
  91. document.documentElement.style.height = "100%";
  92. css(document.body, {
  93. height: "100%",
  94. overflow: "hidden"
  95. });
  96. var props = {
  97. position: "absolute",
  98. transformOrigin: "top left",
  99. transition: "all 1s ease-in-out",
  100. transformStyle: "preserve-3d"
  101. }
  102. css(impress, props);
  103. css(impress, {
  104. top: "50%",
  105. left: "50%",
  106. perspective: "1000px"
  107. });
  108. css(canvas, props);
  109. var current = {
  110. translate: { x: 0, y: 0, z: 0 },
  111. rotate: { x: 0, y: 0, z: 0 },
  112. scale: { x: 1, y: 1, z: 1 }
  113. };
  114. steps.forEach(function ( el, idx ) {
  115. var data = el.dataset,
  116. step = {
  117. translate: {
  118. x: data.x || 0,
  119. y: data.y || 0,
  120. z: data.z || 0
  121. },
  122. rotate: {
  123. x: data.rotateX || 0,
  124. y: data.rotateY || 0,
  125. z: data.rotateZ || data.rotate || 0
  126. },
  127. scale: {
  128. x: data.scaleX || data.scale || 1,
  129. y: data.scaleY || data.scale || 1,
  130. z: data.scaleZ || 1
  131. }
  132. };
  133. el.stepData = step;
  134. if ( !el.id ) {
  135. el.id = "step-" + (idx + 1);
  136. }
  137. css(el, {
  138. position: "absolute",
  139. transform: "translate(-50%,-50%)" +
  140. translate(step.translate) +
  141. rotate(step.rotate) +
  142. scale(step.scale),
  143. transformStyle: "preserve-3d"
  144. });
  145. });
  146. // making given step active
  147. var active = null;
  148. var select = function ( el ) {
  149. if ( !el || !el.stepData ) {
  150. // selected element is not defined as step
  151. return false;
  152. }
  153. // Sometimes it's possible to trigger focus on first link with some keyboard action.
  154. // Browser in such a case tries to scroll the page to make this element visible
  155. // (even that body overflow is set to hidden) and it breaks our careful positioning.
  156. //
  157. // So, as a lousy (and lazy) workaround we will make the page scroll back to the top
  158. // whenever slide is selected
  159. //
  160. // If you are reading this and know any better way to handle it, I'll be glad to hear about it!
  161. window.scrollTo(0, 0);
  162. var step = el.stepData;
  163. if ( active ) {
  164. active.classList.remove("active");
  165. }
  166. el.classList.add("active");
  167. impress.className = "step-" + el.id;
  168. // `#/step-id` is used instead of `#step-id` to prevent default browser
  169. // scrolling to element in hash
  170. window.location.hash = "#/" + el.id;
  171. var target = {
  172. rotate: {
  173. x: -parseInt(step.rotate.x, 10),
  174. y: -parseInt(step.rotate.y, 10),
  175. z: -parseInt(step.rotate.z, 10)
  176. },
  177. scale: {
  178. x: 1 / parseFloat(step.scale.x),
  179. y: 1 / parseFloat(step.scale.y),
  180. z: 1 / parseFloat(step.scale.z)
  181. },
  182. translate: {
  183. x: -step.translate.x,
  184. y: -step.translate.y,
  185. z: -step.translate.z
  186. }
  187. };
  188. var zoomin = target.scale.x >= current.scale.x;
  189. css(impress, {
  190. // to keep the perspective look similar for different scales
  191. // we need to 'scale' the perspective, too
  192. perspective: step.scale.x * 1000 + "px",
  193. transform: scale(target.scale),
  194. transitionDelay: (zoomin ? "500ms" : "0ms")
  195. });
  196. css(canvas, {
  197. transform: rotate(target.rotate, true) + translate(target.translate),
  198. transitionDelay: (zoomin ? "0ms" : "500ms")
  199. });
  200. current = target;
  201. active = el;
  202. return el;
  203. }
  204. // EVENTS
  205. document.addEventListener("keydown", function ( event ) {
  206. if ( event.keyCode == 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
  207. var next = active;
  208. switch( event.keyCode ) {
  209. case 33: ; // pg up
  210. case 37: ; // left
  211. case 38: // up
  212. next = steps.indexOf( active ) - 1;
  213. next = next >= 0 ? steps[ next ] : steps[ steps.length-1 ];
  214. break;
  215. case 9: ; // tab
  216. case 32: ; // space
  217. case 34: ; // pg down
  218. case 39: ; // right
  219. case 40: // down
  220. next = steps.indexOf( active ) + 1;
  221. next = next < steps.length ? steps[ next ] : steps[ 0 ];
  222. break;
  223. }
  224. select(next);
  225. event.preventDefault();
  226. }
  227. }, false);
  228. document.addEventListener("click", function ( event ) {
  229. // event delegation with "bubbling"
  230. // check if event target (or any of its parents is a link or a step)
  231. var target = event.target;
  232. while ( (target.tagName != "A") &&
  233. (!target.stepData) &&
  234. (target != document.body) ) {
  235. target = target.parentNode;
  236. }
  237. if ( target.tagName == "A" ) {
  238. var href = target.getAttribute("href");
  239. // if it's a link to presentation step, target this step
  240. if ( href && href[0] == '#' ) {
  241. target = byId( href.slice(1) );
  242. }
  243. }
  244. if ( select(target) ) {
  245. event.preventDefault();
  246. }
  247. });
  248. var getElementFromUrl = function () {
  249. // get id from url # by removing `#` or `#/` from the beginning,
  250. // so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work
  251. return byId( window.location.hash.replace(/^#\/?/,"") );
  252. }
  253. window.addEventListener("hashchange", function () {
  254. select( getElementFromUrl() );
  255. }, false);
  256. // START
  257. // by selecting step defined in url or first step of the presentation
  258. select(getElementFromUrl() || steps[0]);
  259. })(document, window);