PageSourceSearch

https://www.vistra.com/themes/custom/vistra2024/js/animate-grid.js?tlu1y1

js vistra.com collected 2026-09-24 18:12:51 UTC 4,228 bytes, 128 lines download raw bytes

1/**
2 * @file
3 * Grid item stagger animation behavior.
4 */
5(function (Drupal, once) {
6  'use strict';
7
8  const GRID_CONFIG = {
9    containerSelector: '.js-animate-grid',
10    itemSelector: '.js-animate-grid-item',
11    duration: 0.96,
12    stagger: 0.212,
13    yOffsetPercent: 50,
14    ease: "power2.out",
15    startLocationRow1: "top 80%",
16    startLocationRow2: "top 85%",
17    debug: false,
18    desktopBreakpoint: "(min-width: 768px)",
19    mobileBreakpoint: "(max-width: 767px)"
20  };
21
22  Drupal.behaviors.animateGrid = {
23    attach: function (context) {
24      if (typeof gsap === 'undefined' || typeof ScrollTrigger === 'undefined') {
25        return;
26      }
27
28      gsap.registerPlugin(ScrollTrigger);
29
30      const gridContainers = once('animateGrid', GRID_CONFIG.containerSelector, context);
31
32      gridContainers.forEach((gridContainer) => {
33
34        // Skip GSAP animation completely for tabs 2 and 3
35        if (gridContainer.closest('.is-tab-two-or-three')) {
36          return;
37        }
38
39        const gridItems = Array.from(gridContainer.querySelectorAll(GRID_CONFIG.itemSelector));
40        const isMobileFade = gridContainer.classList.contains('js-mobile-fade');
41
42        if (gridItems.length === 7) {
43
44          const row1 = gridItems.slice(0, 3); // Items 1, 2, 3
45          const row2 = gridItems.slice(3, 7); // Items 4, 5, 6, 7
46
47          // Helper function for the standard desktop/default behavior
48          const createDefaultAnimations = () => {
49            // Animate Row 1
50            gsap.fromTo(row1,
51              { yPercent: GRID_CONFIG.yOffsetPercent, autoAlpha: 0 },
52              {
53                scrollTrigger: {
54                  trigger: row1[0],
55                  start: GRID_CONFIG.startLocationRow1,
56                  markers: GRID_CONFIG.debug,
57                },
58                duration: GRID_CONFIG.duration,
59                yPercent: 0,
60                autoAlpha: 1,
61                stagger: GRID_CONFIG.stagger,
62                ease: GRID_CONFIG.ease,
63              }
64            );
65
66            // Animate Row 2
67            gsap.fromTo(row2,
68              { yPercent: GRID_CONFIG.yOffsetPercent, autoAlpha: 0 },
69              {
70                scrollTrigger: {
71                  trigger: row2[0],
72                  start: GRID_CONFIG.startLocationRow2,
73                  markers: GRID_CONFIG.debug,
74                },
75                duration: GRID_CONFIG.duration,
76                yPercent: 0,
77                autoAlpha: 1,
78                stagger: GRID_CONFIG.stagger,
79                ease: GRID_CONFIG.ease,
80              }
81            );
82          };
83
84          // If the grid needs the specific mobile fade effect
85          if (isMobileFade) {
86            let mm = gsap.matchMedia();
87
88            mm.add({
89              isDesktop: GRID_CONFIG.desktopBreakpoint,
90              isMobile: GRID_CONFIG.mobileBreakpoint
91            }, (ctx) => {
92              let { isMobile } = ctx.conditions;
93
94              if (isMobile) {
95                // MOBILE LOGIC: Simple fade-in for all items simultaneously
96                gsap.fromTo(gridItems,
97                  {
98                    autoAlpha: 0,
99                    yPercent: 0 // Explicitly setting to 0 so there is no vertical jump
100                  },
101                  {
102                    scrollTrigger: {
103                      // Triggering on the container is safer since they all animate together
104                      trigger: gridContainer,
105                      start: GRID_CONFIG.startLocationRow1,
106                      markers: GRID_CONFIG.debug,
107                    },
108                    duration: 1.6,
109                    autoAlpha: 1,
110                    yPercent: 0,
111                    stagger: 0, // 0 ensures they all fade in exactly at the same time
112                    ease: GRID_CONFIG.ease,
113                  }
114                );
115              } else {
116                // DESKTOP LOGIC: Run the standard staggered rows
117                createDefaultAnimations();
118              }
119            });
120          } else {
121            // FALLBACK: Run the default animations for all screen sizes if the flag class isn't present
122            createDefaultAnimations();
123          }
124        }
125      });
126    }
127  };
128})(Drupal, once);

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.