jee.js 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. /*
  2. _ _
  3. |_|___ _ _ ___ ___ ___ ___| |_ ___ ___ ___ ___ ___ ___ ___
  4. | | -_| | | | -_|_ -| | -_| _| | -_| | . | .'| . | -_|_ -|
  5. _| |___|___|_|_|___|___| |___|_| |___|_|_|_ |__,|_ |___|___|
  6. |___| |___| |___|
  7. Bachir Soussi Chiadmi
  8. 2015
  9. */
  10. jQuery(document).ready(function($) {
  11. // console.log('Hello Jee');
  12. // http://stackoverflow.com/questions/2890898/preventing-mouse-emulation-events-ie-click-from-touch-events-in-mobile-safari
  13. // FastClick.attach(document.body);
  14. var _debug = false,
  15. _avgDelay = 1,
  16. _lastDraw = new Date,
  17. _fps,
  18. _$nav_cursor;
  19. var _$body = $('body'),
  20. _$header = $("#header"),
  21. _$chapitres = $('.node-chapitre', '#main'),
  22. _chapitres_len = _$chapitres.length,
  23. _chapters = [],
  24. _$container = $('#main'),
  25. _container = {
  26. w:_$container.width(),
  27. h:_$container.height()
  28. },
  29. _center = {x:_container.w/2,y:_container.h/2},
  30. _nav_pos = {x:0, y:0},
  31. _mouse_down_pos = {x:0,y:0},
  32. _prev_mouse_pos = {x:0,y:0},
  33. _fps = 1000/12,
  34. _dragging = false, _timeout_dragging,
  35. _previewed_chapter = false;
  36. var _$chapter_wrapper = $('<div>').attr('id', 'chapter-wrapper').appendTo(_$container),
  37. _loaded_chapter = false;
  38. var _bubbles = new Array(),
  39. _stars = new Array();
  40. var _$footer = $('#footer'),
  41. _$static_wrapper = $('<div><div class="inner"></div></div>').attr('id', 'static-wrapper').appendTo(_$container),
  42. _$close_static = $('<div>').addClass('close').appendTo(_$static_wrapper);
  43. _loaded_static = false;
  44. var _$loader = $('<div>').attr('id','loader').appendTo(_$body);
  45. var _touch_started = false;
  46. function init(){
  47. if(_debug)
  48. initDebug();
  49. initChapterWrapper();
  50. initChapters();
  51. initStaticLinks();
  52. launchNav();
  53. // FULL SCREEN
  54. var $fullscreenBtn = $('<div>Plein écran</div>').attr('id','fullscreen-btn').appendTo("#root");
  55. $fullscreenBtn.on('click', onFullScreen);
  56. // create bubbles
  57. for (var i = 2; i > 0; i--) {
  58. _bubbles.push($('<div>').addClass('bubble bubble-'+i).prependTo(_$container));
  59. };
  60. // create stars
  61. // for (var i = 20; i > 0; i--) {
  62. // _stars.push(
  63. // $('<div>')
  64. // .addClass('star star-'+i)
  65. // .css({
  66. // left:randB(-400, _container.w+400),
  67. // top:randB(-400, _container.h+400)
  68. // })
  69. // .prependTo(_$container)
  70. // );
  71. // };
  72. };
  73. function initDebug(){
  74. $('<p>').attr('id', 'fps').appendTo(_$container);
  75. _fps = document.getElementById('fps');
  76. requestAnimationFrame(displayFps);
  77. _$nav_cursor = $('<div id="nav-cursor"></div>').appendTo(_$container);
  78. moveDebugCursor();
  79. };
  80. function displayFps(){
  81. requestAnimationFrame(displayFps);
  82. var now = new Date;
  83. var delay = now - _lastDraw;
  84. _avgDelay += (delay - _avgDelay) / 10;
  85. _lastDraw = now;
  86. _fps.innerHTML = (1000/_avgDelay).toFixed(1) + " fps";
  87. };
  88. function moveDebugCursor(){
  89. _$nav_cursor.css({
  90. left:_nav_pos.x+_center.x+"px",
  91. top:_nav_pos.y+_center.y+"px"
  92. });
  93. };
  94. function initChapterWrapper(){
  95. $('<div id="home-btn">')
  96. .on("click", onCloseChapterWrapper)
  97. .appendTo(_$chapter_wrapper);
  98. };
  99. function onCloseChapterWrapper(e){
  100. _loaded_chapter.stopAndClose();
  101. _loaded_chapter = false;
  102. _$chapter_wrapper.removeClass('visible');
  103. _$body.removeClass('chapter-displayed');
  104. setTimeout(function(){
  105. _$chapter_wrapper.find('.node').remove();
  106. }, 2000);
  107. };
  108. function initChapters(){
  109. // Place each chapters on the ellipse contained on the screen
  110. var base_a = Math.random() *360;
  111. _$chapitres.each(function(i, e) {
  112. // Lets create the chapter object and place him self
  113. _chapters.push(new Chapter(i, e, base_a));
  114. });
  115. };
  116. function launchNav(){
  117. $("#block-system-main")
  118. /*
  119. ____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
  120. | \| __| __| | |_ _| | _ | | __| | | __| | |_ _| __|
  121. | | | __|__ | -| | | | | | __| | __| | | __| | | | | | |__ |
  122. |____/|_____|_____|__|__| |_| |_____|__| |_____|\___/|_____|_|___| |_| |_____|
  123. */
  124. .on('mousemove', function(e){
  125. e.preventDefault();
  126. // prevent firing mousemove with touch events
  127. if(_touch_started)
  128. return false;
  129. console.log('document mousemove');
  130. clearTimeout(_timeout_dragging);
  131. // if(_previewed_chapter || _loaded_chapter || _loaded_static)
  132. // return false;
  133. // activate dragging if already activated
  134. if(!_dragging){
  135. _dragging = true;
  136. startMoveNav();
  137. }else{
  138. updateNavPos(e.clientX, e.clientY, false, false);
  139. }
  140. })
  141. .on('mouseup', function(e){
  142. e.preventDefault();
  143. console.log('document mouseup');
  144. if(_loaded_chapter || _loaded_static)
  145. return false;
  146. for (var i = _chapitres_len - 1; i >= 0; i--)
  147. _chapters[i].closePreview().unMitigate();
  148. })
  149. /*
  150. _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
  151. |_ _| | | | | | | | __| | | __| | |_ _| __|
  152. | | | | | | | --| | | __| | | __| | | | | | |__ |
  153. |_| |_____|_____|_____|__|__| |_____|\___/|_____|_|___| |_| |_____|
  154. */
  155. .on('touchstart', function(e){
  156. // e.preventDefault();
  157. console.log('document touchstart');
  158. _touch_started = true;
  159. clearTimeout(_timeout_dragging);
  160. if(_loaded_chapter || _loaded_static)
  161. return false;
  162. // set initial pos
  163. updateNavPos(e.originalEvent.touches[0].clientX, e.originalEvent.touches[0].clientY, true, true);
  164. // activate dragging if already activated
  165. if(!_dragging){
  166. _dragging = true;
  167. startMoveNav();
  168. }
  169. })
  170. .on('touchmove', function(e){
  171. // e.preventDefault();
  172. console.log('document touchmove');
  173. if(_loaded_chapter || _loaded_static)
  174. return false;
  175. updateNavPos(e.originalEvent.touches[0].clientX, e.originalEvent.touches[0].clientY, true, false);
  176. })
  177. .on('touchend', function(e){
  178. // e.preventDefault();
  179. console.log("document touchend");
  180. if(_loaded_chapter || _loaded_static)
  181. return false;
  182. stopMoveNav();
  183. setTimeout(function(){_touch_started = false;}, 500);
  184. });
  185. // TODO : nav on scroll events
  186. };
  187. function updateNavPos(x,y,touch,init){
  188. if(touch){
  189. if(!init){
  190. _nav_pos.x += x - _prev_mouse_pos.x;
  191. _nav_pos.y += y - _prev_mouse_pos.y;
  192. // constrain nav pos on container
  193. _nav_pos.x = _nav_pos.x < -_center.x*2
  194. ? -_center.x*2
  195. : _nav_pos.x > _center.x*2
  196. ? _center.x*2
  197. : _nav_pos.x;
  198. _nav_pos.y = _nav_pos.y < -_center.y*2
  199. ? -_center.y*2
  200. : _nav_pos.y > _center.y*2
  201. ? _center.y*2
  202. : _nav_pos.y;
  203. }
  204. }else{
  205. _nav_pos.x = (_center.x -x)*0.5;
  206. _nav_pos.y = (_center.y -y)*0.5;
  207. }
  208. _prev_mouse_pos.x = x;
  209. _prev_mouse_pos.y = y;
  210. // debuging cursor
  211. if(_debug)
  212. moveDebugCursor();
  213. };
  214. function startMoveNav(){
  215. window.requestAnimationFrame(moveNav);
  216. };
  217. function moveNav(){
  218. // console.log("moveNav");
  219. if(!_dragging) return;
  220. window.requestAnimationFrame(moveNav);
  221. // move chapters
  222. for (var i = _chapitres_len - 1; i >= 0; i--)
  223. _chapters[i].move();
  224. // move header
  225. // _$header.css({
  226. // transform:"translate3d("+(_nav_pos.x)*0.2+"px, "+(_nav_pos.y)*0.2+"px,0)"
  227. // });
  228. _$header.translate3d({x:_nav_pos.x*0.2,y:_nav_pos.y*0.2});
  229. // bubbles and stars dont move so smoothly on tablette ...
  230. // should keep it only on desktop
  231. // move bubbles
  232. // for (var i = _bubbles.length - 1; i >= 0; i--) {
  233. // _bubbles[i].translate3d({x:_nav_pos.x*0.4,y:_nav_pos.y*0.4});
  234. // };
  235. // move stars
  236. // for (var i = _stars.length - 1; i >= 0; i--) {
  237. // _stars[i].translate3d({x:_nav_pos.x*-0.3,y:_nav_pos.y*-0.3});
  238. // };
  239. };
  240. function stopMoveNav(){
  241. console.log('stopMoveNav');
  242. clearTimeout(_timeout_dragging);
  243. _timeout_dragging = setTimeout(function(){
  244. console.log("dragging stoped");
  245. _dragging = false;
  246. },3000);
  247. };
  248. function onFullScreen(e){
  249. if(_$body.is('fullscreen')){
  250. exitFullscreen();
  251. _$body.removeClass('fullscreen');
  252. }else{
  253. launchIntoFullscreen(document.getElementById("root"));
  254. _$body.addClass('fullscreen');
  255. }
  256. if(_loaded_chapter)
  257. setTimeout(_loaded_chapter.buildVideos(), 100);
  258. };
  259. /*
  260. _____ _____ _____ _____ _____ _____ _____
  261. | __|_ _| _ |_ _| | | __|
  262. |__ | | | | | | | |- -| --|__ |
  263. |_____| |_| |__|__| |_| |_____|_____|_____|
  264. */
  265. function initStaticLinks(){
  266. $('ul.menu a', _$footer).on('click', onClickStaticLink);
  267. _$close_static.on('click', onCloseStatic);
  268. };
  269. function onClickStaticLink(e){
  270. e.preventDefault();
  271. _$static_wrapper.removeClass('visible');
  272. loadStaticContent($(this).attr("href"));
  273. _$body.addClass('loading');
  274. _loaded_static = true;
  275. return false;
  276. };
  277. function loadStaticContent(h){
  278. $.getJSON(
  279. '/jee/static',
  280. {"href":h},
  281. onStaticLoaded
  282. );
  283. };
  284. function onStaticLoaded(data, textstatus){
  285. console.log('data',data);
  286. displayStatic(data.node);
  287. };
  288. function displayStatic(node){
  289. _$static_wrapper.addClass('visible').find('.inner').html(node);
  290. _$body.removeClass('loading');
  291. };
  292. function onCloseStatic(e){
  293. _$static_wrapper.removeClass('visible');
  294. _loaded_static = false;
  295. };
  296. /*
  297. ________ __
  298. / ____/ /_ ____ _____ / /____ _____
  299. / / / __ \/ __ `/ __ \/ __/ _ \/ ___/
  300. / /___/ / / / /_/ / /_/ / /_/ __/ /
  301. \____/_/ /_/\__,_/ .___/\__/\___/_/
  302. /_/
  303. */
  304. function Chapter(i, e, base_a){
  305. // $e.obj = this;
  306. this.i = i;
  307. this.e = e;
  308. this.$e = $(e);
  309. this.nid = this.$e.attr("id").match(/^node-(\d+)/)[1];
  310. this.geom = {
  311. base_a:base_a,
  312. a:0,
  313. r:0,
  314. w:this.$e.outerWidth(true),
  315. h:this.$e.outerHeight(true)
  316. }
  317. this.pos = {x:0,y:0};
  318. this.trans = {x:0, y:0,z:0};
  319. this.trans_previewed = {x:0, y:0,z:0};
  320. this.ease = randB(0.05, 0.2);
  321. //drifting
  322. this.$title = $('h2.node-title', this.$e);
  323. this.$content = $('.content:first', this.$e);
  324. this.title_x = 0;
  325. this.content_x = 0;
  326. this.drifting_direction = Math.random()-0.5 > 0 ? 1 : -1;
  327. this.drifting_time = null;
  328. //preview
  329. this.is_previewed = false;
  330. //mitigate
  331. this.is_mitigated = false;
  332. //parties
  333. this.$parties = $('.field-name-field-partie', e);
  334. this.parts_pos = {xs:new Array(), ys:new Array()};
  335. this.lines = new Array();
  336. this.displayPreviewAnimeStartTime = 0,
  337. this.displayPreviewAnimeDuration = 4000, // milli sec
  338. this.are_lines_animated = false;
  339. // chapter
  340. this.$n = false;
  341. this.$blocks = false;
  342. this.$vids_container = false;
  343. this.$vids = false;
  344. this.texts_pos = shuffleArray([1,2,3]);
  345. this.dimvideo = {w:0, h:0};
  346. this.$slider = null;
  347. this.cur_vid_playing = 0;
  348. // prototypes
  349. if (typeof Chapter.initialized == "undefined") {
  350. Chapter.prototype.init = function(){
  351. this.setInitPos();
  352. this.drawLines();
  353. this.setEvents();
  354. // this.initDrifiting();
  355. // enable nodes after intro anime
  356. setTimeout(
  357. (function(t){
  358. return function(){
  359. t.$e.addClass('enabled');
  360. }
  361. }(this)),
  362. randB(5000, 8000));
  363. };
  364. Chapter.prototype.setInitPos = function(){
  365. // distribute elements arround the center
  366. this.geom.a = (360/_chapitres_len*this.i+this.geom.base_a)*Math.PI/180;
  367. // console.log("Chapter :: setInitPos", this.$e);
  368. this.geom.c = Math.cos(this.geom.a);
  369. this.geom.s = Math.sin(this.geom.a);
  370. this.geom.abs_c = Math.abs(this.geom.c);
  371. this.geom.abs_s = Math.abs(this.geom.s);
  372. if (this.geom.abs_c * _container.h > this.geom.abs_s * _container.w) {
  373. // It crosses left or right side
  374. this.geom.r = (_center.x / this.geom.abs_c)*0.5;
  375. }else {
  376. // Top or bottom side
  377. this.geom.r = (_center.y / this.geom.abs_s)*0.5;
  378. }
  379. // change randomly radius
  380. if(this.i%2){
  381. this.geom.r = randB(this.geom.r*1.5, this.geom.r*2);
  382. }else{
  383. this.geom.r = randB(this.geom.r*0.8, this.geom.r*1.5);
  384. }
  385. this.pos.x = Math.round(_center.x+this.geom.r * this.geom.c) - this.geom.w/2;
  386. this.pos.y = Math.round(_center.y+this.geom.r * -this.geom.s) - this.geom.h/2;
  387. // calculate the translation needed for the previewed position (center top)
  388. this.trans_previewed.x = -(this.pos.x - _center.x) - this.geom.w*0.5;
  389. this.trans_previewed.y = -this.pos.y+this.$e.find('.node-title').height()*1.3;
  390. this.$e.css({
  391. left:this.pos.x,
  392. top:this.pos.y
  393. });
  394. };
  395. Chapter.prototype.setEvents = function(){
  396. //http://technify.me/user-experience/javascript/jquery/trigger-custom-events-with-jquery/
  397. // click to preview chapter
  398. // $('h2.node-title, .field-name-field-partie:first>.field-name-field-vignette', this.$e)
  399. this.$e
  400. .on('click', this, function(e){
  401. // e.stopImmediatePropagation();
  402. console.log('click on chapter');
  403. e.stopPropagation();
  404. e.preventDefault();
  405. e.data.preview(e);
  406. return false;
  407. });
  408. $('.links a', this.$e)
  409. .on('click', this, function(e){
  410. e.stopPropagation();
  411. e.preventDefault();
  412. e.data.loadNode();
  413. return false;
  414. });
  415. };
  416. Chapter.prototype.initDrifiting = function(){
  417. // an other option could be to drift the whole page with the same engine than draging
  418. requestAnimationFrame(this.drift.bind(this));
  419. };
  420. Chapter.prototype.drift = function(timestamp){
  421. requestAnimationFrame(this.drift.bind(this));
  422. var now = new Date().getTime(),
  423. dt = now - (this.drifting_time || now);
  424. this.drifting_time = now;
  425. if(!this.is_previewed){
  426. this.title_x += (10/1000)*dt*this.drifting_direction;
  427. this.content_x += (6/1000)*dt*this.drifting_direction;
  428. this.drifting_direction =
  429. this.content_x > randB(100,130)
  430. ? -1
  431. : this.content_x < -randB(100,130)
  432. ? 1
  433. : this.drifting_direction;
  434. this.$title.translate3d({x:this.title_x});
  435. this.$content.translate3d({x:this.content_x});
  436. }
  437. };
  438. Chapter.prototype.move = function(){
  439. if(this.is_previewed)
  440. return false;
  441. this.trans.x += (_nav_pos.x - this.trans.x)*this.ease;
  442. this.trans.y += (_nav_pos.y - this.trans.y)*this.ease;
  443. // this.trans.z = Math.floor(Math.sqrt(
  444. // Math.pow(
  445. // _center.x-(this.pos.x+this.trans.x)
  446. // ,2
  447. // )
  448. // +
  449. // Math.pow(
  450. // _center.y-(this.pos.y+this.trans.y)
  451. // ,2
  452. // )
  453. // ));
  454. // if(this.i === 0)
  455. // console.log(this.i+" this.trans.z", this.trans.z);
  456. this.$e.translate3d({x:this.trans.x,y:this.trans.y});
  457. };
  458. Chapter.prototype.preview = function(){
  459. // don't relaunch preview more that one time
  460. if(this.is_previewed) return false;
  461. _previewed_chapter = this;
  462. console.log('preview', this.i);
  463. this.unMitigate();
  464. this.is_previewed = true;
  465. // close other chapters
  466. for (var i = _chapitres_len - 1; i >= 0; i--)
  467. if(i !== this.i)
  468. _chapters[i].closePreview().mitigate();
  469. this.displayPreview();
  470. // moveToChapter(this);
  471. };
  472. Chapter.prototype.displayPreview = function(e){
  473. // define randomly position of parties
  474. this.resetPartsPos();
  475. this.are_lines_animated = false;
  476. requestAnimationFrame(this.animePreviewDisplay.bind(this));
  477. };
  478. Chapter.prototype.resetPartsPos = function(){
  479. this.parts_pos = {xs:new Array(), ys:new Array()};
  480. var h = _container.h * 0.6;
  481. for (var i = 0; i < 2; i++) {
  482. switch(i){
  483. case 0:
  484. this.parts_pos.xs.push(randB(180,280));
  485. this.parts_pos.ys.push(randB(h*0.55,h*0.6));
  486. break;
  487. case 1:
  488. this.parts_pos.xs.push(randB(-280,-180));
  489. this.parts_pos.ys.push(randB(h*0.65,h));
  490. break;
  491. }
  492. };
  493. this.parts_pos.xs = shuffleArray(this.parts_pos.xs);
  494. this.parts_pos.ys = shuffleArray(this.parts_pos.ys);
  495. // always place the first circle on top center
  496. this.parts_pos.xs.unshift(randB(-30,30));
  497. this.parts_pos.ys.unshift(120);
  498. };
  499. Chapter.prototype.closePreview = function(){
  500. if(!this.is_previewed) return this;
  501. this.$e.removeClass('previewed')
  502. .find('.field-name-field-partie')
  503. .css({transform:"none"});
  504. this.is_previewed = false;
  505. _previewed_chapter = false;
  506. requestAnimationFrame(this.animePreviewDisplay.bind(this));
  507. return this;
  508. };
  509. Chapter.prototype.mitigate = function(){
  510. if(this.is_mitigated) return this;
  511. this.$e.addClass('mitigated');
  512. return this;
  513. };
  514. Chapter.prototype.unMitigate = function(){
  515. if(this.is_mitigated) return this;
  516. this.$e.removeClass('mitigated');
  517. return this;
  518. };
  519. Chapter.prototype.drawLines = function(){
  520. for (var i = 0; i < 2; i++) {
  521. this.lines.push({
  522. $line:$("<div>").addClass('line', 'line-'+i).prependTo(this.$parties[i])
  523. });
  524. };
  525. };
  526. Chapter.prototype.animePreviewDisplay = function(timestamp){
  527. // console.log("anime line "+this.nid);
  528. // get the time on first anime launch
  529. if(this.displayPreviewAnimeStartTime === 0)
  530. this.displayPreviewAnimeStartTime = timestamp;
  531. // limit the animation time
  532. if(timestamp - this.displayPreviewAnimeStartTime < this.displayPreviewAnimeDuration){
  533. requestAnimationFrame(this.animePreviewDisplay.bind(this));
  534. }else{
  535. this.displayPreviewAnimeStartTime = 0;
  536. }
  537. // first move chapter to previewed pos (center top screen)
  538. if(this.is_previewed && !this.are_lines_animated){
  539. this.trans.x = this.trans.x + (this.trans_previewed.x - this.trans.x)*0.4;
  540. this.trans.y = this.trans.y + (this.trans_previewed.y - this.trans.y)*0.4;
  541. this.$e.translate3d({x:this.trans.x,y:this.trans.y});
  542. // append just once when positioning is done
  543. if(Math.abs(this.trans_previewed.x - this.trans.x) < 5){
  544. // apply new position to parties
  545. var that = this;
  546. this.$parties.each(function(i, e) {
  547. setTimeout(
  548. (function(i, e, xs, ys){
  549. return function(){
  550. $(e).translate3d({x:xs[i],y:ys[i]});
  551. }
  552. }(i, e, that.parts_pos.xs, that.parts_pos.ys)),
  553. 10);
  554. }); // each $parties
  555. //activate lines anime for next frame
  556. this.are_lines_animated = true;
  557. this.$e.addClass('previewed');
  558. }
  559. }
  560. // after positiong juste anime lines
  561. if(this.are_lines_animated){
  562. // get the lines length
  563. var l, a, pos1, pos2;
  564. for (var i = 0; i < this.lines.length; i++) {
  565. pos1 = this.$parties.eq(i).position();
  566. pos2 = this.$parties.eq(i+1).position();
  567. l = Math.sqrt(
  568. Math.pow(
  569. pos2.left - pos1.left
  570. ,2
  571. )
  572. +
  573. Math.pow(
  574. pos2.top - pos1.top
  575. ,2
  576. )
  577. );
  578. // get the rotation
  579. a = 180 / 3.14 * Math.acos((pos2.top - pos1.top) / l);
  580. if(pos2.left > pos1.left)
  581. a *= -1;
  582. // console.log("a = "+a);
  583. this.lines[i].$line.css({
  584. 'height':l,
  585. transform:"rotate3d(0,0,1,"+a+"deg)"
  586. });
  587. };
  588. }
  589. };
  590. // _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
  591. // | | _ | __| | | | | | | _ | _ |_ _| __| __ |
  592. // | | | __| __| | | | | --| | | __| | | | __| -|
  593. // |_____|__| |_____|_|___| |_____|__|__|__|__|__| |_| |_____|__|__|
  594. Chapter.prototype.loadNode = function(e){
  595. // console.log("Chapter :: open : nid", this.nid);
  596. _$body.addClass('loading');
  597. $.getJSON(
  598. '/jee/chapter/'+this.nid,
  599. {},
  600. this.nodeLoaded.bind(this)
  601. );
  602. _$body.addClass('chapter-displayed');
  603. };
  604. Chapter.prototype.nodeLoaded = function(json, textstatus){
  605. console.log('Chapter :: nodeLoaded '+this.nid+' : json', json);
  606. // remove previous loaded nodes
  607. _$chapter_wrapper.find('.node').remove();
  608. // insert ajax loaded into dom
  609. _$chapter_wrapper.append(json.node);
  610. // record some usefull data
  611. this.$n = $('.node-chapitre', _$chapter_wrapper);
  612. this.$blocks = $('.field-type-text-long, .field-type-text', this.$n);
  613. this.$vids_container = $('.field-name-field-partie', this.$n);
  614. this.$vids = $('iframe', this.$vids_container);
  615. // record the current loaded chapter
  616. // this will stop first interface to run
  617. _loaded_chapter = this;
  618. // wait to build correct display of chapter
  619. setTimeout(this.displayNode.bind(this), 100);
  620. };
  621. Chapter.prototype.displayNode = function(){
  622. console.log('Chapter :: displayNode '+this.nid);
  623. // place text blocks
  624. this.texts_pos = shuffleArray([1,2,3,4]);
  625. this.$blocks
  626. .each(this.placeText.bind(this))
  627. .pep({
  628. allowDragEventPropagation:false,
  629. disableSelect:true,
  630. velocityMultiplier:1
  631. });
  632. // build video player
  633. this.buildVideos();
  634. // show the whole thing
  635. _$chapter_wrapper.addClass('visible');
  636. // this.$vids.eq(this.cur_vid_playing).vimeo('play');
  637. _$body.removeClass('loading');
  638. };
  639. Chapter.prototype.placeText = function(i, e){
  640. // console.log("Chapter :: placeText", e);
  641. switch(this.texts_pos[i]){
  642. case 1: // top left
  643. $(e)
  644. .css({
  645. top:randB(_container.h*0.05-$(e).height(),_container.h*0.15-$(e).height()),
  646. left:randB(_container.w*0.1,_container.w*0.2)
  647. })
  648. // .pep({debug:true, startPos:{bottom:randB(80,90),right:randB(80,90)}})
  649. .find('.field-label')
  650. .appendTo(e);
  651. break;
  652. case 2: // top right
  653. $(e)
  654. .css({
  655. top:randB(_container.h*0.05-$(e).height(),_container.h*0.15-$(e).height()),
  656. left:randB(_container.w*0.8-$(e).width(),_container.w*0.9-$(e).width())
  657. })
  658. // .pep({debug:true, startPos:{bottom:randB(80,90),right:randB(80,90)}})
  659. .find('.field-label')
  660. .appendTo(e);
  661. break;
  662. case 3: // bottom left
  663. $(e).css({
  664. top:randB(_container.h*0.8,_container.h*0.9),
  665. left:randB(_container.w*0.1,_container.w*0.2)
  666. });
  667. // $(e).pep({debug:true, startPos:{top:randB(80,90),left:randB(10,30)}});
  668. break;
  669. case 4: // bottom right
  670. $(e).css({
  671. top:randB(_container.h*0.8,_container.h*0.9),
  672. left:randB(_container.w*0.7,_container.w*0.9-$(e).width())
  673. });
  674. // $(e).pep({debug:true, startPos:{top:randB(80,90),right:randB(10,30)}});
  675. break;
  676. }
  677. };
  678. Chapter.prototype.buildVideos = function(){
  679. console.log('Chapter :: buildVideos');
  680. this.dimvideo.h = this.$vids_container.height();
  681. // redim each iframe to fit
  682. // add a mask on top of each iframe to avoid bad interaction with vimeo
  683. this.$vids
  684. .after('<div class="mask"></div>')
  685. .each(this.redimVideo.bind(this));
  686. this.$vids_container.css({
  687. width:this.dimvideo.w*1.2,
  688. height:this.dimvideo.h,
  689. marginLeft:(_container.w-this.dimvideo.w*1.2)/2
  690. });
  691. // create the slider with peppermint
  692. this.$slider = $('.field-items', this.$vids_container).Peppermint({
  693. onSlideChange:this.onSlideChange.bind(this)
  694. });
  695. };
  696. Chapter.prototype.redimVideo = function(i,e){
  697. // compute proportional video width ragarding the parent height
  698. this.dimvideo.w = (this.dimvideo.h * parseInt($(e).attr("width")))/parseInt($(e).attr("height"));
  699. // apply thees sizes
  700. $(e)
  701. .css({ width:this.dimvideo.w, height:this.dimvideo.h })
  702. .attr({ width:this.dimvideo.w, height:this.dimvideo.h })
  703. // add some paading to parent for slider display
  704. .parent()
  705. .css({
  706. paddingLeft:this.dimvideo.w*0.15,
  707. paddingright:this.dimvideo.w*0.15
  708. })
  709. // .on("click", this.onClickVid.bind(this));
  710. };
  711. // not used
  712. Chapter.prototype.onClickVid = function(e){
  713. e.stopPropagation();
  714. e.preventDefault();
  715. console.log('Chapter :: onClickVid '+this.nid, e);
  716. var $vid = $('iframe', e.currentTarget);
  717. $vid.vimeo('paused', function(data){
  718. console.log('paused : ', data)
  719. if(data){
  720. $vid.vimeo('play');
  721. }else{
  722. $vid.vimeo('pause');
  723. }
  724. });
  725. return false;
  726. };
  727. Chapter.prototype.onSlideChange = function(){
  728. console.log('onSlideChange nid :'+this.nid+'| current : ', this.$slider.data('Peppermint').getCurrentPos());
  729. //stop current video playing
  730. this.$vids.eq(this.cur_vid_playing).vimeo('pause');
  731. // start new current video
  732. this.cur_vid_playing = this.$slider.data('Peppermint').getCurrentPos();
  733. this.$vids.eq(this.cur_vid_playing).vimeo('play');
  734. };
  735. Chapter.prototype.stopAndClose = function(){
  736. console.log('stopAndClose nid :'+this.nid+'| current : '+this.cur_vid_playing);
  737. this.$vids.eq(this.cur_vid_playing).vimeo('unload');
  738. };
  739. Node.initialized = true;
  740. };
  741. this.init();
  742. };//Chapter
  743. /*
  744. __ __________ ____ __________ _____
  745. / / / / ____/ / / __ \/ ____/ __ \/ ___/
  746. / /_/ / __/ / / / /_/ / __/ / /_/ /\__ \
  747. / __ / /___/ /___/ ____/ /___/ _, _/___/ /
  748. /_/ /_/_____/_____/_/ /_____/_/ |_|/____/
  749. */
  750. function randB(min, max){
  751. return Math.random() * (max - min) + min;
  752. };
  753. //+ Jonas Raoni Soares Silva
  754. //@ http://jsfromhell.com/array/shuffle [v1.0]
  755. function shuffleArray(o){ //v1.0
  756. for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
  757. return o;
  758. };
  759. if (!Date.now) {
  760. Date.now = function now() {
  761. return new Date().getTime();
  762. };
  763. }
  764. // http://davidwalsh.name/fullscreen
  765. // http://www.sitepoint.com/html5-full-screen-api/
  766. function launchIntoFullscreen(element) {
  767. // Find the right method, call on correct element
  768. if(element.requestFullscreen) {
  769. element.requestFullscreen();
  770. } else if(element.mozRequestFullScreen) {
  771. element.mozRequestFullScreen();
  772. } else if(element.webkitRequestFullscreen) {
  773. element.webkitRequestFullscreen();
  774. } else if(element.msRequestFullscreen) {
  775. element.msRequestFullscreen();
  776. }
  777. }
  778. // Whack fullscreen
  779. function exitFullscreen() {
  780. if(document.exitFullscreen) {
  781. document.exitFullscreen();
  782. } else if(document.mozCancelFullScreen) {
  783. document.mozCancelFullScreen();
  784. } else if(document.webkitExitFullscreen) {
  785. document.webkitExitFullscreen();
  786. }
  787. }
  788. /*
  789. _ _ __
  790. (_)___ (_) /_
  791. / / __ \/ / __/
  792. / / / / / / /_
  793. /_/_/ /_/_/\__/
  794. */
  795. init();
  796. });
  797. /*
  798. ____ __________ __ ___________________ ___ _ ________ ______ ______________ _ __ __________ ___ __ _________
  799. / __ \/ ____/ __ \/ / / / ____/ ___/_ __/ / | / | / / _/ |/ / |/_ __/ _/ __ \/ | / / / ____/ __ \/ | / |/ / ____/
  800. / /_/ / __/ / / / / / / / __/ \__ \ / / / /| | / |/ // // /|_/ / /| | / / / // / / / |/ / / /_ / /_/ / /| | / /|_/ / __/
  801. / _, _/ /___/ /_/ / /_/ / /___ ___/ // / / ___ |/ /| // // / / / ___ |/ / _/ // /_/ / /| / / __/ / _, _/ ___ |/ / / / /___
  802. /_/ |_/_____/\___\_\____/_____//____//_/ /_/ |_/_/ |_/___/_/ /_/_/ |_/_/ /___/\____/_/ |_/ /_/ /_/ |_/_/ |_/_/ /_/_____/
  803. */
  804. (function() {
  805. var lastTime = 0;
  806. var vendors = ['ms', 'moz', 'webkit', 'o'];
  807. for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  808. window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
  809. window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
  810. || window[vendors[x]+'CancelRequestAnimationFrame'];
  811. }
  812. if (!window.requestAnimationFrame)
  813. window.requestAnimationFrame = function(callback, element) {
  814. var currTime = new Date().getTime();
  815. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  816. var id = window.setTimeout(function() { callback(currTime + timeToCall); },
  817. timeToCall);
  818. lastTime = currTime + timeToCall;
  819. return id;
  820. };
  821. if (!window.cancelAnimationFrame)
  822. window.cancelAnimationFrame = function(id) {
  823. clearTimeout(id);
  824. };
  825. }());
  826. /*
  827. ____ __ __ _____________ _______
  828. / __ \/ / / / / / ____/ _/ | / / ___/
  829. / /_/ / / / / / / / __ / // |/ /\__ \
  830. / ____/ /___/ /_/ / /_/ // // /| /___/ /
  831. /_/ /_____/\____/\____/___/_/ |_//____/
  832. */
  833. // translate3d
  834. (function($) {
  835. $.fn.translate3d = function(opt) {
  836. opt = $.extend({x:0,y:0,z:0}, opt);
  837. var t = "translate3d("+opt.x+"px, "+opt.y+"px,"+opt.z+"px)";
  838. this.css({
  839. "-webkit-transform": t,
  840. "-moz-transform": t,
  841. "-ms-transform": t,
  842. "-o-transform": t,
  843. "transform": t
  844. });
  845. };
  846. })(jQuery);