Antonio Mika
·
11 Oct 24
anim.js
1document.addEventListener("DOMContentLoaded", init);
2const raf = window.requestAnimationFrame;
3
4function init() {
5 const canvas = document.getElementById("canvas");
6 const ctx = canvas.getContext("2d");
7 const data = {
8 ctx,
9 // speed of movement (higher = faster)
10 speed: 200,
11 frame: 1,
12 prev: 0,
13 cur: 0,
14 // boundary balls can traverse inside canvas
15 minY: -20,
16 maxY: canvas.height + 20,
17 // balls
18 entities: [
19 { x: 18, y: 0, mod: 1 },
20 // { x: 25, y: canvas.height / 2, mod: 1 },
21 { x: 32, y: canvas.height, mod: -1 },
22 ],
23 };
24
25 raf(tick(data));
26}
27
28function tick(data) {
29 return (ms) => {
30 const prev = data.cur;
31 const cur = ms * 0.001;
32 const next = {
33 ...data,
34 prev,
35 cur,
36 frame: data.frame + 1,
37 delta: cur - prev,
38 };
39 return loop(next);
40 };
41}
42
43function loop(data) {
44 const { ctx, entities, speed, delta, minY, maxY } = data;
45 const width = ctx.canvas.width;
46 const height = ctx.canvas.height;
47 ctx.clearRect(0, 0, width, height);
48
49 for (let i = 0; i < entities.length; i += 1) {
50 const entity = entities[i];
51 const x = entity.x;
52 const y = entity.y + (speed * delta * entity.mod);
53 const nextMod = () => {
54 if (y < minY) return 1;
55 if (y > maxY) return -1;
56 return entity.mod;
57 };
58
59 // grace for entire ball to leave scene
60 // const buffer = 25
61 // dont bother drawing circle if outside canvas
62 // if (y + buffer >= 0 && y - buffer <= height) {
63 ball(ctx, x, y);
64 // }
65
66 entities[i].x = x;
67 entities[i].y = y;
68 entities[i].mod = nextMod();
69 }
70
71 raf(tick(data));
72}
73
74function ball(ctx, x, y) {
75 ctx.fillStyle = "#f2f2f2";
76 ctx.beginPath();
77 ctx.arc(x, y, 5, 0, 2 * Math.PI);
78 ctx.fill();
79}