solid-drift 0.2.0 → 0.8.0
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/README.md +933 -10
- package/dist/ai.d.ts +207 -0
- package/dist/ai.js +570 -0
- package/dist/animate.d.ts +2 -2
- package/dist/animate.js +2 -2
- package/dist/cartoon.d.ts +190 -0
- package/dist/cartoon.js +334 -0
- package/dist/color.d.ts +53 -0
- package/dist/color.js +391 -0
- package/dist/directive.d.ts +5 -5
- package/dist/directive.js +15 -7
- package/dist/easing.d.ts +22 -1
- package/dist/easing.js +49 -1
- package/dist/flip.d.ts +44 -0
- package/dist/flip.js +108 -0
- package/dist/horizontal.d.ts +107 -0
- package/dist/horizontal.js +208 -0
- package/dist/index.d.ts +20 -3
- package/dist/index.js +17 -3
- package/dist/inview.d.ts +4 -4
- package/dist/inview.js +5 -5
- package/dist/motion.d.ts +404 -0
- package/dist/motion.js +761 -0
- package/dist/physics.d.ts +146 -0
- package/dist/physics.js +352 -0
- package/dist/pointer.d.ts +76 -0
- package/dist/pointer.js +123 -0
- package/dist/reduced-motion.d.ts +3 -3
- package/dist/reduced-motion.js +5 -4
- package/dist/scroll.d.ts +3 -3
- package/dist/scroll.js +5 -5
- package/dist/scrollfx.d.ts +156 -0
- package/dist/scrollfx.js +148 -0
- package/dist/scrub.d.ts +51 -0
- package/dist/scrub.js +67 -0
- package/dist/spring.d.ts +39 -4
- package/dist/spring.js +26 -7
- package/dist/stagger.d.ts +4 -4
- package/dist/stagger.js +4 -4
- package/dist/text.d.ts +27 -0
- package/dist/text.js +84 -0
- package/dist/timeline.d.ts +45 -0
- package/dist/timeline.js +93 -0
- package/dist/trail.d.ts +27 -0
- package/dist/trail.js +75 -0
- package/dist/tween.d.ts +3 -3
- package/dist/tween.js +3 -3
- package/dist/typography.d.ts +241 -0
- package/dist/typography.js +812 -0
- package/dist/velocity.d.ts +44 -0
- package/dist/velocity.js +88 -0
- package/dist/web3.d.ts +213 -0
- package/dist/web3.js +640 -0
- package/package.json +1 -1
package/dist/color.js
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { resolveEasing } from "./easing.js";
|
|
2
|
+
function clamp01(v) {
|
|
3
|
+
return v < 0 ? 0 : v > 1 ? 1 : v;
|
|
4
|
+
}
|
|
5
|
+
/** sRGB channel (0 to 1) to linear light. */
|
|
6
|
+
function srgbToLinear(c) {
|
|
7
|
+
return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
8
|
+
}
|
|
9
|
+
/** Linear light channel (0 to 1) back to sRGB. */
|
|
10
|
+
function linearToSrgb(c) {
|
|
11
|
+
return c <= 0.0031308
|
|
12
|
+
? 12.92 * c
|
|
13
|
+
: 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
|
|
14
|
+
}
|
|
15
|
+
/** Round to at most 4 decimals so values like 0.30000000000000004 never leak. */
|
|
16
|
+
function fmtNum(v) {
|
|
17
|
+
return String(Math.round(v * 10000) / 10000);
|
|
18
|
+
}
|
|
19
|
+
function failColor(input) {
|
|
20
|
+
throw new Error(`[solid-drift] could not parse color "${input}". ` +
|
|
21
|
+
"Use hex (#rgb, #rrggbb), rgb()/rgba(), hsl()/hsla(), or a CSS color name.");
|
|
22
|
+
}
|
|
23
|
+
function parseHexColor(raw) {
|
|
24
|
+
const hex = raw.slice(1);
|
|
25
|
+
if (!/^[0-9a-f]+$/.test(hex))
|
|
26
|
+
failColor(raw);
|
|
27
|
+
const pair = (s) => parseInt(s, 16);
|
|
28
|
+
let r = 0;
|
|
29
|
+
let g = 0;
|
|
30
|
+
let b = 0;
|
|
31
|
+
let a = 1;
|
|
32
|
+
if (hex.length === 3 || hex.length === 4) {
|
|
33
|
+
const d = (c) => pair(c + c);
|
|
34
|
+
r = d(hex[0]);
|
|
35
|
+
g = d(hex[1]);
|
|
36
|
+
b = d(hex[2]);
|
|
37
|
+
if (hex.length === 4)
|
|
38
|
+
a = d(hex[3]) / 255;
|
|
39
|
+
}
|
|
40
|
+
else if (hex.length === 6 || hex.length === 8) {
|
|
41
|
+
r = pair(hex.slice(0, 2));
|
|
42
|
+
g = pair(hex.slice(2, 4));
|
|
43
|
+
b = pair(hex.slice(4, 6));
|
|
44
|
+
if (hex.length === 8)
|
|
45
|
+
a = pair(hex.slice(6, 8)) / 255;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
failColor(raw);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
r: srgbToLinear(r / 255),
|
|
52
|
+
g: srgbToLinear(g / 255),
|
|
53
|
+
b: srgbToLinear(b / 255),
|
|
54
|
+
a,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** Split the inside of a rgb()/hsl() call into its 3 or 4 components. */
|
|
58
|
+
function splitColorArgs(inner) {
|
|
59
|
+
return inner
|
|
60
|
+
.replace(/\//g, " ")
|
|
61
|
+
.split(/[\s,]+/)
|
|
62
|
+
.filter((part) => part.length > 0);
|
|
63
|
+
}
|
|
64
|
+
function parseAlpha(part) {
|
|
65
|
+
if (part.endsWith("%"))
|
|
66
|
+
return clamp01(parseFloat(part) / 100);
|
|
67
|
+
return clamp01(parseFloat(part));
|
|
68
|
+
}
|
|
69
|
+
function parseRgbChannel(part) {
|
|
70
|
+
if (part.endsWith("%"))
|
|
71
|
+
return clamp01(parseFloat(part) / 100);
|
|
72
|
+
return clamp01(parseFloat(part) / 255);
|
|
73
|
+
}
|
|
74
|
+
function parseRgbColor(raw) {
|
|
75
|
+
const inner = raw.slice(raw.indexOf("(") + 1, raw.lastIndexOf(")"));
|
|
76
|
+
const parts = splitColorArgs(inner);
|
|
77
|
+
if (parts.length < 3 || parts.length > 4)
|
|
78
|
+
failColor(raw);
|
|
79
|
+
const [r, g, b] = parts.map(parseRgbChannel);
|
|
80
|
+
const a = parts.length === 4 ? parseAlpha(parts[3]) : 1;
|
|
81
|
+
return {
|
|
82
|
+
r: srgbToLinear(r),
|
|
83
|
+
g: srgbToLinear(g),
|
|
84
|
+
b: srgbToLinear(b),
|
|
85
|
+
a,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function parseHue(part) {
|
|
89
|
+
let h = parseFloat(part);
|
|
90
|
+
if (part.endsWith("turn"))
|
|
91
|
+
h *= 360;
|
|
92
|
+
// Bare numbers and "deg" are degrees; wrap negative values around.
|
|
93
|
+
return ((h % 360) + 360) % 360;
|
|
94
|
+
}
|
|
95
|
+
function parsePercent(part) {
|
|
96
|
+
return clamp01(parseFloat(part) / 100);
|
|
97
|
+
}
|
|
98
|
+
function hslToRgb(h, s, l) {
|
|
99
|
+
const c = (1 - Math.abs(2 * l - 1)) * s;
|
|
100
|
+
const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
|
|
101
|
+
const m = l - c / 2;
|
|
102
|
+
let r = 0;
|
|
103
|
+
let g = 0;
|
|
104
|
+
let b = 0;
|
|
105
|
+
if (h < 60) {
|
|
106
|
+
r = c;
|
|
107
|
+
g = x;
|
|
108
|
+
}
|
|
109
|
+
else if (h < 120) {
|
|
110
|
+
r = x;
|
|
111
|
+
g = c;
|
|
112
|
+
}
|
|
113
|
+
else if (h < 180) {
|
|
114
|
+
g = c;
|
|
115
|
+
b = x;
|
|
116
|
+
}
|
|
117
|
+
else if (h < 240) {
|
|
118
|
+
g = x;
|
|
119
|
+
b = c;
|
|
120
|
+
}
|
|
121
|
+
else if (h < 300) {
|
|
122
|
+
r = x;
|
|
123
|
+
b = c;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
r = c;
|
|
127
|
+
b = x;
|
|
128
|
+
}
|
|
129
|
+
return [r + m, g + m, b + m];
|
|
130
|
+
}
|
|
131
|
+
function parseHslColor(raw) {
|
|
132
|
+
const inner = raw.slice(raw.indexOf("(") + 1, raw.lastIndexOf(")"));
|
|
133
|
+
const parts = splitColorArgs(inner);
|
|
134
|
+
if (parts.length < 3 || parts.length > 4)
|
|
135
|
+
failColor(raw);
|
|
136
|
+
const h = parseHue(parts[0]);
|
|
137
|
+
const s = parsePercent(parts[1]);
|
|
138
|
+
const l = parsePercent(parts[2]);
|
|
139
|
+
const a = parts.length === 4 ? parseAlpha(parts[3]) : 1;
|
|
140
|
+
const [r, g, b] = hslToRgb(h, s, l);
|
|
141
|
+
return {
|
|
142
|
+
r: srgbToLinear(r),
|
|
143
|
+
g: srgbToLinear(g),
|
|
144
|
+
b: srgbToLinear(b),
|
|
145
|
+
a,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/** The 148 CSS named colors, stored as hex. */
|
|
149
|
+
const NAMED_COLORS = {
|
|
150
|
+
aliceblue: "#f0f8ff",
|
|
151
|
+
antiquewhite: "#faebd7",
|
|
152
|
+
aqua: "#00ffff",
|
|
153
|
+
aquamarine: "#7fffd4",
|
|
154
|
+
azure: "#f0ffff",
|
|
155
|
+
beige: "#f5f5dc",
|
|
156
|
+
bisque: "#ffe4c4",
|
|
157
|
+
black: "#000000",
|
|
158
|
+
blanchedalmond: "#ffebcd",
|
|
159
|
+
blue: "#0000ff",
|
|
160
|
+
blueviolet: "#8a2be2",
|
|
161
|
+
brown: "#a52a2a",
|
|
162
|
+
burlywood: "#deb887",
|
|
163
|
+
cadetblue: "#5f9ea0",
|
|
164
|
+
chartreuse: "#7fff00",
|
|
165
|
+
chocolate: "#d2691e",
|
|
166
|
+
coral: "#ff7f50",
|
|
167
|
+
cornflowerblue: "#6495ed",
|
|
168
|
+
cornsilk: "#fff8dc",
|
|
169
|
+
crimson: "#dc143c",
|
|
170
|
+
cyan: "#00ffff",
|
|
171
|
+
darkblue: "#00008b",
|
|
172
|
+
darkcyan: "#008b8b",
|
|
173
|
+
darkgoldenrod: "#b8860b",
|
|
174
|
+
darkgray: "#a9a9a9",
|
|
175
|
+
darkgrey: "#a9a9a9",
|
|
176
|
+
darkgreen: "#006400",
|
|
177
|
+
darkkhaki: "#bdb76b",
|
|
178
|
+
darkmagenta: "#8b008b",
|
|
179
|
+
darkolivegreen: "#556b2f",
|
|
180
|
+
darkorange: "#ff8c00",
|
|
181
|
+
darkorchid: "#9932cc",
|
|
182
|
+
darkred: "#8b0000",
|
|
183
|
+
darksalmon: "#e9967a",
|
|
184
|
+
darkseagreen: "#8fbc8f",
|
|
185
|
+
darkslateblue: "#483d8b",
|
|
186
|
+
darkslategray: "#2f4f4f",
|
|
187
|
+
darkslategrey: "#2f4f4f",
|
|
188
|
+
darkturquoise: "#00ced1",
|
|
189
|
+
darkviolet: "#9400d3",
|
|
190
|
+
deeppink: "#ff1493",
|
|
191
|
+
deepskyblue: "#00bfff",
|
|
192
|
+
dimgray: "#696969",
|
|
193
|
+
dimgrey: "#696969",
|
|
194
|
+
dodgerblue: "#1e90ff",
|
|
195
|
+
firebrick: "#b22222",
|
|
196
|
+
floralwhite: "#fffaf0",
|
|
197
|
+
forestgreen: "#228b22",
|
|
198
|
+
fuchsia: "#ff00ff",
|
|
199
|
+
gainsboro: "#dcdcdc",
|
|
200
|
+
ghostwhite: "#f8f8ff",
|
|
201
|
+
gold: "#ffd700",
|
|
202
|
+
goldenrod: "#daa520",
|
|
203
|
+
gray: "#808080",
|
|
204
|
+
grey: "#808080",
|
|
205
|
+
green: "#008000",
|
|
206
|
+
greenyellow: "#adff2f",
|
|
207
|
+
honeydew: "#f0fff0",
|
|
208
|
+
hotpink: "#ff69b4",
|
|
209
|
+
indianred: "#cd5c5c",
|
|
210
|
+
indigo: "#4b0082",
|
|
211
|
+
ivory: "#fffff0",
|
|
212
|
+
khaki: "#f0e68c",
|
|
213
|
+
lavender: "#e6e6fa",
|
|
214
|
+
lavenderblush: "#fff0f5",
|
|
215
|
+
lawngreen: "#7cfc00",
|
|
216
|
+
lemonchiffon: "#fffacd",
|
|
217
|
+
lightblue: "#add8e6",
|
|
218
|
+
lightcoral: "#f08080",
|
|
219
|
+
lightcyan: "#e0ffff",
|
|
220
|
+
lightgoldenrodyellow: "#fafad2",
|
|
221
|
+
lightgray: "#d3d3d3",
|
|
222
|
+
lightgrey: "#d3d3d3",
|
|
223
|
+
lightgreen: "#90ee90",
|
|
224
|
+
lightpink: "#ffb6c1",
|
|
225
|
+
lightsalmon: "#ffa07a",
|
|
226
|
+
lightseagreen: "#20b2aa",
|
|
227
|
+
lightskyblue: "#87cefa",
|
|
228
|
+
lightslategray: "#778899",
|
|
229
|
+
lightslategrey: "#778899",
|
|
230
|
+
lightsteelblue: "#b0c4de",
|
|
231
|
+
lightyellow: "#ffffe0",
|
|
232
|
+
lime: "#00ff00",
|
|
233
|
+
limegreen: "#32cd32",
|
|
234
|
+
linen: "#faf0e6",
|
|
235
|
+
magenta: "#ff00ff",
|
|
236
|
+
maroon: "#800000",
|
|
237
|
+
mediumaquamarine: "#66cdaa",
|
|
238
|
+
mediumblue: "#0000cd",
|
|
239
|
+
mediumorchid: "#ba55d3",
|
|
240
|
+
mediumpurple: "#9370db",
|
|
241
|
+
mediumseagreen: "#3cb371",
|
|
242
|
+
mediumslateblue: "#7b68ee",
|
|
243
|
+
mediumspringgreen: "#00fa9a",
|
|
244
|
+
mediumturquoise: "#48d1cc",
|
|
245
|
+
mediumvioletred: "#c71585",
|
|
246
|
+
midnightblue: "#191970",
|
|
247
|
+
mintcream: "#f5fffa",
|
|
248
|
+
mistyrose: "#ffe4e1",
|
|
249
|
+
moccasin: "#ffe4b5",
|
|
250
|
+
navajowhite: "#ffdead",
|
|
251
|
+
navy: "#000080",
|
|
252
|
+
oldlace: "#fdf5e6",
|
|
253
|
+
olive: "#808000",
|
|
254
|
+
olivedrab: "#6b8e23",
|
|
255
|
+
orange: "#ffa500",
|
|
256
|
+
orangered: "#ff4500",
|
|
257
|
+
orchid: "#da70d6",
|
|
258
|
+
palegoldenrod: "#eee8aa",
|
|
259
|
+
palegreen: "#98fb98",
|
|
260
|
+
paleturquoise: "#afeeee",
|
|
261
|
+
palevioletred: "#db7093",
|
|
262
|
+
papayawhip: "#ffefd5",
|
|
263
|
+
peachpuff: "#ffdab9",
|
|
264
|
+
peru: "#cd853f",
|
|
265
|
+
pink: "#ffc0cb",
|
|
266
|
+
plum: "#dda0dd",
|
|
267
|
+
powderblue: "#b0e0e6",
|
|
268
|
+
purple: "#800080",
|
|
269
|
+
rebeccapurple: "#663399",
|
|
270
|
+
red: "#ff0000",
|
|
271
|
+
rosybrown: "#bc8f8f",
|
|
272
|
+
royalblue: "#4169e1",
|
|
273
|
+
saddlebrown: "#8b4513",
|
|
274
|
+
salmon: "#fa8072",
|
|
275
|
+
sandybrown: "#f4a460",
|
|
276
|
+
seagreen: "#2e8b57",
|
|
277
|
+
seashell: "#fff5ee",
|
|
278
|
+
sienna: "#a0522d",
|
|
279
|
+
silver: "#c0c0c0",
|
|
280
|
+
skyblue: "#87ceeb",
|
|
281
|
+
slateblue: "#6a5acd",
|
|
282
|
+
slategray: "#708090",
|
|
283
|
+
slategrey: "#708090",
|
|
284
|
+
snow: "#fffafa",
|
|
285
|
+
springgreen: "#00ff7f",
|
|
286
|
+
steelblue: "#4682b4",
|
|
287
|
+
tan: "#d2b48c",
|
|
288
|
+
teal: "#008080",
|
|
289
|
+
thistle: "#d8bfd8",
|
|
290
|
+
tomato: "#ff6347",
|
|
291
|
+
turquoise: "#40e0d0",
|
|
292
|
+
violet: "#ee82ee",
|
|
293
|
+
wheat: "#f5deb3",
|
|
294
|
+
white: "#ffffff",
|
|
295
|
+
whitesmoke: "#f5f5f5",
|
|
296
|
+
yellow: "#ffff00",
|
|
297
|
+
yellowgreen: "#9acd32",
|
|
298
|
+
};
|
|
299
|
+
/** Parse any supported CSS color into linear RGB plus alpha. */
|
|
300
|
+
export function parseColor(input) {
|
|
301
|
+
const raw = input.trim().toLowerCase();
|
|
302
|
+
if (raw.startsWith("#"))
|
|
303
|
+
return parseHexColor(raw);
|
|
304
|
+
if (raw.startsWith("rgb"))
|
|
305
|
+
return parseRgbColor(raw);
|
|
306
|
+
if (raw.startsWith("hsl"))
|
|
307
|
+
return parseHslColor(raw);
|
|
308
|
+
const named = NAMED_COLORS[raw];
|
|
309
|
+
if (named)
|
|
310
|
+
return parseHexColor(named);
|
|
311
|
+
return failColor(input);
|
|
312
|
+
}
|
|
313
|
+
export function lerpColor(a, b, t) {
|
|
314
|
+
return {
|
|
315
|
+
r: a.r + (b.r - a.r) * t,
|
|
316
|
+
g: a.g + (b.g - a.g) * t,
|
|
317
|
+
b: a.b + (b.b - a.b) * t,
|
|
318
|
+
a: a.a + (b.a - a.a) * t,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
function rgbToHsl(r, g, b) {
|
|
322
|
+
const max = Math.max(r, g, b);
|
|
323
|
+
const min = Math.min(r, g, b);
|
|
324
|
+
const l = (max + min) / 2;
|
|
325
|
+
let h = 0;
|
|
326
|
+
let s = 0;
|
|
327
|
+
if (max !== min) {
|
|
328
|
+
const d = max - min;
|
|
329
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
330
|
+
if (max === r)
|
|
331
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) * 60;
|
|
332
|
+
else if (max === g)
|
|
333
|
+
h = ((b - r) / d + 2) * 60;
|
|
334
|
+
else
|
|
335
|
+
h = ((r - g) / d + 4) * 60;
|
|
336
|
+
}
|
|
337
|
+
return { h, s, l };
|
|
338
|
+
}
|
|
339
|
+
export function formatColor(color, format) {
|
|
340
|
+
const r = Math.round(clamp01(linearToSrgb(color.r)) * 255);
|
|
341
|
+
const g = Math.round(clamp01(linearToSrgb(color.g)) * 255);
|
|
342
|
+
const b = Math.round(clamp01(linearToSrgb(color.b)) * 255);
|
|
343
|
+
const a = clamp01(color.a);
|
|
344
|
+
const hex2 = (n) => n.toString(16).padStart(2, "0");
|
|
345
|
+
if (format === "hex") {
|
|
346
|
+
const base = `#${hex2(r)}${hex2(g)}${hex2(b)}`;
|
|
347
|
+
return a >= 0.999 ? base : `${base}${hex2(Math.round(a * 255))}`;
|
|
348
|
+
}
|
|
349
|
+
if (format === "rgb") {
|
|
350
|
+
return a >= 0.999
|
|
351
|
+
? `rgb(${r}, ${g}, ${b})`
|
|
352
|
+
: `rgba(${r}, ${g}, ${b}, ${fmtNum(a)})`;
|
|
353
|
+
}
|
|
354
|
+
const { h, s, l } = rgbToHsl(r / 255, g / 255, b / 255);
|
|
355
|
+
const hsl = `hsl(${Math.round(h)}, ${Math.round(s * 100)}%, ${Math.round(l * 100)}%)`;
|
|
356
|
+
return a >= 0.999
|
|
357
|
+
? hsl
|
|
358
|
+
: `hsla(${Math.round(h)}, ${Math.round(s * 100)}%, ${Math.round(l * 100)}%, ${fmtNum(a)})`;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Sort stops by `at`, parse every color, and resolve each segment's
|
|
362
|
+
* easing. Shared by the scroll-driven and time-driven color primitives.
|
|
363
|
+
*/
|
|
364
|
+
export function parseColorStops(stops, fallbackEasing) {
|
|
365
|
+
const sorted = [...stops].sort((a, b) => a.at - b.at);
|
|
366
|
+
return sorted.map((stop) => ({
|
|
367
|
+
at: stop.at,
|
|
368
|
+
color: parseColor(stop.color),
|
|
369
|
+
easing: resolveEasing(stop.easing ?? fallbackEasing ?? "linear"),
|
|
370
|
+
}));
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Sample a parsed stop list at progress `p` (clamped 0 to 1) and return
|
|
374
|
+
* the interpolated color string in the requested format.
|
|
375
|
+
*/
|
|
376
|
+
export function sampleColorStops(stops, p, format) {
|
|
377
|
+
const t = p < 0 ? 0 : p > 1 ? 1 : p;
|
|
378
|
+
if (t <= stops[0].at)
|
|
379
|
+
return formatColor(stops[0].color, format);
|
|
380
|
+
const last = stops[stops.length - 1];
|
|
381
|
+
if (t >= last.at)
|
|
382
|
+
return formatColor(last.color, format);
|
|
383
|
+
let i = 0;
|
|
384
|
+
while (i < stops.length - 2 && stops[i + 1].at <= t)
|
|
385
|
+
i++;
|
|
386
|
+
const a = stops[i];
|
|
387
|
+
const b = stops[i + 1];
|
|
388
|
+
const span = b.at - a.at;
|
|
389
|
+
const local = span <= 0 ? 0 : (t - a.at) / span;
|
|
390
|
+
return formatColor(lerpColor(a.color, b.color, b.easing(local)), format);
|
|
391
|
+
}
|
package/dist/directive.d.ts
CHANGED
|
@@ -25,15 +25,15 @@ declare module "solid-js" {
|
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Directive that binds animated values straight to an element's style.
|
|
28
|
-
* Each prop can be a plain number or any signal
|
|
28
|
+
* Each prop can be a plain number or any signal. Combine with
|
|
29
29
|
* `createSpring` / `createTween` for buttery motion:
|
|
30
30
|
*
|
|
31
31
|
* ```tsx
|
|
32
|
-
* import { drift } from "solid-drift"
|
|
32
|
+
* import { drift } from "solid-drift"
|
|
33
33
|
*
|
|
34
|
-
* const [open, setOpen] = createSignal(false)
|
|
35
|
-
* const y = createSpring(() => (open() ? 0 : 24))
|
|
36
|
-
* const opacity = createTween(() => (open() ? 1 : 0), { duration: 250 })
|
|
34
|
+
* const [open, setOpen] = createSignal(false)
|
|
35
|
+
* const y = createSpring(() => (open() ? 0 : 24))
|
|
36
|
+
* const opacity = createTween(() => (open() ? 1 : 0), { duration: 250 })
|
|
37
37
|
*
|
|
38
38
|
* <div use:drift={{ y, opacity }}>slides and fades</div>
|
|
39
39
|
* ```
|
package/dist/directive.js
CHANGED
|
@@ -4,15 +4,15 @@ function resolve(value) {
|
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
6
|
* Directive that binds animated values straight to an element's style.
|
|
7
|
-
* Each prop can be a plain number or any signal
|
|
7
|
+
* Each prop can be a plain number or any signal. Combine with
|
|
8
8
|
* `createSpring` / `createTween` for buttery motion:
|
|
9
9
|
*
|
|
10
10
|
* ```tsx
|
|
11
|
-
* import { drift } from "solid-drift"
|
|
11
|
+
* import { drift } from "solid-drift"
|
|
12
12
|
*
|
|
13
|
-
* const [open, setOpen] = createSignal(false)
|
|
14
|
-
* const y = createSpring(() => (open() ? 0 : 24))
|
|
15
|
-
* const opacity = createTween(() => (open() ? 1 : 0), { duration: 250 })
|
|
13
|
+
* const [open, setOpen] = createSignal(false)
|
|
14
|
+
* const y = createSpring(() => (open() ? 0 : 24))
|
|
15
|
+
* const opacity = createTween(() => (open() ? 1 : 0), { duration: 250 })
|
|
16
16
|
*
|
|
17
17
|
* <div use:drift={{ y, opacity }}>slides and fades</div>
|
|
18
18
|
* ```
|
|
@@ -30,8 +30,16 @@ export function drift(el, props) {
|
|
|
30
30
|
const rotate = p.rotate !== undefined ? resolve(p.rotate) : 0;
|
|
31
31
|
if (rotate !== 0)
|
|
32
32
|
parts.push(`rotate(${rotate}deg)`);
|
|
33
|
-
const sx = p.scaleX !== undefined
|
|
34
|
-
|
|
33
|
+
const sx = p.scaleX !== undefined
|
|
34
|
+
? resolve(p.scaleX)
|
|
35
|
+
: p.scale !== undefined
|
|
36
|
+
? resolve(p.scale)
|
|
37
|
+
: 1;
|
|
38
|
+
const sy = p.scaleY !== undefined
|
|
39
|
+
? resolve(p.scaleY)
|
|
40
|
+
: p.scale !== undefined
|
|
41
|
+
? resolve(p.scale)
|
|
42
|
+
: 1;
|
|
35
43
|
if (sx !== 1 || sy !== 1)
|
|
36
44
|
parts.push(`scale(${sx}, ${sy})`);
|
|
37
45
|
el.style.transform = parts.join(" ");
|
package/dist/easing.d.ts
CHANGED
|
@@ -12,6 +12,23 @@ export declare const easeOutQuart: Easing;
|
|
|
12
12
|
export declare const easeInOutQuart: Easing;
|
|
13
13
|
export declare const easeOutExpo: Easing;
|
|
14
14
|
export declare const easeOutBack: Easing;
|
|
15
|
+
/**
|
|
16
|
+
* Anticipation easing: dips below the start value before climbing to 1.
|
|
17
|
+
* The classic cartoon wind-up, a character crouching before the jump.
|
|
18
|
+
*/
|
|
19
|
+
export declare const easeInBack: Easing;
|
|
20
|
+
/** Overshoot at both ends: winds up, fires past the target, settles back. */
|
|
21
|
+
export declare const easeInOutBack: Easing;
|
|
22
|
+
/**
|
|
23
|
+
* Elastic wobble: overshoots and oscillates with decaying amplitude,
|
|
24
|
+
* like a plucked rubber band or a jelly landing.
|
|
25
|
+
*/
|
|
26
|
+
export declare const easeOutElastic: Easing;
|
|
27
|
+
/**
|
|
28
|
+
* Cartoon bounce: hits the end value with a series of shrinking hops,
|
|
29
|
+
* like a dropped rubber ball.
|
|
30
|
+
*/
|
|
31
|
+
export declare const easeOutBounce: Easing;
|
|
15
32
|
/**
|
|
16
33
|
* Cubic bezier easing, same parameters as CSS `cubic-bezier(x1, y1, x2, y2)`.
|
|
17
34
|
*/
|
|
@@ -29,7 +46,11 @@ export declare const easings: {
|
|
|
29
46
|
readonly easeInOutQuart: Easing;
|
|
30
47
|
readonly easeOutExpo: Easing;
|
|
31
48
|
readonly easeOutBack: Easing;
|
|
49
|
+
readonly easeInBack: Easing;
|
|
50
|
+
readonly easeInOutBack: Easing;
|
|
51
|
+
readonly easeOutElastic: Easing;
|
|
52
|
+
readonly easeOutBounce: Easing;
|
|
32
53
|
};
|
|
33
54
|
export type EasingName = keyof typeof easings;
|
|
34
|
-
/** Accept an easing function or its name
|
|
55
|
+
/** Accept an easing function or its name. Throws on unknown names. */
|
|
35
56
|
export declare function resolveEasing(easing: Easing | EasingName | undefined): Easing;
|
package/dist/easing.js
CHANGED
|
@@ -14,6 +14,50 @@ export const easeOutBack = (t) => {
|
|
|
14
14
|
const c3 = c1 + 1;
|
|
15
15
|
return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Anticipation easing: dips below the start value before climbing to 1.
|
|
19
|
+
* The classic cartoon wind-up, a character crouching before the jump.
|
|
20
|
+
*/
|
|
21
|
+
export const easeInBack = (t) => {
|
|
22
|
+
const c1 = 1.70158;
|
|
23
|
+
const c3 = c1 + 1;
|
|
24
|
+
return c3 * t * t * t - c1 * t * t;
|
|
25
|
+
};
|
|
26
|
+
/** Overshoot at both ends: winds up, fires past the target, settles back. */
|
|
27
|
+
export const easeInOutBack = (t) => {
|
|
28
|
+
const c1 = 1.70158;
|
|
29
|
+
const c2 = c1 * 1.525;
|
|
30
|
+
return t < 0.5
|
|
31
|
+
? (Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2
|
|
32
|
+
: (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Elastic wobble: overshoots and oscillates with decaying amplitude,
|
|
36
|
+
* like a plucked rubber band or a jelly landing.
|
|
37
|
+
*/
|
|
38
|
+
export const easeOutElastic = (t) => {
|
|
39
|
+
if (t <= 0)
|
|
40
|
+
return 0;
|
|
41
|
+
if (t >= 1)
|
|
42
|
+
return 1;
|
|
43
|
+
const c4 = (2 * Math.PI) / 3;
|
|
44
|
+
return Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Cartoon bounce: hits the end value with a series of shrinking hops,
|
|
48
|
+
* like a dropped rubber ball.
|
|
49
|
+
*/
|
|
50
|
+
export const easeOutBounce = (t) => {
|
|
51
|
+
const n1 = 7.5625;
|
|
52
|
+
const d1 = 2.75;
|
|
53
|
+
if (t < 1 / d1)
|
|
54
|
+
return n1 * t * t;
|
|
55
|
+
if (t < 2 / d1)
|
|
56
|
+
return n1 * (t -= 1.5 / d1) * t + 0.75;
|
|
57
|
+
if (t < 2.5 / d1)
|
|
58
|
+
return n1 * (t -= 2.25 / d1) * t + 0.9375;
|
|
59
|
+
return n1 * (t -= 2.625 / d1) * t + 0.984375;
|
|
60
|
+
};
|
|
17
61
|
/**
|
|
18
62
|
* Cubic bezier easing, same parameters as CSS `cubic-bezier(x1, y1, x2, y2)`.
|
|
19
63
|
*/
|
|
@@ -67,8 +111,12 @@ export const easings = {
|
|
|
67
111
|
easeInOutQuart,
|
|
68
112
|
easeOutExpo,
|
|
69
113
|
easeOutBack,
|
|
114
|
+
easeInBack,
|
|
115
|
+
easeInOutBack,
|
|
116
|
+
easeOutElastic,
|
|
117
|
+
easeOutBounce,
|
|
70
118
|
};
|
|
71
|
-
/** Accept an easing function or its name
|
|
119
|
+
/** Accept an easing function or its name. Throws on unknown names. */
|
|
72
120
|
export function resolveEasing(easing) {
|
|
73
121
|
if (!easing)
|
|
74
122
|
return easeOutCubic;
|
package/dist/flip.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type AnimateOptions, type AnimationControls } from "./animate.js";
|
|
2
|
+
export interface FlipOptions {
|
|
3
|
+
/** Duration in milliseconds. Default 400. */
|
|
4
|
+
duration?: number;
|
|
5
|
+
/** Delay before starting, in milliseconds. Default 0. */
|
|
6
|
+
delay?: number;
|
|
7
|
+
/** Easing function or name. Default "easeOutCubic". */
|
|
8
|
+
easing?: AnimateOptions["easing"];
|
|
9
|
+
/**
|
|
10
|
+
* Also animate the size delta as scale, so growing or shrinking
|
|
11
|
+
* elements morph instead of just sliding. Default true.
|
|
12
|
+
*/
|
|
13
|
+
scale?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* FLIP layout animation around a DOM mutation.
|
|
17
|
+
*
|
|
18
|
+
* Records the element's position and size (First), runs your `mutate()`
|
|
19
|
+
* which changes the layout (Last), then Inverts the delta as a transform
|
|
20
|
+
* and Plays it back to identity. List reorders, expanding panels, and
|
|
21
|
+
* grid reshuffles glide to their new spots instead of jumping.
|
|
22
|
+
*
|
|
23
|
+
* The element's pre-existing `transform` is captured and restored after
|
|
24
|
+
* the animation, so FLIP composes with other transform animations.
|
|
25
|
+
* `stop()` halts mid-flight and restores the original transform.
|
|
26
|
+
*
|
|
27
|
+
* SSR-safe and reduced-motion safe: the mutation runs with no animation.
|
|
28
|
+
* If the element does not move, no animation runs either.
|
|
29
|
+
*
|
|
30
|
+
* ```tsx
|
|
31
|
+
* import { animateFlip } from "solid-drift"
|
|
32
|
+
*
|
|
33
|
+
* const [items, setItems] = createSignal(["a", "b", "c"])
|
|
34
|
+
* let list!: HTMLUListElement
|
|
35
|
+
*
|
|
36
|
+
* const shuffle = () =>
|
|
37
|
+
* animateFlip(
|
|
38
|
+
* () => list,
|
|
39
|
+
* () => setItems((prev) => [...prev].reverse()),
|
|
40
|
+
* { duration: 450 },
|
|
41
|
+
* )
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function animateFlip(ref: () => Element | null | undefined, mutate: () => void, options?: FlipOptions): AnimationControls;
|