PageSourceSearch

https://www.discourse.org/a/js/features-icons-animation.js?1790174693181339485

js discourse.org collected 2026-09-24 06:55:07 UTC 1,747 bytes, 81 lines download raw bytes

1document.addEventListener("DOMContentLoaded", function () {
2  if (typeof gsap === "undefined") {
3    // eslint-disable-next-line no-console
4    console.warn("GSAP not loaded");
5    return;
6  }
7
8  const scrollTriggerAvailable =
9    typeof ScrollTriggerUtils !== "undefined" && ScrollTriggerUtils.register();
10
11  const featuresSection = document.querySelector(".features-section");
12  const iconContainer = document.querySelector(".floating-icon-container");
13
14  if (!featuresSection || !iconContainer) {
15    return;
16  }
17
18  const iconFrames = document.querySelectorAll(
19    ".floating-icon-container .icon-frame"
20  );
21
22  if (iconFrames.length === 0) {
23    return;
24  }
25
26  iconFrames.forEach((icon) => {
27    gsap.set(icon, {
28      opacity: 0,
29      scale: 0.92,
30      y: 15,
31      transformOrigin: "center center",
32    });
33  });
34
35  if (scrollTriggerAvailable) {
36    const tl = gsap.timeline({
37      scrollTrigger: {
38        trigger: featuresSection,
39        start: "top 80%",
40        end: "bottom 20%",
41        toggleActions: "play none none none",
42        once: true,
43      },
44    });
45
46    tl.to(iconFrames, {
47      opacity: 1,
48      scale: 1,
49      y: 0,
50      duration: 0.5,
51      ease: "power1.out",
52      stagger: {
53        amount: 0.6,
54        from: "start",
55      },
56      force3D: true,
57    });
58
59    let resizeTimer;
60    window.addEventListener("resize", () => {
61      clearTimeout(resizeTimer);
62      resizeTimer = setTimeout(() => {
63        ScrollTrigger.refresh();
64      }, 250);
65    });
66  } else {
67    gsap.to(iconFrames, {
68      opacity: 1,
69      scale: 1,
70      y: 0,
71      duration: 0.5,
72      ease: "power1.out",
73      stagger: {
74        amount: 0.6,
75        from: "start",
76      },
77      force3D: true,
78      delay: 0.2,
79    });
80  }
81});

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.