74 lines
1.9 KiB
Svelte
74 lines
1.9 KiB
Svelte
<script lang="ts">
|
|
import {
|
|
ballRadius,
|
|
brickHeight,
|
|
brickWidth,
|
|
fieldWidth,
|
|
paddleHeight,
|
|
paddleWidth,
|
|
paddleY,
|
|
type Ball,
|
|
type Brick
|
|
} from '#lib/games/breakout';
|
|
import { themeState } from '#lib/theme/theme.svelte';
|
|
|
|
let {
|
|
paddleX,
|
|
ball,
|
|
bricks,
|
|
width,
|
|
height
|
|
}: { paddleX: number; ball: Ball; bricks: Brick[]; width: number; height: number } = $props();
|
|
|
|
const brickRowColors = ['--red', '--orange', '--yellow', '--green', '--cyan', '--blue'];
|
|
|
|
let canvasElement = $state<HTMLCanvasElement>();
|
|
let pixelRatio = $state(1);
|
|
|
|
const canvasWidth = $derived(Math.round(width * pixelRatio));
|
|
const canvasHeight = $derived(Math.round(height * pixelRatio));
|
|
|
|
function drawField(context: CanvasRenderingContext2D) {
|
|
const style = getComputedStyle(canvasElement!);
|
|
const themeColor = (name: string) => style.getPropertyValue(name).trim();
|
|
const scale = canvasWidth / fieldWidth;
|
|
|
|
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
context.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
context.setTransform(scale, 0, 0, scale, 0, 0);
|
|
|
|
bricks.forEach((brick) => {
|
|
if (brick.broken) return;
|
|
context.fillStyle = themeColor(brickRowColors[brick.row % brickRowColors.length]);
|
|
context.fillRect(brick.x, brick.y, brickWidth, brickHeight);
|
|
});
|
|
|
|
context.fillStyle = themeColor('--accent');
|
|
context.fillRect(paddleX, paddleY, paddleWidth, paddleHeight);
|
|
|
|
context.fillStyle = themeColor('--foreground');
|
|
context.beginPath();
|
|
context.arc(ball.x, ball.y, ballRadius, 0, Math.PI * 2);
|
|
context.fill();
|
|
}
|
|
|
|
$effect(() => {
|
|
width;
|
|
pixelRatio = window.devicePixelRatio || 1;
|
|
});
|
|
|
|
$effect(() => {
|
|
themeState.currentId;
|
|
const context = canvasElement?.getContext('2d');
|
|
if (context && canvasWidth > 0) drawField(context);
|
|
});
|
|
</script>
|
|
|
|
<canvas bind:this={canvasElement} width={canvasWidth} height={canvasHeight} style="width: {width}px; height: {height}px"></canvas>
|
|
|
|
<style>
|
|
canvas {
|
|
display: block;
|
|
}
|
|
</style>
|