@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.
Files changed (56) hide show
  1. package/README.md +256 -23
  2. package/dist/anim-kit.standalone.js +5 -5
  3. package/dist/anim-kit.standalone.js.map +1 -1
  4. package/dist/core/smooth-scroll.d.ts +29 -1
  5. package/dist/core/smooth-scroll.d.ts.map +1 -1
  6. package/dist/core/smooth-scroll.js +23 -3
  7. package/dist/core/smooth-scroll.js.map +1 -1
  8. package/dist/effects/horizontal-scroll.d.ts.map +1 -1
  9. package/dist/effects/horizontal-scroll.js +3 -0
  10. package/dist/effects/horizontal-scroll.js.map +1 -1
  11. package/dist/effects/ink-wipe.d.ts +41 -0
  12. package/dist/effects/ink-wipe.d.ts.map +1 -0
  13. package/dist/effects/ink-wipe.js +342 -0
  14. package/dist/effects/ink-wipe.js.map +1 -0
  15. package/dist/effects/scatter-text.d.ts.map +1 -1
  16. package/dist/effects/scatter-text.js +3 -0
  17. package/dist/effects/scatter-text.js.map +1 -1
  18. package/dist/effects/stacked-cards.d.ts.map +1 -1
  19. package/dist/effects/stacked-cards.js +3 -0
  20. package/dist/effects/stacked-cards.js.map +1 -1
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +2 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/three/coverflow-wheel.d.ts +26 -0
  26. package/dist/three/coverflow-wheel.d.ts.map +1 -0
  27. package/dist/three/coverflow-wheel.js +495 -0
  28. package/dist/three/coverflow-wheel.js.map +1 -0
  29. package/dist/three/dither-reveal.d.ts +36 -0
  30. package/dist/three/dither-reveal.d.ts.map +1 -0
  31. package/dist/three/dither-reveal.js +292 -0
  32. package/dist/three/dither-reveal.js.map +1 -0
  33. package/dist/three/index.d.ts +8 -0
  34. package/dist/three/index.d.ts.map +1 -1
  35. package/dist/three/index.js +4 -0
  36. package/dist/three/index.js.map +1 -1
  37. package/dist/three/tear-reveal.d.ts +54 -0
  38. package/dist/three/tear-reveal.d.ts.map +1 -0
  39. package/dist/three/tear-reveal.js +269 -0
  40. package/dist/three/tear-reveal.js.map +1 -0
  41. package/dist/three/wordmark-wave.d.ts +29 -0
  42. package/dist/three/wordmark-wave.d.ts.map +1 -0
  43. package/dist/three/wordmark-wave.js +461 -0
  44. package/dist/three/wordmark-wave.js.map +1 -0
  45. package/package.json +1 -1
  46. package/src/core/smooth-scroll.ts +44 -2
  47. package/src/effects/horizontal-scroll.ts +3 -0
  48. package/src/effects/ink-wipe.ts +409 -0
  49. package/src/effects/scatter-text.ts +3 -0
  50. package/src/effects/stacked-cards.ts +3 -0
  51. package/src/index.ts +3 -0
  52. package/src/three/coverflow-wheel.ts +569 -0
  53. package/src/three/dither-reveal.ts +365 -0
  54. package/src/three/index.ts +8 -0
  55. package/src/three/tear-reveal.ts +351 -0
  56. package/src/three/wordmark-wave.ts +517 -0
@@ -0,0 +1,36 @@
1
+ import type { CommonOptions, Destroy, TargetLike } from "../core/types.js";
2
+ export interface DitherRevealOptions extends CommonOptions {
3
+ /** Image source — defaults to the wrapper's first `<img>`. */
4
+ src?: string;
5
+ /** Reveal duration, seconds. @default 1.15 */
6
+ duration?: number;
7
+ /** GSAP ease for the reveal. @default "power4.out" */
8
+ ease?: string;
9
+ /**
10
+ * Flat placeholder colour shown where the mask has not opened yet
11
+ * (their "develop" plate). Omit to let the wrapper's own background
12
+ * show through the not-yet-revealed area.
13
+ */
14
+ plate?: string;
15
+ /** fbm frequency across the element — the lump scale of the edge. @default 50 */
16
+ maskScale?: number;
17
+ /**
18
+ * How far (in normalised radius) the noise can push the boundary ahead of
19
+ * and behind the clean circle. @default 0.35
20
+ */
21
+ spread?: number;
22
+ /** fbm octaves — 1 is a soft blob, 6 is gritty. @default 4 */
23
+ detail?: number;
24
+ /** Hard-edged speckle (the signature) vs a soft dissolve. @default true */
25
+ hard?: boolean;
26
+ /**
27
+ * When the reveal fires: on first viewport entry (default) or as soon as
28
+ * the texture has decoded. Falls back to `"load"` without IntersectionObserver.
29
+ * @default "visible"
30
+ */
31
+ play?: "load" | "visible";
32
+ /** Device-pixel-ratio cap. @default 2 */
33
+ dpr?: number;
34
+ }
35
+ export declare function ditherReveal(target: TargetLike, options?: DitherRevealOptions): Destroy;
36
+ //# sourceMappingURL=dither-reveal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dither-reveal.d.ts","sourceRoot":"","sources":["../../src/three/dither-reveal.ts"],"names":[],"mappings":"AA8CA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE3E,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAsFD,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAsM3F"}
@@ -0,0 +1,292 @@
1
+ /**
2
+ * Dither reveal — a photo that punches through its placeholder in a speckled
3
+ * ring expanding from the centre outward.
4
+ *
5
+ * The mask is the whole trick: a radial threshold displaced by fbm noise, so
6
+ * the boundary is lumpy at low frequency and speckled at high frequency, and
7
+ * every pixel on the boundary flips hard between "hole" and "not hole" — no
8
+ * soft dissolve, no crossfade. The noise spread ramps to zero at both ends of
9
+ * the travel, so progress 0 is exactly empty and progress 1 exactly solid
10
+ * (no half-revealed corners, no leftover speckle).
11
+ *
12
+ * The image keeps owning layout and alt text; the effect paints it onto a
13
+ * canvas that covers the wrapper and hands the pixels over only once its
14
+ * texture has decoded — a 404 or a WebGL-less browser leaves the plain `<img>`
15
+ * exactly where it was.
16
+ *
17
+ * - **Optional peer.** Lives behind the `@cosmictraveler002/anim-kit/three`
18
+ * subpath; the core barrel stays gsap+lenis only. `three` is an optional
19
+ * peer — install it to use this entry, the core never imports it.
20
+ * - **Silent no-op ladder.** Missing target → no-op. No
21
+ * `WebGLRenderingContext` (jsdom, SSR, WebGL-disabled browsers) → no-op
22
+ * *before* a context is ever requested (a probe call would itself log).
23
+ * Renderer construction throws → no-op. Texture 404s → the plain `<img>`
24
+ * stays visible. Under `prefers-reduced-motion` the canvas never mounts —
25
+ * the image simply shows, which is the motion-reduced end state anyway.
26
+ * - **Cover crop in-shader.** The texture is sampled with `object-fit: cover`
27
+ * maths (`scale = uRes / uTexSize`, windowed around the centre), so any
28
+ * source aspect fills the card without letterboxing.
29
+ * - **Trigger model.** The reveal fires once, when the texture is decoded
30
+ * *and* the wrapper has been on screen (`play: "visible"`, the default) —
31
+ * a reveal that runs before anyone can see it is not a reveal. `play:
32
+ * "load"` fires it the moment the texture lands, regardless of viewport.
33
+ * - **Fidelity.** `destroy()` kills the tween + observers/listeners, disposes
34
+ * geometry/material/texture/renderer, removes the canvas and restores the
35
+ * `<img>` opacity and wrapper position it changed.
36
+ *
37
+ * ditherReveal("[data-reveal]", { plate: "#14140f", duration: 1.15 })
38
+ *
39
+ * Markup: a wrapper element containing `<img>` (or pass `src` explicitly):
40
+ *
41
+ * <figure class="shot" data-reveal><img src="photo.jpg" alt="" /></figure>
42
+ */
43
+ import * as THREE from "three";
44
+ import { gsap, initGSAP } from "../core/gsap.js";
45
+ import { guard } from "../core/guard.js";
46
+ import { one } from "../core/util.js";
47
+ const VERT = /* glsl */ `
48
+ varying vec2 vUv;
49
+
50
+ void main() {
51
+ vUv = uv;
52
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
53
+ }
54
+ `;
55
+ const FRAG = /* glsl */ `
56
+ precision highp float;
57
+ varying vec2 vUv;
58
+ uniform sampler2D uTex;
59
+ uniform vec2 uRes;
60
+ uniform vec2 uTexSize;
61
+ uniform vec3 uPlate;
62
+ uniform float uPlateA;
63
+ uniform float uProgress;
64
+ uniform float uMaskScale;
65
+ uniform float uSpread;
66
+ uniform float uDetail;
67
+ uniform float uHard;
68
+
69
+ float hash(vec2 p) {
70
+ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
71
+ }
72
+
73
+ float vnoise(vec2 p) {
74
+ vec2 i = floor(p);
75
+ vec2 f = fract(p);
76
+ vec2 u = f * f * (3.0 - 2.0 * f);
77
+ return mix(
78
+ mix(hash(i), hash(i + vec2(1.0, 0.0)), u.x),
79
+ mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), u.x),
80
+ u.y);
81
+ }
82
+
83
+ /* Normalised to ~0..1 for any octave count, so spread means the same thing
84
+ whether detail is 1 or 6. */
85
+ float fbm(vec2 p) {
86
+ float v = 0.0;
87
+ float a = 0.5;
88
+ for (int i = 0; i < 6; i++) {
89
+ if (float(i) >= uDetail) break;
90
+ v += a * vnoise(p);
91
+ p = p * 2.03 + 17.0;
92
+ a *= 0.5;
93
+ }
94
+ return v / max(1.0 - pow(0.5, uDetail), 0.0001);
95
+ }
96
+
97
+ void main() {
98
+ /* object-fit: cover — window the texture around its centre. */
99
+ vec2 scale = uRes / max(uTexSize, vec2(1.0));
100
+ vec2 cover = (vUv - 0.5) * (scale / max(scale.x, scale.y)) + 0.5;
101
+ vec3 photo = texture2D(uTex, cover).rgb;
102
+
103
+ /* Radial distance in normalised half-diagonal units: 0 centre, 1 corners. */
104
+ float d = length((vUv - 0.5) * uRes) / (0.5 * length(uRes));
105
+
106
+ float mask;
107
+ if (uProgress <= 0.0001) {
108
+ mask = 0.0; /* exactly empty */
109
+ } else if (uProgress >= 0.9999) {
110
+ mask = 1.0; /* exactly solid */
111
+ } else {
112
+ /* Noise spread dies off at both ends of the travel: the start stays
113
+ empty and the finish stays sealed however far the fbm drags. */
114
+ float ramp = smoothstep(0.0, 0.18, uProgress) *
115
+ smoothstep(1.0, 0.82, uProgress);
116
+ float gap = fbm(vUv * uMaskScale);
117
+ float th = uProgress + (0.5 - gap) * uSpread * ramp;
118
+ mask = uHard > 0.5
119
+ ? 1.0 - step(th, d) /* round(): the speckle */
120
+ : 1.0 - smoothstep(th - 0.04, th + 0.04, d);
121
+ }
122
+
123
+ vec3 col = mix(uPlate, photo, mask);
124
+ float alpha = mix(uPlateA, 1.0, mask);
125
+ if (alpha < 0.003) discard;
126
+ gl_FragColor = vec4(col, alpha);
127
+ }
128
+ `;
129
+ export function ditherReveal(target, options = {}) {
130
+ initGSAP();
131
+ const host = one(target);
132
+ if (!host)
133
+ return () => { };
134
+ const { src, duration = 1.15, ease = "power4.out", plate, maskScale = 50, spread = 0.35, detail = 4, hard = true, play = "visible", dpr = 2, } = options;
135
+ return guard(options, () => {
136
+ /* ---------------- availability ladder (silent, no probes) ---------------- */
137
+ if (typeof window === "undefined" || !("WebGLRenderingContext" in window))
138
+ return () => { };
139
+ let renderer;
140
+ try {
141
+ renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
142
+ }
143
+ catch {
144
+ return () => { }; // context refused (disabled/blacklisted) — plain img stays
145
+ }
146
+ const img = host.tagName === "IMG" ? null : host.querySelector("img");
147
+ const textureSrc = src || img?.currentSrc || img?.src;
148
+ if (!textureSrc) {
149
+ renderer.dispose();
150
+ return () => { };
151
+ }
152
+ /* ---------------- layout + styles we must restore ---------------- */
153
+ const prevPosition = host.style.position;
154
+ if (!prevPosition && getComputedStyle(host).position === "static") {
155
+ host.style.position = "relative";
156
+ }
157
+ const prevImgOpacity = img?.style.opacity ?? "";
158
+ host.dataset.akReveal = "true";
159
+ const w = Math.max(1, host.clientWidth);
160
+ const h = Math.max(1, host.clientHeight);
161
+ renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, dpr));
162
+ renderer.setSize(w, h, false);
163
+ const canvas = renderer.domElement;
164
+ canvas.style.cssText =
165
+ "position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none;";
166
+ const scene = new THREE.Scene();
167
+ const camera = new THREE.OrthographicCamera(-w / 2, w / 2, h / 2, -h / 2, -100, 100);
168
+ camera.position.z = 10;
169
+ const plateColor = new THREE.Color(plate || "#000000");
170
+ const geometry = new THREE.PlaneGeometry(1, 1, 1, 1);
171
+ const uniforms = {
172
+ uTex: { value: null },
173
+ uRes: { value: new THREE.Vector2(w, h) },
174
+ uTexSize: { value: new THREE.Vector2(1, 1) },
175
+ uPlate: { value: plateColor },
176
+ uPlateA: { value: plate ? 1 : 0 },
177
+ uProgress: { value: 0 },
178
+ uMaskScale: { value: maskScale },
179
+ uSpread: { value: spread },
180
+ uDetail: { value: detail },
181
+ uHard: { value: hard ? 1 : 0 },
182
+ };
183
+ const material = new THREE.ShaderMaterial({
184
+ vertexShader: VERT,
185
+ fragmentShader: FRAG,
186
+ uniforms,
187
+ transparent: true,
188
+ });
189
+ const mesh = new THREE.Mesh(geometry, material);
190
+ mesh.scale.set(w, h, 1);
191
+ mesh.visible = false;
192
+ scene.add(mesh);
193
+ host.appendChild(canvas);
194
+ /* ---------------- texture + play trigger ---------------- */
195
+ let disposed = false;
196
+ let loaded = false;
197
+ let seen = play === "load"; // armed for "visible" once the wrapper is on screen
198
+ let played = false;
199
+ let revealTween = null;
200
+ const loader = new THREE.TextureLoader();
201
+ const tryPlay = () => {
202
+ if (played || !loaded || !seen || disposed)
203
+ return;
204
+ played = true;
205
+ /* With a plate the placeholder has been covering the <img> since the
206
+ texture landed; without one the <img> only steps aside now, so the
207
+ area is never empty before the reveal actually starts. */
208
+ if (img && !plate)
209
+ img.style.opacity = "0";
210
+ revealTween = gsap.fromTo(uniforms.uProgress, { value: 0 }, { value: 1, duration, ease, overwrite: true });
211
+ };
212
+ loader.load(textureSrc, (texture) => {
213
+ if (disposed) {
214
+ texture.dispose();
215
+ return;
216
+ }
217
+ texture.minFilter = THREE.LinearFilter;
218
+ texture.magFilter = THREE.LinearFilter;
219
+ // No sRGB decode: the raw shader passes sampled values through, so the
220
+ // texture must stay an ordinary RGBA8 upload (built-in colorSpace
221
+ // conversion only happens inside three's own material chunks).
222
+ uniforms.uTex.value = texture;
223
+ uniforms.uTexSize.value.set(texture.image.width || 1, texture.image.height || 1);
224
+ mesh.visible = true;
225
+ loaded = true;
226
+ if (plate && img)
227
+ img.style.opacity = "0"; // plate owns the pixels now
228
+ tryPlay();
229
+ }, undefined, () => {
230
+ /* 404 / decode failure — the plain <img> was never hidden. */
231
+ });
232
+ /* ---------------- loop / observers ---------------- */
233
+ let visible = true;
234
+ let io = null;
235
+ if (typeof IntersectionObserver === "function") {
236
+ io = new IntersectionObserver(([entry]) => {
237
+ visible = entry.isIntersecting;
238
+ if (entry.isIntersecting) {
239
+ seen = true;
240
+ tryPlay();
241
+ }
242
+ }, { rootMargin: "80px" });
243
+ io.observe(host);
244
+ }
245
+ else {
246
+ seen = true; // no viewport signal available — play on load instead
247
+ tryPlay();
248
+ }
249
+ let ro = null;
250
+ const resize = () => {
251
+ const rw = Math.max(1, host.clientWidth);
252
+ const rh = Math.max(1, host.clientHeight);
253
+ renderer.setSize(rw, rh, false);
254
+ camera.left = -rw / 2;
255
+ camera.right = rw / 2;
256
+ camera.top = rh / 2;
257
+ camera.bottom = -rh / 2;
258
+ camera.updateProjectionMatrix();
259
+ mesh.scale.set(rw, rh, 1);
260
+ uniforms.uRes.value.set(rw, rh);
261
+ };
262
+ if (typeof ResizeObserver === "function") {
263
+ ro = new ResizeObserver(resize);
264
+ ro.observe(host);
265
+ }
266
+ const render = () => {
267
+ if (!visible || !mesh.visible)
268
+ return;
269
+ renderer.render(scene, camera);
270
+ };
271
+ gsap.ticker.add(render);
272
+ /* ---------------- teardown ---------------- */
273
+ return () => {
274
+ disposed = true;
275
+ gsap.ticker.remove(render);
276
+ revealTween?.kill();
277
+ gsap.killTweensOf(uniforms.uProgress);
278
+ io?.disconnect();
279
+ ro?.disconnect();
280
+ uniforms.uTex.value?.dispose();
281
+ geometry.dispose();
282
+ material.dispose();
283
+ renderer.dispose();
284
+ canvas.remove();
285
+ delete host.dataset.akReveal;
286
+ host.style.position = prevPosition;
287
+ if (img)
288
+ img.style.opacity = prevImgOpacity;
289
+ };
290
+ });
291
+ }
292
+ //# sourceMappingURL=dither-reveal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dither-reveal.js","sourceRoot":"","sources":["../../src/three/dither-reveal.ts"],"names":[],"mappings":"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"}
@@ -12,4 +12,12 @@ export { webglMedia } from "./webgl-media.js";
12
12
  export type { WebglMediaOptions } from "./webgl-media.js";
13
13
  export { glRail } from "./gl-rail.js";
14
14
  export type { GlRailOptions } from "./gl-rail.js";
15
+ export { tearReveal } from "./tear-reveal.js";
16
+ export type { TearRevealOptions, TearRevealDirection } from "./tear-reveal.js";
17
+ export { ditherReveal } from "./dither-reveal.js";
18
+ export type { DitherRevealOptions } from "./dither-reveal.js";
19
+ export { wordmarkWave } from "./wordmark-wave.js";
20
+ export type { WordmarkWaveOptions } from "./wordmark-wave.js";
21
+ export { coverflowWheel } from "./coverflow-wheel.js";
22
+ export type { CoverflowWheelOptions, CoverflowWheelHandle } from "./coverflow-wheel.js";
15
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/three/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/three/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -10,4 +10,8 @@
10
10
  */
11
11
  export { webglMedia } from "./webgl-media.js";
12
12
  export { glRail } from "./gl-rail.js";
13
+ export { tearReveal } from "./tear-reveal.js";
14
+ export { ditherReveal } from "./dither-reveal.js";
15
+ export { wordmarkWave } from "./wordmark-wave.js";
16
+ export { coverflowWheel } from "./coverflow-wheel.js";
13
17
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/three/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/three/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,54 @@
1
+ import type { CommonOptions, Destroy, TargetLike } from "../core/types.js";
2
+ export type TearRevealDirection = "up" | "down" | "left" | "right";
3
+ export interface TearRevealOptions extends CommonOptions {
4
+ /** Sheet colour — one colour or `[foot, top]` gradient stops. @default "#111111" */
5
+ color?: string | [string, string];
6
+ /**
7
+ * CSS `mix-blend-mode` for the canvas. `multiply` tints everything under
8
+ * the sheet instead of covering it; `none` = plain overlay.
9
+ * @default "none"
10
+ */
11
+ blend?: string;
12
+ /** Which way the boundary travels. @default "up" */
13
+ direction?: TearRevealDirection;
14
+ /** How far the noise drags the boundary. @default 0.175 */
15
+ dispAmp?: number;
16
+ /** Tear size — high is shrapnel, low is a wave. @default 12.2 */
17
+ dispScale?: number;
18
+ /** Noise octaves — 1 is a smooth wobble, 5 is debris. @default 5 */
19
+ dispDetail?: number;
20
+ /** How fast the noise pattern crawls (0 holds it still). @default 0 */
21
+ dispDrift?: number;
22
+ /** Threshold half-width — small keeps shards crisp. @default 0.001 */
23
+ soft?: number;
24
+ /**
25
+ * Barrel warp strength — negative bows the middle of the boundary up,
26
+ * 0 is a flat horizon. @default -0.275
27
+ */
28
+ lens?: number;
29
+ /** Timed-run duration, seconds (ignored when `scrub` is set). @default 1 */
30
+ duration?: number;
31
+ /** GSAP ease for the timed run. @default "power2.inOut" */
32
+ ease?: string;
33
+ /** "scroll" plays on enter, "immediate" plays at once. @default "scroll" */
34
+ mode?: "scroll" | "immediate";
35
+ /** ScrollTrigger start position. @default "top 85%" */
36
+ start?: string;
37
+ /** ScrollTrigger end position (scrub mode). @default "top 25%" */
38
+ end?: string;
39
+ /** Re-run when leaving / re-entering the viewport. @default false */
40
+ replay?: boolean;
41
+ /**
42
+ * Bind progress to scroll instead of playing it on enter —
43
+ * number = scrub smoothing seconds, `true` = immediate. unset = one-shot.
44
+ */
45
+ scrub?: number | boolean;
46
+ /** Mount the canvas over the viewport instead of the target box. @default false */
47
+ fixed?: boolean;
48
+ /** Canvas z-index inside its stacking context. @default 1 */
49
+ z?: number;
50
+ /** Device-pixel-ratio cap. @default 2 */
51
+ dpr?: number;
52
+ }
53
+ export declare function tearReveal(target: TargetLike, options?: TearRevealOptions): Destroy;
54
+ //# sourceMappingURL=tear-reveal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tear-reveal.d.ts","sourceRoot":"","sources":["../../src/three/tear-reveal.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE3E,MAAM,MAAM,mBAAmB,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEnE,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,IAAI,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC9B,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,mFAAmF;IACnF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6DAA6D;IAC7D,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAiFD,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CA4LvF"}