@cosmictraveler002/anim-kit 1.4.0 → 1.6.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 +256 -23
- package/dist/anim-kit.standalone.js +5 -5
- package/dist/anim-kit.standalone.js.map +1 -1
- package/dist/core/smooth-scroll.d.ts +29 -1
- package/dist/core/smooth-scroll.d.ts.map +1 -1
- package/dist/core/smooth-scroll.js +23 -3
- package/dist/core/smooth-scroll.js.map +1 -1
- package/dist/effects/horizontal-scroll.d.ts.map +1 -1
- package/dist/effects/horizontal-scroll.js +3 -0
- package/dist/effects/horizontal-scroll.js.map +1 -1
- package/dist/effects/ink-wipe.d.ts +41 -0
- package/dist/effects/ink-wipe.d.ts.map +1 -0
- package/dist/effects/ink-wipe.js +342 -0
- package/dist/effects/ink-wipe.js.map +1 -0
- package/dist/effects/scatter-text.d.ts.map +1 -1
- package/dist/effects/scatter-text.js +3 -0
- package/dist/effects/scatter-text.js.map +1 -1
- package/dist/effects/stacked-cards.d.ts.map +1 -1
- package/dist/effects/stacked-cards.js +3 -0
- package/dist/effects/stacked-cards.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/three/coverflow-wheel.d.ts +26 -0
- package/dist/three/coverflow-wheel.d.ts.map +1 -0
- package/dist/three/coverflow-wheel.js +495 -0
- package/dist/three/coverflow-wheel.js.map +1 -0
- package/dist/three/dither-reveal.d.ts +36 -0
- package/dist/three/dither-reveal.d.ts.map +1 -0
- package/dist/three/dither-reveal.js +292 -0
- package/dist/three/dither-reveal.js.map +1 -0
- package/dist/three/index.d.ts +8 -0
- package/dist/three/index.d.ts.map +1 -1
- package/dist/three/index.js +4 -0
- package/dist/three/index.js.map +1 -1
- package/dist/three/tear-reveal.d.ts +54 -0
- package/dist/three/tear-reveal.d.ts.map +1 -0
- package/dist/three/tear-reveal.js +269 -0
- package/dist/three/tear-reveal.js.map +1 -0
- package/dist/three/wordmark-wave.d.ts +29 -0
- package/dist/three/wordmark-wave.d.ts.map +1 -0
- package/dist/three/wordmark-wave.js +461 -0
- package/dist/three/wordmark-wave.js.map +1 -0
- package/package.json +1 -1
- package/src/core/smooth-scroll.ts +44 -2
- package/src/effects/horizontal-scroll.ts +3 -0
- package/src/effects/ink-wipe.ts +409 -0
- package/src/effects/scatter-text.ts +3 -0
- package/src/effects/stacked-cards.ts +3 -0
- package/src/index.ts +3 -0
- package/src/three/coverflow-wheel.ts +569 -0
- package/src/three/dither-reveal.ts +365 -0
- package/src/three/index.ts +8 -0
- package/src/three/tear-reveal.ts +351 -0
- package/src/three/wordmark-wave.ts +517 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wordmark wave — the giant wordmark that ripples under the pointer and
|
|
3
|
+
* throws red/cyan chromatic fringes while it deforms.
|
|
4
|
+
*
|
|
5
|
+
* The whole effect is one deformable plane textured with the wordmark drawn
|
|
6
|
+
* from the target's own text and font — no bundled typeface, no baked mesh:
|
|
7
|
+
*
|
|
8
|
+
* - **The sim runs on the CPU, per vertex** (a ~5 k-vertex grid is nothing
|
|
9
|
+
* at 60 Hz), stepping the reference's frame constants verbatim: pointer
|
|
10
|
+
* falloff `1/(1 + d/0.05) − 0.1`, a `0.02` pointer-velocity "drag" term,
|
|
11
|
+
* a `0.1` spring back to rest, `0.9` damping, `0.1` integration scale.
|
|
12
|
+
* The step is fixed at 1/60 s (accumulated, max 4 per frame) so the
|
|
13
|
+
* physics are identical on 60/120/144 Hz displays; pointer velocity is
|
|
14
|
+
* measured per frame, folded to 1/60 s after a stall and zeroed above
|
|
15
|
+
* 10 units/s (teleport guard).
|
|
16
|
+
* - **The chroma is three additive draws, not a post effect.** The same
|
|
17
|
+
* geometry renders once per channel with the displacement scaled
|
|
18
|
+
* 0.9 / 1.0 / 1.1 — at rest the passes coincide and the wordmark is solid;
|
|
19
|
+
* wherever the mesh moves the channels separate into red/cyan fringes.
|
|
20
|
+
* (Light base colours only — a saturated colour kills its own channels.)
|
|
21
|
+
* - **Normalized space.** Positions, cursor and falloff live in half-width
|
|
22
|
+
* units (x ∈ [−1, 1], y ∈ [−h/w, h/w]) so waves stay circles on screen at
|
|
23
|
+
* any element aspect; the vertex shader converts y to NDC with one aspect
|
|
24
|
+
* multiply.
|
|
25
|
+
* - **Silent no-op ladder.** Missing target / empty text → no-op. No WebGL
|
|
26
|
+
* (SSR, jsdom, disabled) → no-op before any context is requested.
|
|
27
|
+
* Renderer construction throws → no-op. Off-screen → the ticker idles
|
|
28
|
+
* (IntersectionObserver) and a settled wordmark stops stepping entirely.
|
|
29
|
+
* Under `prefers-reduced-motion` nothing mounts — the real text simply
|
|
30
|
+
* stays visible (it is only hidden while the effect owns it).
|
|
31
|
+
* - **Fidelity.** `destroy()` restores the text colour and the inline
|
|
32
|
+
* position, removes the canvas, listeners and observers, and disposes
|
|
33
|
+
* geometry, materials, texture and renderer.
|
|
34
|
+
*
|
|
35
|
+
* wordmarkWave("[data-wordmark]", { outline: 3, tracking: 8 });
|
|
36
|
+
*
|
|
37
|
+
* CSS: the target holds a single line of text; it is hidden (colour
|
|
38
|
+
* transparent) while mounted and re-drawn centred in its own box. Style the
|
|
39
|
+
* font there — the effect inherits it.
|
|
40
|
+
*/
|
|
41
|
+
import * as THREE from "three";
|
|
42
|
+
import { gsap, initGSAP } from "../core/gsap.js";
|
|
43
|
+
import { guard } from "../core/guard.js";
|
|
44
|
+
import { one } from "../core/util.js";
|
|
45
|
+
/* Reference frame constants — the sim is stepped at a fixed 60 Hz so these
|
|
46
|
+
stay exactly as measured, whatever the display's refresh rate. */
|
|
47
|
+
const FALLOFF = 0.05; // pointer falloff radius, half-width units
|
|
48
|
+
const FLOOR = 0.1; // strength = 1/(1+d/FALLOFF) − FLOOR, clamped
|
|
49
|
+
const REACH = FALLOFF * (1 / FLOOR - 1); // where strength hits 0 → 0.45
|
|
50
|
+
const DRAG_K = 0.02; // pointer-velocity term
|
|
51
|
+
const SPRING = 0.1; // return-to-rest term
|
|
52
|
+
const DAMP = 0.9; // velocity damping per step
|
|
53
|
+
const INTEG = 0.1; // displacement per velocity per step
|
|
54
|
+
const STEP = 1 / 60; // fixed sim step, seconds
|
|
55
|
+
const MAX_STEPS = 4; // accumulated steps allowed per frame
|
|
56
|
+
const V_CLAMP = 10; // pointer speed above which the delta is discarded
|
|
57
|
+
const SETTLE_EPS = 1e-4; // |disp|/|vel| below which the sim sleeps
|
|
58
|
+
const VERT = /* glsl */ `
|
|
59
|
+
attribute vec2 aDisp; // sim displacement, half-width units
|
|
60
|
+
uniform float uDispScale; // chroma pass multiplier: 0.9 / 1.0 / 1.1
|
|
61
|
+
uniform float uAspect; // w/h — sim y to NDC (y extent is h/w)
|
|
62
|
+
varying vec2 vUv;
|
|
63
|
+
|
|
64
|
+
void main() {
|
|
65
|
+
vUv = uv;
|
|
66
|
+
vec2 p = position.xy + aDisp * uDispScale;
|
|
67
|
+
gl_Position = vec4(p.x, p.y * uAspect, 0.0, 1.0);
|
|
68
|
+
}
|
|
69
|
+
`;
|
|
70
|
+
/* Chroma pass: premultiplied rgb, alpha = opacity/3. The three passes add up
|
|
71
|
+
to base * coverage * opacity at rest; where only one channel reaches, the
|
|
72
|
+
fringe sits at a third of the coverage — brighter than its alpha says,
|
|
73
|
+
which is exactly the additive look the reference has. */
|
|
74
|
+
const CHROMA_FRAG = /* glsl */ `
|
|
75
|
+
precision highp float;
|
|
76
|
+
uniform sampler2D uMap;
|
|
77
|
+
uniform vec3 uPass; // channel * base colour
|
|
78
|
+
uniform float uOpacity;
|
|
79
|
+
varying vec2 vUv;
|
|
80
|
+
|
|
81
|
+
void main() {
|
|
82
|
+
float a = texture2D(uMap, vUv).a;
|
|
83
|
+
if (a <= 0.002) discard;
|
|
84
|
+
gl_FragColor = vec4(uPass * a * uOpacity, a * uOpacity / 3.0);
|
|
85
|
+
}
|
|
86
|
+
`;
|
|
87
|
+
/* Single pass (chroma: false): straight alpha, like every other overlay. */
|
|
88
|
+
const PLAIN_FRAG = /* glsl */ `
|
|
89
|
+
precision highp float;
|
|
90
|
+
uniform sampler2D uMap;
|
|
91
|
+
uniform vec3 uPass;
|
|
92
|
+
uniform float uOpacity;
|
|
93
|
+
varying vec2 vUv;
|
|
94
|
+
|
|
95
|
+
void main() {
|
|
96
|
+
float a = texture2D(uMap, vUv).a;
|
|
97
|
+
if (a <= 0.002) discard;
|
|
98
|
+
gl_FragColor = vec4(uPass, a * uOpacity);
|
|
99
|
+
}
|
|
100
|
+
`;
|
|
101
|
+
export function wordmarkWave(target, options = {}) {
|
|
102
|
+
initGSAP();
|
|
103
|
+
const host = one(target);
|
|
104
|
+
if (!host)
|
|
105
|
+
return () => { };
|
|
106
|
+
const text = (options.text ?? host.textContent ?? "").trim().replace(/\s+/g, " ");
|
|
107
|
+
if (!text)
|
|
108
|
+
return () => { };
|
|
109
|
+
const { color, opacity = 1, outline = 0, tracking = 0, drag = 1, push = 0, chroma = true, dpr = 2, segments = 0, z = 1, } = options;
|
|
110
|
+
return guard(options, () => {
|
|
111
|
+
/* ---------------- availability ladder (silent, no probes) ---------------- */
|
|
112
|
+
if (typeof window === "undefined" || !("WebGLRenderingContext" in window))
|
|
113
|
+
return () => { };
|
|
114
|
+
let renderer;
|
|
115
|
+
try {
|
|
116
|
+
renderer = new THREE.WebGLRenderer({ alpha: true, antialias: false });
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return () => { }; // context refused — the plain text simply stays
|
|
120
|
+
}
|
|
121
|
+
/* --------------- the font + colour live on the element ------------------ */
|
|
122
|
+
const computed = getComputedStyle(host);
|
|
123
|
+
const family = computed.fontFamily;
|
|
124
|
+
const weight = computed.fontWeight;
|
|
125
|
+
const style = computed.fontStyle;
|
|
126
|
+
const variant = computed.fontVariant;
|
|
127
|
+
const size0 = parseFloat(computed.fontSize) || 16;
|
|
128
|
+
const baseColor = color || computed.color || "#ffffff";
|
|
129
|
+
const pass = new THREE.Color(baseColor);
|
|
130
|
+
/* ---------------- layout + styles we must restore ---------------- */
|
|
131
|
+
const prevPosition = host.style.position;
|
|
132
|
+
if (!prevPosition && computed.position === "static")
|
|
133
|
+
host.style.position = "relative";
|
|
134
|
+
const prevColor = host.style.color;
|
|
135
|
+
host.style.color = "transparent"; // the canvas owns the pixels now
|
|
136
|
+
let w = Math.max(1, host.clientWidth);
|
|
137
|
+
let h = Math.max(1, host.clientHeight);
|
|
138
|
+
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, dpr));
|
|
139
|
+
renderer.setSize(w, h, false);
|
|
140
|
+
renderer.setClearColor(0x000000, 0);
|
|
141
|
+
const canvas = renderer.domElement;
|
|
142
|
+
canvas.style.cssText = `position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none;z-index:${z};`;
|
|
143
|
+
const scene = new THREE.Scene();
|
|
144
|
+
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);
|
|
145
|
+
/* ---------------- the wordmark texture ---------------- */
|
|
146
|
+
const texCanvas = document.createElement("canvas");
|
|
147
|
+
const ctx = texCanvas.getContext("2d");
|
|
148
|
+
let texture = null;
|
|
149
|
+
/* The font: the target's computed shorthand by default; options.font
|
|
150
|
+
verbatim when the canvas accepts it (px sizes are never rewritten —
|
|
151
|
+
a rejected value falls back to the computed one). */
|
|
152
|
+
const applyFont = () => {
|
|
153
|
+
const fallback = `${style} ${variant} ${weight} ${size0}px ${family}`;
|
|
154
|
+
const cand = options.font || fallback;
|
|
155
|
+
ctx.font = "1px monospace"; // sentinel: survives a rejected assignment
|
|
156
|
+
ctx.font = cand;
|
|
157
|
+
if (ctx.font === "1px monospace")
|
|
158
|
+
ctx.font = fallback;
|
|
159
|
+
};
|
|
160
|
+
const drawText = () => {
|
|
161
|
+
const capDpr = Math.min(window.devicePixelRatio || 1, dpr);
|
|
162
|
+
texCanvas.width = Math.max(1, Math.round(w * capDpr));
|
|
163
|
+
texCanvas.height = Math.max(1, Math.round(h * capDpr));
|
|
164
|
+
ctx.setTransform(capDpr, 0, 0, capDpr, 0, 0);
|
|
165
|
+
ctx.clearRect(0, 0, w, h);
|
|
166
|
+
applyFont();
|
|
167
|
+
ctx.textBaseline = "middle";
|
|
168
|
+
ctx.fillStyle = "#ffffff";
|
|
169
|
+
ctx.strokeStyle = "#ffffff";
|
|
170
|
+
ctx.lineWidth = outline;
|
|
171
|
+
/* Letter spacing: native where it exists (Chromium 99+, FF 128+),
|
|
172
|
+
manual elsewhere. typeof keeps this a runtime probe — an `in` check
|
|
173
|
+
would narrow ctx to never (the property is in the type lib). */
|
|
174
|
+
const canTrack = typeof ctx.letterSpacing === "string";
|
|
175
|
+
if (tracking && canTrack)
|
|
176
|
+
ctx.letterSpacing = `${tracking}px`;
|
|
177
|
+
const chars = [...text];
|
|
178
|
+
const manual = tracking > 0 && !canTrack;
|
|
179
|
+
const trackW = manual ? tracking * (chars.length - 1) : 0;
|
|
180
|
+
const m = ctx.measureText(text);
|
|
181
|
+
const inkH = isFinite(m.actualBoundingBoxAscent) && isFinite(m.actualBoundingBoxDescent)
|
|
182
|
+
? m.actualBoundingBoxAscent + m.actualBoundingBoxDescent
|
|
183
|
+
: size0 * 1.2;
|
|
184
|
+
/* Fit-to-box on both axes: scale the whole drawing (font, stroke,
|
|
185
|
+
tracking) rather than parsing sizes out of arbitrary shorthands.
|
|
186
|
+
Padding leaves the stroke room to breathe at the edges. */
|
|
187
|
+
const padW = Math.min(16, w * 0.06) + outline;
|
|
188
|
+
const padH = Math.min(12, h * 0.06) + outline;
|
|
189
|
+
const fw = m.width + trackW > 0 ? (w - padW) / (m.width + trackW) : 1;
|
|
190
|
+
const fh = inkH > 0 ? (h - padH) / inkH : 1;
|
|
191
|
+
const f = Math.max(0.05, Math.min(1, fw, fh));
|
|
192
|
+
ctx.save();
|
|
193
|
+
ctx.translate(w / 2, h / 2);
|
|
194
|
+
ctx.scale(f, f);
|
|
195
|
+
const paint = () => (outline > 0 ? ctx.strokeText(text, 0, 0) : ctx.fillText(text, 0, 0));
|
|
196
|
+
if (!manual) {
|
|
197
|
+
ctx.textAlign = "center";
|
|
198
|
+
paint();
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
/* Manual tracking: left-align each glyph on a running cursor. */
|
|
202
|
+
const widths = chars.map((c) => ctx.measureText(c).width);
|
|
203
|
+
const total = widths.reduce((a, b) => a + b, 0) + trackW;
|
|
204
|
+
ctx.textAlign = "left";
|
|
205
|
+
let x = -total / 2;
|
|
206
|
+
chars.forEach((c, i) => {
|
|
207
|
+
if (outline > 0)
|
|
208
|
+
ctx.strokeText(c, x, 0);
|
|
209
|
+
else
|
|
210
|
+
ctx.fillText(c, x, 0);
|
|
211
|
+
x += widths[i] + tracking;
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
ctx.restore();
|
|
215
|
+
};
|
|
216
|
+
const buildTexture = () => {
|
|
217
|
+
drawText();
|
|
218
|
+
if (texture)
|
|
219
|
+
texture.dispose();
|
|
220
|
+
texture = new THREE.CanvasTexture(texCanvas);
|
|
221
|
+
texture.minFilter = THREE.LinearFilter;
|
|
222
|
+
texture.magFilter = THREE.LinearFilter;
|
|
223
|
+
texture.generateMipmaps = false;
|
|
224
|
+
/* Uniform values are read every render — no material.needsUpdate,
|
|
225
|
+
which would recompile the program on every resize. */
|
|
226
|
+
for (const m of materials) {
|
|
227
|
+
m.uniforms.uMap.value = texture;
|
|
228
|
+
m.uniforms.uAspect.value = w / Math.max(1, h);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
/* ---------------- materials + the three chroma passes ---------------- */
|
|
232
|
+
const passColors = chroma
|
|
233
|
+
? [new THREE.Color(pass.r, 0, 0), new THREE.Color(0, pass.g, 0), new THREE.Color(0, 0, pass.b)]
|
|
234
|
+
: [pass];
|
|
235
|
+
const passScales = chroma ? [0.9, 1, 1.1] : [1];
|
|
236
|
+
const materials = passColors.map((pc, i) => new THREE.ShaderMaterial({
|
|
237
|
+
vertexShader: VERT,
|
|
238
|
+
fragmentShader: chroma ? CHROMA_FRAG : PLAIN_FRAG,
|
|
239
|
+
uniforms: {
|
|
240
|
+
uMap: { value: null },
|
|
241
|
+
uPass: { value: pc },
|
|
242
|
+
uOpacity: { value: opacity },
|
|
243
|
+
uDispScale: { value: passScales[i] },
|
|
244
|
+
uAspect: { value: w / Math.max(1, h) },
|
|
245
|
+
},
|
|
246
|
+
transparent: true,
|
|
247
|
+
depthTest: false,
|
|
248
|
+
depthWrite: false,
|
|
249
|
+
blending: chroma ? THREE.CustomBlending : THREE.NormalBlending,
|
|
250
|
+
blendSrc: THREE.OneFactor,
|
|
251
|
+
blendDst: THREE.OneFactor,
|
|
252
|
+
blendEquation: THREE.AddEquation,
|
|
253
|
+
}));
|
|
254
|
+
/* ---------------- grid + sim state ---------------- */
|
|
255
|
+
let geometry;
|
|
256
|
+
let meshes = [];
|
|
257
|
+
let disp = new Float32Array(0); // x,y displacement
|
|
258
|
+
let vel = new Float32Array(0); // x,y velocity
|
|
259
|
+
let verts = 0;
|
|
260
|
+
const buildGrid = () => {
|
|
261
|
+
geometry?.dispose();
|
|
262
|
+
for (const m of meshes)
|
|
263
|
+
scene.remove(m);
|
|
264
|
+
const cols = segments > 0 ? Math.round(segments) : Math.min(160, Math.max(40, Math.round(w / 10)));
|
|
265
|
+
const cell = w / cols;
|
|
266
|
+
const rows = Math.min(96, Math.max(8, Math.round(h / cell)));
|
|
267
|
+
/* Half-width space: x spans ±1, y spans ±h/w (isotropic units). */
|
|
268
|
+
geometry = new THREE.PlaneGeometry(2, (2 * h) / w, cols, rows);
|
|
269
|
+
verts = geometry.attributes.position.count;
|
|
270
|
+
disp = new Float32Array(verts * 2);
|
|
271
|
+
vel = new Float32Array(verts * 2);
|
|
272
|
+
const attr = new THREE.BufferAttribute(disp, 2);
|
|
273
|
+
attr.setUsage(THREE.DynamicDrawUsage);
|
|
274
|
+
geometry.setAttribute("aDisp", attr);
|
|
275
|
+
meshes = passColors.map((_, i) => {
|
|
276
|
+
const mesh = new THREE.Mesh(geometry, materials[i]);
|
|
277
|
+
mesh.frustumCulled = false; // the shader moves the verts
|
|
278
|
+
scene.add(mesh);
|
|
279
|
+
return mesh;
|
|
280
|
+
});
|
|
281
|
+
};
|
|
282
|
+
buildTexture();
|
|
283
|
+
buildGrid();
|
|
284
|
+
host.appendChild(canvas);
|
|
285
|
+
/* ---------------- pointer + sim ---------------- */
|
|
286
|
+
const cursor = { x: 0, y: 0 };
|
|
287
|
+
const prevCursor = { x: 0, y: 0 };
|
|
288
|
+
let hasCursor = false;
|
|
289
|
+
let settled = true;
|
|
290
|
+
let needsRender = true;
|
|
291
|
+
let acc = 0;
|
|
292
|
+
const toSim = (cx, cy, rect) => {
|
|
293
|
+
const rw = Math.max(1, rect.width);
|
|
294
|
+
const rh = Math.max(1, rect.height);
|
|
295
|
+
return { x: (cx / rw) * 2 - 1, y: (1 - (cy / rh) * 2) * (rh / rw) };
|
|
296
|
+
};
|
|
297
|
+
const onMove = (e) => {
|
|
298
|
+
const rect = host.getBoundingClientRect();
|
|
299
|
+
const p = toSim(e.clientX - rect.left, e.clientY - rect.top, rect);
|
|
300
|
+
if (!hasCursor) {
|
|
301
|
+
prevCursor.x = p.x; // first sighting: no delta from the origin
|
|
302
|
+
prevCursor.y = p.y;
|
|
303
|
+
hasCursor = true;
|
|
304
|
+
}
|
|
305
|
+
cursor.x = p.x;
|
|
306
|
+
cursor.y = p.y;
|
|
307
|
+
/* Outside the box + reach nothing can move — don't wake the sim. */
|
|
308
|
+
const dx = Math.max(0, Math.abs(p.x) - 1);
|
|
309
|
+
const dy = Math.max(0, Math.abs(p.y) - h / Math.max(1, w));
|
|
310
|
+
if (Math.hypot(dx, dy) < REACH + 0.05)
|
|
311
|
+
settled = false;
|
|
312
|
+
};
|
|
313
|
+
window.addEventListener("pointermove", onMove, { passive: true });
|
|
314
|
+
/* One fixed 1/60 s step — mirrors the reference's transform-feedback
|
|
315
|
+
shader: velocity += drag + spring + push, damping, integrate, clamp. */
|
|
316
|
+
const step = (vx, vy) => {
|
|
317
|
+
const rest = geometry.attributes.position.array;
|
|
318
|
+
const stride = geometry.attributes.position.itemSize; // 3: x,y,z
|
|
319
|
+
let maxD = 0;
|
|
320
|
+
let maxV = 0;
|
|
321
|
+
for (let i = 0; i < verts; i++) {
|
|
322
|
+
const ix = i * 2;
|
|
323
|
+
const iy = ix + 1;
|
|
324
|
+
const rx = i * stride;
|
|
325
|
+
/* cursorToPos: from the cursor to the vertex's current position */
|
|
326
|
+
const ox = rest[rx] + disp[ix] - cursor.x;
|
|
327
|
+
const oy = rest[rx + 1] + disp[iy] - cursor.y;
|
|
328
|
+
const dist = Math.hypot(ox, oy);
|
|
329
|
+
let strength = 1 / (1 + dist / FALLOFF) - FLOOR;
|
|
330
|
+
if (strength <= 0)
|
|
331
|
+
strength = 0;
|
|
332
|
+
else if (strength > 1)
|
|
333
|
+
strength = 1;
|
|
334
|
+
vel[ix] =
|
|
335
|
+
(vel[ix] + vx * DRAG_K * strength * drag - disp[ix] * SPRING + ox * strength * push) * DAMP;
|
|
336
|
+
vel[iy] =
|
|
337
|
+
(vel[iy] + vy * DRAG_K * strength * drag - disp[iy] * SPRING + oy * strength * push) * DAMP;
|
|
338
|
+
disp[ix] += vel[ix] * INTEG;
|
|
339
|
+
disp[iy] += vel[iy] * INTEG;
|
|
340
|
+
disp[ix] = disp[ix] > 1 ? 1 : disp[ix] < -1 ? -1 : disp[ix];
|
|
341
|
+
disp[iy] = disp[iy] > 1 ? 1 : disp[iy] < -1 ? -1 : disp[iy];
|
|
342
|
+
vel[ix] = vel[ix] > 1 ? 1 : vel[ix] < -1 ? -1 : vel[ix];
|
|
343
|
+
vel[iy] = vel[iy] > 1 ? 1 : vel[iy] < -1 ? -1 : vel[iy];
|
|
344
|
+
const ad = Math.abs(disp[ix]) + Math.abs(disp[iy]);
|
|
345
|
+
const av = Math.abs(vel[ix]) + Math.abs(vel[iy]);
|
|
346
|
+
if (ad > maxD)
|
|
347
|
+
maxD = ad;
|
|
348
|
+
if (av > maxV)
|
|
349
|
+
maxV = av;
|
|
350
|
+
}
|
|
351
|
+
/* Asleep only when every vertex is back at rest: strength is 0 beyond
|
|
352
|
+
REACH anyway, so a pointer moving elsewhere can't wake it — onMove
|
|
353
|
+
does that when it comes back within reach. */
|
|
354
|
+
if (maxD < SETTLE_EPS && maxV < SETTLE_EPS)
|
|
355
|
+
settled = true;
|
|
356
|
+
};
|
|
357
|
+
const render = () => {
|
|
358
|
+
geometry.attributes.aDisp.needsUpdate = true;
|
|
359
|
+
renderer.render(scene, camera);
|
|
360
|
+
needsRender = false;
|
|
361
|
+
};
|
|
362
|
+
/* ---------------- visibility gate ---------------- */
|
|
363
|
+
let visible = true;
|
|
364
|
+
let io = null;
|
|
365
|
+
if (typeof IntersectionObserver === "function") {
|
|
366
|
+
io = new IntersectionObserver(([entry]) => {
|
|
367
|
+
const was = visible;
|
|
368
|
+
visible = entry.isIntersecting;
|
|
369
|
+
if (visible && !was)
|
|
370
|
+
needsRender = true;
|
|
371
|
+
}, { rootMargin: "80px" });
|
|
372
|
+
io.observe(host);
|
|
373
|
+
}
|
|
374
|
+
/* ---------------- ticker: frame velocity + fixed-step sim ---------------- */
|
|
375
|
+
const tick = (_t, deltaMs) => {
|
|
376
|
+
let dt = deltaMs / 1000;
|
|
377
|
+
if (!(dt > 0))
|
|
378
|
+
dt = STEP;
|
|
379
|
+
if (dt > 0.2)
|
|
380
|
+
dt = STEP; // a stalled tab folds into one clean step
|
|
381
|
+
/* Pointer velocity is a per-frame quantity: cursor - last frame's.
|
|
382
|
+
Consumed every frame — even off-screen — so a delta accumulated
|
|
383
|
+
while hidden never lands as one phantom impulse on re-entry. */
|
|
384
|
+
let vx = 0;
|
|
385
|
+
let vy = 0;
|
|
386
|
+
if (hasCursor) {
|
|
387
|
+
vx = (cursor.x - prevCursor.x) / dt;
|
|
388
|
+
vy = (cursor.y - prevCursor.y) / dt;
|
|
389
|
+
if (Math.hypot(vx, vy) > V_CLAMP) {
|
|
390
|
+
vx = 0;
|
|
391
|
+
vy = 0;
|
|
392
|
+
}
|
|
393
|
+
prevCursor.x = cursor.x;
|
|
394
|
+
prevCursor.y = cursor.y;
|
|
395
|
+
}
|
|
396
|
+
if (!visible) {
|
|
397
|
+
needsRender = true;
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (settled) {
|
|
401
|
+
if (needsRender)
|
|
402
|
+
render();
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
acc += dt;
|
|
406
|
+
let n = Math.floor(acc / STEP);
|
|
407
|
+
if (n > MAX_STEPS)
|
|
408
|
+
n = MAX_STEPS;
|
|
409
|
+
acc -= n * STEP;
|
|
410
|
+
if (n <= 0) {
|
|
411
|
+
if (needsRender)
|
|
412
|
+
render();
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
for (let i = 0; i < n; i++)
|
|
416
|
+
step(vx, vy);
|
|
417
|
+
render();
|
|
418
|
+
};
|
|
419
|
+
gsap.ticker.add(tick);
|
|
420
|
+
/* ---------------- resize ---------------- */
|
|
421
|
+
let ro = null;
|
|
422
|
+
const resize = () => {
|
|
423
|
+
const rw = Math.max(1, host.clientWidth);
|
|
424
|
+
const rh = Math.max(1, host.clientHeight);
|
|
425
|
+
if (rw === w && rh === h)
|
|
426
|
+
return;
|
|
427
|
+
w = rw;
|
|
428
|
+
h = rh;
|
|
429
|
+
renderer.setSize(w, h, false);
|
|
430
|
+
buildTexture();
|
|
431
|
+
buildGrid();
|
|
432
|
+
settled = false;
|
|
433
|
+
needsRender = true;
|
|
434
|
+
};
|
|
435
|
+
/* ResizeObserver alone: a vw-sized host reflows on window resize too,
|
|
436
|
+
so the box change is always what actually needs the rebuild. */
|
|
437
|
+
if (typeof ResizeObserver === "function") {
|
|
438
|
+
ro = new ResizeObserver(resize);
|
|
439
|
+
ro.observe(host);
|
|
440
|
+
}
|
|
441
|
+
render(); // the rest state, before the pointer ever arrives
|
|
442
|
+
/* ---------------- teardown ---------------- */
|
|
443
|
+
return () => {
|
|
444
|
+
gsap.ticker.remove(tick);
|
|
445
|
+
window.removeEventListener("pointermove", onMove);
|
|
446
|
+
io?.disconnect();
|
|
447
|
+
ro?.disconnect();
|
|
448
|
+
for (const m of meshes)
|
|
449
|
+
scene.remove(m);
|
|
450
|
+
geometry.dispose();
|
|
451
|
+
for (const m of materials)
|
|
452
|
+
m.dispose();
|
|
453
|
+
texture?.dispose();
|
|
454
|
+
renderer.dispose();
|
|
455
|
+
canvas.remove();
|
|
456
|
+
host.style.color = prevColor;
|
|
457
|
+
host.style.position = prevPosition;
|
|
458
|
+
};
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
//# sourceMappingURL=wordmark-wave.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wordmark-wave.js","sourceRoot":"","sources":["../../src/three/wordmark-wave.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmictraveler002/anim-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Modular, framework-agnostic animation library — GSAP + ScrollTrigger + Lenis effects packaged as composable ES modules.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -4,10 +4,14 @@
|
|
|
4
4
|
* Uses the canonical Lenis + GSAP recipe:
|
|
5
5
|
* lenis.on("scroll", ScrollTrigger.update)
|
|
6
6
|
* gsap.ticker.add(t => lenis.raf(t * 1000))
|
|
7
|
-
* gsap.ticker.lagSmoothing(0)
|
|
8
7
|
*
|
|
9
8
|
* Driving Lenis from GSAP's ticker (rather than its own rAF) keeps both
|
|
10
9
|
* clocks on the same frame, which is what stops ScrollTrigger from stuttering.
|
|
10
|
+
* Those ticker callbacks receive the *same* adjusted clock the tweens run on,
|
|
11
|
+
* so GSAP's lag smoothing is deliberately left on: a stalled frame (GC pause,
|
|
12
|
+
* buffer tick) advances one short step everywhere instead of snapping the
|
|
13
|
+
* scroll and every scroll-linked tween to a new time at once. See
|
|
14
|
+
* SmoothScrollOptions.lagSmoothing to retune it or restore the old opt-out.
|
|
11
15
|
*
|
|
12
16
|
* `useScrollerProxy: true` additionally proxies `document.documentElement`,
|
|
13
17
|
* matching kalakritico.in's setup — only needed if you scroll a nested
|
|
@@ -31,6 +35,27 @@ export interface SmoothScrollOptions extends CommonOptions {
|
|
|
31
35
|
initialScroll?: number;
|
|
32
36
|
/** Proxy documentElement through ScrollTrigger (nested scrollers). @default false */
|
|
33
37
|
useScrollerProxy?: boolean;
|
|
38
|
+
/** Touch-drag sensitivity — forwarded to Lenis `touchMultiplier`. @default 1 */
|
|
39
|
+
touchMultiplier?: number;
|
|
40
|
+
/** Mouse-wheel sensitivity — forwarded to Lenis `wheelMultiplier`. @default 1 */
|
|
41
|
+
wheelMultiplier?: number;
|
|
42
|
+
/**
|
|
43
|
+
* GSAP lag smoothing on the shared ticker: a frame longer than `threshold`
|
|
44
|
+
* advances only `adjustedLag` ms, so a hitch can't teleport the scroll and
|
|
45
|
+
* every scroll-linked tween in one jump.
|
|
46
|
+
*
|
|
47
|
+
* - `undefined` — leave GSAP's setup alone; its built-in compensation
|
|
48
|
+
* (500ms → 33ms) stays active.
|
|
49
|
+
* - `false` — disable lag smoothing (anim-kit ≤1.4 behaviour, what the
|
|
50
|
+
* Lenis README recipe asks for): timing stays exactly wall-clock, but
|
|
51
|
+
* every frame longer than the threshold snaps.
|
|
52
|
+
* - `{ threshold, adjustedLag }` — retune it. Lower the threshold (e.g.
|
|
53
|
+
* `150`) to smooth short mobile hitches; raise it if slow devices should
|
|
54
|
+
* keep real-time speed instead of briefly running slow-motion.
|
|
55
|
+
*
|
|
56
|
+
* `destroy()` restores GSAP's default (500/33) whenever this was set.
|
|
57
|
+
*/
|
|
58
|
+
lagSmoothing?: false | { threshold?: number; adjustedLag?: number };
|
|
34
59
|
}
|
|
35
60
|
|
|
36
61
|
export interface SmoothScrollHandle {
|
|
@@ -61,6 +86,9 @@ export function smoothScroll(options: SmoothScrollOptions = {}): SmoothScrollHan
|
|
|
61
86
|
orientation = "vertical",
|
|
62
87
|
initialScroll = 0,
|
|
63
88
|
useScrollerProxy = false,
|
|
89
|
+
touchMultiplier,
|
|
90
|
+
wheelMultiplier,
|
|
91
|
+
lagSmoothing,
|
|
64
92
|
} = options;
|
|
65
93
|
|
|
66
94
|
if (typeof window === "undefined") return INERT;
|
|
@@ -74,6 +102,9 @@ export function smoothScroll(options: SmoothScrollOptions = {}): SmoothScrollHan
|
|
|
74
102
|
syncTouch: smoothTouch,
|
|
75
103
|
orientation,
|
|
76
104
|
autoRaf: false,
|
|
105
|
+
// undefined falls through to Lenis's own defaults (1 / 1).
|
|
106
|
+
touchMultiplier,
|
|
107
|
+
wheelMultiplier,
|
|
77
108
|
});
|
|
78
109
|
|
|
79
110
|
if (initialScroll) lenis.scrollTo(initialScroll, { immediate: true });
|
|
@@ -85,7 +116,17 @@ export function smoothScroll(options: SmoothScrollOptions = {}): SmoothScrollHan
|
|
|
85
116
|
// 2. Run Lenis off GSAP's ticker so both share one frame clock.
|
|
86
117
|
const tick = (time: number) => lenis.raf(time * 1000);
|
|
87
118
|
gsap.ticker.add(tick);
|
|
88
|
-
|
|
119
|
+
|
|
120
|
+
// Lag smoothing drives *one* clock — the tweens' and this ticker's alike —
|
|
121
|
+
// so leaving GSAP's compensation on turns a stalled frame into one short
|
|
122
|
+
// step everywhere instead of a snap. Only touch the ticker when asked, so a
|
|
123
|
+
// host page's own setup is never clobbered.
|
|
124
|
+
let lagTouched = false;
|
|
125
|
+
if (lagSmoothing !== undefined) {
|
|
126
|
+
lagTouched = true;
|
|
127
|
+
if (lagSmoothing === false) gsap.ticker.lagSmoothing(0);
|
|
128
|
+
else gsap.ticker.lagSmoothing(lagSmoothing.threshold ?? 500, lagSmoothing.adjustedLag ?? 33);
|
|
129
|
+
}
|
|
89
130
|
|
|
90
131
|
// 3. Optional: proxy the scroller (for nested/element scrollers).
|
|
91
132
|
if (useScrollerProxy) {
|
|
@@ -126,6 +167,7 @@ export function smoothScroll(options: SmoothScrollOptions = {}): SmoothScrollHan
|
|
|
126
167
|
window.removeEventListener("resize", onResize);
|
|
127
168
|
window.removeEventListener("load", refresh);
|
|
128
169
|
gsap.ticker.remove(tick);
|
|
170
|
+
if (lagTouched) gsap.ticker.lagSmoothing(500, 33); // undo our change — GSAP's default
|
|
129
171
|
lenis.off("scroll", onScroll);
|
|
130
172
|
if (useScrollerProxy) {
|
|
131
173
|
ScrollTrigger.scrollerProxy(document.documentElement, {} as never);
|
|
@@ -68,6 +68,9 @@ export function horizontalScroll(
|
|
|
68
68
|
scrollTrigger: {
|
|
69
69
|
trigger: section,
|
|
70
70
|
pin: true,
|
|
71
|
+
// Refresh pins first (creation order ≠ document order): our spacer must
|
|
72
|
+
// exist before triggers below us measure, or they start ~9k px early.
|
|
73
|
+
refreshPriority: 1,
|
|
71
74
|
scrub,
|
|
72
75
|
end: () => "+=" + travel(),
|
|
73
76
|
invalidateOnRefresh: true,
|