studio.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Studio page — vanilla fade-carousel + tab sync + per-slide choreography.
  2. // Replaces Bootstrap Carousel/Tab, jQuery, and backstretch. Keeps DrawFillSVG
  3. // (window.DrawFillSVG, self-exposed from the v4-script bundle).
  4. // --- shared chrome: navbar hide/show on scroll (ported from jQuery dw_hidenav) ---
  5. (function () {
  6. const navbar = document.querySelector('.navbar');
  7. if (!navbar) return;
  8. const title = document.querySelector('.site-title a');
  9. const headerHeight = navbar.offsetHeight;
  10. let previousTop = 0;
  11. window.addEventListener('scroll', function () {
  12. const currentTop = window.scrollY;
  13. if (currentTop < previousTop) {
  14. if (currentTop > 0 && navbar.classList.contains('fixed')) {
  15. navbar.classList.add('visible');
  16. if (title) title.classList.remove('light');
  17. } else {
  18. navbar.classList.remove('visible', 'fixed');
  19. if (title) title.classList.add('light');
  20. }
  21. } else {
  22. navbar.classList.remove('visible');
  23. if (currentTop > headerHeight && !navbar.classList.contains('fixed')) {
  24. navbar.classList.add('fixed');
  25. }
  26. }
  27. previousTop = currentTop;
  28. }, { passive: true });
  29. })();
  30. document.querySelectorAll('.nav-toggle').forEach(function (el) {
  31. el.addEventListener('click', function (e) {
  32. e.preventDefault();
  33. el.classList.toggle('active');
  34. });
  35. });
  36. // --- studio fade-carousel ---
  37. (function () {
  38. const stage = document.getElementById('studio-caro');
  39. const caro = document.getElementById('caro');
  40. if (!stage || !caro) return;
  41. const slides = Array.from(caro.querySelectorAll('.dw-fade-slide'));
  42. const tabs = Array.from(document.querySelectorAll('.dw-studio-tab'));
  43. const panes = Array.from(document.querySelectorAll('#studio-tab .tab-pane'));
  44. const bg = stage.querySelector('.dw-studio-bg');
  45. const video = stage.querySelector('.dw-studio-video');
  46. const title = document.querySelector('.site-title a');
  47. const GRADS = ['caro-grad', 'caro-grad2', 'caro-grad3', 'caro-grad5'];
  48. // per slide: gradient class · background image · show video · navbar-title light
  49. const CONFIG = [
  50. { grad: 'caro-grad5', img: stage.dataset.bg0 || null, video: false, light: true }, // 0 Studio
  51. { grad: 'caro-grad', img: null, video: false, light: true }, // 1 Web
  52. { grad: 'caro-grad2', img: null, video: false, light: true }, // 2 UX
  53. { grad: 'caro-grad3', img: null, video: false, light: false }, // 3 Graphic
  54. { grad: 'caro-grad5', img: null, video: true, light: true }, // 4 Media
  55. { grad: 'caro-grad5', img: stage.dataset.bg5 || null, video: false, light: true }, // 5 Art
  56. ];
  57. const INTERVAL = 5000;
  58. let index = 0;
  59. let timer = null;
  60. function drawSVGs(slide) {
  61. if (!window.DrawFillSVG) return;
  62. slide.querySelectorAll('svg[id]').forEach(function (svg) {
  63. try {
  64. new window.DrawFillSVG({ elementId: svg.id }).replay();
  65. } catch (e) {
  66. /* svg not animatable — skip */
  67. }
  68. });
  69. }
  70. function activate(i) {
  71. i = (i + slides.length) % slides.length;
  72. index = i;
  73. const cfg = CONFIG[i];
  74. slides.forEach((s, n) => {
  75. const on = n === i;
  76. s.classList.toggle('active', on);
  77. // reveal the active slide's content (slides 2/3/5 ship with .hide-svg)
  78. const animac = s.querySelector('.animac');
  79. if (animac && on) animac.classList.remove('hide-svg');
  80. });
  81. tabs.forEach((t, n) => t.classList.toggle('active', n === i));
  82. panes.forEach((p, n) => p.classList.toggle('active', n === i));
  83. GRADS.forEach((g) => stage.classList.remove(g));
  84. stage.classList.add(cfg.grad);
  85. if (bg) bg.style.backgroundImage = cfg.img ? 'url("' + cfg.img + '")' : '';
  86. if (video) {
  87. if (cfg.video) {
  88. video.style.display = 'block';
  89. video.play().catch(function () {});
  90. } else {
  91. video.pause();
  92. video.style.display = 'none';
  93. }
  94. }
  95. if (title) title.classList.toggle('light', cfg.light);
  96. drawSVGs(slides[i]);
  97. }
  98. function next() { activate(index + 1); }
  99. function start() { stop(); timer = window.setInterval(next, INTERVAL); }
  100. function stop() { if (timer) { window.clearInterval(timer); timer = null; } }
  101. tabs.forEach(function (t) {
  102. t.addEventListener('click', function (e) {
  103. e.preventDefault();
  104. activate(parseInt(t.dataset.slide, 10) || 0);
  105. start(); // restart the autoplay clock after manual navigation
  106. });
  107. });
  108. // pause autoplay while the pointer is over the hero
  109. stage.addEventListener('mouseenter', stop);
  110. stage.addEventListener('mouseleave', start);
  111. activate(0);
  112. start();
  113. })();