Skip to content

Commit 27a01ee

Browse files
committed
add point adding animation loop
1 parent 8df064e commit 27a01ee

File tree

2 files changed

+72
-7
lines changed

2 files changed

+72
-7
lines changed

demo/content.ts

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import {genFromOptions} from "../internal/gen";
2727
import {BlobOptions} from "../public/blobs";
2828
import {interpolateBetween, interpolateBetweenSmooth} from "../internal/animate/interpolate";
2929
import {divide} from "../internal/animate/prepare";
30+
import {statefulAnimationGenerator} from "../internal/animate/state";
31+
import {CanvasKeyframe} from "../public/animate";
3032

3133
const makePoly = (pointCount: number, radius: number, center: Coord): Point[] => {
3234
const angle = (2 * Math.PI) / pointCount;
@@ -127,20 +129,28 @@ addCanvas(
127129
);
128130

129131
addCanvas(2, (ctx, width, height, animate) => {
130-
const startPeriod = Math.E * 1000;
131-
const endPeriod = Math.PI * 1000;
132+
const startPeriod = (1 + Math.E) * 1000;
133+
const endPeriod = (1 + Math.PI) * 1000;
132134

133135
animate((frameTime) => {
134136
const startPercentage = calcBouncePercentage(startPeriod, timingFunctions.ease, frameTime);
137+
const startLengthPercentage = calcBouncePercentage(
138+
startPeriod * 0.8,
139+
timingFunctions.ease,
140+
frameTime,
141+
);
135142
const startAngle = split(startPercentage, -45, +45);
136-
const startLengthPercentage = mod(startPercentage * 0.8, 1);
137-
const startLength = width * 0.2 + width * 0.1 * startLengthPercentage;
143+
const startLength = width * 0.1 + width * 0.2 * startLengthPercentage;
138144
const start = point(width * 0.2, height * 0.5, 0, 0, startAngle, startLength);
139145

140146
const endPercentage = calcBouncePercentage(endPeriod, timingFunctions.ease, frameTime);
147+
const endLengthPercentage = calcBouncePercentage(
148+
endPeriod * 0.8,
149+
timingFunctions.ease,
150+
frameTime,
151+
);
141152
const endAngle = split(endPercentage, 135, 225);
142-
const endLengthPercentage = mod(endPercentage * 0.8, 1);
143-
const endLength = width * 0.2 + width * 0.1 * endLengthPercentage;
153+
const endLength = width * 0.1 + width * 0.2 * endLengthPercentage;
144154
const end = point(width * 0.8, height * 0.5, endAngle, endLength, 0, 0);
145155

146156
drawOpen(ctx, start, end, true);
@@ -416,7 +426,6 @@ addCanvas(2, (ctx, width, height, animate) => {
416426
drawClosed(ctx, interpolateBetween(percentage, blobA, blobB), true);
417427
});
418428

419-
// TODO have content about why being able to interrupt transitions with another.
420429
return `Interpolation requires points to be paired up from shape A to B. This means both blobs
421430
must have the same number of points and that the points should be matched in a way that
422431
minimizes movement.`;
@@ -627,3 +636,54 @@ addCanvas(
627636
makes either side of the final point the handles.`;
628637
},
629638
);
639+
640+
addCanvas(1.6, (ctx, width, height) => {
641+
const period = Math.PI * 1000;
642+
const center: Coord = {x: width * 0.5, y: height * 0.5};
643+
const size = Math.min(width, height) * 0.8;
644+
645+
const canvasBlobGenerator = (keyframe: CanvasKeyframe): Point[] => {
646+
return mapPoints(genFromOptions(keyframe.blobOptions), ({curr}) => {
647+
curr.x += center.x - size / 2;
648+
curr.y += center.y - size / 2;
649+
return curr;
650+
});
651+
};
652+
653+
const animation = statefulAnimationGenerator(
654+
canvasBlobGenerator,
655+
(points: Point[]) => drawClosed(ctx, points, true),
656+
() => {},
657+
)();
658+
659+
const renderFrame = () => {
660+
ctx.clearRect(0, 0, width, height);
661+
animation.renderFrame();
662+
requestAnimationFrame(renderFrame);
663+
};
664+
requestAnimationFrame(renderFrame);
665+
666+
const loopAnimation = (): void => animation.transition(genFrame());
667+
668+
let frameCount = -1;
669+
const genFrame = (overrides: Partial<CanvasKeyframe> = {}): CanvasKeyframe => {
670+
frameCount++;
671+
return {
672+
duration: period,
673+
timingFunction: "ease",
674+
callback: loopAnimation,
675+
blobOptions: {
676+
extraPoints: Math.max(0, mod(frameCount, 4) - 1),
677+
randomness: 4,
678+
seed: Math.random(),
679+
size,
680+
},
681+
...overrides,
682+
};
683+
};
684+
685+
animation.transition(genFrame({duration: 0}));
686+
687+
// TODO have content about why being able to interrupt transitions with another.
688+
return ``;
689+
});

demo/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<html>
22
<head>
3+
<!-- TODO favicon -->
34
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
45
<style>
56
html {
@@ -33,6 +34,8 @@
3334
padding: 0.5rem;
3435
text-decoration: none;
3536
text-transform: uppercase;
37+
user-select: none;
38+
-moz-user-select: none;
3639
}
3740

3841
main {
@@ -144,5 +147,7 @@
144147
</main>
145148
<script src="./example.ts"></script>
146149
<script src="./content.ts"></script>
150+
<!-- TODO suggestions -->
151+
<!-- TODO mobile -->
147152
</body>
148153
</html>

0 commit comments

Comments
 (0)