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 7f166b7

Browse files
committed
update content
1 parent d3bfbf1 commit 7f166b7

File tree

1 file changed

+114
-104
lines changed

1 file changed

+114
-104
lines changed

‎demo/content.ts

Lines changed: 114 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -554,113 +554,19 @@ addCanvas(2, (ctx, width, height, animate) => {
554554
drawClosed(ctx, interpolateBetween(percentage, blobA, blobB), true);
555555
});
556556

557-
return `Interpolation requires points to be paired up from shape A to B. This means both blobs
558-
must have the same number of points and that the points should be matched in a way that
559-
minimizes movement.`;
557+
return `The simplest way to interpolate between blobs would be to move the points that make up
558+
the blob between the two shapes while running the smoothing pass every frame. The problem
559+
with this approach is that it doesn't allow for any blob to map to any blob. Specifically it
560+
would only be possible to animate between blobs that have the same number of points. This
561+
means something more generic is required.`;
560562
});
561563

562564
addCanvas(
563565
1.3,
564566
(ctx, width, height, animate) => {
565-
const period = (Math.E / Math.PI) * 1000;
566567
const center: Coord = {x: width * 0.5, y: height * 0.5};
567-
568-
const blob = centeredBlob(
569-
{
570-
extraPoints: 3,
571-
randomness: 6,
572-
seed: "shift",
573-
size: height * 0.9,
574-
},
575-
center,
576-
);
577-
578-
const shiftedBlob = shift(1, blob);
579-
580-
let prev = 0;
581-
let count = 0;
582-
animate((frameTime) => {
583-
const animationTime = mod(frameTime, period);
584-
const percentage = timingFunctions.ease(mod(animationTime, period) / period);
585-
586-
// Count animation loops.
587-
if (percentage < prev) count++;
588-
prev = percentage;
589-
590-
// Draw lines points are travelling.
591-
tempStyles(
592-
ctx,
593-
() => {
594-
ctx.fillStyle = colors.secondary;
595-
ctx.strokeStyle = colors.secondary;
596-
},
597-
() => {
598-
drawPoint(ctx, center, 2);
599-
forPoints(blob, ({curr, next}) => {
600-
drawLine(ctx, curr, next(), 1, 2);
601-
});
602-
},
603-
);
604-
605-
// Pause in-place every other animation loop.
606-
if (count % 2 === 0) {
607-
drawClosed(ctx, interpolateBetweenSmooth(2, percentage, blob, shiftedBlob), true);
608-
} else {
609-
drawClosed(ctx, blob, true);
610-
}
611-
});
612-
613-
return `Points cannot be swapped without resulting in a different shape. However, a likely
614-
enough optimal order can be selected by shifting the points and comparing the point
615-
position deltas.`;
616-
},
617-
(ctx, width, height, animate) => {
618-
const period = Math.PI * Math.E * 1000;
619-
const center: Coord = {x: width * 0.5, y: height * 0.5};
620-
621-
const blob = centeredBlob(
622-
{
623-
extraPoints: 3,
624-
randomness: 6,
625-
seed: "flip",
626-
size: height * 0.9,
627-
},
628-
center,
629-
);
630-
const reversedBlob = mapPoints(blob, ({curr}) => {
631-
const temp = curr.handleIn;
632-
curr.handleIn = curr.handleOut;
633-
curr.handleOut = temp;
634-
return curr;
635-
});
636-
reversedBlob.reverse();
637-
638-
animate((frameTime) => {
639-
const percentage = calcBouncePercentage(period, timingFunctions.ease, frameTime);
640-
641-
forceStyles(ctx, () => {
642-
const {pt} = sizes();
643-
ctx.fillStyle = "transparent";
644-
ctx.lineWidth = pt;
645-
ctx.strokeStyle = colors.secondary;
646-
ctx.setLineDash([2 * pt]);
647-
drawClosed(ctx, blob, false);
648-
});
649-
650-
drawClosed(ctx, interpolateBetweenSmooth(2, percentage, blob, reversedBlob), true);
651-
});
652-
653-
return `The only safe re-ordering is to reverse the points and again iterate through all
654-
possible shifts.`;
655-
},
656-
);
657-
658-
addCanvas(
659-
1.3,
660-
(ctx, width, height, animate) => {
661-
const period = Math.PI * 1000;
662-
const center: Coord = {x: width * 0.5, y: height * 0.5};
663-
const maxExtraPoints = 4;
568+
const maxExtraPoints = 7;
569+
const period = maxExtraPoints * Math.PI * 400;
664570
const {pt} = sizes();
665571

666572
const blob = centeredBlob(
@@ -695,8 +601,12 @@ addCanvas(
695601
});
696602
});
697603

698-
return `Points are added until they both have the same count. These new points should be as
699-
evenly distributed as possible.`;
604+
return `The first step to prepare animation is to make the number of points between the
605+
start and end shapes equal. This is done by adding points to the shape with least points
606+
until they are both equal.
607+
<br><br>
608+
For best animation quality it is important that these points are as evenly distributed
609+
as possible all around the shape so this is not a recursive algorithm.`;
700610
},
701611
(ctx, width, height, animate) => {
702612
const period = Math.PI ** Math.E * 1000;
@@ -759,11 +669,111 @@ addCanvas(
759669
);
760670
});
761671

762-
return `Curve splitting uses the innermost line from the cubic bezier curve drawing demo and
672+
return `It is only possible to reliably <i>add</i> points to a blob because attempting to
673+
remove points without modifying the shape is almost never possible and is expensive to
674+
compute.
675+
676+
Curve splitting uses the innermost line from the cubic bezier curve drawing demo and
763677
makes either side of the final point the handles.`;
764678
},
765679
);
766680

681+
addCanvas(
682+
1.3,
683+
(ctx, width, height, animate) => {
684+
const period = (Math.E / Math.PI) * 1000;
685+
const center: Coord = {x: width * 0.5, y: height * 0.5};
686+
687+
const blob = centeredBlob(
688+
{
689+
extraPoints: 3,
690+
randomness: 6,
691+
seed: "shift",
692+
size: height * 0.9,
693+
},
694+
center,
695+
);
696+
697+
const shiftedBlob = shift(1, blob);
698+
699+
let prev = 0;
700+
let count = 0;
701+
animate((frameTime) => {
702+
const animationTime = mod(frameTime, period);
703+
const percentage = timingFunctions.ease(mod(animationTime, period) / period);
704+
705+
// Count animation loops.
706+
if (percentage < prev) count++;
707+
prev = percentage;
708+
709+
// Draw lines points are travelling.
710+
tempStyles(
711+
ctx,
712+
() => {
713+
ctx.fillStyle = colors.secondary;
714+
ctx.strokeStyle = colors.secondary;
715+
},
716+
() => {
717+
drawPoint(ctx, center, 2);
718+
forPoints(blob, ({curr, next}) => {
719+
drawLine(ctx, curr, next(), 1, 2);
720+
});
721+
},
722+
);
723+
724+
// Pause in-place every other animation loop.
725+
if (count % 2 === 0) {
726+
drawClosed(ctx, interpolateBetweenSmooth(2, percentage, blob, shiftedBlob), true);
727+
} else {
728+
drawClosed(ctx, blob, true);
729+
}
730+
});
731+
732+
return `Points cannot be swapped without resulting in a different shape. However, a likely
733+
enough optimal order can be selected by shifting the points and comparing the point
734+
position deltas.`;
735+
},
736+
(ctx, width, height, animate) => {
737+
const period = Math.PI * Math.E * 1000;
738+
const center: Coord = {x: width * 0.5, y: height * 0.5};
739+
740+
const blob = centeredBlob(
741+
{
742+
extraPoints: 3,
743+
randomness: 6,
744+
seed: "flip",
745+
size: height * 0.9,
746+
},
747+
center,
748+
);
749+
const reversedBlob = mapPoints(blob, ({curr}) => {
750+
const temp = curr.handleIn;
751+
curr.handleIn = curr.handleOut;
752+
curr.handleOut = temp;
753+
return curr;
754+
});
755+
reversedBlob.reverse();
756+
757+
animate((frameTime) => {
758+
const percentage = calcBouncePercentage(period, timingFunctions.ease, frameTime);
759+
760+
forceStyles(ctx, () => {
761+
const {pt} = sizes();
762+
ctx.fillStyle = "transparent";
763+
ctx.lineWidth = pt;
764+
ctx.strokeStyle = colors.secondary;
765+
ctx.setLineDash([2 * pt]);
766+
drawClosed(ctx, blob, false);
767+
});
768+
769+
drawClosed(ctx, interpolateBetweenSmooth(2, percentage, blob, reversedBlob), true);
770+
});
771+
772+
return `The only safe re-ordering is to reverse the points and again iterate through all
773+
possible shifts.`;
774+
},
775+
);
776+
767777
addCanvas(1.8, (ctx, width, height) => {
768778
// Only animate in the most recent painter call.
769779
const animationID = Math.random();

0 commit comments

Comments
(0)

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