Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 

235 righe
7.4 KiB

  1. import Slider from './slider';
  2. const $ = require('jquery');
  3. class Timeline {
  4. constructor(section) {
  5. this.section = section;
  6. this.itemSlider = section.find('.item-slider');
  7. this.yearsWrapper = section.find('.years-wrapper');
  8. this.yearsContainer = section.find('.years .container');
  9. this.years = this.yearsWrapper.find('.year-item');
  10. this.initResize();
  11. this.initDragging();
  12. this.buildSlider();
  13. this.initYearClick();
  14. this.activateItem(0);
  15. this.initSwitch();
  16. // this.initDocking();
  17. }
  18. initDocking() {
  19. this.winPosition = 0;
  20. this.secPosition = $(this.section.parent()).offset().top;
  21. this.scrolling = false;
  22. $(window).on('scroll', () => {
  23. if (this.scrolling) {
  24. return false;
  25. }
  26. const st = $(window).scrollTop();
  27. if (st > this.winPosition && st < this.secPosition - 100) {
  28. this.scrolling = true;
  29. $('html, body').animate({scrollTop: this.secPosition - 100}, 200, () => {
  30. this.scrolling = false;
  31. })
  32. }
  33. this.winPosition = st;
  34. })
  35. }
  36. initSwitch() {
  37. this.switches = this.section.siblings('.timeline-tabs').find('a');
  38. this.switchSlides = [];
  39. this.switches.each((index, tab) => {
  40. const href = tab.href;
  41. const id = href.substr(href.indexOf('#'));
  42. const target = parseInt($(id).attr('data-index'));
  43. this.switchSlides.push(target);
  44. tab.setAttribute('data-index', index);
  45. tab.setAttribute('data-target', target);
  46. })
  47. this.slider.section.on('slide-change', () => {
  48. this.switches.removeClass('active');
  49. const cs = this.slider.currentSlide;
  50. let i = this.switchSlides.length - 1;
  51. while (i >= 0) {
  52. if (cs >= this.switchSlides[i]) {
  53. this.switches.eq(i).addClass('active');
  54. break;
  55. }
  56. i--;
  57. }
  58. })
  59. this.switches.on('click', (e) => {
  60. e.preventDefault();
  61. const target = parseInt(e.currentTarget.getAttribute('data-target'));
  62. this.slider.goTo(target, false);
  63. })
  64. }
  65. initResize() {
  66. this.resizeTimeout = null;
  67. $(window).on('resize', () => {
  68. if (this.resizeTimeout) {
  69. clearTimeout(this.resizeTimeout);
  70. }
  71. this.resizeTimeout = setTimeout(() => {
  72. this.handleResize();
  73. }, 200)
  74. })
  75. this.handleResize();
  76. }
  77. handleResize() {
  78. this.containerWidth = this.yearsContainer.width();
  79. this.wrapperWidth = this.yearsWrapper.get(0).scrollWidth;
  80. this.scrollWidth = this.containerWidth - this.wrapperWidth;
  81. this.yearsWrapper.css({'width': this.wrapperWidth + 'px'});
  82. }
  83. initDragging() {
  84. this.dragOffset = 0;
  85. this.wrapperOffset = 0;
  86. this.yearsWrapper.get(0).onmousedown = (e) => { this.dragStart(e) };
  87. this.yearsWrapper.get(0).addEventListener('touchstart', (e) => {this.dragStart(e)});
  88. this.yearsWrapper.get(0).addEventListener('touchend', (e) => {this.dragEnd(e)});
  89. this.yearsWrapper.get(0).addEventListener('touchmove', (e) => {this.dragMove(e)});
  90. }
  91. dragStart(e) {
  92. this.dragOffset = 0;
  93. this.dragLast = 0;
  94. if (e.type === 'touchstart') {
  95. this.dragOrigin = e.touches[0].clientX;
  96. } else {
  97. this.dragOrigin = e.clientX;
  98. document.onmouseup = (e) => { this.dragEnd(e) };
  99. document.onmousemove = (e) => { this.dragMove(e) };
  100. }
  101. }
  102. dragMove(e) {
  103. if (e.type === 'touchmove') {
  104. this.dragLast = this.dragOffset;
  105. this.dragOffset = this.dragOrigin - e.touches[0].clientX;
  106. } else {
  107. this.dragLast = this.dragOffset;
  108. this.dragOffset = this.dragOrigin - e.clientX;
  109. }
  110. if (Math.abs(this.dragOffset) > 3) {
  111. this.yearsWrapper.addClass('dragging');
  112. }
  113. this.wrapperTarget = this.wrapperOffset - this.dragOffset;
  114. if (this.wrapperTarget > 0) {
  115. this.wrapperTarget = this.wrapperTarget / 4;
  116. } else if (this.wrapperTarget < this.scrollWidth) {
  117. this.wrapperTarget = this.scrollWidth + (this.wrapperTarget - this.scrollWidth) / 4;
  118. }
  119. this.yearsWrapper.css({'transform': 'translateX(' + this.wrapperTarget + 'px)'});
  120. }
  121. dragEnd() {
  122. const velocity = this.dragOffset - this.dragLast;
  123. if (Math.abs(velocity) > 5) {
  124. this.wrapperTarget = this.wrapperTarget - velocity * 10;
  125. }
  126. const bounceBack = this.checkScrollEnd();
  127. this.yearsWrapper.removeClass('dragging');
  128. this.wrapperOffset = this.wrapperTarget;
  129. if (bounceBack || Math.abs(velocity) > 5) {
  130. this.animateToPosition();
  131. }
  132. document.onmouseup = null;
  133. document.onmousemove = null;
  134. }
  135. animateToPosition() {
  136. this.yearsWrapper.addClass('animate');
  137. requestAnimationFrame(() => {
  138. this.yearsWrapper.css({'transform': 'translateX(' + this.wrapperTarget + 'px)'});
  139. setTimeout(() => {
  140. this.yearsWrapper.removeClass('animate');
  141. }, 300);
  142. })
  143. }
  144. buildSlider() {
  145. const slides = this.itemSlider.addClass('slider').appendTo(this.itemSlider);
  146. this.years.find('.items > li').each((i, li) => {
  147. const listItem = $(li);
  148. listItem.attr('data-index', i).find('.slide').appendTo(slides);
  149. listItem.on('click', () => {
  150. this.slider.goTo(i, true);
  151. this.activateItem(i);
  152. })
  153. })
  154. this.slider = new Slider(slides);
  155. this.slider.section.on('slide-change', () => {
  156. this.activateItem(this.slider.currentSlide);
  157. })
  158. this.slides = this.slider.section.find('.slide');
  159. }
  160. initYearClick() {
  161. this.years.children('.year').on('click', (e) => {
  162. $(e.currentTarget).next('.items').children('li').first().trigger('click');
  163. })
  164. }
  165. activateItem(index) {
  166. this.years.removeClass('current').find('li.active').removeClass('active');
  167. const yearItem = this.years.find('li[data-index="' + index + '"]').addClass('active').closest('.year-item').addClass('current');
  168. const ww = $(window).width();
  169. const iw = yearItem.outerWidth() * 1.5;
  170. if (yearItem.offset().left + iw > ww || yearItem.offset().left < 50) {
  171. this.wrapperOffset = this.wrapperTarget = yearItem.position().left * -1;
  172. this.checkScrollEnd();
  173. this.animateToPosition();
  174. }
  175. if (this.slides.eq(index).hasClass('has-image')) {
  176. this.slider.section.addClass('hide-circle');
  177. } else {
  178. this.slider.section.removeClass('hide-circle');
  179. }
  180. }
  181. checkScrollEnd() {
  182. if (this.wrapperTarget > 0) {
  183. this.wrapperTarget = 0;
  184. return true;
  185. } else if (this.wrapperTarget < this.scrollWidth) {
  186. this.wrapperTarget = this.scrollWidth;
  187. return true;
  188. }
  189. return false;
  190. }
  191. }
  192. $('body').on('ihk-init dynamic-component-loaded gfi-dynamic-init', function () {
  193. $('.timeline:not(.initiated)').each((i, el) => {
  194. new Timeline($(el));
  195. })
  196. })