@toriistudio/shader-ui 0.0.3 → 0.0.4
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/dist/index.d.mts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +552 -2
- package/dist/index.mjs +549 -1
- package/package.json +3 -1
package/dist/index.d.mts
CHANGED
|
@@ -163,4 +163,29 @@ type EfectoProps = Omit<ComponentProps<"div">, "ref"> & {
|
|
|
163
163
|
};
|
|
164
164
|
declare function Efecto({ postProcessing, src, mouseParallax, parallaxIntensity, mediaAdjustments, cellSize, invert, colorMode, style, asciiStyle, ...wrapperProps }: EfectoProps): react_jsx_runtime.JSX.Element;
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
type SnowUniforms = {
|
|
167
|
+
color: string;
|
|
168
|
+
fallSpeed: number;
|
|
169
|
+
windStrength: number;
|
|
170
|
+
turbulence: number;
|
|
171
|
+
flakeSize: number;
|
|
172
|
+
twinkleStrength: number;
|
|
173
|
+
flakeCount: number;
|
|
174
|
+
};
|
|
175
|
+
type SnowProps = SnowUniforms & Omit<ComponentProps<"div">, keyof SnowUniforms | "ref" | "width" | "height"> & {
|
|
176
|
+
width?: string | number;
|
|
177
|
+
height?: string | number;
|
|
178
|
+
mouseWindInteraction?: boolean;
|
|
179
|
+
};
|
|
180
|
+
declare function Snow({ className, style, width, height, color, fallSpeed, windStrength, turbulence, flakeSize, twinkleStrength, flakeCount, mouseWindInteraction, ...divProps }: SnowProps): react_jsx_runtime.JSX.Element;
|
|
181
|
+
|
|
182
|
+
type AnimatedDrawingSVGProps = {
|
|
183
|
+
svgMarkup: string;
|
|
184
|
+
animated?: boolean;
|
|
185
|
+
size?: number | string;
|
|
186
|
+
onAnimated?: () => void;
|
|
187
|
+
delay?: number;
|
|
188
|
+
} & Omit<ComponentProps<"div">, "children">;
|
|
189
|
+
declare function AnimatedDrawingSVG({ svgMarkup, animated, size, onAnimated, delay, className, style, ...divProps }: AnimatedDrawingSVGProps): react_jsx_runtime.JSX.Element;
|
|
190
|
+
|
|
191
|
+
export { AnimatedDrawingSVG, EFECTO_ASCII_COMPONENT_DEFAULTS, EFECTO_ASCII_POST_PROCESSING_DEFAULTS, Efecto, type EfectoAsciiColorPalette, type EfectoAsciiStyle, type PublicPostProcessingSettings as EfectoPublicAsciiPostProcessingSettings, FractalFlower, MenuGlitch, type MenuGlitchUniforms, OranoParticles, type OranoParticlesUniforms, ShaderArt, type ShaderArtUniforms, Snow };
|
package/dist/index.d.ts
CHANGED
|
@@ -163,4 +163,29 @@ type EfectoProps = Omit<ComponentProps<"div">, "ref"> & {
|
|
|
163
163
|
};
|
|
164
164
|
declare function Efecto({ postProcessing, src, mouseParallax, parallaxIntensity, mediaAdjustments, cellSize, invert, colorMode, style, asciiStyle, ...wrapperProps }: EfectoProps): react_jsx_runtime.JSX.Element;
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
type SnowUniforms = {
|
|
167
|
+
color: string;
|
|
168
|
+
fallSpeed: number;
|
|
169
|
+
windStrength: number;
|
|
170
|
+
turbulence: number;
|
|
171
|
+
flakeSize: number;
|
|
172
|
+
twinkleStrength: number;
|
|
173
|
+
flakeCount: number;
|
|
174
|
+
};
|
|
175
|
+
type SnowProps = SnowUniforms & Omit<ComponentProps<"div">, keyof SnowUniforms | "ref" | "width" | "height"> & {
|
|
176
|
+
width?: string | number;
|
|
177
|
+
height?: string | number;
|
|
178
|
+
mouseWindInteraction?: boolean;
|
|
179
|
+
};
|
|
180
|
+
declare function Snow({ className, style, width, height, color, fallSpeed, windStrength, turbulence, flakeSize, twinkleStrength, flakeCount, mouseWindInteraction, ...divProps }: SnowProps): react_jsx_runtime.JSX.Element;
|
|
181
|
+
|
|
182
|
+
type AnimatedDrawingSVGProps = {
|
|
183
|
+
svgMarkup: string;
|
|
184
|
+
animated?: boolean;
|
|
185
|
+
size?: number | string;
|
|
186
|
+
onAnimated?: () => void;
|
|
187
|
+
delay?: number;
|
|
188
|
+
} & Omit<ComponentProps<"div">, "children">;
|
|
189
|
+
declare function AnimatedDrawingSVG({ svgMarkup, animated, size, onAnimated, delay, className, style, ...divProps }: AnimatedDrawingSVGProps): react_jsx_runtime.JSX.Element;
|
|
190
|
+
|
|
191
|
+
export { AnimatedDrawingSVG, EFECTO_ASCII_COMPONENT_DEFAULTS, EFECTO_ASCII_POST_PROCESSING_DEFAULTS, Efecto, type EfectoAsciiColorPalette, type EfectoAsciiStyle, type PublicPostProcessingSettings as EfectoPublicAsciiPostProcessingSettings, FractalFlower, MenuGlitch, type MenuGlitchUniforms, OranoParticles, type OranoParticlesUniforms, ShaderArt, type ShaderArtUniforms, Snow };
|
package/dist/index.js
CHANGED
|
@@ -30,13 +30,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
+
AnimatedDrawingSVG: () => AnimatedDrawingSVG,
|
|
33
34
|
EFECTO_ASCII_COMPONENT_DEFAULTS: () => EFECTO_ASCII_COMPONENT_DEFAULTS,
|
|
34
35
|
EFECTO_ASCII_POST_PROCESSING_DEFAULTS: () => EFECTO_ASCII_POST_PROCESSING_DEFAULTS,
|
|
35
36
|
Efecto: () => Efecto,
|
|
36
37
|
FractalFlower: () => FractalFlower,
|
|
37
38
|
MenuGlitch: () => MenuGlitch,
|
|
38
39
|
OranoParticles: () => OranoParticles,
|
|
39
|
-
ShaderArt: () => ShaderArt
|
|
40
|
+
ShaderArt: () => ShaderArt,
|
|
41
|
+
Snow: () => Snow
|
|
40
42
|
});
|
|
41
43
|
module.exports = __toCommonJS(src_exports);
|
|
42
44
|
|
|
@@ -2111,13 +2113,561 @@ function Efecto({
|
|
|
2111
2113
|
}
|
|
2112
2114
|
);
|
|
2113
2115
|
}
|
|
2116
|
+
|
|
2117
|
+
// src/components/Snow.tsx
|
|
2118
|
+
var import_react7 = require("react");
|
|
2119
|
+
var THREE7 = __toESM(require("three"));
|
|
2120
|
+
|
|
2121
|
+
// src/shaders/snow/fragment.glsl
|
|
2122
|
+
var fragment_default7 = "precision mediump float;\n\nuniform vec3 uColor;\n\nvarying float vAlpha;\n\nvoid main() {\n vec2 uv = gl_PointCoord - 0.5;\n float dist = length(uv);\n float mask = smoothstep(0.5, 0.0, dist);\n if (mask <= 0.01) {\n discard;\n }\n\n float centerGlow = smoothstep(0.22, 0.0, dist);\n vec3 color = mix(uColor * 1.2, uColor, centerGlow);\n\n gl_FragColor = vec4(color, mask * vAlpha);\n}\n";
|
|
2123
|
+
|
|
2124
|
+
// src/shaders/snow/vertex.glsl
|
|
2125
|
+
var vertex_default6 = "uniform float uTime;\nuniform float uFallSpeed;\nuniform float uWindStrength;\nuniform float uTurbulence;\nuniform float uSize;\nuniform float uTwinkleStrength;\nuniform vec3 uArea;\n\nattribute float aSpeed;\nattribute float aSize;\nattribute float aSeed;\n\nvarying float vAlpha;\n\nfloat wrap(float value, float size) {\n return mod(value + size * 0.5, size) - size * 0.5;\n}\n\nvoid main() {\n float height = uArea.y;\n float width = uArea.x;\n float depth = uArea.z;\n\n float fall = uFallSpeed * (0.3 + aSpeed);\n float droppedY = position.y - uTime * fall;\n float wrappedY = wrap(droppedY, height);\n\n float sway =\n sin((wrappedY + aSeed) * 0.45 + uTime * 0.8) * uTurbulence +\n cos(uTime * 0.35 + aSeed) * 0.15;\n float wind = uWindStrength * (0.4 + aSpeed);\n float displacedX = wrap(position.x + sway + wind, width);\n\n float driftZ =\n sin(uTime * 0.25 + aSeed * 1.7) * 0.5 +\n cos((wrappedY + aSeed) * 0.2) * 0.4;\n float displacedZ = wrap(position.z + driftZ, depth);\n\n vec4 modelPosition =\n modelMatrix * vec4(displacedX, wrappedY, displacedZ, 1.0);\n vec4 viewPosition = viewMatrix * modelPosition;\n\n float baseSize = mix(0.45, 1.0, aSize) * uSize;\n float twinkle =\n 1.0 + sin(uTime * (0.6 + aSpeed) + aSeed) * uTwinkleStrength;\n float perspective = clamp(15.0 / max(1.0, -viewPosition.z), 0.5, 3.0);\n gl_PointSize = baseSize * twinkle * perspective;\n gl_Position = projectionMatrix * viewPosition;\n\n vAlpha = mix(0.35, 1.0, aSize);\n}\n";
|
|
2126
|
+
|
|
2127
|
+
// src/components/Snow.tsx
|
|
2128
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2129
|
+
var AREA_BOUNDS = {
|
|
2130
|
+
width: 36,
|
|
2131
|
+
height: 44,
|
|
2132
|
+
depth: 26
|
|
2133
|
+
};
|
|
2134
|
+
function createSnowGeometry(count) {
|
|
2135
|
+
const geometry = new THREE7.BufferGeometry();
|
|
2136
|
+
const positions = new Float32Array(count * 3);
|
|
2137
|
+
const speeds = new Float32Array(count);
|
|
2138
|
+
const sizes = new Float32Array(count);
|
|
2139
|
+
const seeds = new Float32Array(count);
|
|
2140
|
+
for (let i = 0; i < count; i += 1) {
|
|
2141
|
+
const x = (Math.random() - 0.5) * AREA_BOUNDS.width;
|
|
2142
|
+
const y = (Math.random() - 0.5) * AREA_BOUNDS.height;
|
|
2143
|
+
const z = (Math.random() - 0.5) * AREA_BOUNDS.depth;
|
|
2144
|
+
positions[i * 3] = x;
|
|
2145
|
+
positions[i * 3 + 1] = y;
|
|
2146
|
+
positions[i * 3 + 2] = z;
|
|
2147
|
+
speeds[i] = Math.random();
|
|
2148
|
+
sizes[i] = Math.random();
|
|
2149
|
+
seeds[i] = Math.random() * 100;
|
|
2150
|
+
}
|
|
2151
|
+
geometry.setAttribute("position", new THREE7.BufferAttribute(positions, 3));
|
|
2152
|
+
geometry.setAttribute("aSpeed", new THREE7.BufferAttribute(speeds, 1));
|
|
2153
|
+
geometry.setAttribute("aSize", new THREE7.BufferAttribute(sizes, 1));
|
|
2154
|
+
geometry.setAttribute("aSeed", new THREE7.BufferAttribute(seeds, 1));
|
|
2155
|
+
geometry.computeBoundingSphere();
|
|
2156
|
+
return geometry;
|
|
2157
|
+
}
|
|
2158
|
+
function buildUniforms2({
|
|
2159
|
+
color,
|
|
2160
|
+
fallSpeed,
|
|
2161
|
+
windStrength,
|
|
2162
|
+
turbulence,
|
|
2163
|
+
flakeSize,
|
|
2164
|
+
twinkleStrength
|
|
2165
|
+
}) {
|
|
2166
|
+
return {
|
|
2167
|
+
uTime: { value: 0 },
|
|
2168
|
+
uFallSpeed: { value: fallSpeed },
|
|
2169
|
+
uWindStrength: { value: windStrength },
|
|
2170
|
+
uTurbulence: { value: turbulence },
|
|
2171
|
+
uSize: { value: flakeSize },
|
|
2172
|
+
uTwinkleStrength: { value: twinkleStrength },
|
|
2173
|
+
uColor: { value: new THREE7.Color(color) },
|
|
2174
|
+
uArea: {
|
|
2175
|
+
value: new THREE7.Vector3(
|
|
2176
|
+
AREA_BOUNDS.width,
|
|
2177
|
+
AREA_BOUNDS.height,
|
|
2178
|
+
AREA_BOUNDS.depth
|
|
2179
|
+
)
|
|
2180
|
+
}
|
|
2181
|
+
};
|
|
2182
|
+
}
|
|
2183
|
+
function Snow({
|
|
2184
|
+
className,
|
|
2185
|
+
style,
|
|
2186
|
+
width,
|
|
2187
|
+
height,
|
|
2188
|
+
color,
|
|
2189
|
+
fallSpeed,
|
|
2190
|
+
windStrength,
|
|
2191
|
+
turbulence,
|
|
2192
|
+
flakeSize,
|
|
2193
|
+
twinkleStrength,
|
|
2194
|
+
flakeCount,
|
|
2195
|
+
mouseWindInteraction = false,
|
|
2196
|
+
...divProps
|
|
2197
|
+
}) {
|
|
2198
|
+
const snowRef = (0, import_react7.useRef)(null);
|
|
2199
|
+
const uniformsRef = (0, import_react7.useRef)({
|
|
2200
|
+
color,
|
|
2201
|
+
fallSpeed,
|
|
2202
|
+
windStrength,
|
|
2203
|
+
turbulence,
|
|
2204
|
+
flakeSize,
|
|
2205
|
+
twinkleStrength,
|
|
2206
|
+
flakeCount
|
|
2207
|
+
});
|
|
2208
|
+
uniformsRef.current = {
|
|
2209
|
+
color,
|
|
2210
|
+
fallSpeed,
|
|
2211
|
+
windStrength,
|
|
2212
|
+
turbulence,
|
|
2213
|
+
flakeSize,
|
|
2214
|
+
twinkleStrength,
|
|
2215
|
+
flakeCount
|
|
2216
|
+
};
|
|
2217
|
+
const pointerWindOffsetRef = (0, import_react7.useRef)(0);
|
|
2218
|
+
const pointerWindTargetRef = (0, import_react7.useRef)(0);
|
|
2219
|
+
const pointerStateRef = (0, import_react7.useRef)({
|
|
2220
|
+
lastX: 0,
|
|
2221
|
+
lastTime: 0,
|
|
2222
|
+
timeoutId: null
|
|
2223
|
+
});
|
|
2224
|
+
const pointerActiveRef = (0, import_react7.useRef)(false);
|
|
2225
|
+
const baseWindRef = (0, import_react7.useRef)(windStrength);
|
|
2226
|
+
(0, import_react7.useEffect)(() => {
|
|
2227
|
+
baseWindRef.current = windStrength;
|
|
2228
|
+
}, [windStrength]);
|
|
2229
|
+
const handleCreate = (0, import_react7.useCallback)(({ scene }) => {
|
|
2230
|
+
const uniforms = buildUniforms2(uniformsRef.current);
|
|
2231
|
+
const geometry = createSnowGeometry(
|
|
2232
|
+
Math.max(1, Math.floor(uniformsRef.current.flakeCount))
|
|
2233
|
+
);
|
|
2234
|
+
const material = new THREE7.ShaderMaterial({
|
|
2235
|
+
fragmentShader: fragment_default7,
|
|
2236
|
+
vertexShader: vertex_default6,
|
|
2237
|
+
uniforms,
|
|
2238
|
+
transparent: true,
|
|
2239
|
+
depthWrite: false,
|
|
2240
|
+
blending: THREE7.AdditiveBlending
|
|
2241
|
+
});
|
|
2242
|
+
const points = new THREE7.Points(geometry, material);
|
|
2243
|
+
points.frustumCulled = false;
|
|
2244
|
+
scene.add(points);
|
|
2245
|
+
snowRef.current = { points, geometry, material, uniforms };
|
|
2246
|
+
return () => {
|
|
2247
|
+
scene.remove(points);
|
|
2248
|
+
geometry.dispose();
|
|
2249
|
+
material.dispose();
|
|
2250
|
+
snowRef.current = null;
|
|
2251
|
+
};
|
|
2252
|
+
}, []);
|
|
2253
|
+
const handleRender = (0, import_react7.useCallback)(
|
|
2254
|
+
(_context, delta, elapsedTime) => {
|
|
2255
|
+
const assets = snowRef.current;
|
|
2256
|
+
if (!assets) return;
|
|
2257
|
+
assets.uniforms.uTime.value = elapsedTime;
|
|
2258
|
+
const currentOffset = pointerWindOffsetRef.current;
|
|
2259
|
+
const targetOffset = pointerWindTargetRef.current;
|
|
2260
|
+
const nextOffset = THREE7.MathUtils.damp(
|
|
2261
|
+
currentOffset,
|
|
2262
|
+
targetOffset,
|
|
2263
|
+
3.5,
|
|
2264
|
+
delta
|
|
2265
|
+
);
|
|
2266
|
+
if (Math.abs(nextOffset - currentOffset) > 5e-5) {
|
|
2267
|
+
pointerWindOffsetRef.current = nextOffset;
|
|
2268
|
+
assets.uniforms.uWindStrength.value = baseWindRef.current + nextOffset;
|
|
2269
|
+
}
|
|
2270
|
+
},
|
|
2271
|
+
[]
|
|
2272
|
+
);
|
|
2273
|
+
const { containerRef } = useScene({
|
|
2274
|
+
camera: {
|
|
2275
|
+
position: [0, 0, 18]
|
|
2276
|
+
},
|
|
2277
|
+
onCreate: handleCreate,
|
|
2278
|
+
onRender: handleRender
|
|
2279
|
+
});
|
|
2280
|
+
(0, import_react7.useEffect)(() => {
|
|
2281
|
+
const assets = snowRef.current;
|
|
2282
|
+
if (!assets) return;
|
|
2283
|
+
assets.uniforms.uColor.value.set(color);
|
|
2284
|
+
}, [color]);
|
|
2285
|
+
(0, import_react7.useEffect)(() => {
|
|
2286
|
+
const assets = snowRef.current;
|
|
2287
|
+
if (!assets) return;
|
|
2288
|
+
assets.uniforms.uFallSpeed.value = fallSpeed;
|
|
2289
|
+
}, [fallSpeed]);
|
|
2290
|
+
(0, import_react7.useEffect)(() => {
|
|
2291
|
+
const assets = snowRef.current;
|
|
2292
|
+
if (!assets) return;
|
|
2293
|
+
assets.uniforms.uWindStrength.value = windStrength + pointerWindOffsetRef.current;
|
|
2294
|
+
}, [windStrength]);
|
|
2295
|
+
(0, import_react7.useEffect)(() => {
|
|
2296
|
+
const assets = snowRef.current;
|
|
2297
|
+
if (!assets) return;
|
|
2298
|
+
assets.uniforms.uTurbulence.value = turbulence;
|
|
2299
|
+
}, [turbulence]);
|
|
2300
|
+
(0, import_react7.useEffect)(() => {
|
|
2301
|
+
const assets = snowRef.current;
|
|
2302
|
+
if (!assets) return;
|
|
2303
|
+
assets.uniforms.uSize.value = flakeSize;
|
|
2304
|
+
}, [flakeSize]);
|
|
2305
|
+
(0, import_react7.useEffect)(() => {
|
|
2306
|
+
const assets = snowRef.current;
|
|
2307
|
+
if (!assets) return;
|
|
2308
|
+
assets.uniforms.uTwinkleStrength.value = twinkleStrength;
|
|
2309
|
+
}, [twinkleStrength]);
|
|
2310
|
+
(0, import_react7.useEffect)(() => {
|
|
2311
|
+
const assets = snowRef.current;
|
|
2312
|
+
if (!assets) return;
|
|
2313
|
+
const geometry = createSnowGeometry(Math.max(1, Math.floor(flakeCount)));
|
|
2314
|
+
assets.points.geometry.dispose();
|
|
2315
|
+
assets.points.geometry = geometry;
|
|
2316
|
+
assets.geometry = geometry;
|
|
2317
|
+
}, [flakeCount]);
|
|
2318
|
+
(0, import_react7.useEffect)(() => {
|
|
2319
|
+
const pointerState = pointerStateRef.current;
|
|
2320
|
+
const clearTimeoutIfNeeded = () => {
|
|
2321
|
+
if (pointerState.timeoutId !== null) {
|
|
2322
|
+
window.clearTimeout(pointerState.timeoutId);
|
|
2323
|
+
pointerState.timeoutId = null;
|
|
2324
|
+
}
|
|
2325
|
+
};
|
|
2326
|
+
if (!mouseWindInteraction) {
|
|
2327
|
+
clearTimeoutIfNeeded();
|
|
2328
|
+
pointerWindOffsetRef.current = 0;
|
|
2329
|
+
pointerWindTargetRef.current = 0;
|
|
2330
|
+
pointerState.lastTime = 0;
|
|
2331
|
+
pointerActiveRef.current = false;
|
|
2332
|
+
const assets = snowRef.current;
|
|
2333
|
+
if (assets) {
|
|
2334
|
+
assets.uniforms.uWindStrength.value = windStrength;
|
|
2335
|
+
}
|
|
2336
|
+
return;
|
|
2337
|
+
}
|
|
2338
|
+
const container = containerRef.current;
|
|
2339
|
+
if (!container) return;
|
|
2340
|
+
const scheduleReset = () => {
|
|
2341
|
+
clearTimeoutIfNeeded();
|
|
2342
|
+
pointerState.timeoutId = window.setTimeout(() => {
|
|
2343
|
+
pointerWindTargetRef.current = 0;
|
|
2344
|
+
pointerState.timeoutId = null;
|
|
2345
|
+
}, 220);
|
|
2346
|
+
};
|
|
2347
|
+
const handlePointerMove = (event) => {
|
|
2348
|
+
const isMouse = event.pointerType === "mouse";
|
|
2349
|
+
if (!isMouse && !pointerActiveRef.current) return;
|
|
2350
|
+
const now = performance.now();
|
|
2351
|
+
if (pointerState.lastTime === 0) {
|
|
2352
|
+
pointerState.lastX = event.clientX;
|
|
2353
|
+
pointerState.lastTime = now;
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
2356
|
+
const dx = event.clientX - pointerState.lastX;
|
|
2357
|
+
const dt = Math.max(1, now - pointerState.lastTime);
|
|
2358
|
+
const velocity = dx / dt;
|
|
2359
|
+
const offset = THREE7.MathUtils.clamp(velocity * 0.9, -1.6, 1.6);
|
|
2360
|
+
pointerWindTargetRef.current = offset;
|
|
2361
|
+
pointerState.lastX = event.clientX;
|
|
2362
|
+
pointerState.lastTime = now;
|
|
2363
|
+
scheduleReset();
|
|
2364
|
+
};
|
|
2365
|
+
const handlePointerDown = (event) => {
|
|
2366
|
+
pointerActiveRef.current = true;
|
|
2367
|
+
pointerState.lastX = event.clientX;
|
|
2368
|
+
pointerState.lastTime = performance.now();
|
|
2369
|
+
scheduleReset();
|
|
2370
|
+
};
|
|
2371
|
+
const handlePointerUp = () => {
|
|
2372
|
+
pointerActiveRef.current = false;
|
|
2373
|
+
pointerState.lastTime = 0;
|
|
2374
|
+
pointerWindTargetRef.current = 0;
|
|
2375
|
+
scheduleReset();
|
|
2376
|
+
};
|
|
2377
|
+
const handlePointerLeave = () => {
|
|
2378
|
+
pointerActiveRef.current = false;
|
|
2379
|
+
pointerState.lastTime = 0;
|
|
2380
|
+
pointerWindTargetRef.current = 0;
|
|
2381
|
+
clearTimeoutIfNeeded();
|
|
2382
|
+
};
|
|
2383
|
+
container.addEventListener("pointermove", handlePointerMove);
|
|
2384
|
+
container.addEventListener("pointerdown", handlePointerDown);
|
|
2385
|
+
container.addEventListener("pointerup", handlePointerUp);
|
|
2386
|
+
container.addEventListener("pointercancel", handlePointerUp);
|
|
2387
|
+
container.addEventListener("pointerout", handlePointerLeave);
|
|
2388
|
+
container.addEventListener("pointerleave", handlePointerLeave);
|
|
2389
|
+
return () => {
|
|
2390
|
+
container.removeEventListener("pointermove", handlePointerMove);
|
|
2391
|
+
container.removeEventListener("pointerdown", handlePointerDown);
|
|
2392
|
+
container.removeEventListener("pointerup", handlePointerUp);
|
|
2393
|
+
container.removeEventListener("pointercancel", handlePointerUp);
|
|
2394
|
+
container.removeEventListener("pointerout", handlePointerLeave);
|
|
2395
|
+
container.removeEventListener("pointerleave", handlePointerLeave);
|
|
2396
|
+
pointerState.lastTime = 0;
|
|
2397
|
+
pointerWindOffsetRef.current = 0;
|
|
2398
|
+
pointerWindTargetRef.current = 0;
|
|
2399
|
+
pointerActiveRef.current = false;
|
|
2400
|
+
clearTimeoutIfNeeded();
|
|
2401
|
+
const assets = snowRef.current;
|
|
2402
|
+
if (assets) {
|
|
2403
|
+
assets.uniforms.uWindStrength.value = windStrength;
|
|
2404
|
+
}
|
|
2405
|
+
};
|
|
2406
|
+
}, [containerRef, mouseWindInteraction, windStrength]);
|
|
2407
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2408
|
+
"div",
|
|
2409
|
+
{
|
|
2410
|
+
ref: containerRef,
|
|
2411
|
+
className,
|
|
2412
|
+
style: {
|
|
2413
|
+
width: width ?? "100%",
|
|
2414
|
+
height: height ?? "100%",
|
|
2415
|
+
...style
|
|
2416
|
+
},
|
|
2417
|
+
...divProps
|
|
2418
|
+
}
|
|
2419
|
+
);
|
|
2420
|
+
}
|
|
2421
|
+
|
|
2422
|
+
// src/components/AnimatedDrawingSVG.tsx
|
|
2423
|
+
var import_clsx = __toESM(require("clsx"));
|
|
2424
|
+
var import_react8 = require("react");
|
|
2425
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2426
|
+
var PATH_SELECTOR = "path, line, polyline, polygon, circle, ellipse";
|
|
2427
|
+
function AnimatedDrawingSVG({
|
|
2428
|
+
svgMarkup,
|
|
2429
|
+
animated = true,
|
|
2430
|
+
size,
|
|
2431
|
+
onAnimated,
|
|
2432
|
+
delay,
|
|
2433
|
+
className,
|
|
2434
|
+
style,
|
|
2435
|
+
...divProps
|
|
2436
|
+
}) {
|
|
2437
|
+
const containerRef = (0, import_react8.useRef)(null);
|
|
2438
|
+
const animationsRef = (0, import_react8.useRef)([]);
|
|
2439
|
+
const parserRef = (0, import_react8.useRef)(null);
|
|
2440
|
+
const onAnimatedRef = (0, import_react8.useRef)(onAnimated);
|
|
2441
|
+
const animationRunIdRef = (0, import_react8.useRef)(0);
|
|
2442
|
+
const onAnimationCompleteRef = (0, import_react8.useRef)(false);
|
|
2443
|
+
const timeoutRef = (0, import_react8.useRef)([]);
|
|
2444
|
+
const monitorRafRef = (0, import_react8.useRef)(null);
|
|
2445
|
+
const sanitizedMarkup = (svgMarkup ?? "").toString().trim();
|
|
2446
|
+
const normalizedDelay = typeof delay === "number" && delay > 0 ? delay : 0;
|
|
2447
|
+
(0, import_react8.useEffect)(() => {
|
|
2448
|
+
onAnimatedRef.current = onAnimated;
|
|
2449
|
+
}, [onAnimated]);
|
|
2450
|
+
(0, import_react8.useEffect)(() => {
|
|
2451
|
+
return () => {
|
|
2452
|
+
animationsRef.current.forEach((animation) => animation.cancel());
|
|
2453
|
+
animationsRef.current = [];
|
|
2454
|
+
timeoutRef.current.forEach((id) => window.clearTimeout(id));
|
|
2455
|
+
timeoutRef.current = [];
|
|
2456
|
+
if (monitorRafRef.current !== null) {
|
|
2457
|
+
cancelAnimationFrame(monitorRafRef.current);
|
|
2458
|
+
monitorRafRef.current = null;
|
|
2459
|
+
}
|
|
2460
|
+
};
|
|
2461
|
+
}, []);
|
|
2462
|
+
(0, import_react8.useLayoutEffect)(() => {
|
|
2463
|
+
const container = containerRef.current;
|
|
2464
|
+
if (!container) return;
|
|
2465
|
+
let rafId = null;
|
|
2466
|
+
let delayId = null;
|
|
2467
|
+
let started = false;
|
|
2468
|
+
if (normalizedDelay > 0) {
|
|
2469
|
+
container.style.visibility = "hidden";
|
|
2470
|
+
} else {
|
|
2471
|
+
container.style.removeProperty("visibility");
|
|
2472
|
+
}
|
|
2473
|
+
animationRunIdRef.current += 1;
|
|
2474
|
+
const currentRunId = animationRunIdRef.current;
|
|
2475
|
+
onAnimationCompleteRef.current = false;
|
|
2476
|
+
timeoutRef.current.forEach((id) => window.clearTimeout(id));
|
|
2477
|
+
timeoutRef.current = [];
|
|
2478
|
+
const markComplete = () => {
|
|
2479
|
+
if (animationRunIdRef.current === currentRunId && !onAnimationCompleteRef.current) {
|
|
2480
|
+
onAnimationCompleteRef.current = true;
|
|
2481
|
+
onAnimatedRef.current?.();
|
|
2482
|
+
}
|
|
2483
|
+
};
|
|
2484
|
+
animationsRef.current.forEach((animation) => animation.cancel());
|
|
2485
|
+
animationsRef.current = [];
|
|
2486
|
+
if (monitorRafRef.current !== null) {
|
|
2487
|
+
cancelAnimationFrame(monitorRafRef.current);
|
|
2488
|
+
monitorRafRef.current = null;
|
|
2489
|
+
}
|
|
2490
|
+
if (!sanitizedMarkup) {
|
|
2491
|
+
container.replaceChildren();
|
|
2492
|
+
markComplete();
|
|
2493
|
+
return;
|
|
2494
|
+
}
|
|
2495
|
+
const parser = parserRef.current ?? new DOMParser();
|
|
2496
|
+
parserRef.current = parser;
|
|
2497
|
+
let parsed;
|
|
2498
|
+
try {
|
|
2499
|
+
parsed = parser.parseFromString(sanitizedMarkup, "image/svg+xml");
|
|
2500
|
+
} catch {
|
|
2501
|
+
return;
|
|
2502
|
+
}
|
|
2503
|
+
if (parsed.querySelector("parsererror")) {
|
|
2504
|
+
return;
|
|
2505
|
+
}
|
|
2506
|
+
const parsedSvg = parsed.querySelector("svg");
|
|
2507
|
+
if (!parsedSvg) {
|
|
2508
|
+
container.replaceChildren();
|
|
2509
|
+
onAnimatedRef.current?.();
|
|
2510
|
+
return;
|
|
2511
|
+
}
|
|
2512
|
+
const svgElement = document.importNode(parsedSvg, true);
|
|
2513
|
+
svgElement.setAttribute("preserveAspectRatio", "xMidYMid meet");
|
|
2514
|
+
if (size !== void 0) {
|
|
2515
|
+
svgElement.removeAttribute("width");
|
|
2516
|
+
svgElement.removeAttribute("height");
|
|
2517
|
+
const sizeValue = typeof size === "number" ? `${Math.max(0, size)}px` : `${size}`;
|
|
2518
|
+
svgElement.style.width = sizeValue;
|
|
2519
|
+
svgElement.style.height = "auto";
|
|
2520
|
+
} else {
|
|
2521
|
+
svgElement.style.width = "100%";
|
|
2522
|
+
svgElement.style.height = "100%";
|
|
2523
|
+
svgElement.style.maxWidth = "100%";
|
|
2524
|
+
svgElement.style.maxHeight = "100%";
|
|
2525
|
+
}
|
|
2526
|
+
svgElement.style.display = "block";
|
|
2527
|
+
container.replaceChildren(svgElement);
|
|
2528
|
+
const runAnimations = () => {
|
|
2529
|
+
const drawTargets = Array.from(
|
|
2530
|
+
svgElement.querySelectorAll(PATH_SELECTOR)
|
|
2531
|
+
);
|
|
2532
|
+
const scheduleFallback = (delay2) => {
|
|
2533
|
+
const fallbackId = window.setTimeout(markComplete, delay2);
|
|
2534
|
+
timeoutRef.current.push(fallbackId);
|
|
2535
|
+
};
|
|
2536
|
+
if (!drawTargets.length) {
|
|
2537
|
+
if (!animated) {
|
|
2538
|
+
markComplete();
|
|
2539
|
+
} else {
|
|
2540
|
+
Promise.resolve().then(() => {
|
|
2541
|
+
markComplete();
|
|
2542
|
+
});
|
|
2543
|
+
}
|
|
2544
|
+
return;
|
|
2545
|
+
}
|
|
2546
|
+
let maxDuration = 0;
|
|
2547
|
+
const resolveTimingValue = (value, fallback) => {
|
|
2548
|
+
if (typeof value === "number") {
|
|
2549
|
+
return value;
|
|
2550
|
+
}
|
|
2551
|
+
if (typeof value === "string") {
|
|
2552
|
+
const parsed2 = Number.parseFloat(value);
|
|
2553
|
+
return Number.isFinite(parsed2) ? parsed2 : fallback;
|
|
2554
|
+
}
|
|
2555
|
+
if (typeof value === "object" && value !== null) {
|
|
2556
|
+
const parsed2 = Number.parseFloat(value.toString());
|
|
2557
|
+
return Number.isFinite(parsed2) ? parsed2 : fallback;
|
|
2558
|
+
}
|
|
2559
|
+
return fallback;
|
|
2560
|
+
};
|
|
2561
|
+
drawTargets.forEach((element, index) => {
|
|
2562
|
+
const length = typeof element.getTotalLength === "function" ? element.getTotalLength() : null;
|
|
2563
|
+
if (!length || Number.isNaN(length)) {
|
|
2564
|
+
element.style.removeProperty("stroke-dasharray");
|
|
2565
|
+
element.style.removeProperty("stroke-dashoffset");
|
|
2566
|
+
return;
|
|
2567
|
+
}
|
|
2568
|
+
const dashValue = `${length}`;
|
|
2569
|
+
element.style.strokeDasharray = dashValue;
|
|
2570
|
+
element.style.strokeDashoffset = animated ? dashValue : "0";
|
|
2571
|
+
if (!element.style.strokeLinecap) {
|
|
2572
|
+
element.style.strokeLinecap = "round";
|
|
2573
|
+
}
|
|
2574
|
+
if (!animated) {
|
|
2575
|
+
return;
|
|
2576
|
+
}
|
|
2577
|
+
const animation = element.animate(
|
|
2578
|
+
[{ strokeDashoffset: dashValue }, { strokeDashoffset: "0" }],
|
|
2579
|
+
{
|
|
2580
|
+
duration: Math.min(6500, Math.max(1200, length * 12)),
|
|
2581
|
+
delay: index * 120,
|
|
2582
|
+
easing: "ease-in-out",
|
|
2583
|
+
fill: "forwards"
|
|
2584
|
+
}
|
|
2585
|
+
);
|
|
2586
|
+
const timing = animation.effect?.getTiming();
|
|
2587
|
+
const baseDuration = Math.min(6500, Math.max(1200, length * 12));
|
|
2588
|
+
const total = resolveTimingValue(timing?.delay, index * 120) + resolveTimingValue(timing?.duration, baseDuration);
|
|
2589
|
+
if (total > maxDuration) {
|
|
2590
|
+
maxDuration = total;
|
|
2591
|
+
}
|
|
2592
|
+
animationsRef.current.push(animation);
|
|
2593
|
+
});
|
|
2594
|
+
if (!animated) {
|
|
2595
|
+
markComplete();
|
|
2596
|
+
return;
|
|
2597
|
+
}
|
|
2598
|
+
const startMonitor = () => {
|
|
2599
|
+
const monitor = () => {
|
|
2600
|
+
if (animationRunIdRef.current !== currentRunId) {
|
|
2601
|
+
return;
|
|
2602
|
+
}
|
|
2603
|
+
const allFinished = animationsRef.current.every((animation) => {
|
|
2604
|
+
const state = animation.playState;
|
|
2605
|
+
return state === "finished" || state === "idle";
|
|
2606
|
+
});
|
|
2607
|
+
if (allFinished) {
|
|
2608
|
+
if (monitorRafRef.current !== null) {
|
|
2609
|
+
cancelAnimationFrame(monitorRafRef.current);
|
|
2610
|
+
monitorRafRef.current = null;
|
|
2611
|
+
}
|
|
2612
|
+
markComplete();
|
|
2613
|
+
return;
|
|
2614
|
+
}
|
|
2615
|
+
monitorRafRef.current = requestAnimationFrame(monitor);
|
|
2616
|
+
};
|
|
2617
|
+
if (monitorRafRef.current !== null) {
|
|
2618
|
+
cancelAnimationFrame(monitorRafRef.current);
|
|
2619
|
+
}
|
|
2620
|
+
monitorRafRef.current = requestAnimationFrame(monitor);
|
|
2621
|
+
};
|
|
2622
|
+
startMonitor();
|
|
2623
|
+
if (animated && maxDuration > 0) {
|
|
2624
|
+
scheduleFallback(maxDuration + 50);
|
|
2625
|
+
}
|
|
2626
|
+
};
|
|
2627
|
+
const triggerStart = () => {
|
|
2628
|
+
if (started) return;
|
|
2629
|
+
started = true;
|
|
2630
|
+
container.style.removeProperty("visibility");
|
|
2631
|
+
rafId = requestAnimationFrame(runAnimations);
|
|
2632
|
+
};
|
|
2633
|
+
if (normalizedDelay > 0) {
|
|
2634
|
+
delayId = window.setTimeout(triggerStart, normalizedDelay);
|
|
2635
|
+
} else {
|
|
2636
|
+
triggerStart();
|
|
2637
|
+
}
|
|
2638
|
+
return () => {
|
|
2639
|
+
if (delayId !== null) {
|
|
2640
|
+
window.clearTimeout(delayId);
|
|
2641
|
+
}
|
|
2642
|
+
if (rafId !== null) {
|
|
2643
|
+
cancelAnimationFrame(rafId);
|
|
2644
|
+
}
|
|
2645
|
+
};
|
|
2646
|
+
}, [sanitizedMarkup, animated, size, normalizedDelay]);
|
|
2647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2648
|
+
"div",
|
|
2649
|
+
{
|
|
2650
|
+
ref: containerRef,
|
|
2651
|
+
className: (0, import_clsx.default)(
|
|
2652
|
+
"flex items-center justify-center [&_svg]:block",
|
|
2653
|
+
className
|
|
2654
|
+
),
|
|
2655
|
+
style: {
|
|
2656
|
+
...style
|
|
2657
|
+
},
|
|
2658
|
+
...divProps
|
|
2659
|
+
}
|
|
2660
|
+
);
|
|
2661
|
+
}
|
|
2114
2662
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2115
2663
|
0 && (module.exports = {
|
|
2664
|
+
AnimatedDrawingSVG,
|
|
2116
2665
|
EFECTO_ASCII_COMPONENT_DEFAULTS,
|
|
2117
2666
|
EFECTO_ASCII_POST_PROCESSING_DEFAULTS,
|
|
2118
2667
|
Efecto,
|
|
2119
2668
|
FractalFlower,
|
|
2120
2669
|
MenuGlitch,
|
|
2121
2670
|
OranoParticles,
|
|
2122
|
-
ShaderArt
|
|
2671
|
+
ShaderArt,
|
|
2672
|
+
Snow
|
|
2123
2673
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -2090,12 +2090,560 @@ function Efecto({
|
|
|
2090
2090
|
}
|
|
2091
2091
|
);
|
|
2092
2092
|
}
|
|
2093
|
+
|
|
2094
|
+
// src/components/Snow.tsx
|
|
2095
|
+
import { useCallback as useCallback6, useEffect as useEffect7, useRef as useRef7 } from "react";
|
|
2096
|
+
import * as THREE7 from "three";
|
|
2097
|
+
|
|
2098
|
+
// src/shaders/snow/fragment.glsl
|
|
2099
|
+
var fragment_default7 = "precision mediump float;\n\nuniform vec3 uColor;\n\nvarying float vAlpha;\n\nvoid main() {\n vec2 uv = gl_PointCoord - 0.5;\n float dist = length(uv);\n float mask = smoothstep(0.5, 0.0, dist);\n if (mask <= 0.01) {\n discard;\n }\n\n float centerGlow = smoothstep(0.22, 0.0, dist);\n vec3 color = mix(uColor * 1.2, uColor, centerGlow);\n\n gl_FragColor = vec4(color, mask * vAlpha);\n}\n";
|
|
2100
|
+
|
|
2101
|
+
// src/shaders/snow/vertex.glsl
|
|
2102
|
+
var vertex_default6 = "uniform float uTime;\nuniform float uFallSpeed;\nuniform float uWindStrength;\nuniform float uTurbulence;\nuniform float uSize;\nuniform float uTwinkleStrength;\nuniform vec3 uArea;\n\nattribute float aSpeed;\nattribute float aSize;\nattribute float aSeed;\n\nvarying float vAlpha;\n\nfloat wrap(float value, float size) {\n return mod(value + size * 0.5, size) - size * 0.5;\n}\n\nvoid main() {\n float height = uArea.y;\n float width = uArea.x;\n float depth = uArea.z;\n\n float fall = uFallSpeed * (0.3 + aSpeed);\n float droppedY = position.y - uTime * fall;\n float wrappedY = wrap(droppedY, height);\n\n float sway =\n sin((wrappedY + aSeed) * 0.45 + uTime * 0.8) * uTurbulence +\n cos(uTime * 0.35 + aSeed) * 0.15;\n float wind = uWindStrength * (0.4 + aSpeed);\n float displacedX = wrap(position.x + sway + wind, width);\n\n float driftZ =\n sin(uTime * 0.25 + aSeed * 1.7) * 0.5 +\n cos((wrappedY + aSeed) * 0.2) * 0.4;\n float displacedZ = wrap(position.z + driftZ, depth);\n\n vec4 modelPosition =\n modelMatrix * vec4(displacedX, wrappedY, displacedZ, 1.0);\n vec4 viewPosition = viewMatrix * modelPosition;\n\n float baseSize = mix(0.45, 1.0, aSize) * uSize;\n float twinkle =\n 1.0 + sin(uTime * (0.6 + aSpeed) + aSeed) * uTwinkleStrength;\n float perspective = clamp(15.0 / max(1.0, -viewPosition.z), 0.5, 3.0);\n gl_PointSize = baseSize * twinkle * perspective;\n gl_Position = projectionMatrix * viewPosition;\n\n vAlpha = mix(0.35, 1.0, aSize);\n}\n";
|
|
2103
|
+
|
|
2104
|
+
// src/components/Snow.tsx
|
|
2105
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
2106
|
+
var AREA_BOUNDS = {
|
|
2107
|
+
width: 36,
|
|
2108
|
+
height: 44,
|
|
2109
|
+
depth: 26
|
|
2110
|
+
};
|
|
2111
|
+
function createSnowGeometry(count) {
|
|
2112
|
+
const geometry = new THREE7.BufferGeometry();
|
|
2113
|
+
const positions = new Float32Array(count * 3);
|
|
2114
|
+
const speeds = new Float32Array(count);
|
|
2115
|
+
const sizes = new Float32Array(count);
|
|
2116
|
+
const seeds = new Float32Array(count);
|
|
2117
|
+
for (let i = 0; i < count; i += 1) {
|
|
2118
|
+
const x = (Math.random() - 0.5) * AREA_BOUNDS.width;
|
|
2119
|
+
const y = (Math.random() - 0.5) * AREA_BOUNDS.height;
|
|
2120
|
+
const z = (Math.random() - 0.5) * AREA_BOUNDS.depth;
|
|
2121
|
+
positions[i * 3] = x;
|
|
2122
|
+
positions[i * 3 + 1] = y;
|
|
2123
|
+
positions[i * 3 + 2] = z;
|
|
2124
|
+
speeds[i] = Math.random();
|
|
2125
|
+
sizes[i] = Math.random();
|
|
2126
|
+
seeds[i] = Math.random() * 100;
|
|
2127
|
+
}
|
|
2128
|
+
geometry.setAttribute("position", new THREE7.BufferAttribute(positions, 3));
|
|
2129
|
+
geometry.setAttribute("aSpeed", new THREE7.BufferAttribute(speeds, 1));
|
|
2130
|
+
geometry.setAttribute("aSize", new THREE7.BufferAttribute(sizes, 1));
|
|
2131
|
+
geometry.setAttribute("aSeed", new THREE7.BufferAttribute(seeds, 1));
|
|
2132
|
+
geometry.computeBoundingSphere();
|
|
2133
|
+
return geometry;
|
|
2134
|
+
}
|
|
2135
|
+
function buildUniforms2({
|
|
2136
|
+
color,
|
|
2137
|
+
fallSpeed,
|
|
2138
|
+
windStrength,
|
|
2139
|
+
turbulence,
|
|
2140
|
+
flakeSize,
|
|
2141
|
+
twinkleStrength
|
|
2142
|
+
}) {
|
|
2143
|
+
return {
|
|
2144
|
+
uTime: { value: 0 },
|
|
2145
|
+
uFallSpeed: { value: fallSpeed },
|
|
2146
|
+
uWindStrength: { value: windStrength },
|
|
2147
|
+
uTurbulence: { value: turbulence },
|
|
2148
|
+
uSize: { value: flakeSize },
|
|
2149
|
+
uTwinkleStrength: { value: twinkleStrength },
|
|
2150
|
+
uColor: { value: new THREE7.Color(color) },
|
|
2151
|
+
uArea: {
|
|
2152
|
+
value: new THREE7.Vector3(
|
|
2153
|
+
AREA_BOUNDS.width,
|
|
2154
|
+
AREA_BOUNDS.height,
|
|
2155
|
+
AREA_BOUNDS.depth
|
|
2156
|
+
)
|
|
2157
|
+
}
|
|
2158
|
+
};
|
|
2159
|
+
}
|
|
2160
|
+
function Snow({
|
|
2161
|
+
className,
|
|
2162
|
+
style,
|
|
2163
|
+
width,
|
|
2164
|
+
height,
|
|
2165
|
+
color,
|
|
2166
|
+
fallSpeed,
|
|
2167
|
+
windStrength,
|
|
2168
|
+
turbulence,
|
|
2169
|
+
flakeSize,
|
|
2170
|
+
twinkleStrength,
|
|
2171
|
+
flakeCount,
|
|
2172
|
+
mouseWindInteraction = false,
|
|
2173
|
+
...divProps
|
|
2174
|
+
}) {
|
|
2175
|
+
const snowRef = useRef7(null);
|
|
2176
|
+
const uniformsRef = useRef7({
|
|
2177
|
+
color,
|
|
2178
|
+
fallSpeed,
|
|
2179
|
+
windStrength,
|
|
2180
|
+
turbulence,
|
|
2181
|
+
flakeSize,
|
|
2182
|
+
twinkleStrength,
|
|
2183
|
+
flakeCount
|
|
2184
|
+
});
|
|
2185
|
+
uniformsRef.current = {
|
|
2186
|
+
color,
|
|
2187
|
+
fallSpeed,
|
|
2188
|
+
windStrength,
|
|
2189
|
+
turbulence,
|
|
2190
|
+
flakeSize,
|
|
2191
|
+
twinkleStrength,
|
|
2192
|
+
flakeCount
|
|
2193
|
+
};
|
|
2194
|
+
const pointerWindOffsetRef = useRef7(0);
|
|
2195
|
+
const pointerWindTargetRef = useRef7(0);
|
|
2196
|
+
const pointerStateRef = useRef7({
|
|
2197
|
+
lastX: 0,
|
|
2198
|
+
lastTime: 0,
|
|
2199
|
+
timeoutId: null
|
|
2200
|
+
});
|
|
2201
|
+
const pointerActiveRef = useRef7(false);
|
|
2202
|
+
const baseWindRef = useRef7(windStrength);
|
|
2203
|
+
useEffect7(() => {
|
|
2204
|
+
baseWindRef.current = windStrength;
|
|
2205
|
+
}, [windStrength]);
|
|
2206
|
+
const handleCreate = useCallback6(({ scene }) => {
|
|
2207
|
+
const uniforms = buildUniforms2(uniformsRef.current);
|
|
2208
|
+
const geometry = createSnowGeometry(
|
|
2209
|
+
Math.max(1, Math.floor(uniformsRef.current.flakeCount))
|
|
2210
|
+
);
|
|
2211
|
+
const material = new THREE7.ShaderMaterial({
|
|
2212
|
+
fragmentShader: fragment_default7,
|
|
2213
|
+
vertexShader: vertex_default6,
|
|
2214
|
+
uniforms,
|
|
2215
|
+
transparent: true,
|
|
2216
|
+
depthWrite: false,
|
|
2217
|
+
blending: THREE7.AdditiveBlending
|
|
2218
|
+
});
|
|
2219
|
+
const points = new THREE7.Points(geometry, material);
|
|
2220
|
+
points.frustumCulled = false;
|
|
2221
|
+
scene.add(points);
|
|
2222
|
+
snowRef.current = { points, geometry, material, uniforms };
|
|
2223
|
+
return () => {
|
|
2224
|
+
scene.remove(points);
|
|
2225
|
+
geometry.dispose();
|
|
2226
|
+
material.dispose();
|
|
2227
|
+
snowRef.current = null;
|
|
2228
|
+
};
|
|
2229
|
+
}, []);
|
|
2230
|
+
const handleRender = useCallback6(
|
|
2231
|
+
(_context, delta, elapsedTime) => {
|
|
2232
|
+
const assets = snowRef.current;
|
|
2233
|
+
if (!assets) return;
|
|
2234
|
+
assets.uniforms.uTime.value = elapsedTime;
|
|
2235
|
+
const currentOffset = pointerWindOffsetRef.current;
|
|
2236
|
+
const targetOffset = pointerWindTargetRef.current;
|
|
2237
|
+
const nextOffset = THREE7.MathUtils.damp(
|
|
2238
|
+
currentOffset,
|
|
2239
|
+
targetOffset,
|
|
2240
|
+
3.5,
|
|
2241
|
+
delta
|
|
2242
|
+
);
|
|
2243
|
+
if (Math.abs(nextOffset - currentOffset) > 5e-5) {
|
|
2244
|
+
pointerWindOffsetRef.current = nextOffset;
|
|
2245
|
+
assets.uniforms.uWindStrength.value = baseWindRef.current + nextOffset;
|
|
2246
|
+
}
|
|
2247
|
+
},
|
|
2248
|
+
[]
|
|
2249
|
+
);
|
|
2250
|
+
const { containerRef } = useScene({
|
|
2251
|
+
camera: {
|
|
2252
|
+
position: [0, 0, 18]
|
|
2253
|
+
},
|
|
2254
|
+
onCreate: handleCreate,
|
|
2255
|
+
onRender: handleRender
|
|
2256
|
+
});
|
|
2257
|
+
useEffect7(() => {
|
|
2258
|
+
const assets = snowRef.current;
|
|
2259
|
+
if (!assets) return;
|
|
2260
|
+
assets.uniforms.uColor.value.set(color);
|
|
2261
|
+
}, [color]);
|
|
2262
|
+
useEffect7(() => {
|
|
2263
|
+
const assets = snowRef.current;
|
|
2264
|
+
if (!assets) return;
|
|
2265
|
+
assets.uniforms.uFallSpeed.value = fallSpeed;
|
|
2266
|
+
}, [fallSpeed]);
|
|
2267
|
+
useEffect7(() => {
|
|
2268
|
+
const assets = snowRef.current;
|
|
2269
|
+
if (!assets) return;
|
|
2270
|
+
assets.uniforms.uWindStrength.value = windStrength + pointerWindOffsetRef.current;
|
|
2271
|
+
}, [windStrength]);
|
|
2272
|
+
useEffect7(() => {
|
|
2273
|
+
const assets = snowRef.current;
|
|
2274
|
+
if (!assets) return;
|
|
2275
|
+
assets.uniforms.uTurbulence.value = turbulence;
|
|
2276
|
+
}, [turbulence]);
|
|
2277
|
+
useEffect7(() => {
|
|
2278
|
+
const assets = snowRef.current;
|
|
2279
|
+
if (!assets) return;
|
|
2280
|
+
assets.uniforms.uSize.value = flakeSize;
|
|
2281
|
+
}, [flakeSize]);
|
|
2282
|
+
useEffect7(() => {
|
|
2283
|
+
const assets = snowRef.current;
|
|
2284
|
+
if (!assets) return;
|
|
2285
|
+
assets.uniforms.uTwinkleStrength.value = twinkleStrength;
|
|
2286
|
+
}, [twinkleStrength]);
|
|
2287
|
+
useEffect7(() => {
|
|
2288
|
+
const assets = snowRef.current;
|
|
2289
|
+
if (!assets) return;
|
|
2290
|
+
const geometry = createSnowGeometry(Math.max(1, Math.floor(flakeCount)));
|
|
2291
|
+
assets.points.geometry.dispose();
|
|
2292
|
+
assets.points.geometry = geometry;
|
|
2293
|
+
assets.geometry = geometry;
|
|
2294
|
+
}, [flakeCount]);
|
|
2295
|
+
useEffect7(() => {
|
|
2296
|
+
const pointerState = pointerStateRef.current;
|
|
2297
|
+
const clearTimeoutIfNeeded = () => {
|
|
2298
|
+
if (pointerState.timeoutId !== null) {
|
|
2299
|
+
window.clearTimeout(pointerState.timeoutId);
|
|
2300
|
+
pointerState.timeoutId = null;
|
|
2301
|
+
}
|
|
2302
|
+
};
|
|
2303
|
+
if (!mouseWindInteraction) {
|
|
2304
|
+
clearTimeoutIfNeeded();
|
|
2305
|
+
pointerWindOffsetRef.current = 0;
|
|
2306
|
+
pointerWindTargetRef.current = 0;
|
|
2307
|
+
pointerState.lastTime = 0;
|
|
2308
|
+
pointerActiveRef.current = false;
|
|
2309
|
+
const assets = snowRef.current;
|
|
2310
|
+
if (assets) {
|
|
2311
|
+
assets.uniforms.uWindStrength.value = windStrength;
|
|
2312
|
+
}
|
|
2313
|
+
return;
|
|
2314
|
+
}
|
|
2315
|
+
const container = containerRef.current;
|
|
2316
|
+
if (!container) return;
|
|
2317
|
+
const scheduleReset = () => {
|
|
2318
|
+
clearTimeoutIfNeeded();
|
|
2319
|
+
pointerState.timeoutId = window.setTimeout(() => {
|
|
2320
|
+
pointerWindTargetRef.current = 0;
|
|
2321
|
+
pointerState.timeoutId = null;
|
|
2322
|
+
}, 220);
|
|
2323
|
+
};
|
|
2324
|
+
const handlePointerMove = (event) => {
|
|
2325
|
+
const isMouse = event.pointerType === "mouse";
|
|
2326
|
+
if (!isMouse && !pointerActiveRef.current) return;
|
|
2327
|
+
const now = performance.now();
|
|
2328
|
+
if (pointerState.lastTime === 0) {
|
|
2329
|
+
pointerState.lastX = event.clientX;
|
|
2330
|
+
pointerState.lastTime = now;
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
const dx = event.clientX - pointerState.lastX;
|
|
2334
|
+
const dt = Math.max(1, now - pointerState.lastTime);
|
|
2335
|
+
const velocity = dx / dt;
|
|
2336
|
+
const offset = THREE7.MathUtils.clamp(velocity * 0.9, -1.6, 1.6);
|
|
2337
|
+
pointerWindTargetRef.current = offset;
|
|
2338
|
+
pointerState.lastX = event.clientX;
|
|
2339
|
+
pointerState.lastTime = now;
|
|
2340
|
+
scheduleReset();
|
|
2341
|
+
};
|
|
2342
|
+
const handlePointerDown = (event) => {
|
|
2343
|
+
pointerActiveRef.current = true;
|
|
2344
|
+
pointerState.lastX = event.clientX;
|
|
2345
|
+
pointerState.lastTime = performance.now();
|
|
2346
|
+
scheduleReset();
|
|
2347
|
+
};
|
|
2348
|
+
const handlePointerUp = () => {
|
|
2349
|
+
pointerActiveRef.current = false;
|
|
2350
|
+
pointerState.lastTime = 0;
|
|
2351
|
+
pointerWindTargetRef.current = 0;
|
|
2352
|
+
scheduleReset();
|
|
2353
|
+
};
|
|
2354
|
+
const handlePointerLeave = () => {
|
|
2355
|
+
pointerActiveRef.current = false;
|
|
2356
|
+
pointerState.lastTime = 0;
|
|
2357
|
+
pointerWindTargetRef.current = 0;
|
|
2358
|
+
clearTimeoutIfNeeded();
|
|
2359
|
+
};
|
|
2360
|
+
container.addEventListener("pointermove", handlePointerMove);
|
|
2361
|
+
container.addEventListener("pointerdown", handlePointerDown);
|
|
2362
|
+
container.addEventListener("pointerup", handlePointerUp);
|
|
2363
|
+
container.addEventListener("pointercancel", handlePointerUp);
|
|
2364
|
+
container.addEventListener("pointerout", handlePointerLeave);
|
|
2365
|
+
container.addEventListener("pointerleave", handlePointerLeave);
|
|
2366
|
+
return () => {
|
|
2367
|
+
container.removeEventListener("pointermove", handlePointerMove);
|
|
2368
|
+
container.removeEventListener("pointerdown", handlePointerDown);
|
|
2369
|
+
container.removeEventListener("pointerup", handlePointerUp);
|
|
2370
|
+
container.removeEventListener("pointercancel", handlePointerUp);
|
|
2371
|
+
container.removeEventListener("pointerout", handlePointerLeave);
|
|
2372
|
+
container.removeEventListener("pointerleave", handlePointerLeave);
|
|
2373
|
+
pointerState.lastTime = 0;
|
|
2374
|
+
pointerWindOffsetRef.current = 0;
|
|
2375
|
+
pointerWindTargetRef.current = 0;
|
|
2376
|
+
pointerActiveRef.current = false;
|
|
2377
|
+
clearTimeoutIfNeeded();
|
|
2378
|
+
const assets = snowRef.current;
|
|
2379
|
+
if (assets) {
|
|
2380
|
+
assets.uniforms.uWindStrength.value = windStrength;
|
|
2381
|
+
}
|
|
2382
|
+
};
|
|
2383
|
+
}, [containerRef, mouseWindInteraction, windStrength]);
|
|
2384
|
+
return /* @__PURE__ */ jsx8(
|
|
2385
|
+
"div",
|
|
2386
|
+
{
|
|
2387
|
+
ref: containerRef,
|
|
2388
|
+
className,
|
|
2389
|
+
style: {
|
|
2390
|
+
width: width ?? "100%",
|
|
2391
|
+
height: height ?? "100%",
|
|
2392
|
+
...style
|
|
2393
|
+
},
|
|
2394
|
+
...divProps
|
|
2395
|
+
}
|
|
2396
|
+
);
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
// src/components/AnimatedDrawingSVG.tsx
|
|
2400
|
+
import clsx from "clsx";
|
|
2401
|
+
import { useEffect as useEffect8, useLayoutEffect, useRef as useRef8 } from "react";
|
|
2402
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
2403
|
+
var PATH_SELECTOR = "path, line, polyline, polygon, circle, ellipse";
|
|
2404
|
+
function AnimatedDrawingSVG({
|
|
2405
|
+
svgMarkup,
|
|
2406
|
+
animated = true,
|
|
2407
|
+
size,
|
|
2408
|
+
onAnimated,
|
|
2409
|
+
delay,
|
|
2410
|
+
className,
|
|
2411
|
+
style,
|
|
2412
|
+
...divProps
|
|
2413
|
+
}) {
|
|
2414
|
+
const containerRef = useRef8(null);
|
|
2415
|
+
const animationsRef = useRef8([]);
|
|
2416
|
+
const parserRef = useRef8(null);
|
|
2417
|
+
const onAnimatedRef = useRef8(onAnimated);
|
|
2418
|
+
const animationRunIdRef = useRef8(0);
|
|
2419
|
+
const onAnimationCompleteRef = useRef8(false);
|
|
2420
|
+
const timeoutRef = useRef8([]);
|
|
2421
|
+
const monitorRafRef = useRef8(null);
|
|
2422
|
+
const sanitizedMarkup = (svgMarkup ?? "").toString().trim();
|
|
2423
|
+
const normalizedDelay = typeof delay === "number" && delay > 0 ? delay : 0;
|
|
2424
|
+
useEffect8(() => {
|
|
2425
|
+
onAnimatedRef.current = onAnimated;
|
|
2426
|
+
}, [onAnimated]);
|
|
2427
|
+
useEffect8(() => {
|
|
2428
|
+
return () => {
|
|
2429
|
+
animationsRef.current.forEach((animation) => animation.cancel());
|
|
2430
|
+
animationsRef.current = [];
|
|
2431
|
+
timeoutRef.current.forEach((id) => window.clearTimeout(id));
|
|
2432
|
+
timeoutRef.current = [];
|
|
2433
|
+
if (monitorRafRef.current !== null) {
|
|
2434
|
+
cancelAnimationFrame(monitorRafRef.current);
|
|
2435
|
+
monitorRafRef.current = null;
|
|
2436
|
+
}
|
|
2437
|
+
};
|
|
2438
|
+
}, []);
|
|
2439
|
+
useLayoutEffect(() => {
|
|
2440
|
+
const container = containerRef.current;
|
|
2441
|
+
if (!container) return;
|
|
2442
|
+
let rafId = null;
|
|
2443
|
+
let delayId = null;
|
|
2444
|
+
let started = false;
|
|
2445
|
+
if (normalizedDelay > 0) {
|
|
2446
|
+
container.style.visibility = "hidden";
|
|
2447
|
+
} else {
|
|
2448
|
+
container.style.removeProperty("visibility");
|
|
2449
|
+
}
|
|
2450
|
+
animationRunIdRef.current += 1;
|
|
2451
|
+
const currentRunId = animationRunIdRef.current;
|
|
2452
|
+
onAnimationCompleteRef.current = false;
|
|
2453
|
+
timeoutRef.current.forEach((id) => window.clearTimeout(id));
|
|
2454
|
+
timeoutRef.current = [];
|
|
2455
|
+
const markComplete = () => {
|
|
2456
|
+
if (animationRunIdRef.current === currentRunId && !onAnimationCompleteRef.current) {
|
|
2457
|
+
onAnimationCompleteRef.current = true;
|
|
2458
|
+
onAnimatedRef.current?.();
|
|
2459
|
+
}
|
|
2460
|
+
};
|
|
2461
|
+
animationsRef.current.forEach((animation) => animation.cancel());
|
|
2462
|
+
animationsRef.current = [];
|
|
2463
|
+
if (monitorRafRef.current !== null) {
|
|
2464
|
+
cancelAnimationFrame(monitorRafRef.current);
|
|
2465
|
+
monitorRafRef.current = null;
|
|
2466
|
+
}
|
|
2467
|
+
if (!sanitizedMarkup) {
|
|
2468
|
+
container.replaceChildren();
|
|
2469
|
+
markComplete();
|
|
2470
|
+
return;
|
|
2471
|
+
}
|
|
2472
|
+
const parser = parserRef.current ?? new DOMParser();
|
|
2473
|
+
parserRef.current = parser;
|
|
2474
|
+
let parsed;
|
|
2475
|
+
try {
|
|
2476
|
+
parsed = parser.parseFromString(sanitizedMarkup, "image/svg+xml");
|
|
2477
|
+
} catch {
|
|
2478
|
+
return;
|
|
2479
|
+
}
|
|
2480
|
+
if (parsed.querySelector("parsererror")) {
|
|
2481
|
+
return;
|
|
2482
|
+
}
|
|
2483
|
+
const parsedSvg = parsed.querySelector("svg");
|
|
2484
|
+
if (!parsedSvg) {
|
|
2485
|
+
container.replaceChildren();
|
|
2486
|
+
onAnimatedRef.current?.();
|
|
2487
|
+
return;
|
|
2488
|
+
}
|
|
2489
|
+
const svgElement = document.importNode(parsedSvg, true);
|
|
2490
|
+
svgElement.setAttribute("preserveAspectRatio", "xMidYMid meet");
|
|
2491
|
+
if (size !== void 0) {
|
|
2492
|
+
svgElement.removeAttribute("width");
|
|
2493
|
+
svgElement.removeAttribute("height");
|
|
2494
|
+
const sizeValue = typeof size === "number" ? `${Math.max(0, size)}px` : `${size}`;
|
|
2495
|
+
svgElement.style.width = sizeValue;
|
|
2496
|
+
svgElement.style.height = "auto";
|
|
2497
|
+
} else {
|
|
2498
|
+
svgElement.style.width = "100%";
|
|
2499
|
+
svgElement.style.height = "100%";
|
|
2500
|
+
svgElement.style.maxWidth = "100%";
|
|
2501
|
+
svgElement.style.maxHeight = "100%";
|
|
2502
|
+
}
|
|
2503
|
+
svgElement.style.display = "block";
|
|
2504
|
+
container.replaceChildren(svgElement);
|
|
2505
|
+
const runAnimations = () => {
|
|
2506
|
+
const drawTargets = Array.from(
|
|
2507
|
+
svgElement.querySelectorAll(PATH_SELECTOR)
|
|
2508
|
+
);
|
|
2509
|
+
const scheduleFallback = (delay2) => {
|
|
2510
|
+
const fallbackId = window.setTimeout(markComplete, delay2);
|
|
2511
|
+
timeoutRef.current.push(fallbackId);
|
|
2512
|
+
};
|
|
2513
|
+
if (!drawTargets.length) {
|
|
2514
|
+
if (!animated) {
|
|
2515
|
+
markComplete();
|
|
2516
|
+
} else {
|
|
2517
|
+
Promise.resolve().then(() => {
|
|
2518
|
+
markComplete();
|
|
2519
|
+
});
|
|
2520
|
+
}
|
|
2521
|
+
return;
|
|
2522
|
+
}
|
|
2523
|
+
let maxDuration = 0;
|
|
2524
|
+
const resolveTimingValue = (value, fallback) => {
|
|
2525
|
+
if (typeof value === "number") {
|
|
2526
|
+
return value;
|
|
2527
|
+
}
|
|
2528
|
+
if (typeof value === "string") {
|
|
2529
|
+
const parsed2 = Number.parseFloat(value);
|
|
2530
|
+
return Number.isFinite(parsed2) ? parsed2 : fallback;
|
|
2531
|
+
}
|
|
2532
|
+
if (typeof value === "object" && value !== null) {
|
|
2533
|
+
const parsed2 = Number.parseFloat(value.toString());
|
|
2534
|
+
return Number.isFinite(parsed2) ? parsed2 : fallback;
|
|
2535
|
+
}
|
|
2536
|
+
return fallback;
|
|
2537
|
+
};
|
|
2538
|
+
drawTargets.forEach((element, index) => {
|
|
2539
|
+
const length = typeof element.getTotalLength === "function" ? element.getTotalLength() : null;
|
|
2540
|
+
if (!length || Number.isNaN(length)) {
|
|
2541
|
+
element.style.removeProperty("stroke-dasharray");
|
|
2542
|
+
element.style.removeProperty("stroke-dashoffset");
|
|
2543
|
+
return;
|
|
2544
|
+
}
|
|
2545
|
+
const dashValue = `${length}`;
|
|
2546
|
+
element.style.strokeDasharray = dashValue;
|
|
2547
|
+
element.style.strokeDashoffset = animated ? dashValue : "0";
|
|
2548
|
+
if (!element.style.strokeLinecap) {
|
|
2549
|
+
element.style.strokeLinecap = "round";
|
|
2550
|
+
}
|
|
2551
|
+
if (!animated) {
|
|
2552
|
+
return;
|
|
2553
|
+
}
|
|
2554
|
+
const animation = element.animate(
|
|
2555
|
+
[{ strokeDashoffset: dashValue }, { strokeDashoffset: "0" }],
|
|
2556
|
+
{
|
|
2557
|
+
duration: Math.min(6500, Math.max(1200, length * 12)),
|
|
2558
|
+
delay: index * 120,
|
|
2559
|
+
easing: "ease-in-out",
|
|
2560
|
+
fill: "forwards"
|
|
2561
|
+
}
|
|
2562
|
+
);
|
|
2563
|
+
const timing = animation.effect?.getTiming();
|
|
2564
|
+
const baseDuration = Math.min(6500, Math.max(1200, length * 12));
|
|
2565
|
+
const total = resolveTimingValue(timing?.delay, index * 120) + resolveTimingValue(timing?.duration, baseDuration);
|
|
2566
|
+
if (total > maxDuration) {
|
|
2567
|
+
maxDuration = total;
|
|
2568
|
+
}
|
|
2569
|
+
animationsRef.current.push(animation);
|
|
2570
|
+
});
|
|
2571
|
+
if (!animated) {
|
|
2572
|
+
markComplete();
|
|
2573
|
+
return;
|
|
2574
|
+
}
|
|
2575
|
+
const startMonitor = () => {
|
|
2576
|
+
const monitor = () => {
|
|
2577
|
+
if (animationRunIdRef.current !== currentRunId) {
|
|
2578
|
+
return;
|
|
2579
|
+
}
|
|
2580
|
+
const allFinished = animationsRef.current.every((animation) => {
|
|
2581
|
+
const state = animation.playState;
|
|
2582
|
+
return state === "finished" || state === "idle";
|
|
2583
|
+
});
|
|
2584
|
+
if (allFinished) {
|
|
2585
|
+
if (monitorRafRef.current !== null) {
|
|
2586
|
+
cancelAnimationFrame(monitorRafRef.current);
|
|
2587
|
+
monitorRafRef.current = null;
|
|
2588
|
+
}
|
|
2589
|
+
markComplete();
|
|
2590
|
+
return;
|
|
2591
|
+
}
|
|
2592
|
+
monitorRafRef.current = requestAnimationFrame(monitor);
|
|
2593
|
+
};
|
|
2594
|
+
if (monitorRafRef.current !== null) {
|
|
2595
|
+
cancelAnimationFrame(monitorRafRef.current);
|
|
2596
|
+
}
|
|
2597
|
+
monitorRafRef.current = requestAnimationFrame(monitor);
|
|
2598
|
+
};
|
|
2599
|
+
startMonitor();
|
|
2600
|
+
if (animated && maxDuration > 0) {
|
|
2601
|
+
scheduleFallback(maxDuration + 50);
|
|
2602
|
+
}
|
|
2603
|
+
};
|
|
2604
|
+
const triggerStart = () => {
|
|
2605
|
+
if (started) return;
|
|
2606
|
+
started = true;
|
|
2607
|
+
container.style.removeProperty("visibility");
|
|
2608
|
+
rafId = requestAnimationFrame(runAnimations);
|
|
2609
|
+
};
|
|
2610
|
+
if (normalizedDelay > 0) {
|
|
2611
|
+
delayId = window.setTimeout(triggerStart, normalizedDelay);
|
|
2612
|
+
} else {
|
|
2613
|
+
triggerStart();
|
|
2614
|
+
}
|
|
2615
|
+
return () => {
|
|
2616
|
+
if (delayId !== null) {
|
|
2617
|
+
window.clearTimeout(delayId);
|
|
2618
|
+
}
|
|
2619
|
+
if (rafId !== null) {
|
|
2620
|
+
cancelAnimationFrame(rafId);
|
|
2621
|
+
}
|
|
2622
|
+
};
|
|
2623
|
+
}, [sanitizedMarkup, animated, size, normalizedDelay]);
|
|
2624
|
+
return /* @__PURE__ */ jsx9(
|
|
2625
|
+
"div",
|
|
2626
|
+
{
|
|
2627
|
+
ref: containerRef,
|
|
2628
|
+
className: clsx(
|
|
2629
|
+
"flex items-center justify-center [&_svg]:block",
|
|
2630
|
+
className
|
|
2631
|
+
),
|
|
2632
|
+
style: {
|
|
2633
|
+
...style
|
|
2634
|
+
},
|
|
2635
|
+
...divProps
|
|
2636
|
+
}
|
|
2637
|
+
);
|
|
2638
|
+
}
|
|
2093
2639
|
export {
|
|
2640
|
+
AnimatedDrawingSVG,
|
|
2094
2641
|
EFECTO_ASCII_COMPONENT_DEFAULTS,
|
|
2095
2642
|
EFECTO_ASCII_POST_PROCESSING_DEFAULTS,
|
|
2096
2643
|
Efecto,
|
|
2097
2644
|
FractalFlower,
|
|
2098
2645
|
MenuGlitch,
|
|
2099
2646
|
OranoParticles,
|
|
2100
|
-
ShaderArt
|
|
2647
|
+
ShaderArt,
|
|
2648
|
+
Snow
|
|
2101
2649
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toriistudio/shader-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Shader components",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"homepage": "https://github.com/toriistudio/shader-ui#readme",
|
|
56
56
|
"peerDependencies": {
|
|
57
|
+
"clsx": "^2.1.1",
|
|
57
58
|
"gsap": ">=3.14.2",
|
|
58
59
|
"postprocessing": ">=6.38.1",
|
|
59
60
|
"react": ">=19 <20",
|
|
@@ -74,6 +75,7 @@
|
|
|
74
75
|
"@types/react": "^19.0.0",
|
|
75
76
|
"@types/react-dom": "^19.0.0",
|
|
76
77
|
"@types/three": "^0.177.0",
|
|
78
|
+
"clsx": "^2.1.1",
|
|
77
79
|
"gsap": "^3.14.2",
|
|
78
80
|
"postprocessing": "^6.38.1",
|
|
79
81
|
"three": "^0.177.0",
|