PageSourceSearch

https://gv-lastfm-playground.vercel.app/js/animations/JoyDivision.anime.js

js gv-lastfm-playground.vercel.app collected 2026-10-03 07:02:43 UTC 4,035 bytes, 163 lines download raw bytes

1import {delay} from "./settings.anime.js";
2
3export const joyDivisionChartAnimation = (
4  element,
5  slide,
6  animationDirection
7) => {
8  let series = element.querySelectorAll("td path.highcharts-graph");
9  let indicator = element.querySelector("#joy-division-indicator");
10  let indicatorHeight = indicator.offsetHeight;
11  let firstWeekLabel = element.querySelector("#joy-division-first-week-label");
12  let tableBody = element.querySelector("#tbody-sparkline");
13  let tableFooter = element.querySelector("#joy-division-footer-ticks");
14  let tds = Array.from(element.querySelectorAll("td.joy-division-sparkline"));
15  let stagger = 45;
16  // remove the footer height
17  let height = element.offsetHeight - 48;
18
19
20  let animateInInit = () => {
21    slide.classList.add("stop-animation");
22
23    let fadeOutIndicator = () => {
24      anime({
25        duration: 100,
26        targets: indicator,
27        delay: 0,
28        opacity: [1, 0],
29        easing: "linear",
30      });
31    };
32
33    let fadeInFooter = () => {
34      anime({
35        targets: indicator,
36        duration: 500,
37        delay: 0,
38        translateY: height - indicatorHeight / 2,
39        easing: "linear",
40      });
41      anime({
42        duration: 500,
43        targets: [tableFooter],
44        delay: 0,
45        translateY: ["50%", "0%"],
46        opacity: [0, 1],
47        easing: "linear",
48        complete: (_) => {
49          fadeOutIndicator();
50        },
51      });
52    };
53
54    // Joy division Animations
55    anime({
56      targets: series,
57      duration: stagger,
58      delay: anime.stagger(stagger),
59      opacity: [0.15, 1],
60      easing: "linear",
61      begin: function (anim) {
62        //   // Anime.js doesn't support dropshadow
63        //   // so the halo effect can only be achived using
64        //   // keyframes inside LESS
65        tds.forEach((td, index) => {
66          setTimeout(() => {
67            td.classList.add("animate-in");
68            // sum of all lines adds up to 4000ms
69          }, anim.animations[index].delay);
70        });
71      },
72    });
73
74    // Initial first week indicator animation
75    anime({
76      targets: firstWeekLabel,
77      duration: 2000,
78      opacity: [1, 0],
79      easing: "linear",
80    });
81
82    // Week indicator animation
83    anime({
84      targets: indicator,
85      duration: stagger * series.length,
86      round: true,
87      innerHTML: 52,
88      translateY: `${height}px`,
89      easing: "linear",
90      begin: (_) => {
91        // for some reasone, anime.js can't animate opacity
92        // and number count at the same time, so we manually
93        // control the opacity.
94        indicator.classList.add("animate-opacity");
95      },
96      update: (anim) => {
97        const value = anim.animations[0].currentValue;
98        if (value === 52) {
99          indicator;
100          indicator.innerHTML = `Week ${value}`;
101        }
102      },
103      complete: () => {
104        fadeInFooter();
105      },
106    });
107  };
108
109  let animateIn = () => {
110    anime({
111      targets: tableBody,
112      duration: 383,
113      delay: delay + 333,
114      opacity: [0, 1],
115      translateY: [-20, 0],
116      easing: "cubicBezier(0.17, 0.24, 0.06, 1.00)",
117    });
118
119    anime({
120      targets: tableFooter,
121      duration: 383,
122      delay: delay + 383,
123      opacity: [0, 1],
124      translateY: [-20, 0],
125      easing: "cubicBezier(0.17, 0.24, 0.06, 1.00)",
126    });
127  };
128
129  let animateOut = () => {
130    anime({
131      targets: tableBody,
132      duration: 383,
133      delay: 38,
134      opacity: [1, 0],
135      translateY: [0, -20],
136      easing: "cubicBezier(0.84,0.00,0.81,1.00)",
137    });
138
139    anime({
140      targets: tableFooter,
141      duration: 383,
142      delay: 76,
143      opacity: [1, 0],
144      translateY: [0, -20],
145      easing: "cubicBezier(0.84,0.00,0.81,1.00)",
146    });
147  };
148
149  if (!slide.className.includes("stop-animation")) {
150    setTimeout(
151      () => {
152        animateInInit();
153      },
154      delay + 1000 // allow heading to animate first
155    );
156  } else {
157    if (animationDirection === "animateIn") {
158      animateIn();
159    } else {
160      animateOut();
161    }
162  }
163};

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.