interactive-bg 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.
Files changed (122) hide show
  1. package/README.md +55 -7
  2. package/dist/fluid/canvas2d.cjs +14 -0
  3. package/dist/fluid/canvas2d.cjs.map +1 -0
  4. package/dist/fluid/canvas2d.d.cts +5 -0
  5. package/dist/fluid/canvas2d.d.ts +5 -0
  6. package/dist/fluid/canvas2d.js +13 -0
  7. package/dist/fluid/canvas2d.js.map +1 -0
  8. package/dist/fluid/index.cjs +16 -0
  9. package/dist/fluid/index.cjs.map +1 -0
  10. package/dist/fluid/index.d.cts +5 -0
  11. package/dist/fluid/index.d.ts +5 -0
  12. package/dist/fluid/index.js +15 -0
  13. package/dist/fluid/index.js.map +1 -0
  14. package/dist/fluid/webgl.cjs +14 -0
  15. package/dist/fluid/webgl.cjs.map +1 -0
  16. package/dist/fluid/webgl.d.cts +5 -0
  17. package/dist/fluid/webgl.d.ts +5 -0
  18. package/dist/fluid/webgl.js +13 -0
  19. package/dist/fluid/webgl.js.map +1 -0
  20. package/dist/index.cjs +4 -0
  21. package/dist/index.d.cts +4 -0
  22. package/dist/index.d.ts +4 -0
  23. package/dist/index.js +3 -1
  24. package/dist/index.umd.js +255 -12
  25. package/dist/index.umd.js.map +1 -1
  26. package/dist/shimmer/canvas2d.cjs +14 -0
  27. package/dist/shimmer/canvas2d.cjs.map +1 -0
  28. package/dist/shimmer/canvas2d.d.cts +5 -0
  29. package/dist/shimmer/canvas2d.d.ts +5 -0
  30. package/dist/shimmer/canvas2d.js +13 -0
  31. package/dist/shimmer/canvas2d.js.map +1 -0
  32. package/dist/shimmer/index.cjs +16 -0
  33. package/dist/shimmer/index.cjs.map +1 -0
  34. package/dist/shimmer/index.d.cts +5 -0
  35. package/dist/shimmer/index.d.ts +5 -0
  36. package/dist/shimmer/index.js +15 -0
  37. package/dist/shimmer/index.js.map +1 -0
  38. package/dist/shimmer/webgl.cjs +14 -0
  39. package/dist/shimmer/webgl.cjs.map +1 -0
  40. package/dist/shimmer/webgl.d.cts +5 -0
  41. package/dist/shimmer/webgl.d.ts +5 -0
  42. package/dist/shimmer/webgl.js +13 -0
  43. package/dist/shimmer/webgl.js.map +1 -0
  44. package/dist/styles/fluid/canvas2d.cjs +155 -0
  45. package/dist/styles/fluid/canvas2d.cjs.map +1 -0
  46. package/dist/styles/fluid/canvas2d.d.cts +8 -0
  47. package/dist/styles/fluid/canvas2d.d.ts +8 -0
  48. package/dist/styles/fluid/canvas2d.js +155 -0
  49. package/dist/styles/fluid/canvas2d.js.map +1 -0
  50. package/dist/styles/fluid/color.cjs +40 -0
  51. package/dist/styles/fluid/color.cjs.map +1 -0
  52. package/dist/styles/fluid/color.d.cts +4 -0
  53. package/dist/styles/fluid/color.d.ts +4 -0
  54. package/dist/styles/fluid/color.js +40 -0
  55. package/dist/styles/fluid/color.js.map +1 -0
  56. package/dist/styles/fluid/definition.cjs +14 -0
  57. package/dist/styles/fluid/definition.cjs.map +1 -0
  58. package/dist/styles/fluid/definition.d.cts +8 -0
  59. package/dist/styles/fluid/definition.d.ts +8 -0
  60. package/dist/styles/fluid/definition.js +15 -0
  61. package/dist/styles/fluid/definition.js.map +1 -0
  62. package/dist/styles/fluid/options.cjs +29 -0
  63. package/dist/styles/fluid/options.cjs.map +1 -0
  64. package/dist/styles/fluid/options.d.cts +31 -0
  65. package/dist/styles/fluid/options.d.ts +31 -0
  66. package/dist/styles/fluid/options.js +28 -0
  67. package/dist/styles/fluid/options.js.map +1 -0
  68. package/dist/styles/fluid/settings.cjs +32 -0
  69. package/dist/styles/fluid/settings.cjs.map +1 -0
  70. package/dist/styles/fluid/settings.d.cts +24 -0
  71. package/dist/styles/fluid/settings.d.ts +24 -0
  72. package/dist/styles/fluid/settings.js +23 -0
  73. package/dist/styles/fluid/settings.js.map +1 -0
  74. package/dist/styles/fluid/simulation.cjs +183 -0
  75. package/dist/styles/fluid/simulation.cjs.map +1 -0
  76. package/dist/styles/fluid/simulation.d.cts +22 -0
  77. package/dist/styles/fluid/simulation.d.ts +22 -0
  78. package/dist/styles/fluid/simulation.js +183 -0
  79. package/dist/styles/fluid/simulation.js.map +1 -0
  80. package/dist/styles/fluid/size.cjs +17 -0
  81. package/dist/styles/fluid/size.cjs.map +1 -0
  82. package/dist/styles/fluid/size.d.cts +5 -0
  83. package/dist/styles/fluid/size.d.ts +5 -0
  84. package/dist/styles/fluid/size.js +17 -0
  85. package/dist/styles/fluid/size.js.map +1 -0
  86. package/dist/styles/fluid/webgl.cjs +607 -0
  87. package/dist/styles/fluid/webgl.cjs.map +1 -0
  88. package/dist/styles/fluid/webgl.d.cts +3 -0
  89. package/dist/styles/fluid/webgl.d.ts +3 -0
  90. package/dist/styles/fluid/webgl.js +607 -0
  91. package/dist/styles/fluid/webgl.js.map +1 -0
  92. package/dist/styles/shimmer/canvas2d.cjs +84 -0
  93. package/dist/styles/shimmer/canvas2d.cjs.map +1 -0
  94. package/dist/styles/shimmer/canvas2d.d.cts +3 -0
  95. package/dist/styles/shimmer/canvas2d.d.ts +3 -0
  96. package/dist/styles/shimmer/canvas2d.js +84 -0
  97. package/dist/styles/shimmer/canvas2d.js.map +1 -0
  98. package/dist/styles/shimmer/definition.cjs +15 -0
  99. package/dist/styles/shimmer/definition.cjs.map +1 -0
  100. package/dist/styles/shimmer/definition.d.cts +8 -0
  101. package/dist/styles/shimmer/definition.d.ts +8 -0
  102. package/dist/styles/shimmer/definition.js +16 -0
  103. package/dist/styles/shimmer/definition.js.map +1 -0
  104. package/dist/styles/shimmer/field.cjs +79 -0
  105. package/dist/styles/shimmer/field.cjs.map +1 -0
  106. package/dist/styles/shimmer/field.d.cts +11 -0
  107. package/dist/styles/shimmer/field.d.ts +11 -0
  108. package/dist/styles/shimmer/field.js +78 -0
  109. package/dist/styles/shimmer/field.js.map +1 -0
  110. package/dist/styles/shimmer/options.cjs +28 -0
  111. package/dist/styles/shimmer/options.cjs.map +1 -0
  112. package/dist/styles/shimmer/options.d.cts +22 -0
  113. package/dist/styles/shimmer/options.d.ts +22 -0
  114. package/dist/styles/shimmer/options.js +27 -0
  115. package/dist/styles/shimmer/options.js.map +1 -0
  116. package/dist/styles/shimmer/webgl.cjs +89 -0
  117. package/dist/styles/shimmer/webgl.cjs.map +1 -0
  118. package/dist/styles/shimmer/webgl.d.cts +4 -0
  119. package/dist/styles/shimmer/webgl.d.ts +4 -0
  120. package/dist/styles/shimmer/webgl.js +89 -0
  121. package/dist/styles/shimmer/webgl.js.map +1 -0
  122. package/package.json +76 -2
@@ -0,0 +1,183 @@
1
+ import { DYE_INTENSITY, VELOCITY_FADE } from "./settings.js";
2
+ // src/styles/fluid/simulation.ts
3
+ var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
4
+ function createFluidSimulation(width, height) {
5
+ const w = width;
6
+ const h = height;
7
+ const cells = w * h;
8
+ let u = new Float32Array(cells);
9
+ let v = new Float32Array(cells);
10
+ let uNext = new Float32Array(cells);
11
+ let vNext = new Float32Array(cells);
12
+ let dyeR = new Float32Array(cells);
13
+ let dyeG = new Float32Array(cells);
14
+ let dyeB = new Float32Array(cells);
15
+ let dyeRNext = new Float32Array(cells);
16
+ let dyeGNext = new Float32Array(cells);
17
+ let dyeBNext = new Float32Array(cells);
18
+ const divergence = new Float32Array(cells);
19
+ const curl = new Float32Array(cells);
20
+ let pressure = new Float32Array(cells);
21
+ let pressureNext = new Float32Array(cells);
22
+ /** Bilinear sample of a field at grid coordinates, clamped at the edges. */
23
+ function sample(field, x, y) {
24
+ const gx = clamp(x, 0, w - 1);
25
+ const gy = clamp(y, 0, h - 1);
26
+ const i0 = Math.floor(gx);
27
+ const j0 = Math.floor(gy);
28
+ const i1 = Math.min(i0 + 1, w - 1);
29
+ const j1 = Math.min(j0 + 1, h - 1);
30
+ const fx = gx - i0;
31
+ const fy = gy - j0;
32
+ const top = field[j0 * w + i0] * (1 - fx) + field[j0 * w + i1] * fx;
33
+ const bottom = field[j1 * w + i0] * (1 - fx) + field[j1 * w + i1] * fx;
34
+ return top * (1 - fy) + bottom * fy;
35
+ }
36
+ /** Zero the velocity along the walls, so the field doesn't leak. */
37
+ function walls() {
38
+ for (let i = 0; i < w; i++) {
39
+ u[i] = 0;
40
+ u[(h - 1) * w + i] = 0;
41
+ v[i] = 0;
42
+ v[(h - 1) * w + i] = 0;
43
+ }
44
+ for (let j = 0; j < h; j++) {
45
+ u[j * w] = 0;
46
+ u[j * w + w - 1] = 0;
47
+ v[j * w] = 0;
48
+ v[j * w + w - 1] = 0;
49
+ }
50
+ }
51
+ function addCurl(dt, amount) {
52
+ for (let j = 1; j < h - 1; j++) for (let i = 1; i < w - 1; i++) {
53
+ const k = j * w + i;
54
+ curl[k] = .5 * (v[k + 1] - v[k - 1] - (u[k + w] - u[k - w]));
55
+ }
56
+ for (let j = 1; j < h - 1; j++) for (let i = 1; i < w - 1; i++) {
57
+ const k = j * w + i;
58
+ const forceX = .5 * (Math.abs(curl[k + 1]) - Math.abs(curl[k - 1]));
59
+ const forceY = .5 * (Math.abs(curl[k - w]) - Math.abs(curl[k + w]));
60
+ const length = Math.hypot(forceX, forceY) + 1e-4;
61
+ const strength = amount * curl[k] * dt / length;
62
+ u[k] = clamp(u[k] + forceX * strength, -1e3, 1e3);
63
+ v[k] = clamp(v[k] + forceY * strength, -1e3, 1e3);
64
+ }
65
+ }
66
+ function project(dt, options) {
67
+ if (options.curl > 0) addCurl(dt, options.curl);
68
+ for (let j = 1; j < h - 1; j++) for (let i = 1; i < w - 1; i++) {
69
+ const k = j * w + i;
70
+ divergence[k] = .5 * (u[k + 1] - u[k - 1] + v[k + w] - v[k - w]);
71
+ }
72
+ pressure.fill(0);
73
+ for (let iteration = 0; iteration < 14; iteration++) {
74
+ for (let j = 1; j < h - 1; j++) for (let i = 1; i < w - 1; i++) {
75
+ const k = j * w + i;
76
+ pressureNext[k] = (pressure[k - 1] + pressure[k + 1] + pressure[k - w] + pressure[k + w] - divergence[k]) * .25;
77
+ }
78
+ [pressure, pressureNext] = [pressureNext, pressure];
79
+ }
80
+ for (let j = 1; j < h - 1; j++) for (let i = 1; i < w - 1; i++) {
81
+ const k = j * w + i;
82
+ u[k] -= .5 * (pressure[k + 1] - pressure[k - 1]);
83
+ v[k] -= .5 * (pressure[k + w] - pressure[k - w]);
84
+ }
85
+ walls();
86
+ }
87
+ function advectVelocity(dt, decay) {
88
+ for (let j = 0; j < h; j++) for (let i = 0; i < w; i++) {
89
+ const k = j * w + i;
90
+ const sx = i - u[k] * dt;
91
+ const sy = j - v[k] * dt;
92
+ uNext[k] = sample(u, sx, sy) * decay;
93
+ vNext[k] = sample(v, sx, sy) * decay;
94
+ }
95
+ [u, uNext] = [uNext, u];
96
+ [v, vNext] = [vNext, v];
97
+ walls();
98
+ }
99
+ function advectDye(dt, decay) {
100
+ for (let j = 0; j < h; j++) for (let i = 0; i < w; i++) {
101
+ const k = j * w + i;
102
+ const sx = i - u[k] * dt;
103
+ const sy = j - v[k] * dt;
104
+ dyeRNext[k] = sample(dyeR, sx, sy) * decay;
105
+ dyeGNext[k] = sample(dyeG, sx, sy) * decay;
106
+ dyeBNext[k] = sample(dyeB, sx, sy) * decay;
107
+ }
108
+ [dyeR, dyeRNext] = [dyeRNext, dyeR];
109
+ [dyeG, dyeGNext] = [dyeGNext, dyeG];
110
+ [dyeB, dyeBNext] = [dyeBNext, dyeB];
111
+ }
112
+ return {
113
+ width: w,
114
+ height: h,
115
+ get dyeR() {
116
+ return dyeR;
117
+ },
118
+ get dyeG() {
119
+ return dyeG;
120
+ },
121
+ get dyeB() {
122
+ return dyeB;
123
+ },
124
+ splat(x, y, vx, vy, color, radius, viewWidth, viewHeight) {
125
+ const aspect = Math.max(1, viewWidth) / Math.max(1, viewHeight);
126
+ const sigma = Math.max(5e-4, radius / viewHeight);
127
+ const cx = x / Math.max(1, viewWidth);
128
+ const cy = y / Math.max(1, viewHeight);
129
+ const reachX = sigma / aspect * w * 3;
130
+ const reachY = sigma * h * 3;
131
+ const x0 = Math.max(0, Math.floor(cx * w - reachX));
132
+ const x1 = Math.min(w - 1, Math.ceil(cx * w + reachX));
133
+ const y0 = Math.max(0, Math.floor(cy * h - reachY));
134
+ const y1 = Math.min(h - 1, Math.ceil(cy * h + reachY));
135
+ const velocityX = clamp(vx, -1e3, 1e3);
136
+ const velocityY = clamp(vy, -1e3, 1e3);
137
+ const sigma2 = sigma * sigma;
138
+ for (let j = y0; j <= y1; j++) {
139
+ const dy = (j + .5) / h - cy;
140
+ for (let i = x0; i <= x1; i++) {
141
+ const dx = ((i + .5) / w - cx) * aspect;
142
+ const distance = dx * dx + dy * dy;
143
+ if (distance > sigma2 * 9) continue;
144
+ const falloff = Math.exp(-distance / sigma2);
145
+ const k = j * w + i;
146
+ u[k] = clamp(u[k] + velocityX * falloff, -1e3, 1e3);
147
+ v[k] = clamp(v[k] + velocityY * falloff, -1e3, 1e3);
148
+ dyeR[k] += color[0] * DYE_INTENSITY * falloff;
149
+ dyeG[k] += color[1] * DYE_INTENSITY * falloff;
150
+ dyeB[k] += color[2] * DYE_INTENSITY * falloff;
151
+ }
152
+ }
153
+ },
154
+ step(dt, options) {
155
+ const stepTime = Math.min(dt, 1 / 30);
156
+ if (stepTime <= 0) return;
157
+ project(stepTime, options);
158
+ advectVelocity(stepTime, 1 / (1 + stepTime / VELOCITY_FADE));
159
+ advectDye(stepTime, 1 / (1 + stepTime / options.fade));
160
+ },
161
+ clear() {
162
+ for (const field of [
163
+ u,
164
+ v,
165
+ uNext,
166
+ vNext,
167
+ dyeR,
168
+ dyeG,
169
+ dyeB,
170
+ dyeRNext,
171
+ dyeGNext,
172
+ dyeBNext,
173
+ pressure,
174
+ pressureNext,
175
+ divergence,
176
+ curl
177
+ ]) field.fill(0);
178
+ }
179
+ };
180
+ }
181
+ export { createFluidSimulation };
182
+
183
+ //# sourceMappingURL=simulation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulation.js","names":[],"sources":["../../../src/styles/fluid/simulation.ts"],"sourcesContent":["import type { RGB } from './color';\nimport type { ResolvedFluidOptions } from './options';\nimport { CPU_PRESSURE_ITERATIONS, DYE_INTENSITY, VELOCITY_FADE } from './settings';\n\n/**\n * The CPU fluid field: a stable-fluids solver at `resolution` cells on its longer\n * side. The Canvas 2D renderer draws it upscaled; the WebGL renderer runs the\n * same steps in shaders instead. Velocities are in grid cells per second; dye\n * channels are straight colour densities.\n */\nexport interface FluidSimulation {\n readonly width: number;\n readonly height: number;\n readonly dyeR: Float32Array;\n readonly dyeG: Float32Array;\n readonly dyeB: Float32Array;\n /** Add a splash of colour and velocity at `(x, y)`, in CSS pixels of a view of `viewWidth` × `viewHeight`. */\n splat(\n x: number,\n y: number,\n vx: number,\n vy: number,\n color: RGB,\n radius: number,\n viewWidth: number,\n viewHeight: number,\n ): void;\n /** Advance the simulation by `dt` seconds. */\n step(dt: number, options: ResolvedFluidOptions): void;\n /** Clear the velocity and dye fields. */\n clear(): void;\n}\n\nconst clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));\n\nexport function createFluidSimulation(width: number, height: number): FluidSimulation {\n const w = width;\n const h = height;\n const cells = w * h;\n\n let u = new Float32Array(cells);\n let v = new Float32Array(cells);\n let uNext = new Float32Array(cells);\n let vNext = new Float32Array(cells);\n let dyeR = new Float32Array(cells);\n let dyeG = new Float32Array(cells);\n let dyeB = new Float32Array(cells);\n let dyeRNext = new Float32Array(cells);\n let dyeGNext = new Float32Array(cells);\n let dyeBNext = new Float32Array(cells);\n const divergence = new Float32Array(cells);\n const curl = new Float32Array(cells);\n let pressure = new Float32Array(cells);\n let pressureNext = new Float32Array(cells);\n\n /** Bilinear sample of a field at grid coordinates, clamped at the edges. */\n function sample(field: Float32Array, x: number, y: number): number {\n const gx = clamp(x, 0, w - 1);\n const gy = clamp(y, 0, h - 1);\n const i0 = Math.floor(gx);\n const j0 = Math.floor(gy);\n const i1 = Math.min(i0 + 1, w - 1);\n const j1 = Math.min(j0 + 1, h - 1);\n const fx = gx - i0;\n const fy = gy - j0;\n const top = field[j0 * w + i0] * (1 - fx) + field[j0 * w + i1] * fx;\n const bottom = field[j1 * w + i0] * (1 - fx) + field[j1 * w + i1] * fx;\n return top * (1 - fy) + bottom * fy;\n }\n\n /** Zero the velocity along the walls, so the field doesn't leak. */\n function walls(): void {\n for (let i = 0; i < w; i++) {\n u[i] = 0;\n u[(h - 1) * w + i] = 0;\n v[i] = 0;\n v[(h - 1) * w + i] = 0;\n }\n for (let j = 0; j < h; j++) {\n u[j * w] = 0;\n u[j * w + w - 1] = 0;\n v[j * w] = 0;\n v[j * w + w - 1] = 0;\n }\n }\n\n function addCurl(dt: number, amount: number): void {\n for (let j = 1; j < h - 1; j++) {\n for (let i = 1; i < w - 1; i++) {\n const k = j * w + i;\n curl[k] = 0.5 * (v[k + 1] - v[k - 1] - (u[k + w] - u[k - w]));\n }\n }\n for (let j = 1; j < h - 1; j++) {\n for (let i = 1; i < w - 1; i++) {\n const k = j * w + i;\n const forceX = 0.5 * (Math.abs(curl[k + 1]) - Math.abs(curl[k - 1]));\n const forceY = 0.5 * (Math.abs(curl[k - w]) - Math.abs(curl[k + w]));\n const length = Math.hypot(forceX, forceY) + 1e-4;\n const strength = (amount * curl[k] * dt) / length;\n u[k] = clamp(u[k] + forceX * strength, -1000, 1000);\n v[k] = clamp(v[k] + forceY * strength, -1000, 1000);\n }\n }\n }\n\n function project(dt: number, options: ResolvedFluidOptions): void {\n if (options.curl > 0) addCurl(dt, options.curl);\n for (let j = 1; j < h - 1; j++) {\n for (let i = 1; i < w - 1; i++) {\n const k = j * w + i;\n divergence[k] = 0.5 * (u[k + 1] - u[k - 1] + v[k + w] - v[k - w]);\n }\n }\n pressure.fill(0);\n for (let iteration = 0; iteration < CPU_PRESSURE_ITERATIONS; iteration++) {\n for (let j = 1; j < h - 1; j++) {\n for (let i = 1; i < w - 1; i++) {\n const k = j * w + i;\n pressureNext[k] =\n (pressure[k - 1] + pressure[k + 1] + pressure[k - w] + pressure[k + w] - divergence[k]) * 0.25;\n }\n }\n [pressure, pressureNext] = [pressureNext, pressure];\n }\n for (let j = 1; j < h - 1; j++) {\n for (let i = 1; i < w - 1; i++) {\n const k = j * w + i;\n u[k] -= 0.5 * (pressure[k + 1] - pressure[k - 1]);\n v[k] -= 0.5 * (pressure[k + w] - pressure[k - w]);\n }\n }\n walls();\n }\n\n function advectVelocity(dt: number, decay: number): void {\n for (let j = 0; j < h; j++) {\n for (let i = 0; i < w; i++) {\n const k = j * w + i;\n const sx = i - u[k] * dt;\n const sy = j - v[k] * dt;\n uNext[k] = sample(u, sx, sy) * decay;\n vNext[k] = sample(v, sx, sy) * decay;\n }\n }\n [u, uNext] = [uNext, u];\n [v, vNext] = [vNext, v];\n walls();\n }\n\n function advectDye(dt: number, decay: number): void {\n for (let j = 0; j < h; j++) {\n for (let i = 0; i < w; i++) {\n const k = j * w + i;\n const sx = i - u[k] * dt;\n const sy = j - v[k] * dt;\n dyeRNext[k] = sample(dyeR, sx, sy) * decay;\n dyeGNext[k] = sample(dyeG, sx, sy) * decay;\n dyeBNext[k] = sample(dyeB, sx, sy) * decay;\n }\n }\n [dyeR, dyeRNext] = [dyeRNext, dyeR];\n [dyeG, dyeGNext] = [dyeGNext, dyeG];\n [dyeB, dyeBNext] = [dyeBNext, dyeB];\n }\n\n return {\n width: w,\n height: h,\n get dyeR() {\n return dyeR;\n },\n get dyeG() {\n return dyeG;\n },\n get dyeB() {\n return dyeB;\n },\n splat(x, y, vx, vy, color, radius, viewWidth, viewHeight) {\n const aspect = Math.max(1, viewWidth) / Math.max(1, viewHeight);\n const sigma = Math.max(0.0005, radius / viewHeight);\n const cx = x / Math.max(1, viewWidth);\n const cy = y / Math.max(1, viewHeight);\n const reachX = (sigma / aspect) * w * 3;\n const reachY = sigma * h * 3;\n const x0 = Math.max(0, Math.floor(cx * w - reachX));\n const x1 = Math.min(w - 1, Math.ceil(cx * w + reachX));\n const y0 = Math.max(0, Math.floor(cy * h - reachY));\n const y1 = Math.min(h - 1, Math.ceil(cy * h + reachY));\n // Velocities are in simulation texels per second, which is cells per second here.\n const velocityX = clamp(vx, -1000, 1000);\n const velocityY = clamp(vy, -1000, 1000);\n const sigma2 = sigma * sigma;\n for (let j = y0; j <= y1; j++) {\n const ny = (j + 0.5) / h;\n const dy = ny - cy;\n for (let i = x0; i <= x1; i++) {\n const nx = (i + 0.5) / w;\n const dx = (nx - cx) * aspect;\n const distance = dx * dx + dy * dy;\n if (distance > sigma2 * 9) continue;\n const falloff = Math.exp(-distance / sigma2);\n const k = j * w + i;\n u[k] = clamp(u[k] + velocityX * falloff, -1000, 1000);\n v[k] = clamp(v[k] + velocityY * falloff, -1000, 1000);\n dyeR[k] += color[0] * DYE_INTENSITY * falloff;\n dyeG[k] += color[1] * DYE_INTENSITY * falloff;\n dyeB[k] += color[2] * DYE_INTENSITY * falloff;\n }\n }\n },\n step(dt, options) {\n const stepTime = Math.min(dt, 1 / 30);\n if (stepTime <= 0) return;\n project(stepTime, options);\n advectVelocity(stepTime, 1 / (1 + stepTime / VELOCITY_FADE));\n advectDye(stepTime, 1 / (1 + stepTime / options.fade));\n },\n clear() {\n for (const field of [u, v, uNext, vNext, dyeR, dyeG, dyeB, dyeRNext, dyeGNext, dyeBNext, pressure, pressureNext, divergence, curl]) {\n field.fill(0);\n }\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ // src/styles/fluid/size.ts
2
+ /** Grid size for a view: the longer side gets `resolution` cells. */
3
+ function simulationSize(resolution, width, height) {
4
+ const aspect = Math.max(1, width) / Math.max(1, height);
5
+ const long = Math.max(16, Math.round(resolution));
6
+ if (aspect >= 1) return {
7
+ width: long,
8
+ height: Math.max(12, Math.round(long / aspect))
9
+ };
10
+ return {
11
+ width: Math.max(12, Math.round(long * aspect)),
12
+ height: long
13
+ };
14
+ }
15
+ exports.simulationSize = simulationSize;
16
+
17
+ //# sourceMappingURL=size.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size.cjs","names":[],"sources":["../../../src/styles/fluid/size.ts"],"sourcesContent":["/** Grid size for a view: the longer side gets `resolution` cells. */\nexport function simulationSize(\n resolution: number,\n width: number,\n height: number,\n): { width: number; height: number } {\n const aspect = Math.max(1, width) / Math.max(1, height);\n const long = Math.max(16, Math.round(resolution));\n if (aspect >= 1) return { width: long, height: Math.max(12, Math.round(long / aspect)) };\n return { width: Math.max(12, Math.round(long * aspect)), height: long };\n}\n"],"mappings":";;AACA,SAAgB,eACd,YACA,OACA,QACmC;CACnC,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,MAAM;CACtD,MAAM,OAAO,KAAK,IAAI,IAAI,KAAK,MAAM,UAAU,CAAC;CAChD,IAAI,UAAU,GAAG,OAAO;EAAE,OAAO;EAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,OAAO,MAAM,CAAC;CAAE;CACvF,OAAO;EAAE,OAAO,KAAK,IAAI,IAAI,KAAK,MAAM,OAAO,MAAM,CAAC;EAAG,QAAQ;CAAK;AACxE"}
@@ -0,0 +1,5 @@
1
+ /** Grid size for a view: the longer side gets `resolution` cells. */
2
+ export declare function simulationSize(resolution: number, width: number, height: number): {
3
+ width: number;
4
+ height: number;
5
+ };
@@ -0,0 +1,5 @@
1
+ /** Grid size for a view: the longer side gets `resolution` cells. */
2
+ export declare function simulationSize(resolution: number, width: number, height: number): {
3
+ width: number;
4
+ height: number;
5
+ };
@@ -0,0 +1,17 @@
1
+ // src/styles/fluid/size.ts
2
+ /** Grid size for a view: the longer side gets `resolution` cells. */
3
+ function simulationSize(resolution, width, height) {
4
+ const aspect = Math.max(1, width) / Math.max(1, height);
5
+ const long = Math.max(16, Math.round(resolution));
6
+ if (aspect >= 1) return {
7
+ width: long,
8
+ height: Math.max(12, Math.round(long / aspect))
9
+ };
10
+ return {
11
+ width: Math.max(12, Math.round(long * aspect)),
12
+ height: long
13
+ };
14
+ }
15
+ export { simulationSize };
16
+
17
+ //# sourceMappingURL=size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size.js","names":[],"sources":["../../../src/styles/fluid/size.ts"],"sourcesContent":["/** Grid size for a view: the longer side gets `resolution` cells. */\nexport function simulationSize(\n resolution: number,\n width: number,\n height: number,\n): { width: number; height: number } {\n const aspect = Math.max(1, width) / Math.max(1, height);\n const long = Math.max(16, Math.round(resolution));\n if (aspect >= 1) return { width: long, height: Math.max(12, Math.round(long / aspect)) };\n return { width: Math.max(12, Math.round(long * aspect)), height: long };\n}\n"],"mappings":";;AACA,SAAgB,eACd,YACA,OACA,QACmC;CACnC,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,MAAM;CACtD,MAAM,OAAO,KAAK,IAAI,IAAI,KAAK,MAAM,UAAU,CAAC;CAChD,IAAI,UAAU,GAAG,OAAO;EAAE,OAAO;EAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,OAAO,MAAM,CAAC;CAAE;CACvF,OAAO;EAAE,OAAO,KAAK,IAAI,IAAI,KAAK,MAAM,OAAO,MAAM,CAAC;EAAG,QAAQ;CAAK;AACxE"}