jee.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  1. /*
  2. _ _
  3. |_|___ _ _ ___ ___ ___ ___| |_ ___ ___ ___ ___ ___ ___ ___
  4. | | -_| | | | -_|_ -| | -_| _| | -_| | . | .'| . | -_|_ -|
  5. _| |___|___|_|_|___|___| |___|_| |___|_|_|_ |__,|_ |___|___|
  6. |___| |___| |___|
  7. Bachir Soussi Chiadmi
  8. 2015
  9. */
  10. jQuery(document).ready(function($) {
  11. console.log('Hello Jee');
  12. var _debug = true,
  13. _avgDelay = 1,
  14. _lastDraw = new Date,
  15. _fps,
  16. _$nav_cursor;
  17. var _$body = $('body'),
  18. _$header = $("#header"),
  19. _$chapitres = $('.node-chapitre', '#main'),
  20. _chapitres_len = _$chapitres.length,
  21. _chapters = [],
  22. _$container = $('#main'),
  23. _container = {
  24. w:_$container.width(),
  25. h:_$container.height()
  26. },
  27. _center = {x:_container.w/2,y:_container.h/2},
  28. _nav_pos = {x:0, y:0},
  29. _mouse_down_pos = {x:0,y:0},
  30. _prev_mouse_pos = {x:0,y:0},
  31. _fps = 1000/12,
  32. _dragging = false, _timeout_dragging;
  33. var _$chapter_wrapper = $('<div>').attr('id', 'chapter-wrapper').appendTo(_$container),
  34. _loaded_chapter = false;
  35. var _bubbles = new Array(),
  36. _stars = new Array();
  37. function init(){
  38. if(_debug)
  39. initDebug();
  40. initChapters();
  41. launchNav();
  42. // FULL SCREEN
  43. var $fullscreenBtn = $('<div>enter</div>').attr('id','fullscreen-btn').appendTo("#root");
  44. $fullscreenBtn.on('click', onFullScreen);
  45. // create bubbles
  46. for (var i = 2; i > 0; i--) {
  47. _bubbles.push($('<div>').addClass('bubble bubble-'+i).prependTo(_$container));
  48. };
  49. // create stars
  50. for (var i = 20; i > 0; i--) {
  51. _stars.push(
  52. $('<div>')
  53. .addClass('star star-'+i)
  54. .css({
  55. left:randB(-400, _container.w+400),
  56. top:randB(-400, _container.h+400)
  57. })
  58. .prependTo(_$container)
  59. );
  60. };
  61. };
  62. function initDebug(){
  63. $('<p>').attr('id', 'fps').appendTo(_$container);
  64. _fps = document.getElementById('fps');
  65. requestAnimationFrame(displayFps);
  66. _$nav_cursor = $('<div id="nav-cursor"></div>').appendTo(_$container);
  67. moveDebugCursor();
  68. };
  69. function displayFps(){
  70. requestAnimationFrame(displayFps);
  71. var now = new Date;
  72. var delay = now - _lastDraw;
  73. _avgDelay += (delay - _avgDelay) / 10;
  74. _lastDraw = now;
  75. _fps.innerHTML = (1000/_avgDelay).toFixed(1) + " fps";
  76. };
  77. function moveDebugCursor(){
  78. _$nav_cursor.css({
  79. left:_nav_pos.x+_center.x+"px",
  80. top:_nav_pos.y+_center.y+"px"
  81. });
  82. };
  83. function initChapters(){
  84. // Place each chapters on the ellipse contained on the screen
  85. var base_a = Math.random() *360;
  86. _$chapitres.each(function(i, e) {
  87. // Lets create the chapter object and place him self
  88. _chapters.push(new Chapter(i, e, base_a));
  89. });
  90. };
  91. function launchNav(){
  92. $(document)
  93. /*
  94. ____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
  95. | \| __| __| | |_ _| | _ | | __| | | __| | |_ _| __|
  96. | | | __|__ | -| | | | | | __| | __| | | __| | | | | | |__ |
  97. |____/|_____|_____|__|__| |_| |_____|__| |_____|\___/|_____|_|___| |_| |_____|
  98. */
  99. .bind('mousedown', function(e){
  100. console.log('document mousedown');
  101. clearTimeout(_timeout_dragging);
  102. if(_loaded_chapter)
  103. return false;
  104. // set initial cursor pos
  105. _mouse_down_pos.x = e.clientX;
  106. _mouse_down_pos.y = e.clientY;
  107. updateNavPos(e.clientX, e.clientY, true);
  108. $(this).bind('mousemove', function(e){
  109. console.log('document mousemove');
  110. updateNavPos(e.clientX, e.clientY, false);
  111. });
  112. // activate dragging if already activated
  113. if(!_dragging){
  114. _dragging = true;
  115. startMoveNav();
  116. }
  117. })
  118. .bind('mouseup', function(e){
  119. console.log('document mouseup');
  120. if(_loaded_chapter)
  121. return false;
  122. stopMoveNav();
  123. $(this).unbind('mousemove');
  124. // close all preview
  125. if(Math.abs(e.clientX - _mouse_down_pos.x) < 2
  126. && Math.abs(e.clientY - _mouse_down_pos.y) < 2)
  127. for (var i = _chapitres_len - 1; i >= 0; i--)
  128. _chapters[i].closePreview().unMitigate();
  129. })
  130. /*
  131. _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
  132. |_ _| | | | | | | | __| | | __| | |_ _| __|
  133. | | | | | | | --| | | __| | | __| | | | | | |__ |
  134. |_| |_____|_____|_____|__|__| |_____|\___/|_____|_|___| |_| |_____|
  135. */
  136. .bind('document touchstart', function(e){
  137. console.log('touchstart');
  138. clearTimeout(_timeout_dragging);
  139. // set initial pos
  140. updateNavPos(e.originalEvent.touches[0].clientX, e.originalEvent.touches[0].clientY, true);
  141. // activate dragging if already activated
  142. if(!_dragging){
  143. _dragging = true;
  144. startMoveNav();
  145. }
  146. })
  147. .bind('touchmove', function(e){
  148. console.log('document touchmove');
  149. updateNavPos(e.originalEvent.touches[0].clientX, e.originalEvent.touches[0].clientY, false);
  150. })
  151. .bind('touchend', function(e){
  152. console.log("document touchend");
  153. stopMoveNav();
  154. });
  155. };
  156. function updateNavPos(x,y,init){
  157. if(!init){
  158. _nav_pos.x += x - _prev_mouse_pos.x;
  159. _nav_pos.y += y - _prev_mouse_pos.y;
  160. // constrain nav pos on container
  161. _nav_pos.x = _nav_pos.x < -_center.x*2
  162. ? -_center.x*2
  163. : _nav_pos.x > _center.x*2
  164. ? _center.x*2
  165. : _nav_pos.x;
  166. _nav_pos.y = _nav_pos.y < -_center.y*2
  167. ? -_center.y*2
  168. : _nav_pos.y > _center.y*2
  169. ? _center.y*2
  170. : _nav_pos.y;
  171. }
  172. _prev_mouse_pos.x = x;
  173. _prev_mouse_pos.y = y;
  174. // debuging cursor
  175. if(_debug)
  176. moveDebugCursor();
  177. };
  178. function startMoveNav(){
  179. window.requestAnimationFrame(moveNav);
  180. };
  181. function moveNav(){
  182. // console.log("moveNav");
  183. if(!_dragging) return;
  184. window.requestAnimationFrame(moveNav);
  185. // move chapters
  186. for (var i = _chapitres_len - 1; i >= 0; i--)
  187. _chapters[i].move();
  188. // move header
  189. _$header.css({
  190. transform:"translate3d("+(_nav_pos.x)*0.2+"px, "+(_nav_pos.y)*0.2+"px,0)"
  191. });
  192. // bubbles and stars dont move so smoothly on tablette ...
  193. // should keep it only on desktop
  194. // move bubbles
  195. // for (var i = _bubbles.length - 1; i >= 0; i--) {
  196. // _bubbles[i].css({
  197. // transform:"translate3d("+(_nav_pos.x)*0.4+"px, "+(_nav_pos.y)*0.4+"px,0)"
  198. // });
  199. // };
  200. // move stars
  201. // for (var i = _stars.length - 1; i >= 0; i--) {
  202. // _stars[i].css({
  203. // transform:"translate3d("+(_nav_pos.x)*-0.3+"px, "+(_nav_pos.y)*-0.3+"px,0)"
  204. // });
  205. // };
  206. };
  207. function stopMoveNav(){
  208. console.log('stopMoveNav');
  209. clearTimeout(_timeout_dragging);
  210. _timeout_dragging = setTimeout(function(){
  211. console.log("dragging stoped");
  212. _dragging = false;
  213. },3000);
  214. };
  215. function moveToChapter(chapter){
  216. // fake a mousdown by providing first pos as current pos
  217. _prev_mouse_pos.x = _nav_pos.x;
  218. _prev_mouse_pos.y = _nav_pos.y;
  219. // calculate the second pos of faked mousemove
  220. var xl = _center.x - chapter.pos.x - chapter.geom.w/2;
  221. var yl = 100 - chapter.pos.y;
  222. updateNavPos(xl, yl, false);
  223. startMoveNav();
  224. stopMoveNav();
  225. };
  226. function onFullScreen(e){
  227. launchIntoFullscreen(document.getElementById("root"));
  228. if(_loaded_chapter)
  229. setTimeout(_loaded_chapter.buildVideos(), 100);
  230. };
  231. /*
  232. ________ __
  233. / ____/ /_ ____ _____ / /____ _____
  234. / / / __ \/ __ `/ __ \/ __/ _ \/ ___/
  235. / /___/ / / / /_/ / /_/ / /_/ __/ /
  236. \____/_/ /_/\__,_/ .___/\__/\___/_/
  237. /_/
  238. */
  239. function Chapter(i, e, base_a){
  240. // $e.obj = this;
  241. this.i = i;
  242. this.e = e;
  243. this.$e = $(e);
  244. this.nid = this.$e.attr("id").match(/^node-(\d+)/)[1];
  245. this.geom = {
  246. base_a:base_a,
  247. a:0,
  248. r:0,
  249. w:this.$e.outerWidth(true),
  250. h:this.$e.outerHeight(true)
  251. }
  252. this.pos = {x:0,y:0};
  253. this.trans = {x:0, y:0,z:0};
  254. this.ease = randB(0.05, 0.3);
  255. //preview
  256. this.is_previewed = false;
  257. //mitigate
  258. this.is_mitigated = false;
  259. //parties
  260. this.$parties = $('.field-name-field-partie', e);
  261. this.parts_pos = {xs:new Array(), ys:new Array()};
  262. this.lines = new Array();
  263. this.linesAnimeStartTime = 0,
  264. this.linesAnimeDuration = 2000; // milli sec
  265. // chapter
  266. this.$n = false;
  267. this.$blocks = false;
  268. this.$vids = false;
  269. this.texts_pos = shuffleArray([1,2,3]);
  270. this.dimvideo = {w:0, h:0};
  271. // prototypes
  272. if (typeof Chapter.initialized == "undefined") {
  273. Chapter.prototype.init = function(){
  274. this.setInitPos();
  275. this.drawLines();
  276. this.setEvents();
  277. };
  278. Chapter.prototype.setInitPos = function(){
  279. // distribute elements arround the center
  280. this.geom.a = (360/_chapitres_len*this.i+this.geom.base_a)*Math.PI/180;
  281. // console.log("Chapter :: setInitPos", this.$e);
  282. this.geom.c = Math.cos(this.geom.a);
  283. this.geom.s = Math.sin(this.geom.a);
  284. this.geom.abs_c = Math.abs(this.geom.c);
  285. this.geom.abs_s = Math.abs(this.geom.s);
  286. if (this.geom.abs_c * _container.h > this.geom.abs_s * _container.w) {
  287. // It crosses left or right side
  288. this.geom.r = (_center.x / this.geom.abs_c)*0.5;
  289. }else {
  290. // Top or bottom side
  291. this.geom.r = (_center.y / this.geom.abs_s)*0.5;
  292. }
  293. // change randomly radius
  294. if(this.i%2){
  295. this.geom.r = randB(this.geom.r*2, this.geom.r*3);
  296. }else{
  297. this.geom.r = randB(this.geom.r, this.geom.r*2);
  298. }
  299. this.pos.x = Math.round(_center.x+this.geom.r * this.geom.c) - this.geom.w/2;
  300. this.pos.y = Math.round(_center.y+this.geom.r * -this.geom.s) - this.geom.h/2;
  301. console.log('this', this);
  302. this.$e.css({
  303. left:this.pos.x,
  304. top:this.pos.y
  305. });
  306. };// setIniPos()
  307. Chapter.prototype.setEvents = function(){
  308. //http://technify.me/user-experience/javascript/jquery/trigger-custom-events-with-jquery/
  309. // click to preview chapter
  310. $('h2.node-title, .field-name-field-partie:first>.field-name-field-vignette', this.$e)
  311. .on('click', this, function(e){
  312. // e.stopImmediatePropagation();
  313. e.stopPropagation();
  314. e.preventDefault();
  315. e.data.preview(e);
  316. return false;
  317. });
  318. $('.links a', this.$e)
  319. .on('click', this, function(e){
  320. e.stopPropagation();
  321. e.preventDefault();
  322. e.data.loadNode();
  323. return false;
  324. });
  325. };
  326. Chapter.prototype.move = function(){
  327. this.trans.x += (_nav_pos.x - this.trans.x)*this.ease;
  328. this.trans.y += (_nav_pos.y - this.trans.y)*this.ease;
  329. // this.trans.z = Math.floor(Math.sqrt(
  330. // Math.pow(
  331. // _center.x-(this.pos.x+this.trans.x)
  332. // ,2
  333. // )
  334. // +
  335. // Math.pow(
  336. // _center.y-(this.pos.y+this.trans.y)
  337. // ,2
  338. // )
  339. // ));
  340. // if(this.i === 0)
  341. // console.log(this.i+" this.trans.z", this.trans.z);
  342. this.$e.css({
  343. transform:'translate3d('+this.trans.x+'px,'+this.trans.y+'px,0)'
  344. // scale:this.trans.z
  345. });
  346. };
  347. Chapter.prototype.preview = function(){
  348. // don't relaunch preview more that one time
  349. if(this.is_previewed) return;
  350. console.log('preview', this.i);
  351. this.unMitigate();
  352. this.is_previewed = true;
  353. // close other chapters
  354. for (var i = _chapitres_len - 1; i >= 0; i--)
  355. if(i !== this.i)
  356. _chapters[i].closePreview().mitigate();
  357. this.displayPreview();
  358. moveToChapter(this);
  359. };
  360. Chapter.prototype.displayPreview = function(e){
  361. // define randomly position of parties
  362. this.resetPartsPos();
  363. // apply new position to parties
  364. var that = this;
  365. this.$parties.each(function(i, e) {
  366. setTimeout(
  367. (function(i, e, xs, ys){
  368. return function(){
  369. $(e)
  370. .css({
  371. transform:"translate3d("+xs[i]+"px,"+ys[i]+"px,0)",
  372. });
  373. }
  374. }(i, e, that.parts_pos.xs, that.parts_pos.ys)),
  375. 10);
  376. }); // each $parties
  377. this.$e.addClass('previewed');
  378. requestAnimationFrame(this.animeLines.bind(this));
  379. };
  380. Chapter.prototype.resetPartsPos = function(){
  381. this.parts_pos = {xs:new Array(), ys:new Array()};
  382. for (var i = 0; i < 3; i++) {
  383. switch(i){
  384. case 0:
  385. this.parts_pos.xs.push(randB(-30,30)); this.parts_pos.ys.push(randB(90,110)); break;
  386. case 1:
  387. this.parts_pos.xs.push(randB(180,280)); this.parts_pos.ys.push(randB(250,350)); break;
  388. case 2:
  389. this.parts_pos.xs.push(randB(-280,-180)); this.parts_pos.ys.push(randB(430,530)); break;
  390. }
  391. };
  392. this.parts_pos.xs = shuffleArray(this.parts_pos.xs);
  393. this.parts_pos.ys = shuffleArray(this.parts_pos.ys);
  394. };
  395. Chapter.prototype.closePreview = function(){
  396. if(!this.is_previewed) return this;
  397. this.$e.removeClass('previewed')
  398. .find('.field-name-field-partie')
  399. .css({transform:"none"});
  400. requestAnimationFrame(this.animeLines.bind(this));
  401. this.is_previewed = false;
  402. return this;
  403. };
  404. Chapter.prototype.mitigate = function(){
  405. if(this.is_mitigated) return this;
  406. this.$e.addClass('mitigated');
  407. return this;
  408. };
  409. Chapter.prototype.unMitigate = function(){
  410. if(this.is_mitigated) return this;
  411. this.$e.removeClass('mitigated');
  412. return this;
  413. };
  414. Chapter.prototype.drawLines = function(){
  415. for (var i = 0; i < 2; i++) {
  416. this.lines.push({
  417. $line:$("<div>").addClass('line', 'line-'+i).prependTo(this.$parties[i])
  418. });
  419. };
  420. };
  421. Chapter.prototype.animeLines = function(timestamp){
  422. // console.log("anime line "+this.nid);
  423. // get the time on first anime launch
  424. if(this.linesAnimeStartTime === 0)
  425. this.linesAnimeStartTime = timestamp;
  426. // limit the animation time
  427. if(timestamp - this.linesAnimeStartTime < this.linesAnimeDuration){
  428. requestAnimationFrame(this.animeLines.bind(this));
  429. }else{
  430. this.linesAnimeStartTime = 0;
  431. }
  432. // get the lines length
  433. var l, a, pos1, pos2;
  434. for (var i = 0; i < this.lines.length; i++) {
  435. pos1 = this.$parties.eq(i).position();
  436. pos2 = this.$parties.eq(i+1).position();
  437. l = Math.sqrt(
  438. Math.pow(
  439. pos2.left - pos1.left
  440. ,2
  441. )
  442. +
  443. Math.pow(
  444. pos2.top - pos1.top
  445. ,2
  446. )
  447. );
  448. // get the rotation
  449. a = 180 / 3.14 * Math.acos((pos2.top - pos1.top) / l);
  450. if(pos2.left > pos1.left)
  451. a *= -1;
  452. // console.log("a = "+a);
  453. this.lines[i].$line.css({
  454. 'height':l,
  455. transform:"rotate3d(0,0,1,"+a+"deg)"
  456. });
  457. };
  458. };
  459. Chapter.prototype.loadNode = function(e){
  460. // console.log("Chapter :: open : nid", this.nid);
  461. $.getJSON(
  462. '/jee/chapter/'+this.nid,
  463. {},
  464. this.nodeLoaded.bind(this)
  465. );
  466. _$body.addClass('chapter-displayed');
  467. };
  468. Chapter.prototype.nodeLoaded = function(json, textstatus){
  469. console.log('Chapter :: nodeLoaded '+this.nid+' : json', json);
  470. // insert ajax loaded into dom
  471. _$chapter_wrapper.html(json.node);
  472. // record some usefull data
  473. this.$n = $('.node-chapitre', _$chapter_wrapper);
  474. this.$blocks = $('.field-type-text-long', this.$n);
  475. this.$vids = $('.field-name-field-partie', this.$n);
  476. // record the current loaded chapter
  477. // this will stop first interface to run
  478. _loaded_chapter = this;
  479. // wait to build correct display of chapter
  480. setTimeout(this.displayNode.bind(this), 100);
  481. };
  482. Chapter.prototype.displayNode = function(){
  483. console.log('Chapter :: displayNode '+this.nid);
  484. // place text blocks
  485. this.texts_pos = shuffleArray([1,2,3]);
  486. this.$blocks
  487. .each(this.placeText.bind(this))
  488. .pep({
  489. allowDragEventPropagation:false,
  490. disableSelect:true,
  491. velocityMultiplier:1
  492. });
  493. // build video player
  494. this.buildVideos();
  495. $('.node-title', this.$n).pep();
  496. // show the whole thing
  497. _$chapter_wrapper.addClass('visible');
  498. };
  499. Chapter.prototype.placeText = function(i, e){
  500. // console.log("Chapter :: placeText", e);
  501. switch(this.texts_pos[i]){
  502. case 1: // top right
  503. $(e)
  504. .css({
  505. top:randB(_container.h*0.05-$(e).height(),_container.h*0.15-$(e).height()),
  506. left:randB(_container.w*0.8-$(e).width(),_container.w*0.9-$(e).width())
  507. })
  508. // .pep({debug:true, startPos:{bottom:randB(80,90),right:randB(80,90)}})
  509. .find('.field-label')
  510. .appendTo(e);
  511. break;
  512. case 2: // bottom left
  513. $(e).css({
  514. top:randB(_container.h*0.8,_container.h*0.9),
  515. left:randB(_container.w*0.1,_container.w*0.2)
  516. });
  517. // $(e).pep({debug:true, startPos:{top:randB(80,90),left:randB(10,30)}});
  518. break;
  519. case 3: // bottom right
  520. $(e).css({
  521. top:randB(_container.h*0.8,_container.h*0.9),
  522. left:randB(_container.w*0.7,_container.w*0.9-$(e).width())
  523. });
  524. // $(e).pep({debug:true, startPos:{top:randB(80,90),right:randB(10,30)}});
  525. break;
  526. }
  527. };
  528. Chapter.prototype.buildVideos = function(){
  529. console.log('Chapter :: buildVideos');
  530. this.dimvideo.h = this.$vids.height();
  531. // redim each iframe to fit
  532. // add a mask on top of each iframe to avoid bad interaction with vimeo
  533. $('iframe', this.$vids)
  534. .each(this.redimVideo.bind(this))
  535. .after('<div class="mask"></div>');
  536. this.$vids.css({
  537. width:this.dimvideo.w*1.3,
  538. height:this.dimvideo.h,
  539. marginLeft:(_container.w-this.dimvideo.w*1.3)/2
  540. });
  541. // create the slider with peppermint
  542. $('.field-items', this.$vids).Peppermint();
  543. };
  544. Chapter.prototype.redimVideo = function(i,e){
  545. // compute proportional video width ragarding the parent height
  546. this.dimvideo.w = (this.dimvideo.h * parseInt($(e).attr("width")))/parseInt($(e).attr("height"));
  547. // apply thees sizes
  548. $(e)
  549. .css({ width:this.dimvideo.w, height:this.dimvideo.h })
  550. .attr({ width:this.dimvideo.w, height:this.dimvideo.h })
  551. // add some paading to parent for slider display
  552. .parent().css({
  553. paddingLeft:this.dimvideo.w*0.15,
  554. paddingright:this.dimvideo.w*0.15
  555. });
  556. };
  557. Node.initialized = true;
  558. };
  559. this.init();
  560. };//Chapter
  561. /*
  562. __ __________ ____ __________ _____
  563. / / / / ____/ / / __ \/ ____/ __ \/ ___/
  564. / /_/ / __/ / / / /_/ / __/ / /_/ /\__ \
  565. / __ / /___/ /___/ ____/ /___/ _, _/___/ /
  566. /_/ /_/_____/_____/_/ /_____/_/ |_|/____/
  567. */
  568. function randB(min, max){
  569. return Math.random() * (max - min) + min;
  570. };
  571. //+ Jonas Raoni Soares Silva
  572. //@ http://jsfromhell.com/array/shuffle [v1.0]
  573. function shuffleArray(o){ //v1.0
  574. for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
  575. return o;
  576. };
  577. if (!Date.now) {
  578. Date.now = function now() {
  579. return new Date().getTime();
  580. };
  581. }
  582. function translate3d(x, y, z){
  583. // return
  584. };
  585. /*
  586. _ _ __
  587. (_)___ (_) /_
  588. / / __ \/ / __/
  589. / / / / / / /_
  590. /_/_/ /_/_/\__/
  591. */
  592. init();
  593. });
  594. /*
  595. ____ __ __ _____________ _______
  596. / __ \/ / / / / / ____/ _/ | / / ___/
  597. / /_/ / / / / / / / __ / // |/ /\__ \
  598. / ____/ /___/ /_/ / /_/ // // /| /___/ /
  599. /_/ /_____/\____/\____/___/_/ |_//____/
  600. */
  601. // https://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/
  602. // (function($) {
  603. // $.fn.drags = function(opt) {
  604. // opt = $.extend({handle:"",cursor:"move"}, opt);
  605. // if(opt.handle === "") {
  606. // var $el = this;
  607. // } else {
  608. // var $el = this.find(opt.handle);
  609. // }
  610. // return $el.css('cursor', opt.cursor).on("mousedown", function(e) {
  611. // if(opt.handle === "") {
  612. // var $drag = $(this).addClass('draggable');
  613. // } else {
  614. // var $drag = $(this).addClass('active-handle').parent().addClass('draggable');
  615. // }
  616. // var z_idx = $drag.css('z-index'),
  617. // drg_h = $drag.outerHeight(),
  618. // drg_w = $drag.outerWidth(),
  619. // pos_y = $drag.offset().top + drg_h - e.pageY,
  620. // pos_x = $drag.offset().left + drg_w - e.pageX;
  621. // $drag.css('z-index', 1000).parents().on("mousemove", function(e) {
  622. // $('.draggable').offset({
  623. // top:e.pageY + pos_y - drg_h,
  624. // left:e.pageX + pos_x - drg_w
  625. // }).on("mouseup", function() {
  626. // $(this).removeClass('draggable').css('z-index', z_idx);
  627. // });
  628. // });
  629. // e.preventDefault(); // disable selection
  630. // }).on("mouseup", function() {
  631. // if(opt.handle === "") {
  632. // $(this).removeClass('draggable');
  633. // } else {
  634. // $(this).removeClass('active-handle').parent().removeClass('draggable');
  635. // }
  636. // });
  637. // }
  638. // })(jQuery);
  639. /*
  640. ____ __________ __ ___________________ ___ _ ________ ______ ______________ _ __ __________ ___ __ _________
  641. / __ \/ ____/ __ \/ / / / ____/ ___/_ __/ / | / | / / _/ |/ / |/_ __/ _/ __ \/ | / / / ____/ __ \/ | / |/ / ____/
  642. / /_/ / __/ / / / / / / / __/ \__ \ / / / /| | / |/ // // /|_/ / /| | / / / // / / / |/ / / /_ / /_/ / /| | / /|_/ / __/
  643. / _, _/ /___/ /_/ / /_/ / /___ ___/ // / / ___ |/ /| // // / / / ___ |/ / _/ // /_/ / /| / / __/ / _, _/ ___ |/ / / / /___
  644. /_/ |_/_____/\___\_\____/_____//____//_/ /_/ |_/_/ |_/___/_/ /_/_/ |_/_/ /___/\____/_/ |_/ /_/ /_/ |_/_/ |_/_/ /_/_____/
  645. */
  646. (function() {
  647. var lastTime = 0;
  648. var vendors = ['ms', 'moz', 'webkit', 'o'];
  649. for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  650. window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
  651. window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
  652. || window[vendors[x]+'CancelRequestAnimationFrame'];
  653. }
  654. if (!window.requestAnimationFrame)
  655. window.requestAnimationFrame = function(callback, element) {
  656. var currTime = new Date().getTime();
  657. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  658. var id = window.setTimeout(function() { callback(currTime + timeToCall); },
  659. timeToCall);
  660. lastTime = currTime + timeToCall;
  661. return id;
  662. };
  663. if (!window.cancelAnimationFrame)
  664. window.cancelAnimationFrame = function(id) {
  665. clearTimeout(id);
  666. };
  667. }());
  668. /* ____ ____
  669. / __/_ __/ / / __________________ ___ ____
  670. / /_/ / / / / / / ___/ ___/ ___/ _ \/ _ \/ __ \
  671. / __/ /_/ / / / (__ ) /__/ / / __/ __/ / / /
  672. /_/ \__,_/_/_/ /____/\___/_/ \___/\___/_/ /_/
  673. */
  674. // http://davidwalsh.name/fullscreen
  675. // http://www.sitepoint.com/html5-full-screen-api/
  676. // Find the right method, call on correct element
  677. function launchIntoFullscreen(element) {
  678. if(element.requestFullscreen) {
  679. element.requestFullscreen();
  680. } else if(element.mozRequestFullScreen) {
  681. element.mozRequestFullScreen();
  682. } else if(element.webkitRequestFullscreen) {
  683. element.webkitRequestFullscreen();
  684. } else if(element.msRequestFullscreen) {
  685. element.msRequestFullscreen();
  686. }
  687. }
  688. // remove navbar
  689. // $(document).ready(function() {
  690. // if (navigator.userAgent.match(/Android/i)) {
  691. // window.scrollTo(0,0); // reset in case prev not scrolled
  692. // var nPageH = $(document).height();
  693. // var nViewH = window.outerHeight;
  694. // if (nViewH > nPageH) {
  695. // nViewH -= 250;
  696. // $('BODY').css('height',nViewH + 'px');
  697. // }
  698. // window.scrollTo(0,1);
  699. // }
  700. // });
  701. // OR
  702. // function hideAddressBar(){
  703. // if(document.documentElement.scrollHeight<window.outerHeight/window.devicePixelRatio)
  704. // document.documentElement.style.height=(window.outerHeight/window.devicePixelRatio)+'px';
  705. // setTimeout(window.scrollTo(1,1),0);
  706. // }
  707. // window.addEventListener("load",function(){hideAddressBar();});
  708. // window.addEventListener("orientationchange",function(){hideAddressBar();});
  709. // OR
  710. // function hideAddressBar() {
  711. // if(!window.location.hash) {
  712. // if(document.height < window.outerHeight)
  713. // document.body.style.height = (window.outerHeight + 50) + 'px';
  714. // setTimeout( function(){
  715. // window.scrollTo(0, 1);
  716. // document.body.style.height = 'auto';
  717. // }, 50 );
  718. // }
  719. // }
  720. // window.addEventListener("load",function(){hideAddressBar();});
  721. // window.addEventListener("orientationchange",function(){hideAddressBar();});
  722. // Drupal.behaviors.init_theme = function (context) {
  723. // // Growl-style system messages
  724. // $('#messages-and-help > div.messages:not(.processed)')
  725. // .addClass('processed')
  726. // .each(function() {
  727. // // If a message meets these criteria, we don't autoclose
  728. // // - contains a link
  729. // // - is an error or warning
  730. // // - contains a lenghthy amount of text
  731. // if ($('a', this).size() || $(this).is('.error') || $(this).is('.warning') || $(this).text().length > 100) {
  732. // $(this).prepend("<span class='close'>X</span>");
  733. // $('span.close', this).click(function() {
  734. // $(this).parent().slideUp('fast');
  735. // });
  736. // }
  737. // else {
  738. // // This essentially adds a 3 second pause before hiding the message.
  739. // $(this).animate({opacity:1}, 5000, 'linear', function() {
  740. // $(this).slideUp('fast');
  741. // });
  742. // }
  743. // });
  744. // };