Skip to content

Instantly share code, notes, and snippets.

@GMartigny
Created December 8, 2019 23:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GMartigny/94b9d76f647f4a242c6e249390f795cb to your computer and use it in GitHub Desktop.
Save GMartigny/94b9d76f647f4a242c6e249390f795cb to your computer and use it in GitHub Desktop.
Looping exploding dots
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Chaos</title>
</head>
<body>
<script src="https://unpkg.com/pencil.js"></script>
<script src="https://unpkg.com/@pencil.js/gif"></script>
<script>
const { gif, OffScreenCanvas, Circle, RegularPolygon, Position, Math: M } = Pencil;
const scene = new OffScreenCanvas(568, 350, {
fill: "#222",
});
const { width, height } = scene;
const pointsOptions = {
fill: "#fff",
};
const pointsRadius = 5;
const points = [];
const nbCircles = 21;
const margin = (height / 2) / nbCircles;
const norm = new Position(1, 0);
for (let i = 3; i < nbCircles; ++i) {
const nbPoints = i * 3;
const circles = RegularPolygon.getRotatingPoints(nbPoints, i * margin, i / (nbCircles * 3))
.map((circle, j) => {
const radius = M.map((i / nbCircles) ** 3, 0, 1, pointsRadius, 1);
const targets = [
circle.add(scene.center),
new Position((j + 0.5) * (width / nbPoints), (i - 0.5) * (height / nbCircles)),
];
const speed = norm.clone().rotate(M.random()).multiply(radius * 3);
const delay = M.random(10);
return new Circle(targets[targets.length - 1].clone(), radius, {
...pointsOptions,
opacity: radius / pointsRadius,
targets,
speed,
delay,
});
});
points.push(...circles);
}
scene.add(...points);
const nbFrames = 500;
const easeInOut = (t) => {
return t < 0.5 ?
4 * (t ** 3) :
(0.5 * (((2 * t) - 2) ** 3)) + 1;
};
scene.on("draw", () => {
const movingFrames = nbFrames / 4;
points.forEach((point) => {
const to = point.options.targets[(Math.floor(point.frameCount / movingFrames) / 2) - 0.5];
const time = Math.max(0, ((point.frameCount % movingFrames) / movingFrames) - (point.options.delay / movingFrames));
if (to) {
const ratio = easeInOut(time);
point.position.lerp(to, ratio);
}
else {
point.position.add(point.options.speed.clone().multiply((1 - time) ** 2));
}
});
}, true);
console.log("Working ...");
console.time("gif");
gif(scene, nbFrames).then((img) => {
console.timeEnd("gif");
document.body.appendChild(img);
});
</script>
</body>
</html>
@GMartigny
Copy link
Author

chaos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment