ripple-text 0.1.0 → 0.2.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.
@@ -0,0 +1,39 @@
1
+ import type { FieldEffect, LetterInput, RippleSource, RippleTextSettings, SettingsInput } from "./types";
2
+ export declare class RippleTextEngine {
3
+ private canvas;
4
+ private ctx;
5
+ private field;
6
+ private ripple;
7
+ settings: RippleTextSettings;
8
+ private letters;
9
+ private colors;
10
+ private rafId;
11
+ private lastFrameTime;
12
+ private running;
13
+ private fpsFrames;
14
+ private fpsLastTime;
15
+ private fpsDisplay;
16
+ private pointerDown;
17
+ private pointerX;
18
+ private pointerY;
19
+ private prevPointerX;
20
+ private prevPointerY;
21
+ private pointerSpeed;
22
+ private lastRippleTime;
23
+ private _onDown;
24
+ private _onMove;
25
+ private _onUp;
26
+ private _onTouchStart;
27
+ private _onTouchMove;
28
+ private _onTouchEnd;
29
+ constructor(canvas: HTMLCanvasElement, field: FieldEffect, ripple: RippleSource, settings?: SettingsInput);
30
+ setLetters(letters: LetterInput[]): void;
31
+ updateSettings(patch: SettingsInput): void;
32
+ resize(w: number, h: number): void;
33
+ start(): void;
34
+ stop(): void;
35
+ private emitRipples;
36
+ private updatePhysics;
37
+ private render;
38
+ }
39
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAEX,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACd,MAAM,SAAS,CAAC;AA0BjB,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,MAAM,CAAe;IAC7B,QAAQ,EAAE,kBAAkB,CAAC;IAE7B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,OAAO,CAAS;IAGxB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,UAAU,CAAK;IAGvB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,cAAc,CAAK;IAG3B,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,WAAW,CAAa;gBAG9B,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,YAAY,EACpB,QAAQ,CAAC,EAAE,aAAa;IA2E1B,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE;IAajC,cAAc,CAAC,KAAK,EAAE,aAAa;IAOnC,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAS3B,KAAK;IAkCL,IAAI;IAiBJ,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,aAAa;IA0DrB,OAAO,CAAC,MAAM;CAqCf"}
@@ -0,0 +1,78 @@
1
+ /** A single character with physics state */
2
+ export interface Letter {
3
+ char: string;
4
+ ox: number;
5
+ oy: number;
6
+ x: number;
7
+ y: number;
8
+ vx: number;
9
+ vy: number;
10
+ font: string;
11
+ }
12
+ /** Input letter before physics initialization */
13
+ export interface LetterInput {
14
+ char: string;
15
+ x: number;
16
+ y: number;
17
+ font: string;
18
+ }
19
+ /** Sampled field value at a point */
20
+ export interface FieldSample {
21
+ brightness: number;
22
+ gradX: number;
23
+ gradY: number;
24
+ }
25
+ /**
26
+ * A FieldEffect produces a continuous animated field that drives letter physics.
27
+ * Replace this to swap the underlying algorithm (water caustics, perlin noise, etc.)
28
+ */
29
+ export interface FieldEffect {
30
+ /** Initialize or resize the field to cover the given dimensions */
31
+ resize(width: number, height: number): void;
32
+ /** Advance the field simulation by one frame */
33
+ update(time: number): void;
34
+ /** Sample field brightness and gradient at a point */
35
+ sample(x: number, y: number): FieldSample;
36
+ }
37
+ /**
38
+ * A RippleSource creates expanding interactive disturbances in the field.
39
+ * Replace this to change how click/touch interactions propagate.
40
+ */
41
+ export interface RippleSource {
42
+ /** Initialize or resize to match field dimensions */
43
+ resize(width: number, height: number): void;
44
+ /** Create a new ripple at the given screen coordinates */
45
+ addRipple(x: number, y: number, time: number): void;
46
+ /** Advance ripple simulation */
47
+ update(time: number): void;
48
+ /** Remove dead ripples */
49
+ prune(time: number): void;
50
+ /**
51
+ * Compute the force a ripple exerts on a letter.
52
+ * Returns [forceX, forceY, influence] where influence is 0..1
53
+ * indicating how much the letter is currently affected.
54
+ */
55
+ computeForce(letterX: number, letterY: number, time: number): [fx: number, fy: number, influence: number];
56
+ /** Number of active ripples (for debug display) */
57
+ activeCount(): number;
58
+ }
59
+ /** All tunable physics and rendering settings */
60
+ export interface RippleTextSettings {
61
+ gradientForce: number;
62
+ springForce: number;
63
+ darkSpringBoost: number;
64
+ damping: number;
65
+ maxDisplacement: number;
66
+ fieldScale: number;
67
+ rippleInterval: number;
68
+ colorBuckets: number;
69
+ bgColor: string;
70
+ showFps: boolean;
71
+ /** Build an array of CSS color strings for each displacement bucket */
72
+ buildColors(bucketCount: number): string[];
73
+ }
74
+ /** Deep partial — all fields optional */
75
+ export type SettingsInput = {
76
+ [K in keyof RippleTextSettings]?: RippleTextSettings[K];
77
+ };
78
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qCAAqC;AACrC,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,gDAAgD;IAChD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,sDAAsD;IACtD,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;CAC3C;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,0DAA0D;IAC1D,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpD,gCAAgC;IAChC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,0BAA0B;IAC1B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;;OAIG;IACH,YAAY,CACV,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAC/C,mDAAmD;IACnD,WAAW,IAAI,MAAM,CAAC;CACvB;AAED,iDAAiD;AACjD,MAAM,WAAW,kBAAkB;IAEjC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IAGxB,UAAU,EAAE,MAAM,CAAC;IAGnB,cAAc,EAAE,MAAM,CAAC;IAGvB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IAEjB,uEAAuE;IACvE,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC5C;AAED,yCAAyC;AACzC,MAAM,MAAM,aAAa,GAAG;KACzB,CAAC,IAAI,MAAM,kBAAkB,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC;CACxD,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { FieldEffect, FieldSample } from "../core/types";
2
+ export interface WaterFieldSettings {
3
+ noiseScale: number;
4
+ timeSpeed: number;
5
+ sharpness: number;
6
+ }
7
+ export declare class WaterField implements FieldEffect {
8
+ settings: WaterFieldSettings;
9
+ private w;
10
+ private h;
11
+ private brightness;
12
+ private gradXBuf;
13
+ private gradYBuf;
14
+ private frameCount;
15
+ constructor(settings?: Partial<WaterFieldSettings>);
16
+ resize(width: number, height: number): void;
17
+ update(time: number): void;
18
+ sample(x: number, y: number): FieldSample;
19
+ private computeGradients;
20
+ }
21
+ //# sourceMappingURL=waterField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waterField.d.ts","sourceRoot":"","sources":["../../src/effects/waterField.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA4D9D,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AASD,qBAAa,UAAW,YAAW,WAAW;IAC5C,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,OAAO,CAAC,CAAC,CAAK;IACd,OAAO,CAAC,CAAC,CAAK;IACd,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,UAAU,CAAK;gBAEX,QAAQ,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC;IAIlD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IASpC,MAAM,CAAC,IAAI,EAAE,MAAM;IAsCnB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW;IA2BzC,OAAO,CAAC,gBAAgB;CAgBzB"}
@@ -0,0 +1,21 @@
1
+ import type { RippleSource } from "../core/types";
2
+ export interface WaveRippleSettings {
3
+ amplitude: number;
4
+ wavelength: number;
5
+ decay: number;
6
+ force: number;
7
+ waveCenterY: number;
8
+ waveAmpMul: number;
9
+ }
10
+ export declare class WaveRipple implements RippleSource {
11
+ settings: WaveRippleSettings;
12
+ private ripples;
13
+ constructor(settings?: Partial<WaveRippleSettings>);
14
+ resize(_w: number, _h: number): void;
15
+ addRipple(x: number, y: number, time: number): void;
16
+ update(time: number): void;
17
+ prune(_time: number): void;
18
+ computeForce(lx: number, ly: number, _time: number): [number, number, number];
19
+ activeCount(): number;
20
+ }
21
+ //# sourceMappingURL=waveRipple.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waveRipple.d.ts","sourceRoot":"","sources":["../../src/effects/waveRipple.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAelD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAWD,qBAAa,UAAW,YAAW,YAAY;IAC7C,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,OAAO,CAAC,OAAO,CAAgB;gBAEnB,QAAQ,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC;IAIlD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAI7B,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAgB5C,MAAM,CAAC,IAAI,EAAE,MAAM;IAgBnB,KAAK,CAAC,KAAK,EAAE,MAAM;IAQnB,YAAY,CACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GACZ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAqC3B,WAAW;CAGZ"}
@@ -0,0 +1,8 @@
1
+ export { RippleTextEngine } from "./core/engine";
2
+ export type { FieldEffect, FieldSample, Letter, LetterInput, RippleSource, RippleTextSettings, SettingsInput, } from "./core/types";
3
+ export { WaterField } from "./effects/waterField";
4
+ export type { WaterFieldSettings } from "./effects/waterField";
5
+ export { WaveRipple } from "./effects/waveRipple";
6
+ export type { WaveRippleSettings } from "./effects/waveRipple";
7
+ export { extractTextFromDOM, layoutText } from "./utils/extractText";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,YAAY,EACV,WAAW,EACX,WAAW,EACX,MAAM,EACN,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { LetterInput } from "../core/types";
2
+ /**
3
+ * Walk the DOM under `root`, extract every visible character with its
4
+ * screen position and computed font using Range.getBoundingClientRect().
5
+ */
6
+ export declare function extractTextFromDOM(root: HTMLElement, maxChars?: number): LetterInput[];
7
+ /**
8
+ * Create letter inputs from a plain text string, laid out on a canvas context.
9
+ */
10
+ export declare function layoutText(ctx: CanvasRenderingContext2D, text: string, options?: {
11
+ font?: string;
12
+ fontSize?: number;
13
+ margin?: number;
14
+ maxWidth?: number;
15
+ maxHeight?: number;
16
+ lineHeight?: number;
17
+ }): LetterInput[];
18
+ //# sourceMappingURL=extractText.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractText.d.ts","sourceRoot":"","sources":["../../src/utils/extractText.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,WAAW,EACjB,QAAQ,SAAO,GACd,WAAW,EAAE,CAqDf;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACP,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CAChB,GACL,WAAW,EAAE,CA+Bf"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ripple-text",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "Physics-driven text effect with pluggable field and ripple algorithms",
6
6
  "main": "dist/index.js",
@@ -10,7 +10,7 @@
10
10
  ],
11
11
  "scripts": {
12
12
  "dev": "vite demo",
13
- "build": "tsc && vite build",
13
+ "build": "vite build && tsc --emitDeclarationOnly",
14
14
  "typecheck": "tsc --noEmit",
15
15
  "lint": "eslint .",
16
16
  "lint:fix": "eslint . --fix",