-
Notifications
You must be signed in to change notification settings - Fork 0
/
Canvas.svelte
86 lines (68 loc) · 1.91 KB
/
Canvas.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<script lang="ts">
import { onMount } from "svelte";
import { settings } from "$stores";
let canvasSize: number;
let radius: number;
// Setup
let canvas: HTMLCanvasElement;
let ctx: CanvasRenderingContext2D;
let currentFrame: number;
let angle = 0;
let i = 0;
$: if (i >= $settings.iterations) $settings.running = false;
onMount(async () => {
// Setup canvas
canvasSize = Math.min(window.innerWidth, window.innerHeight);
radius = canvasSize / 2 - 50;
ctx = canvas.getContext("2d")!;
setupCanvas(true);
settings.subscribe(() => {
setupCanvas(i === 0);
if ($settings.running) requestAnimationFrame(draw);
else if ($settings.hasResetted) {
// janky ahh way to do this
cancelAnimationFrame(currentFrame);
i = 0;
$settings.hasResetted = false;
}
});
});
async function draw(frame: number) {
currentFrame = frame;
if (!$settings.running) return;
if ($settings.delay > 0) await sleep($settings.delay);
ctx.beginPath();
ctx.moveTo(...getPoint());
ctx.lineTo(...getPoint(true));
ctx.stroke();
angle += $settings.step;
i++;
if ($settings.running && i < $settings.iterations) requestAnimationFrame(draw);
}
function setupCanvas(renewBg = false) {
if (renewBg) {
ctx.fillStyle = $settings.bgColor;
ctx.fillRect(0, 0, canvasSize, canvasSize);
}
ctx.fillStyle = $settings.color;
ctx.strokeStyle = $settings.color;
ctx.lineWidth = $settings.lineWidth;
}
function getPoint(isSecond = false): [number, number] {
const offset = canvasSize / 2;
if (isSecond) {
return [
radius * Math.cos($settings.degreeX * angle) + offset,
radius * Math.sin($settings.degreeY * angle) + offset,
];
} else {
return [radius * Math.cos(angle) + offset, radius * Math.sin(angle) + offset];
}
}
async function sleep(ms: number) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
</script>
<canvas bind:this={canvas} width={canvasSize} height={canvasSize} class="flex-1 outline" id="canvas" />