mirror of
https://github.com/hex248/tsos.git
synced 2026-02-07 18:23:05 +00:00
wobbleRandomness
interpolates between noise and sine wave
This commit is contained in:
@@ -70,6 +70,15 @@ function Index() {
|
|||||||
onValueChange={([v]) => setState({ ...state, wobbleSpeed: v })}
|
onValueChange={([v]) => setState({ ...state, wobbleSpeed: v })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<span className="text-sm font-medium">Wobble Randomness</span>
|
||||||
|
<Slider
|
||||||
|
value={[state.wobbleRandomness]}
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
onValueChange={([v]) => setState({ ...state, wobbleRandomness: v })}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -46,9 +46,10 @@ export default function MorphableShape({
|
|||||||
|
|
||||||
const flatPoints = useMemo(() => {
|
const flatPoints = useMemo(() => {
|
||||||
const wobbleAmount = state.wobble * 0.3; // scale wobble to reasonable range
|
const wobbleAmount = state.wobble * 0.3; // scale wobble to reasonable range
|
||||||
const wobbled = applyWobble(morphedPoints, time, wobbleAmount);
|
const randomness = state.wobbleRandomness / 100;
|
||||||
|
const wobbled = applyWobble(morphedPoints, time, wobbleAmount, randomness);
|
||||||
return wobbled.flatMap((p) => [p.x, p.y]);
|
return wobbled.flatMap((p) => [p.x, p.y]);
|
||||||
}, [morphedPoints, time, state.wobble]);
|
}, [morphedPoints, time, state.wobble, state.wobbleRandomness]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group x={state.x} y={state.y} draggable onDragMove={handleDrag}>
|
<Group x={state.x} y={state.y} draggable onDragMove={handleDrag}>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState, useEffect, useRef } from "react";
|
|
||||||
import type { ShapeState } from "@/types/shape";
|
import type { ShapeState } from "@/types/shape";
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
const DEFAULT_STATE: ShapeState = {
|
const DEFAULT_STATE: ShapeState = {
|
||||||
x: 0,
|
x: 0,
|
||||||
@@ -9,6 +9,7 @@ const DEFAULT_STATE: ShapeState = {
|
|||||||
size: 50, // medium
|
size: 50, // medium
|
||||||
wobble: 20, // subtle
|
wobble: 20, // subtle
|
||||||
wobbleSpeed: 50, // medium
|
wobbleSpeed: 50, // medium
|
||||||
|
wobbleRandomness: 50, // medium
|
||||||
grain: 0, // none
|
grain: 0, // none
|
||||||
color: "#FF0000", // red (C)
|
color: "#FF0000", // red (C)
|
||||||
octave: 4, // middle octave
|
octave: 4, // middle octave
|
||||||
@@ -26,6 +27,7 @@ export function useShapeState(centerX: number, centerY: number) {
|
|||||||
x: centerX,
|
x: centerX,
|
||||||
y: centerY,
|
y: centerY,
|
||||||
});
|
});
|
||||||
|
void initialStateRef;
|
||||||
|
|
||||||
// update center position when canvas resizes
|
// update center position when canvas resizes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -2,14 +2,22 @@ import { noise2D } from "@/lib/noise";
|
|||||||
import type { Point } from "./points";
|
import type { Point } from "./points";
|
||||||
|
|
||||||
// apply noise-based displacement to points. this gives a wobble effect. points are displaced radially
|
// apply noise-based displacement to points. this gives a wobble effect. points are displaced radially
|
||||||
export function applyWobble(points: Point[], time: number, amount: number, noiseScale = 0.5): Point[] {
|
export function applyWobble(
|
||||||
|
points: Point[],
|
||||||
|
time: number,
|
||||||
|
amount: number,
|
||||||
|
randomness: number,
|
||||||
|
noiseScale = 0.5,
|
||||||
|
): Point[] {
|
||||||
if (amount === 0) return points;
|
if (amount === 0) return points;
|
||||||
|
|
||||||
return points.map((point, i) => {
|
return points.map((point, i) => {
|
||||||
// use point index and time for noise input
|
|
||||||
const noiseX = i * noiseScale;
|
const noiseX = i * noiseScale;
|
||||||
const noiseY = time;
|
const noiseY = time;
|
||||||
const displacement = noise2D(noiseX, noiseY) * amount;
|
const noiseValue = noise2D(noiseX, noiseY);
|
||||||
|
const sineValue = Math.sin(time * 2 + i * noiseScale);
|
||||||
|
const blended = sineValue * (1 - randomness) + noiseValue * randomness;
|
||||||
|
const displacement = blended * amount;
|
||||||
|
|
||||||
const angle = Math.atan2(point.y, point.x);
|
const angle = Math.atan2(point.y, point.x);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export interface ShapeState {
|
|||||||
size: number; // 0-100, controls volume
|
size: number; // 0-100, controls volume
|
||||||
wobble: number; // 0-100, visual wobble amount
|
wobble: number; // 0-100, visual wobble amount
|
||||||
wobbleSpeed: number; // 0-100, wobble animation speed
|
wobbleSpeed: number; // 0-100, wobble animation speed
|
||||||
|
wobbleRandomness: number; // 0-100, noise vs sine blend
|
||||||
grain: number; // 0-100, noise mix
|
grain: number; // 0-100, noise mix
|
||||||
color: string; // hex color from clavier keyboard
|
color: string; // hex color from clavier keyboard
|
||||||
octave: number; // 1-8, frequency multiplier
|
octave: number; // 1-8, frequency multiplier
|
||||||
|
|||||||
Reference in New Issue
Block a user