easing-scroll 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +106 -55
- package/dist/easing-scroll.cjs +1 -0
- package/dist/easing-scroll.d.cts +60 -0
- package/dist/easing-scroll.d.ts +60 -20
- package/dist/easing-scroll.js +1 -1
- package/package.json +23 -22
- package/dist/easing-scroll.mjs +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/index.mjs +0 -1
- package/src/easing-scroll.ts +0 -92
- package/src/index.ts +0 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
# easing-scroll
|
|
2
2
|
|
|
3
|
-
[](https://npmjs.org/package/easing-scroll)
|
|
4
|
+
[](https://bundlephobia.com/package/easing-scroll)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://www.typescriptlang.org)
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
Programmatic smooth scrolling with custom easing, abort support, and promise-based completion tracking.
|
|
9
|
+
|
|
10
|
+
[Demo](https://easing-scroll-liard.vercel.app)
|
|
11
|
+
|
|
12
|
+
## Highlights
|
|
13
|
+
|
|
14
|
+
- **Zero dependencies** — ~450 bytes min+gzip
|
|
15
|
+
- **TypeScript-first** — written in TypeScript, ships type declarations
|
|
16
|
+
- **Dual package** — ESM and CJS builds
|
|
17
|
+
- **Customizable** — bring your own [easing function](https://easings.net)
|
|
18
|
+
- **Cancellable** — abort with [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)
|
|
19
|
+
- **Promise-based** — `await` completion or track partial progress
|
|
20
|
+
- **Universal** — works with any scrollable `Element`
|
|
6
21
|
|
|
7
22
|
## Install
|
|
8
23
|
|
|
@@ -10,89 +25,125 @@
|
|
|
10
25
|
npm install easing-scroll
|
|
11
26
|
```
|
|
12
27
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- 📈 Customize [easing function](https://easings.net)
|
|
17
|
-
- 🚫 Abort scrolling ([AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal))
|
|
18
|
-
- 🔄 Waiting for animation to end
|
|
19
|
-
- ☸️ Supports vertical and horizontal scroll
|
|
28
|
+
```sh
|
|
29
|
+
pnpm add easing-scroll
|
|
30
|
+
```
|
|
20
31
|
|
|
21
|
-
##
|
|
32
|
+
## Quick Start
|
|
22
33
|
|
|
23
34
|
```ts
|
|
24
35
|
import { easingScroll } from "easing-scroll";
|
|
25
36
|
|
|
26
|
-
const
|
|
27
|
-
// Abort scrolling
|
|
28
|
-
// controller.abort(); ❌
|
|
29
|
-
|
|
30
|
-
const target = document.querySelector(".container");
|
|
37
|
+
const container = document.querySelector(".container");
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
signal: controller.signal,
|
|
37
|
-
// 👀 https://easings.net/#easeOutCubic
|
|
38
|
-
easing: (x) => 1 - Math.pow(1 - x, 3),
|
|
39
|
+
await easingScroll(container, {
|
|
40
|
+
top: 300,
|
|
41
|
+
duration: 400,
|
|
42
|
+
easing: (x) => 1 - Math.pow(1 - x, 3), // easeOutCubic
|
|
39
43
|
});
|
|
40
|
-
|
|
41
|
-
if (progress === 1) {
|
|
42
|
-
console.log("Completed");
|
|
43
|
-
} else {
|
|
44
|
-
console.log("Aborted");
|
|
45
|
-
}
|
|
46
44
|
```
|
|
47
45
|
|
|
48
|
-
|
|
46
|
+
## API
|
|
47
|
+
|
|
48
|
+
### `easingScroll(target, options): Promise<number>`
|
|
49
|
+
|
|
50
|
+
Smoothly scrolls `target` to the given position.
|
|
51
|
+
|
|
52
|
+
#### `target`
|
|
53
|
+
|
|
54
|
+
Type: `Element`
|
|
55
|
+
|
|
56
|
+
Any scrollable DOM element.
|
|
49
57
|
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
#### `options`
|
|
59
|
+
|
|
60
|
+
| Option | Type | Default | Description |
|
|
61
|
+
| ---------- | ----------------------- | ---------- | ---------------------------------------------------------------------------- |
|
|
62
|
+
| `top` | `number` | — | Target vertical scroll position in pixels |
|
|
63
|
+
| `left` | `number` | — | Target horizontal scroll position in pixels |
|
|
64
|
+
| `duration` | `number` | `0` | Animation duration in milliseconds |
|
|
65
|
+
| `easing` | `(t: number) => number` | `(t) => t` | [Easing function](https://easings.net) mapping progress (0–1) to eased value |
|
|
66
|
+
| `signal` | `AbortSignal` | — | Signal to cancel the animation |
|
|
67
|
+
|
|
68
|
+
#### Return value
|
|
69
|
+
|
|
70
|
+
Resolves with a `number` between `0` and `1` representing animation progress:
|
|
71
|
+
|
|
72
|
+
| Value | Meaning |
|
|
73
|
+
| ----------- | ---------------------------------------------------- |
|
|
74
|
+
| `1` | Animation completed fully |
|
|
75
|
+
| `0 < x < 1` | Animation was aborted at _x_ progress |
|
|
76
|
+
| `0` | Animation never started (signal was already aborted) |
|
|
77
|
+
|
|
78
|
+
### Behavior
|
|
79
|
+
|
|
80
|
+
- **Instant scroll** — when `duration` is `0` or negative, the element scrolls instantly and resolves `1`.
|
|
81
|
+
- **No-op** — when both `top` and `left` are omitted, resolves `1` immediately.
|
|
82
|
+
- **Clamping** — scroll values are clamped to the element's scrollable range. No visual flash occurs.
|
|
83
|
+
- **Already-aborted signal** — resolves `0` without scrolling.
|
|
84
|
+
|
|
85
|
+
## Examples
|
|
86
|
+
|
|
87
|
+
### Custom Easing
|
|
88
|
+
|
|
89
|
+
The default easing is linear `(t) => t`. Pass any function from [easings.net](https://easings.net):
|
|
52
90
|
|
|
53
91
|
```ts
|
|
54
|
-
easingScroll(
|
|
55
|
-
|
|
56
|
-
|
|
92
|
+
await easingScroll(element, {
|
|
93
|
+
top: 500,
|
|
94
|
+
duration: 600,
|
|
95
|
+
// https://easings.net/#easeOutCubic
|
|
57
96
|
easing: (x) => 1 - Math.pow(1 - x, 3),
|
|
58
97
|
});
|
|
59
98
|
```
|
|
60
99
|
|
|
61
|
-
### Abort
|
|
100
|
+
### Abort Scrolling
|
|
62
101
|
|
|
63
|
-
|
|
64
|
-
if you want to abort scrolling.
|
|
102
|
+
Use an `AbortController` to cancel an in-flight animation:
|
|
65
103
|
|
|
66
104
|
```ts
|
|
67
105
|
const controller = new AbortController();
|
|
68
|
-
setTimeout(() => {
|
|
69
|
-
controller.abort();
|
|
70
|
-
}, 100);
|
|
71
106
|
|
|
72
|
-
|
|
73
|
-
|
|
107
|
+
setTimeout(() => controller.abort(), 100);
|
|
108
|
+
|
|
109
|
+
const progress = await easingScroll(element, {
|
|
110
|
+
top: 1000,
|
|
111
|
+
duration: 400,
|
|
74
112
|
signal: controller.signal,
|
|
75
113
|
});
|
|
76
114
|
|
|
77
|
-
if (progress
|
|
78
|
-
console.log(
|
|
115
|
+
if (progress < 1) {
|
|
116
|
+
console.log(`Aborted at ${Math.round(progress * 100)}%`);
|
|
79
117
|
}
|
|
80
118
|
```
|
|
81
119
|
|
|
82
|
-
|
|
120
|
+
### React Hook
|
|
83
121
|
|
|
84
|
-
|
|
122
|
+
A reusable hook that cancels the previous scroll when dependencies change or the component unmounts:
|
|
85
123
|
|
|
86
|
-
|
|
124
|
+
```tsx
|
|
125
|
+
import { useEffect, RefObject } from "react";
|
|
126
|
+
import { easingScroll } from "easing-scroll";
|
|
87
127
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
128
|
+
function useEasingScroll(ref: RefObject<HTMLElement | null>, top: number) {
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
const target = ref.current;
|
|
131
|
+
if (!target) return;
|
|
92
132
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
133
|
+
const controller = new AbortController();
|
|
134
|
+
|
|
135
|
+
easingScroll(target, {
|
|
136
|
+
top,
|
|
137
|
+
duration: 400,
|
|
138
|
+
signal: controller.signal,
|
|
139
|
+
easing: (x) => 1 - Math.pow(1 - x, 3),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return () => controller.abort();
|
|
143
|
+
}, [top]);
|
|
97
144
|
}
|
|
98
145
|
```
|
|
146
|
+
|
|
147
|
+
## License
|
|
148
|
+
|
|
149
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var f=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var y=(e,n)=>{for(var s in n)f(e,s,{get:n[s],enumerable:!0})},A=(e,n,s,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of M(n))!v.call(e,o)&&o!==s&&f(e,o,{get:()=>n[o],enumerable:!(r=x(n,o))||r.enumerable});return e};var O=e=>A(f({},"__esModule",{value:!0}),e);var h={};y(h,{easingScroll:()=>F});module.exports=O(h);var k=e=>e,l=(e,n,s)=>{e.scrollTop=n??e.scrollTop,e.scrollLeft=s??e.scrollLeft},F=(e,{top:n,left:s,signal:r,duration:o=0,easing:p=k})=>r?.aborted?Promise.resolve(0):n===void 0&&s===void 0?Promise.resolve(1):o<=0?(l(e,n,s),Promise.resolve(1)):new Promise(P=>{let d=e.scrollTop,u=e.scrollLeft;l(e,n,s),n=e.scrollTop,s=e.scrollLeft,e.scrollTop=d,e.scrollLeft=u;let c,m,a=t=>c===void 0?0:(t-c)/o,b=()=>{cancelAnimationFrame(m);let t=Math.max(0,Math.min(a(performance.now()),1));P(t)};r?.addEventListener("abort",b,{once:!0});let L=t=>{c===void 0&&(c=t);let i=a(t),T=n===void 0?void 0:d+(n-d)*p(i),E=s===void 0?void 0:u+(s-u)*p(i);if(i<1)l(e,T,E),m=requestAnimationFrame(L);else{l(e,n,s),r?.removeEventListener("abort",b),P(1);return}};m=requestAnimationFrame(L)});0&&(module.exports={easingScroll});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Pixel value */
|
|
2
|
+
type Px = number;
|
|
3
|
+
/** Milliseconds value */
|
|
4
|
+
type Ms = number;
|
|
5
|
+
/**
|
|
6
|
+
* Progress percentage as a number between 0 and 1.
|
|
7
|
+
*
|
|
8
|
+
* - `0` — 0% (animation not started or aborted immediately)
|
|
9
|
+
* - `1` — 100% (animation completed)
|
|
10
|
+
* - `0 < value < 1` — partial progress (animation was aborted mid-way)
|
|
11
|
+
*/
|
|
12
|
+
type Pct = number;
|
|
13
|
+
type Options = {
|
|
14
|
+
/** Target vertical scroll position in pixels */
|
|
15
|
+
top?: Px;
|
|
16
|
+
/** Target horizontal scroll position in pixels */
|
|
17
|
+
left?: Px;
|
|
18
|
+
/**
|
|
19
|
+
* Animation duration in milliseconds.
|
|
20
|
+
* If `0` or negative, scrolls instantly without animation.
|
|
21
|
+
* @default 0
|
|
22
|
+
*/
|
|
23
|
+
duration?: Ms;
|
|
24
|
+
/**
|
|
25
|
+
* An `AbortSignal` to cancel the scroll animation.
|
|
26
|
+
* When aborted, the promise resolves with the current progress (0–1).
|
|
27
|
+
*/
|
|
28
|
+
signal?: AbortSignal;
|
|
29
|
+
/**
|
|
30
|
+
* Easing function that maps animation progress `t` (0–1) to eased value.
|
|
31
|
+
* @default linear
|
|
32
|
+
* @see Easing functions https://easings.net
|
|
33
|
+
*/
|
|
34
|
+
easing?: (t: Pct) => Pct;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Smoothly scroll an element to the given position using a custom easing function.
|
|
38
|
+
*
|
|
39
|
+
* @param target - The scrollable HTML element
|
|
40
|
+
* @param options - Scroll options (top, left, duration, easing, signal)
|
|
41
|
+
* @returns A promise that resolves with the animation progress:
|
|
42
|
+
* - `1` if the animation completed fully
|
|
43
|
+
* - `0` if the signal was already aborted before starting
|
|
44
|
+
* - `0 < value < 1` if the animation was aborted mid-way
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const controller = new AbortController();
|
|
49
|
+
*
|
|
50
|
+
* const progress = await easingScroll(element, {
|
|
51
|
+
* top: 500,
|
|
52
|
+
* duration: 400,
|
|
53
|
+
* easing: (t) => 1 - Math.pow(1 - t, 3), // easeOutCubic
|
|
54
|
+
* signal: controller.signal,
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
declare const easingScroll: <E extends Element>(target: E, { top, left, signal, duration, easing }: Options) => Promise<Pct>;
|
|
59
|
+
|
|
60
|
+
export { easingScroll };
|
package/dist/easing-scroll.d.ts
CHANGED
|
@@ -1,20 +1,60 @@
|
|
|
1
|
-
|
|
2
|
-
type
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
/** Pixel value */
|
|
2
|
+
type Px = number;
|
|
3
|
+
/** Milliseconds value */
|
|
4
|
+
type Ms = number;
|
|
5
|
+
/**
|
|
6
|
+
* Progress percentage as a number between 0 and 1.
|
|
7
|
+
*
|
|
8
|
+
* - `0` — 0% (animation not started or aborted immediately)
|
|
9
|
+
* - `1` — 100% (animation completed)
|
|
10
|
+
* - `0 < value < 1` — partial progress (animation was aborted mid-way)
|
|
11
|
+
*/
|
|
12
|
+
type Pct = number;
|
|
13
|
+
type Options = {
|
|
14
|
+
/** Target vertical scroll position in pixels */
|
|
15
|
+
top?: Px;
|
|
16
|
+
/** Target horizontal scroll position in pixels */
|
|
17
|
+
left?: Px;
|
|
18
|
+
/**
|
|
19
|
+
* Animation duration in milliseconds.
|
|
20
|
+
* If `0` or negative, scrolls instantly without animation.
|
|
21
|
+
* @default 0
|
|
22
|
+
*/
|
|
23
|
+
duration?: Ms;
|
|
24
|
+
/**
|
|
25
|
+
* An `AbortSignal` to cancel the scroll animation.
|
|
26
|
+
* When aborted, the promise resolves with the current progress (0–1).
|
|
27
|
+
*/
|
|
28
|
+
signal?: AbortSignal;
|
|
29
|
+
/**
|
|
30
|
+
* Easing function that maps animation progress `t` (0–1) to eased value.
|
|
31
|
+
* @default linear
|
|
32
|
+
* @see Easing functions https://easings.net
|
|
33
|
+
*/
|
|
34
|
+
easing?: (t: Pct) => Pct;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Smoothly scroll an element to the given position using a custom easing function.
|
|
38
|
+
*
|
|
39
|
+
* @param target - The scrollable HTML element
|
|
40
|
+
* @param options - Scroll options (top, left, duration, easing, signal)
|
|
41
|
+
* @returns A promise that resolves with the animation progress:
|
|
42
|
+
* - `1` if the animation completed fully
|
|
43
|
+
* - `0` if the signal was already aborted before starting
|
|
44
|
+
* - `0 < value < 1` if the animation was aborted mid-way
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const controller = new AbortController();
|
|
49
|
+
*
|
|
50
|
+
* const progress = await easingScroll(element, {
|
|
51
|
+
* top: 500,
|
|
52
|
+
* duration: 400,
|
|
53
|
+
* easing: (t) => 1 - Math.pow(1 - t, 3), // easeOutCubic
|
|
54
|
+
* signal: controller.signal,
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
declare const easingScroll: <E extends Element>(target: E, { top, left, signal, duration, easing }: Options) => Promise<Pct>;
|
|
59
|
+
|
|
60
|
+
export { easingScroll };
|
package/dist/easing-scroll.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
var E=e=>e,c=(e,n,s)=>{e.scrollTop=n??e.scrollTop,e.scrollLeft=s??e.scrollLeft},x=(e,{top:n,left:s,signal:i,duration:m=0,easing:f=E})=>i?.aborted?Promise.resolve(0):n===void 0&&s===void 0?Promise.resolve(1):m<=0?(c(e,n,s),Promise.resolve(1)):new Promise(p=>{let l=e.scrollTop,d=e.scrollLeft;c(e,n,s),n=e.scrollTop,s=e.scrollLeft,e.scrollTop=l,e.scrollLeft=d;let r,u,P=o=>r===void 0?0:(o-r)/m,a=()=>{cancelAnimationFrame(u);let o=Math.max(0,Math.min(P(performance.now()),1));p(o)};i?.addEventListener("abort",a,{once:!0});let b=o=>{r===void 0&&(r=o);let t=P(o),L=n===void 0?void 0:l+(n-l)*f(t),T=s===void 0?void 0:d+(s-d)*f(t);if(t<1)c(e,L,T),u=requestAnimationFrame(b);else{c(e,n,s),i?.removeEventListener("abort",a),p(1);return}};u=requestAnimationFrame(b)});export{x as easingScroll};
|
package/package.json
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "easing-scroll",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "♿️ Smooth scrolling",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"
|
|
7
|
-
"main": "dist/index.js",
|
|
8
|
-
"module": "dist/index.mjs",
|
|
9
|
-
"types": "dist/index.d.ts",
|
|
6
|
+
"types": "dist/easing-scroll.d.ts",
|
|
10
7
|
"exports": {
|
|
11
8
|
".": {
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
"import": "./dist/easing-scroll.mjs",
|
|
19
|
-
"default": "./dist/easing-scroll.mjs"
|
|
9
|
+
"types": "./dist/easing-scroll.d.ts",
|
|
10
|
+
"require": {
|
|
11
|
+
"types": "./dist/easing-scroll.d.cts",
|
|
12
|
+
"default": "./dist/easing-scroll.cjs"
|
|
13
|
+
},
|
|
14
|
+
"import": "./dist/easing-scroll.js"
|
|
20
15
|
}
|
|
21
16
|
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"sideEffects": false,
|
|
22
21
|
"scripts": {
|
|
22
|
+
"test": "vitest run",
|
|
23
23
|
"check-types": "tsc",
|
|
24
|
-
"
|
|
25
|
-
"build": "npm run clean && rollup -c",
|
|
24
|
+
"build": "tsup src/easing-scroll.ts --format cjs,esm --dts --minify --clean",
|
|
26
25
|
"release:patch": "npm version patch",
|
|
27
26
|
"preversion": "npm run check-types && npm run build",
|
|
28
|
-
"postversion": "git add . && git push && git push --tags && npm publish"
|
|
27
|
+
"postversion": "git add . && git push && git push --tags && npm publish",
|
|
28
|
+
"prepare": "husky"
|
|
29
29
|
},
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|
|
@@ -43,12 +43,13 @@
|
|
|
43
43
|
"url": "https://github.com/faustienf/easing-scroll/issues"
|
|
44
44
|
},
|
|
45
45
|
"homepage": "https://github.com/faustienf/easing-scroll#readme",
|
|
46
|
-
"prettier": {},
|
|
47
46
|
"devDependencies": {
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
47
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
48
|
+
"esbuild": "^0.27.3",
|
|
49
|
+
"husky": "^9.1.7",
|
|
50
|
+
"jsdom": "^28.1.0",
|
|
51
|
+
"tsup": "^8.5.1",
|
|
52
|
+
"typescript": "^5.9.3",
|
|
53
|
+
"vitest": "^4.0.18"
|
|
53
54
|
}
|
|
54
55
|
}
|
package/dist/easing-scroll.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const u=o=>o,t=(o,r,n)=>{o.scrollTop=r??o.scrollTop,o.scrollLeft=n??o.scrollLeft},g=(o,{top:r,left:n,signal:l,duration:c=0,easing:a=u})=>l?.aborted?Promise.resolve(0):c?new Promise(i=>{const m=o.scrollTop,v=o.scrollLeft;t(o,r,n),r=o.scrollTop,n=o.scrollLeft;const L=performance.now();let s;const d=()=>(performance.now()-L)/c,p=()=>{cancelAnimationFrame(s);const e=d();i(e)};l?.addEventListener("abort",p);const f=()=>{const e=d(),T=r===void 0?void 0:m+(r-m)*a(e),b=n===void 0?void 0:v+(n-v)*a(e);e<1?(t(o,T,b),s=requestAnimationFrame(f)):(t(o,r,n),l?.removeEventListener("abort",p),i(1))};s=requestAnimationFrame(f)}):(t(o,r,n),Promise.resolve(1));export{g as easingScroll};
|
package/dist/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { easingScroll } from "./easing-scroll";
|
package/dist/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const b=o=>o,t=(o,l,n)=>{o.scrollTop=l!=null?l:o.scrollTop,o.scrollLeft=n!=null?n:o.scrollLeft},g=(o,{top:l,left:n,signal:s,duration:i=0,easing:a=b})=>s!=null&&s.aborted?Promise.resolve(0):i?new Promise(c=>{const m=o.scrollTop,v=o.scrollLeft;t(o,l,n),l=o.scrollTop,n=o.scrollLeft;const d=performance.now();let r;const f=()=>(performance.now()-d)/i,p=()=>{cancelAnimationFrame(r);const e=f();c(e)};s==null||s.addEventListener("abort",p);const u=()=>{const e=f(),L=l===void 0?void 0:m+(l-m)*a(e),T=n===void 0?void 0:v+(n-v)*a(e);e<1?(t(o,L,T),r=requestAnimationFrame(u)):(t(o,l,n),s==null||s.removeEventListener("abort",p),c(1))};r=requestAnimationFrame(u)}):(t(o,l,n),Promise.resolve(1));exports.easingScroll=g;
|
package/dist/index.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const u=o=>o,t=(o,r,n)=>{o.scrollTop=r??o.scrollTop,o.scrollLeft=n??o.scrollLeft},g=(o,{top:r,left:n,signal:l,duration:c=0,easing:a=u})=>l?.aborted?Promise.resolve(0):c?new Promise(i=>{const m=o.scrollTop,v=o.scrollLeft;t(o,r,n),r=o.scrollTop,n=o.scrollLeft;const L=performance.now();let s;const d=()=>(performance.now()-L)/c,p=()=>{cancelAnimationFrame(s);const e=d();i(e)};l?.addEventListener("abort",p);const f=()=>{const e=d(),T=r===void 0?void 0:m+(r-m)*a(e),b=n===void 0?void 0:v+(n-v)*a(e);e<1?(t(o,T,b),s=requestAnimationFrame(f)):(t(o,r,n),l?.removeEventListener("abort",p),i(1))};s=requestAnimationFrame(f)}):(t(o,r,n),Promise.resolve(1));export{g as easingScroll};
|
package/src/easing-scroll.ts
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
type Px = number;
|
|
2
|
-
type Ms = number;
|
|
3
|
-
/**
|
|
4
|
-
* Percent is number 0 - 1
|
|
5
|
-
*
|
|
6
|
-
* 0 = 0%, 1 = 100%
|
|
7
|
-
*/
|
|
8
|
-
type Pct = number;
|
|
9
|
-
|
|
10
|
-
type Options = {
|
|
11
|
-
top?: Px;
|
|
12
|
-
left?: Px;
|
|
13
|
-
duration?: Ms;
|
|
14
|
-
signal?: AbortSignal;
|
|
15
|
-
/**
|
|
16
|
-
* @see Easing functions https://easings.net
|
|
17
|
-
*/
|
|
18
|
-
easing?: (t: Pct) => Pct;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const linear = (t: number): number => t;
|
|
22
|
-
|
|
23
|
-
const scrollTo = <E extends HTMLElement>(
|
|
24
|
-
target: E,
|
|
25
|
-
top: Options["top"],
|
|
26
|
-
left: Options["left"]
|
|
27
|
-
) => {
|
|
28
|
-
target.scrollTop = top ?? target.scrollTop;
|
|
29
|
-
target.scrollLeft = left ?? target.scrollLeft;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const easingScroll = <E extends HTMLElement>(
|
|
33
|
-
target: E,
|
|
34
|
-
{ top, left, signal, duration = 0, easing = linear }: Options
|
|
35
|
-
): Promise<Pct> => {
|
|
36
|
-
if (signal?.aborted) {
|
|
37
|
-
return Promise.resolve(0);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (!duration) {
|
|
41
|
-
scrollTo(target, top, left);
|
|
42
|
-
return Promise.resolve(1);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return new Promise<Pct>((resolve) => {
|
|
46
|
-
const startTop = target.scrollTop;
|
|
47
|
-
const startLeft = target.scrollLeft;
|
|
48
|
-
|
|
49
|
-
scrollTo(target, top, left);
|
|
50
|
-
top = target.scrollTop;
|
|
51
|
-
left = target.scrollLeft;
|
|
52
|
-
|
|
53
|
-
const startTimestamp = performance.now();
|
|
54
|
-
let ramID: number;
|
|
55
|
-
|
|
56
|
-
const getProgress = (): Pct => {
|
|
57
|
-
const elapsed = performance.now() - startTimestamp;
|
|
58
|
-
return elapsed / duration;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const abortHandler = () => {
|
|
62
|
-
cancelAnimationFrame(ramID);
|
|
63
|
-
const progress = getProgress();
|
|
64
|
-
resolve(progress);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
signal?.addEventListener("abort", abortHandler);
|
|
68
|
-
|
|
69
|
-
const tick = () => {
|
|
70
|
-
const progress = getProgress();
|
|
71
|
-
const tickTop =
|
|
72
|
-
top === undefined
|
|
73
|
-
? undefined
|
|
74
|
-
: startTop + (top - startTop) * easing(progress);
|
|
75
|
-
const tickLeft =
|
|
76
|
-
left === undefined
|
|
77
|
-
? undefined
|
|
78
|
-
: startLeft + (left - startLeft) * easing(progress);
|
|
79
|
-
|
|
80
|
-
if (progress < 1) {
|
|
81
|
-
scrollTo(target, tickTop, tickLeft);
|
|
82
|
-
ramID = requestAnimationFrame(tick);
|
|
83
|
-
} else {
|
|
84
|
-
scrollTo(target, top, left);
|
|
85
|
-
signal?.removeEventListener("abort", abortHandler);
|
|
86
|
-
resolve(1);
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
ramID = requestAnimationFrame(tick);
|
|
91
|
-
});
|
|
92
|
-
};
|
package/src/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { easingScroll } from "./easing-scroll";
|