Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5c7f3c0

Browse files
committed
make wiggle transition also wiggle
1 parent 378ae27 commit 5c7f3c0

File tree

5 files changed

+66
-44
lines changed

5 files changed

+66
-44
lines changed

‎demo/content.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -878,10 +878,11 @@ addCanvas(
878878
animation.transition({
879879
points: pointy,
880880
duration: 1000,
881-
callback: () => animation.transition({
882-
points: wobblyGerm,
883-
duration: 4000,
884-
}),
881+
callback: () =>
882+
animation.transition({
883+
points: wobblyGerm,
884+
duration: 4000,
885+
}),
885886
});
886887

887888
animate(() => drawClosed(ctx, animation.renderPoints(), true));

‎demo/example.ts

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {CanvasKeyframe, canvasPath, wigglePreset} from "../public/animate";
2-
import {drawDebugClosed, drawPoint} from "./internal/canvas";
2+
import {drawHandles, drawPoint} from "./internal/canvas";
3+
import {isDebug} from "./internal/debug";
34
import {colors} from "./internal/layout";
45

56
// Fetch reference to example container.
@@ -32,22 +33,12 @@ const renderFrame = () => {
3233
ctx.fillStyle = colors.highlight;
3334
ctx.strokeStyle = colors.highlight;
3435

35-
// Debug
36-
if (false) {
37-
const p = (animation as any).renderPoints();
38-
39-
drawDebugClosed(ctx, p, 60);
40-
if (p.length) drawPoint(ctx, p[0], 400);
41-
42-
const handleLength = p[0]?.handleIn.length;
43-
if (handleLength < 100) {
44-
console.log("shorty detected: ", handleLength);
45-
return;
36+
if (isDebug()) {
37+
const points = animation.renderPoints();
38+
for (const point of points) {
39+
drawPoint(ctx, point, 2);
40+
drawHandles(ctx, point, 1);
4641
}
47-
48-
const fps = 20;
49-
setTimeout(() => requestAnimationFrame(renderFrame), 1000 / fps);
50-
return;
5142
}
5243

5344
ctx.fill(animation.renderFrame());
@@ -68,7 +59,7 @@ const genWiggle = (transition: number) => {
6859
size,
6960
},
7061
{},
71-
{speed: 2, initialTransition: transition,initialTimingFunction: "ease"},
62+
{speed: 2, initialTransition: transition},
7263
);
7364
};
7465

@@ -93,7 +84,7 @@ const genFrame = (overrides: any = {}): CanvasKeyframe => {
9384
// Callback for every frame which starts transition to a new frame.
9485
const loopAnimation = (): void => {
9586
extraPoints = 0;
96-
genWiggle(4000);
87+
genWiggle(2000);
9788
};
9889

9990
// Quickly animate to a new frame when canvas is clicked.

‎demo/internal/debug.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// If debug is initially set to false it will not be toggleable.
2-
let debug = true && location.hostname === "localhost";
2+
let debug = window.location.search.includes("debug") && location.hostname === "localhost";
33
export const isDebug = () => debug;
44

55
const debugListeners: ((debug: boolean) => void)[] = [];

‎internal/animate/state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const statefulAnimationGenerator = <K extends CallbackKeyframe, T>(
5555

5656
// Invoke callback if defined and the first time the frame is reached.
5757
if (renderOutput.lastFrameId && frameCallbackStore[renderOutput.lastFrameId]) {
58-
frameCallbackStore[renderOutput.lastFrameId]();
58+
setTimeout(frameCallbackStore[renderOutput.lastFrameId]);
5959
delete frameCallbackStore[renderOutput.lastFrameId];
6060
}
6161

‎public/animate.ts

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {
1111
} from "../internal/check";
1212
import {BlobOptions, CanvasOptions} from "./blobs";
1313
import {noise} from "../internal/rand";
14+
import {interpolateBetween} from "../internal/animate/interpolate";
15+
import {prepare} from "../internal/animate/prepare";
1416

1517
interface Keyframe {
1618
// Duration of the keyframe animation in milliseconds.
@@ -82,15 +84,9 @@ export interface TimestampProvider {
8284
export interface WiggleOptions {
8385
// Speed of the wiggle movement. Higher is faster.
8486
speed: number;
85-
// Delay before the first wiggle frame.
86-
// Default: 0
87-
initialDelay?: number;
8887
// Length of the transition from the current state to the wiggle blob.
8988
// Default: 0
9089
initialTransition?: number;
91-
// Interpolation function.
92-
// Default: linear
93-
initialTimingFunction?: Keyframe["timingFunction"];
9490
}
9591

9692
const canvasPointGenerator = (keyframe: CanvasKeyframe | CanvasCustomKeyframe): Point[] => {
@@ -147,27 +143,61 @@ export const wigglePreset = (
147143
canvasOptions: CanvasOptions,
148144
wiggleOptions: WiggleOptions,
149145
) => {
150-
const leapSize = 0.01 * wiggleOptions.speed;
151-
152146
// Interval at which a new sample is taken.
153147
// Multiple of 16 to do work every N frames.
154148
const intervalMs = 16 * 5;
155-
149+
constleapSize=0.01*wiggleOptions.speed;
156150
const noiseField = noise(String(blobOptions.seed));
157151

152+
const transitionFrameCount = 1 + Math.min((wiggleOptions.initialTransition || 0) / intervalMs);
153+
let transitionStartFrame = animation.renderPoints();
154+
158155
let count = 0;
159-
const loopAnimation = (first?: boolean,delay?: number) => {
156+
const loopAnimation = () => {
160157
count++;
161-
animation.transition({
162-
duration: first ? wiggleOptions.initialTransition || 0 : intervalMs,
163-
delay: delay || 0,
164-
timingFunction: (first && wiggleOptions.initialTimingFunction) || "linear",
165-
canvasOptions,
166-
points: genFromOptions(blobOptions, (index) => {
167-
return noiseField(leapSize * count, index);
168-
}),
169-
callback: loopAnimation,
158+
159+
// Constantly changing blob.
160+
const noiseBlob = genFromOptions(blobOptions, (index) => {
161+
return noiseField(leapSize * count, index);
170162
});
163+
164+
if (count < transitionFrameCount) {
165+
// Create intermediate frame between the current state and the
166+
// moving noiseBlob target.
167+
const [preparedStartPoints, preparedEndPoints] = prepare(
168+
transitionStartFrame,
169+
noiseBlob,
170+
{
171+
rawAngles: true,
172+
divideRatio: 1,
173+
},
174+
);
175+
const progress = 1 / (transitionFrameCount - count);
176+
const targetPoints = interpolateBetween(
177+
progress,
178+
preparedStartPoints,
179+
preparedEndPoints,
180+
);
181+
transitionStartFrame = targetPoints;
182+
183+
animation.transition({
184+
duration: intervalMs,
185+
delay: 0,
186+
timingFunction: "linear",
187+
canvasOptions,
188+
points: targetPoints,
189+
callback: loopAnimation,
190+
});
191+
} else {
192+
animation.transition({
193+
duration: intervalMs,
194+
delay: 0,
195+
timingFunction: "linear",
196+
canvasOptions,
197+
points: noiseBlob,
198+
callback: loopAnimation,
199+
});
200+
}
171201
};
172-
loopAnimation(true,wiggleOptions.initialDelay);
202+
loopAnimation();
173203
};

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /