PageSourceSearch

https://disniverse.com/assets/js/gsap-motion.js

js disniverse.com collected 2026-10-09 05:20:22 UTC 6,116 bytes, 223 lines download raw bytes

1import { isNarrowViewport, motionEnabled } from './motion.js';
2
3const SCROLL_START = 'top 88%';
4const SCROLL_ENTER = 'top bottom';
5
6function scrollReveal(gsap, targets, vars, trigger, start = SCROLL_START) {
7  const items = gsap.utils.toArray(targets);
8  if (!items.length || !trigger) return;
9
10  gsap.from(items, {
11    y: vars.y ?? 16,
12    duration: vars.duration,
13    stagger: vars.stagger ?? 0,
14    ease: vars.ease,
15    immediateRender: false,
16    scrollTrigger: {
17      trigger,
18      start,
19      once: true,
20      toggleActions: 'play none none none',
21    },
22  });
23}
24
25function animateHero(gsap, narrow, y, duration, ease) {
26  const heroInner = document.querySelector('.hero__inner');
27  if (!heroInner) return;
28
29  const timeline = gsap.timeline({ defaults: { ease, duration: narrow ? duration * 0.85 : duration } });
30  const logo = heroInner.querySelector('.hero__logo');
31  const title = heroInner.querySelector('.hero__title');
32  const desc = heroInner.querySelector('.hero__desc');
33  const actions = heroInner.querySelector('.hero__actions');
34
35  if (logo) {
36    timeline.from(logo, narrow ? { autoAlpha: 0, y: y * 0.6 } : { autoAlpha: 0, y, scale: 0.94 });
37  }
38  if (title) timeline.from(title, { autoAlpha: 0, y: y * 0.85 }, '-=0.42');
39  if (desc) timeline.from(desc, { autoAlpha: 0, y: y * 0.7 }, '-=0.44');
40  if (actions) timeline.from(actions, { autoAlpha: 0, y: y * 0.5 }, '-=0.38');
41}
42
43function animateSectionHeaders(gsap, y, duration, ease) {
44  gsap.utils.toArray('.section__header').forEach((header) => {
45    scrollReveal(gsap, header, { y, duration, ease }, header, SCROLL_ENTER);
46  });
47}
48
49function animateCardGrid(gsap, narrow, y, duration, ease, stagger) {
50  const community = document.getElementById('community');
51  const panel = community?.querySelector('.section__panel');
52  if (!community || !panel) return;
53
54  scrollReveal(
55    gsap,
56    narrow ? panel : gsap.utils.toArray('.card-grid .card'),
57    {
58      y: narrow ? y * 0.45 : y * 0.55,
59      duration: narrow ? duration * 0.85 : duration,
60      stagger: narrow ? 0 : stagger,
61      ease,
62    },
63    community,
64    SCROLL_ENTER
65  );
66}
67
68function animateFeatureBlocks(gsap, narrow, y, duration, ease) {
69  const motion = {
70    y: y * (narrow ? 0.45 : 0.6),
71    duration: narrow ? duration * 0.85 : duration,
72    ease,
73  };
74
75  gsap.utils.toArray('.spotlight, .showcase').forEach((block) => {
76    const section = block.closest('.section');
77    scrollReveal(gsap, block, motion, section || block, SCROLL_ENTER);
78  });
79
80  document.querySelectorAll('.pin-scene').forEach((pinScene) => {
81    const layers = pinScene.querySelectorAll('.pin-scene__copy, .pin-scene__stack');
82    if (!layers.length) return;
83
84    scrollReveal(
85      gsap,
86      layers,
87      { ...motion, stagger: narrow ? 0 : 0.08 },
88      pinScene.closest('.section') || pinScene,
89      SCROLL_ENTER
90    );
91  });
92}
93
94function animateJoinSection(gsap, narrow, y, duration, ease) {
95  const joinSection = document.getElementById('join');
96  const joinLayout = document.querySelector('#join .join-layout');
97  if (!joinSection || !joinLayout) return;
98
99  scrollReveal(
100    gsap,
101    joinLayout,
102    { y: y * (narrow ? 0.45 : 0.6), duration: narrow ? duration * 0.85 : duration, ease },
103    joinSection,
104    SCROLL_ENTER
105  );
106}
107
108function animateFaq(gsap, narrow, y, duration, ease) {
109  const faqSection = document.getElementById('faq');
110  const faq = faqSection?.querySelector('.faq');
111  if (!faqSection || !faq) return;
112
113  scrollReveal(
114    gsap,
115    narrow ? faq : gsap.utils.toArray('.faq__item'),
116    {
117      y: y * 0.4,
118      duration: duration * 0.85,
119      stagger: narrow ? 0 : 0.04,
120      ease,
121    },
122    faqSection,
123    SCROLL_ENTER
124  );
125}
126
127function animateHeader() {
128  const header = document.getElementById('site-header');
129  if (!header) return;
130
131  let isScrolled = header.classList.contains('is-scrolled');
132
133  const update = () => {
134    const next = window.scrollY > 24;
135    if (next === isScrolled) return;
136    isScrolled = next;
137    header.classList.toggle('is-scrolled', next);
138  };
139
140  window.addEventListener('scroll', update, { passive: true });
141  update();
142}
143
144function animateSkyGlow(gsap, narrow) {
145  if (narrow) return;
146
147  const skyGlow = document.querySelector('.sky__glow');
148  if (!skyGlow) return;
149
150  gsap.to(skyGlow, {
151    yPercent: 10,
152    ease: 'none',
153    scrollTrigger: {
154      trigger: document.documentElement,
155      start: 'top top',
156      end: 'bottom bottom',
157      scrub: 0.5,
158    },
159  });
160}
161
162function completePassedTriggers() {
163  const ScrollTrigger = window.ScrollTrigger;
164  if (!ScrollTrigger) return;
165
166  const scroll = ScrollTrigger.scroll();
167
168  ScrollTrigger.getAll().forEach((trigger) => {
169    const animation = trigger.animation;
170    if (!animation || animation.progress() > 0) return;
171    if (trigger.start >= scroll) return;
172
173    animation.progress(1);
174    trigger.kill(false);
175  });
176}
177
178function refreshScrollMotion(ScrollTrigger) {
179  ScrollTrigger.refresh();
180  completePassedTriggers();
181}
182
183export function initGsapMotion() {
184  const gsap = window.gsap;
185  const ScrollTrigger = window.ScrollTrigger;
186
187  if (!gsap || !ScrollTrigger || !motionEnabled()) {
188    return;
189  }
190
191  gsap.registerPlugin(ScrollTrigger);
192  ScrollTrigger.config({
193    ignoreMobileResize: true,
194    autoRefreshEvents: 'visibilitychange,DOMContentLoaded,load',
195  });
196
197  document.documentElement.classList.add('js-motion');
198
199  const narrow = isNarrowViewport();
200  const y = narrow ? 10 : 22;
201  const duration = narrow ? 0.38 : 0.6;
202  const stagger = narrow ? 0 : 0.06;
203  const ease = 'power2.out';
204
205  animateHero(gsap, narrow, y, duration, ease);
206  animateSectionHeaders(gsap, y, duration, ease);
207  animateCardGrid(gsap, narrow, y, duration, ease, stagger);
208  animateFeatureBlocks(gsap, narrow, y, duration, ease);
209  animateJoinSection(gsap, narrow, y, duration, ease);
210  animateFaq(gsap, narrow, y, duration, ease);
211  animateHeader();
212  animateSkyGlow(gsap, narrow);
213
214  refreshScrollMotion(ScrollTrigger);
215
216  window.addEventListener(
217    'orientationchange',
218    () => {
219      window.setTimeout(() => refreshScrollMotion(ScrollTrigger), 150);
220    },
221    { passive: true }
222  );
223}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.