├── .editorconfig
├── .gitignore
├── .npmignore
├── .prettierrc
├── LICENSE
├── README.md
├── demo
├── run-once.css
├── run-once.html
├── track-progress.css
└── track-progress.html
├── package-lock.json
├── package.json
└── src
├── index.js
├── run-once.js
└── track-progress.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = tab
5 | indent_size = 4
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 | end_of_line = lf
10 | max_line_length = 200
11 | quote_type = single
12 |
13 | [*.md]
14 | trim_trailing_whitespace = false
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist/*
2 | node_modules
3 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | demo
2 | src
3 | .editorconfig
4 | .gitignore
5 | .prettierrc
6 | package-lock.json
7 | .github
8 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2023 Bramus Van Damme - https://www.bram.us/
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Scroll-Driven Animations Utilities
2 |
3 | Collection of utility functions for use with Scroll-Driven Animations
4 |
5 | ## Installation
6 |
7 | ```bash
8 | npm i @bramus/sda-utilities
9 | ```
10 |
11 | ## The Utilities
12 |
13 | ### `runOnce` – Run Scroll-Driven Animation only once
14 |
15 | Example: run the `fade-in` animation on the `.hero` element only once.
16 |
17 | ```js
18 | import { runOnce } from '@bramus/sda-utilities';
19 |
20 | window.addEventListener('load', (e) => {
21 | const $hero = document.querySelector('#hero');
22 | runOnce($hero, 'fade-in');
23 | });
24 | ```
25 |
26 | ### `trackProgress` – Sync the progress of an effect to something external
27 |
28 | Example: output the animation progress as text on the page.
29 |
30 | ```js
31 | import { trackProgress } from '@bramus/sda-utilities';
32 |
33 | window.addEventListener('load', (e) => {
34 | trackProgress(document.querySelector('.animation-subject').getAnimations()[0], (progress) => {
35 | document.querySelector('.animation-subject').innerText = `${(progress * 100).toFixed(5)}%`;
36 | });
37 | });
38 | ```
39 |
40 | ## Demos
41 |
42 | Demos are included in this repository. Run `npm run dev` and visit `http://127.0.0.1:8000/` to see the demos.
43 |
44 | ```bash
45 | npm run dev
46 | ```
47 |
48 | ## License
49 |
50 | `@bramus/sda-utilities` is released under the MIT public license. See the enclosed `LICENSE` for details.
51 |
--------------------------------------------------------------------------------
/demo/run-once.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | }
5 |
6 | header,
7 | footer {
8 | height: 100dvh;
9 | display: grid;
10 | place-content: center;
11 | text-align: center;
12 | }
13 |
14 | main {
15 | width: 90vw;
16 | max-width: 800px;
17 | margin: 0 auto;
18 | }
19 |
20 | ul.photos {
21 | display: grid;
22 | grid-auto-flow: dense;
23 | grid-template-columns: repeat(4, 1fr);
24 | padding: 1vw 0;
25 | gap: 1vw;
26 | }
27 |
28 | li {
29 | list-style: none;
30 | }
31 |
32 | .photo {
33 | animation: animate-in ease-in both;
34 | animation-timeline: view();
35 | animation-range: entry 25% entry calc(50% + 300px);
36 | transform-origin: 50% 100%;
37 | border-radius: 1vw;
38 | overflow: hidden;
39 | }
40 |
41 | @keyframes animate-in {
42 | from {
43 | opacity: 0.2;
44 | scale: 0.8;
45 | translate: 0 10%;
46 | }
47 | 99% {
48 | outline: none;
49 | }
50 | 100% {
51 | outline: 2px solid lime;
52 | outline-offset: -2px;
53 | }
54 | }
55 |
56 | img {
57 | display: block;
58 | width: 100%;
59 | height: auto;
60 | }
61 |
62 | li:nth-child(5n),
63 | li:nth-child(7n + 3),
64 | li:nth-child(3n) {
65 | grid-row: span 2;
66 | grid-column: span 2;
67 | }
68 |
--------------------------------------------------------------------------------
/demo/run-once.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Scroll-Driven Animations Utilities: runOnce
8 |
9 |
20 |
21 |
22 |
23 |
24 | Run Scroll-Driven Animations only once
25 | Demo for runOnce
26 | Scroll ↕
27 |
28 |
29 |
30 | 
31 | 
32 | 
33 | 
34 | 
35 | 
36 | 
37 | 
38 | 
39 | 
40 | 
41 | 
42 | 
43 | 
44 | 
45 | 
46 | 
47 | 
48 | 
49 | 
50 | 
51 | 
52 | 
53 | 
54 | 
55 | 
56 | 
57 | 
58 | 
59 | 
60 | 
61 | 
62 | 
63 | 
64 | 
65 | 
66 | 
67 | 
68 | 
69 | 
70 | 
71 | 
72 | 
73 | 
74 | 
75 | 
76 | 
77 | 
78 | 
79 | 
80 | 
81 | 
82 | 
83 | 
84 | 
85 | 
86 | 
87 | 
88 | 
89 | 
90 | 
91 | 
92 | 
93 | 
94 | 
95 | 
96 | 
97 | 
98 | 
99 | 
100 | 
101 | 
102 | 
103 | 
104 | 
105 | 
106 | 
107 | 
108 | 
109 | 
110 | 
111 | 
112 | 
113 | 
114 | 
115 | 
116 | 
117 | 
118 | 
119 | 
120 | 
121 | 
122 | 
123 | 
124 | 
125 | 
126 | 
127 | 
128 | 
129 | 
130 | 
131 | 
132 | 
133 | 
134 | 
135 | 
136 | 
137 | 
138 | 
139 | 
140 | 
141 | 
142 | 
143 | 
144 | 
145 | 
146 | 
147 | 
148 | 
149 | 
150 | 
151 | 
152 | 
153 | 
154 | 
155 | 
156 | 
157 | 
158 | 
159 | 
160 | 
161 | 
162 | 
163 | 
164 | 
165 | 
166 | 
167 | 
168 | 
169 | 
170 | 
171 | 
172 | 
173 | 
174 | 
175 | 
176 | 
177 | 
178 | 
179 | 
180 | 
181 | 
182 | 
183 | 
184 | 
185 | 
186 | 
187 | 
188 | 
189 | 
190 | 
191 | 
192 | 
193 | 
194 | 
195 | 
196 | 
197 | 
198 | 
199 | 
200 | 
201 | 
202 | 
203 | 
204 | 
205 | 
206 | 
207 | 
208 | 
209 | 
210 | 
211 | 
212 | 
213 | 
214 | 
215 | 
216 | 
217 | 
218 | 
219 | 
220 | 
221 | 
222 | 
223 | 
224 | 
225 | 
226 | 
227 |
228 |
229 |
232 |
233 |
234 |
235 |
--------------------------------------------------------------------------------
/demo/track-progress.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | body {
8 | padding: 150vh 0;
9 | display: grid;
10 | place-content: center;
11 | }
12 |
13 | video {
14 | display: block;
15 | position: fixed;
16 | top: 25vh;
17 | left: 1em;
18 | height: 50vh;
19 | width: auto;
20 | z-index: 1;
21 | border: 1px solid #ccc;
22 | }
23 |
24 | @media (orientation: portrait) {
25 | video {
26 | height: auto;
27 | width: 80vw;
28 | }
29 | }
30 |
31 | @keyframes foo {
32 | to {
33 | scale: 1;
34 | }
35 | }
36 |
37 | .animation-subject {
38 | animation: foo linear both;
39 | animation-timeline: view();
40 | animation-range: cover;
41 |
42 | transform-origin: 0% 50%;
43 | height: 24px;
44 | width: 100vw;
45 | background: hotpink;
46 | display: grid;
47 | place-content: center;
48 | }
49 |
50 | header,
51 | footer {
52 | position: fixed;
53 | left: 0;
54 | right: 0;
55 | text-align: center;
56 | font-style: italic;
57 | }
58 | header {
59 | top: 1em;
60 | }
61 | footer {
62 | bottom: 0;
63 | }
64 |
65 | @layer warning {
66 | .warning {
67 | box-sizing: border-box;
68 | padding: 1em;
69 | margin: 1em 0;
70 | border: 1px solid #ccc;
71 | background: rgba(255 255 205 / 0.8);
72 |
73 | position: fixed;
74 | bottom: 1em;
75 | font-size: 2em;
76 | left: 1em;
77 | right: 1em;
78 | max-width: 80ch;
79 | margin: 0 auto;
80 | z-index: 1000;
81 | }
82 |
83 | .warning > :first-child {
84 | margin-top: 0;
85 | }
86 |
87 | .warning > :last-child {
88 | margin-bottom: 0;
89 | }
90 |
91 | .warning a {
92 | color: blue;
93 | }
94 | .warning--info {
95 | border: 1px solid #123456;
96 | background: rgb(205 230 255 / 0.8);
97 | }
98 | .warning--alarm {
99 | border: 1px solid red;
100 | background: #ff000010;
101 | }
102 |
103 | @supports (animation-timeline: view()) {
104 | .warning:not([data-bug]) {
105 | display: none;
106 | }
107 | }
108 |
109 | @supports (animation-range: 0vh 90vh) {
110 | .warning[data-bug="1427062"] {
111 | display: none;
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/demo/track-progress.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Scroll-Driven Animations Utilities: trackProgress
7 |
8 |
15 |
16 |
17 |
18 | Demo showing trackProgress
19 |
20 |
21 | 0%
22 |
23 |
24 |
⚠️ Your browser does not support Scroll-driven Animations. Please use Chrome 115 or newer.
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bramus/sda-utilities",
3 | "version": "1.1.1",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@bramus/sda-utilities",
9 | "version": "1.1.1",
10 | "license": "MIT",
11 | "devDependencies": {
12 | "esbuild": "^0.24.0",
13 | "prettier": "^3.4.1"
14 | }
15 | },
16 | "node_modules/@esbuild/aix-ppc64": {
17 | "version": "0.24.0",
18 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz",
19 | "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==",
20 | "cpu": [
21 | "ppc64"
22 | ],
23 | "dev": true,
24 | "license": "MIT",
25 | "optional": true,
26 | "os": [
27 | "aix"
28 | ],
29 | "engines": {
30 | "node": ">=18"
31 | }
32 | },
33 | "node_modules/@esbuild/android-arm": {
34 | "version": "0.24.0",
35 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz",
36 | "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==",
37 | "cpu": [
38 | "arm"
39 | ],
40 | "dev": true,
41 | "license": "MIT",
42 | "optional": true,
43 | "os": [
44 | "android"
45 | ],
46 | "engines": {
47 | "node": ">=18"
48 | }
49 | },
50 | "node_modules/@esbuild/android-arm64": {
51 | "version": "0.24.0",
52 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz",
53 | "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==",
54 | "cpu": [
55 | "arm64"
56 | ],
57 | "dev": true,
58 | "license": "MIT",
59 | "optional": true,
60 | "os": [
61 | "android"
62 | ],
63 | "engines": {
64 | "node": ">=18"
65 | }
66 | },
67 | "node_modules/@esbuild/android-x64": {
68 | "version": "0.24.0",
69 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz",
70 | "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==",
71 | "cpu": [
72 | "x64"
73 | ],
74 | "dev": true,
75 | "license": "MIT",
76 | "optional": true,
77 | "os": [
78 | "android"
79 | ],
80 | "engines": {
81 | "node": ">=18"
82 | }
83 | },
84 | "node_modules/@esbuild/darwin-arm64": {
85 | "version": "0.24.0",
86 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz",
87 | "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==",
88 | "cpu": [
89 | "arm64"
90 | ],
91 | "dev": true,
92 | "license": "MIT",
93 | "optional": true,
94 | "os": [
95 | "darwin"
96 | ],
97 | "engines": {
98 | "node": ">=18"
99 | }
100 | },
101 | "node_modules/@esbuild/darwin-x64": {
102 | "version": "0.24.0",
103 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz",
104 | "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==",
105 | "cpu": [
106 | "x64"
107 | ],
108 | "dev": true,
109 | "license": "MIT",
110 | "optional": true,
111 | "os": [
112 | "darwin"
113 | ],
114 | "engines": {
115 | "node": ">=18"
116 | }
117 | },
118 | "node_modules/@esbuild/freebsd-arm64": {
119 | "version": "0.24.0",
120 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz",
121 | "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==",
122 | "cpu": [
123 | "arm64"
124 | ],
125 | "dev": true,
126 | "license": "MIT",
127 | "optional": true,
128 | "os": [
129 | "freebsd"
130 | ],
131 | "engines": {
132 | "node": ">=18"
133 | }
134 | },
135 | "node_modules/@esbuild/freebsd-x64": {
136 | "version": "0.24.0",
137 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz",
138 | "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==",
139 | "cpu": [
140 | "x64"
141 | ],
142 | "dev": true,
143 | "license": "MIT",
144 | "optional": true,
145 | "os": [
146 | "freebsd"
147 | ],
148 | "engines": {
149 | "node": ">=18"
150 | }
151 | },
152 | "node_modules/@esbuild/linux-arm": {
153 | "version": "0.24.0",
154 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz",
155 | "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==",
156 | "cpu": [
157 | "arm"
158 | ],
159 | "dev": true,
160 | "license": "MIT",
161 | "optional": true,
162 | "os": [
163 | "linux"
164 | ],
165 | "engines": {
166 | "node": ">=18"
167 | }
168 | },
169 | "node_modules/@esbuild/linux-arm64": {
170 | "version": "0.24.0",
171 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz",
172 | "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==",
173 | "cpu": [
174 | "arm64"
175 | ],
176 | "dev": true,
177 | "license": "MIT",
178 | "optional": true,
179 | "os": [
180 | "linux"
181 | ],
182 | "engines": {
183 | "node": ">=18"
184 | }
185 | },
186 | "node_modules/@esbuild/linux-ia32": {
187 | "version": "0.24.0",
188 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz",
189 | "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==",
190 | "cpu": [
191 | "ia32"
192 | ],
193 | "dev": true,
194 | "license": "MIT",
195 | "optional": true,
196 | "os": [
197 | "linux"
198 | ],
199 | "engines": {
200 | "node": ">=18"
201 | }
202 | },
203 | "node_modules/@esbuild/linux-loong64": {
204 | "version": "0.24.0",
205 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz",
206 | "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==",
207 | "cpu": [
208 | "loong64"
209 | ],
210 | "dev": true,
211 | "license": "MIT",
212 | "optional": true,
213 | "os": [
214 | "linux"
215 | ],
216 | "engines": {
217 | "node": ">=18"
218 | }
219 | },
220 | "node_modules/@esbuild/linux-mips64el": {
221 | "version": "0.24.0",
222 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz",
223 | "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==",
224 | "cpu": [
225 | "mips64el"
226 | ],
227 | "dev": true,
228 | "license": "MIT",
229 | "optional": true,
230 | "os": [
231 | "linux"
232 | ],
233 | "engines": {
234 | "node": ">=18"
235 | }
236 | },
237 | "node_modules/@esbuild/linux-ppc64": {
238 | "version": "0.24.0",
239 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz",
240 | "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==",
241 | "cpu": [
242 | "ppc64"
243 | ],
244 | "dev": true,
245 | "license": "MIT",
246 | "optional": true,
247 | "os": [
248 | "linux"
249 | ],
250 | "engines": {
251 | "node": ">=18"
252 | }
253 | },
254 | "node_modules/@esbuild/linux-riscv64": {
255 | "version": "0.24.0",
256 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz",
257 | "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==",
258 | "cpu": [
259 | "riscv64"
260 | ],
261 | "dev": true,
262 | "license": "MIT",
263 | "optional": true,
264 | "os": [
265 | "linux"
266 | ],
267 | "engines": {
268 | "node": ">=18"
269 | }
270 | },
271 | "node_modules/@esbuild/linux-s390x": {
272 | "version": "0.24.0",
273 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz",
274 | "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==",
275 | "cpu": [
276 | "s390x"
277 | ],
278 | "dev": true,
279 | "license": "MIT",
280 | "optional": true,
281 | "os": [
282 | "linux"
283 | ],
284 | "engines": {
285 | "node": ">=18"
286 | }
287 | },
288 | "node_modules/@esbuild/linux-x64": {
289 | "version": "0.24.0",
290 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz",
291 | "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==",
292 | "cpu": [
293 | "x64"
294 | ],
295 | "dev": true,
296 | "license": "MIT",
297 | "optional": true,
298 | "os": [
299 | "linux"
300 | ],
301 | "engines": {
302 | "node": ">=18"
303 | }
304 | },
305 | "node_modules/@esbuild/netbsd-x64": {
306 | "version": "0.24.0",
307 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz",
308 | "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==",
309 | "cpu": [
310 | "x64"
311 | ],
312 | "dev": true,
313 | "license": "MIT",
314 | "optional": true,
315 | "os": [
316 | "netbsd"
317 | ],
318 | "engines": {
319 | "node": ">=18"
320 | }
321 | },
322 | "node_modules/@esbuild/openbsd-arm64": {
323 | "version": "0.24.0",
324 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz",
325 | "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==",
326 | "cpu": [
327 | "arm64"
328 | ],
329 | "dev": true,
330 | "license": "MIT",
331 | "optional": true,
332 | "os": [
333 | "openbsd"
334 | ],
335 | "engines": {
336 | "node": ">=18"
337 | }
338 | },
339 | "node_modules/@esbuild/openbsd-x64": {
340 | "version": "0.24.0",
341 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz",
342 | "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==",
343 | "cpu": [
344 | "x64"
345 | ],
346 | "dev": true,
347 | "license": "MIT",
348 | "optional": true,
349 | "os": [
350 | "openbsd"
351 | ],
352 | "engines": {
353 | "node": ">=18"
354 | }
355 | },
356 | "node_modules/@esbuild/sunos-x64": {
357 | "version": "0.24.0",
358 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz",
359 | "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==",
360 | "cpu": [
361 | "x64"
362 | ],
363 | "dev": true,
364 | "license": "MIT",
365 | "optional": true,
366 | "os": [
367 | "sunos"
368 | ],
369 | "engines": {
370 | "node": ">=18"
371 | }
372 | },
373 | "node_modules/@esbuild/win32-arm64": {
374 | "version": "0.24.0",
375 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz",
376 | "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==",
377 | "cpu": [
378 | "arm64"
379 | ],
380 | "dev": true,
381 | "license": "MIT",
382 | "optional": true,
383 | "os": [
384 | "win32"
385 | ],
386 | "engines": {
387 | "node": ">=18"
388 | }
389 | },
390 | "node_modules/@esbuild/win32-ia32": {
391 | "version": "0.24.0",
392 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz",
393 | "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==",
394 | "cpu": [
395 | "ia32"
396 | ],
397 | "dev": true,
398 | "license": "MIT",
399 | "optional": true,
400 | "os": [
401 | "win32"
402 | ],
403 | "engines": {
404 | "node": ">=18"
405 | }
406 | },
407 | "node_modules/@esbuild/win32-x64": {
408 | "version": "0.24.0",
409 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz",
410 | "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==",
411 | "cpu": [
412 | "x64"
413 | ],
414 | "dev": true,
415 | "license": "MIT",
416 | "optional": true,
417 | "os": [
418 | "win32"
419 | ],
420 | "engines": {
421 | "node": ">=18"
422 | }
423 | },
424 | "node_modules/esbuild": {
425 | "version": "0.24.0",
426 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz",
427 | "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==",
428 | "dev": true,
429 | "hasInstallScript": true,
430 | "license": "MIT",
431 | "bin": {
432 | "esbuild": "bin/esbuild"
433 | },
434 | "engines": {
435 | "node": ">=18"
436 | },
437 | "optionalDependencies": {
438 | "@esbuild/aix-ppc64": "0.24.0",
439 | "@esbuild/android-arm": "0.24.0",
440 | "@esbuild/android-arm64": "0.24.0",
441 | "@esbuild/android-x64": "0.24.0",
442 | "@esbuild/darwin-arm64": "0.24.0",
443 | "@esbuild/darwin-x64": "0.24.0",
444 | "@esbuild/freebsd-arm64": "0.24.0",
445 | "@esbuild/freebsd-x64": "0.24.0",
446 | "@esbuild/linux-arm": "0.24.0",
447 | "@esbuild/linux-arm64": "0.24.0",
448 | "@esbuild/linux-ia32": "0.24.0",
449 | "@esbuild/linux-loong64": "0.24.0",
450 | "@esbuild/linux-mips64el": "0.24.0",
451 | "@esbuild/linux-ppc64": "0.24.0",
452 | "@esbuild/linux-riscv64": "0.24.0",
453 | "@esbuild/linux-s390x": "0.24.0",
454 | "@esbuild/linux-x64": "0.24.0",
455 | "@esbuild/netbsd-x64": "0.24.0",
456 | "@esbuild/openbsd-arm64": "0.24.0",
457 | "@esbuild/openbsd-x64": "0.24.0",
458 | "@esbuild/sunos-x64": "0.24.0",
459 | "@esbuild/win32-arm64": "0.24.0",
460 | "@esbuild/win32-ia32": "0.24.0",
461 | "@esbuild/win32-x64": "0.24.0"
462 | }
463 | },
464 | "node_modules/prettier": {
465 | "version": "3.4.1",
466 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.1.tgz",
467 | "integrity": "sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==",
468 | "dev": true,
469 | "license": "MIT",
470 | "bin": {
471 | "prettier": "bin/prettier.cjs"
472 | },
473 | "engines": {
474 | "node": ">=14"
475 | },
476 | "funding": {
477 | "url": "https://github.com/prettier/prettier?sponsor=1"
478 | }
479 | }
480 | },
481 | "dependencies": {
482 | "@esbuild/aix-ppc64": {
483 | "version": "0.24.0",
484 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz",
485 | "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==",
486 | "dev": true,
487 | "optional": true
488 | },
489 | "@esbuild/android-arm": {
490 | "version": "0.24.0",
491 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz",
492 | "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==",
493 | "dev": true,
494 | "optional": true
495 | },
496 | "@esbuild/android-arm64": {
497 | "version": "0.24.0",
498 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz",
499 | "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==",
500 | "dev": true,
501 | "optional": true
502 | },
503 | "@esbuild/android-x64": {
504 | "version": "0.24.0",
505 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz",
506 | "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==",
507 | "dev": true,
508 | "optional": true
509 | },
510 | "@esbuild/darwin-arm64": {
511 | "version": "0.24.0",
512 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz",
513 | "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==",
514 | "dev": true,
515 | "optional": true
516 | },
517 | "@esbuild/darwin-x64": {
518 | "version": "0.24.0",
519 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz",
520 | "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==",
521 | "dev": true,
522 | "optional": true
523 | },
524 | "@esbuild/freebsd-arm64": {
525 | "version": "0.24.0",
526 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz",
527 | "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==",
528 | "dev": true,
529 | "optional": true
530 | },
531 | "@esbuild/freebsd-x64": {
532 | "version": "0.24.0",
533 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz",
534 | "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==",
535 | "dev": true,
536 | "optional": true
537 | },
538 | "@esbuild/linux-arm": {
539 | "version": "0.24.0",
540 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz",
541 | "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==",
542 | "dev": true,
543 | "optional": true
544 | },
545 | "@esbuild/linux-arm64": {
546 | "version": "0.24.0",
547 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz",
548 | "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==",
549 | "dev": true,
550 | "optional": true
551 | },
552 | "@esbuild/linux-ia32": {
553 | "version": "0.24.0",
554 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz",
555 | "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==",
556 | "dev": true,
557 | "optional": true
558 | },
559 | "@esbuild/linux-loong64": {
560 | "version": "0.24.0",
561 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz",
562 | "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==",
563 | "dev": true,
564 | "optional": true
565 | },
566 | "@esbuild/linux-mips64el": {
567 | "version": "0.24.0",
568 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz",
569 | "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==",
570 | "dev": true,
571 | "optional": true
572 | },
573 | "@esbuild/linux-ppc64": {
574 | "version": "0.24.0",
575 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz",
576 | "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==",
577 | "dev": true,
578 | "optional": true
579 | },
580 | "@esbuild/linux-riscv64": {
581 | "version": "0.24.0",
582 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz",
583 | "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==",
584 | "dev": true,
585 | "optional": true
586 | },
587 | "@esbuild/linux-s390x": {
588 | "version": "0.24.0",
589 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz",
590 | "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==",
591 | "dev": true,
592 | "optional": true
593 | },
594 | "@esbuild/linux-x64": {
595 | "version": "0.24.0",
596 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz",
597 | "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==",
598 | "dev": true,
599 | "optional": true
600 | },
601 | "@esbuild/netbsd-x64": {
602 | "version": "0.24.0",
603 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz",
604 | "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==",
605 | "dev": true,
606 | "optional": true
607 | },
608 | "@esbuild/openbsd-arm64": {
609 | "version": "0.24.0",
610 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz",
611 | "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==",
612 | "dev": true,
613 | "optional": true
614 | },
615 | "@esbuild/openbsd-x64": {
616 | "version": "0.24.0",
617 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz",
618 | "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==",
619 | "dev": true,
620 | "optional": true
621 | },
622 | "@esbuild/sunos-x64": {
623 | "version": "0.24.0",
624 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz",
625 | "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==",
626 | "dev": true,
627 | "optional": true
628 | },
629 | "@esbuild/win32-arm64": {
630 | "version": "0.24.0",
631 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz",
632 | "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==",
633 | "dev": true,
634 | "optional": true
635 | },
636 | "@esbuild/win32-ia32": {
637 | "version": "0.24.0",
638 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz",
639 | "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==",
640 | "dev": true,
641 | "optional": true
642 | },
643 | "@esbuild/win32-x64": {
644 | "version": "0.24.0",
645 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz",
646 | "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==",
647 | "dev": true,
648 | "optional": true
649 | },
650 | "esbuild": {
651 | "version": "0.24.0",
652 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz",
653 | "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==",
654 | "dev": true,
655 | "requires": {
656 | "@esbuild/aix-ppc64": "0.24.0",
657 | "@esbuild/android-arm": "0.24.0",
658 | "@esbuild/android-arm64": "0.24.0",
659 | "@esbuild/android-x64": "0.24.0",
660 | "@esbuild/darwin-arm64": "0.24.0",
661 | "@esbuild/darwin-x64": "0.24.0",
662 | "@esbuild/freebsd-arm64": "0.24.0",
663 | "@esbuild/freebsd-x64": "0.24.0",
664 | "@esbuild/linux-arm": "0.24.0",
665 | "@esbuild/linux-arm64": "0.24.0",
666 | "@esbuild/linux-ia32": "0.24.0",
667 | "@esbuild/linux-loong64": "0.24.0",
668 | "@esbuild/linux-mips64el": "0.24.0",
669 | "@esbuild/linux-ppc64": "0.24.0",
670 | "@esbuild/linux-riscv64": "0.24.0",
671 | "@esbuild/linux-s390x": "0.24.0",
672 | "@esbuild/linux-x64": "0.24.0",
673 | "@esbuild/netbsd-x64": "0.24.0",
674 | "@esbuild/openbsd-arm64": "0.24.0",
675 | "@esbuild/openbsd-x64": "0.24.0",
676 | "@esbuild/sunos-x64": "0.24.0",
677 | "@esbuild/win32-arm64": "0.24.0",
678 | "@esbuild/win32-ia32": "0.24.0",
679 | "@esbuild/win32-x64": "0.24.0"
680 | }
681 | },
682 | "prettier": {
683 | "version": "3.4.1",
684 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.1.tgz",
685 | "integrity": "sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==",
686 | "dev": true
687 | }
688 | }
689 | }
690 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bramus/sda-utilities",
3 | "version": "1.1.1",
4 | "description": "Collection of utility functions for use with Scroll-Driven Animations",
5 | "type": "module",
6 | "main": "./dist/index.cjs",
7 | "module": "./dist/index.js",
8 | "exports": {
9 | ".": {
10 | "browser": "./dist/index.js",
11 | "import": "./dist/index.js",
12 | "require": "./dist/index.cjs"
13 | }
14 | },
15 | "unpkg": "./dist/index.js",
16 | "jsdelivr": "./dist/index.js",
17 | "files": [
18 | "src",
19 | "dist"
20 | ],
21 | "scripts": {
22 | "build-esm": "esbuild --bundle ./src/index.js --outfile=./dist/index.js --format=esm --sourcemap --minify",
23 | "build-cjs": "esbuild --bundle ./src/index.js --outfile=./dist/index.cjs --format=cjs --sourcemap --minify",
24 | "lint": "prettier --check '{src,test,demo}/**/*.{ts,tsx,js,jsx}'",
25 | "prettier": "prettier --write '{src,test,demo}/**/*.{ts,tsx,js,jsx}'",
26 | "build": "npm run build-esm && npm run build-cjs",
27 | "dev": "esbuild --bundle ./src/index.js --outfile=./demo/sda-utilities.js --format=esm --sourcemap --minify --watch --servedir=demo",
28 | "prepack": "npm run prevent-dirty-tree && npm run test",
29 | "prepublish": "npm run build",
30 | "pretest": "npm run build",
31 | "test": "echo \"No tests specified\"",
32 | "preversion": "npm run prevent-dirty-tree && npm run test",
33 | "prevent-dirty-tree": "exit $(git status --porcelain | wc -l)"
34 | },
35 | "repository": {
36 | "type": "git",
37 | "url": "git+https://github.com/bramus/sda-utilities.git"
38 | },
39 | "keywords": [
40 | "css",
41 | "scroll-driven animations"
42 | ],
43 | "author": {
44 | "name": "Bramus Van Damme",
45 | "email": "bramus@bram.us",
46 | "twitter": "@bramus",
47 | "web": "https://www.bram.us/"
48 | },
49 | "license": "MIT",
50 | "bugs": {
51 | "url": "https://github.com/bramus/sda-utilities/issues"
52 | },
53 | "homepage": "https://github.com/bramus/sda-utilities#readme",
54 | "devDependencies": {
55 | "esbuild": "^0.24.0",
56 | "prettier": "^3.4.1"
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import trackProgress from './track-progress.js';
2 | import runOnce from './run-once.js';
3 |
4 | export { runOnce, trackProgress };
5 |
--------------------------------------------------------------------------------
/src/run-once.js:
--------------------------------------------------------------------------------
1 | // Run a Scroll-Driven Animation only once
2 | // This relies on:
3 | // - An animation of a given name to be applied only once onto an element.
4 | // - The `animation-fill-mode` being set to `forwards` or `both` in case the end frame is not the default styling.
5 | const runOnce = ($el, animationName = null) => {
6 | const animations = $el.getAnimations();
7 |
8 | const shouldAnimationBeStopped = (animation, animationName = null) => {
9 | if (!(animation.timeline instanceof ScrollTimeline)) return false;
10 |
11 | if (animationName === null) {
12 | return true;
13 | }
14 |
15 | return animation.animationName === animationName;
16 | };
17 |
18 | $el.addEventListener('animationend', (e) => {
19 | // animationend is also triggered when back at the start. Ignore those.
20 | if (e.elapsedTime == 0) return;
21 |
22 | // Extract animation
23 | // Could get the wrong one though, see https://github.com/w3c/csswg-drafts/issues/9010 for details
24 | const animation = animations.find((a) => a.animationName == e.animationName);
25 |
26 | // Only process if the animation name matches
27 | if (shouldAnimationBeStopped(animation, animationName)) {
28 | // Give a warning when the fill mode is not the correct one
29 | if (!['forwards', 'both'].includes(animation.effect.getComputedTiming().fill)) {
30 | console.warn(`The fillMode for the animation “${animationName}” is not set to \`forwards\`. This can cause a glitch when removing the animation.`);
31 | }
32 |
33 | // Commit the styles and remove the animation
34 | animation.commitStyles();
35 | animation.cancel();
36 | }
37 | });
38 | };
39 |
40 | export default runOnce;
41 |
--------------------------------------------------------------------------------
/src/track-progress.js:
--------------------------------------------------------------------------------
1 | const trackProgressThroughEffect = (animation, cb, precision) => {
2 | let progress = null;
3 |
4 | const updateValue = () => {
5 | if (animation && animation.currentTime) {
6 | let newProgress = animation.effect.getComputedTiming().progress * 1;
7 | if (animation.playState === 'finished') newProgress = 1;
8 | newProgress = Math.max(0.0, Math.min(1.0, newProgress)).toFixed(precision);
9 |
10 | if (newProgress != progress) {
11 | progress = newProgress;
12 | cb(progress);
13 | }
14 | }
15 | requestAnimationFrame(updateValue);
16 | };
17 |
18 | requestAnimationFrame(updateValue);
19 | };
20 |
21 | // Note: once we have a `progress` event on an Animation, we can drop the rAF
22 | const trackProgressThroughAnimation = (animation, cb, precision) => {
23 | let progress = null;
24 |
25 | const updateValue = () => {
26 | if (animation && animation.currentTime) {
27 | let newProgress = animation.overallProgress.toFixed(precision);
28 |
29 | if (newProgress != progress) {
30 | progress = newProgress;
31 | cb(progress);
32 | }
33 | }
34 | requestAnimationFrame(updateValue);
35 | };
36 |
37 | requestAnimationFrame(updateValue);
38 | };
39 |
40 | const trackProgress = (animation, cb, precision = 5) => {
41 | if (("Animation" in globalThis && "overallProgress" in Animation.prototype)) {
42 | trackProgressThroughAnimation(animation, cb, precision);
43 | } else {
44 | trackProgressThroughEffect(animation, cb, precision);
45 | }
46 | };
47 |
48 | export default trackProgress;
49 |
--------------------------------------------------------------------------------