feat: top screen implement clock
This commit is contained in:
78
app/components/TopScreen/Clock.vue
Normal file
78
app/components/TopScreen/Clock.vue
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const CENTER_X = 63;
|
||||||
|
const CENTER_Y = 95;
|
||||||
|
|
||||||
|
function drawLine(
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
x0: number,
|
||||||
|
y0: number,
|
||||||
|
x1: number,
|
||||||
|
y1: number,
|
||||||
|
width: number,
|
||||||
|
) {
|
||||||
|
const dx = Math.abs(x1 - x0);
|
||||||
|
const dy = Math.abs(y1 - y0);
|
||||||
|
const sx = x0 < x1 ? 1 : -1;
|
||||||
|
const sy = y0 < y1 ? 1 : -1;
|
||||||
|
let err = dx - dy;
|
||||||
|
|
||||||
|
const drawThickPixel = (x: number, y: number) => {
|
||||||
|
const isVertical = dy > dx;
|
||||||
|
|
||||||
|
if (width === 1) {
|
||||||
|
ctx.fillRect(x, y, 1, 1);
|
||||||
|
} else if (isVertical) {
|
||||||
|
const offset = Math.floor((width - 1) / 2);
|
||||||
|
ctx.fillRect(x - offset, y, width, 1);
|
||||||
|
} else {
|
||||||
|
const offset = Math.floor((width - 1) / 2);
|
||||||
|
ctx.fillRect(x, y - offset, 1, width);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
drawThickPixel(x0, y0);
|
||||||
|
|
||||||
|
if (x0 === x1 && y0 === y1) break;
|
||||||
|
|
||||||
|
const e2 = 2 * err;
|
||||||
|
if (e2 > -dy) {
|
||||||
|
err -= dy;
|
||||||
|
x0 += sx;
|
||||||
|
}
|
||||||
|
if (e2 < dx) {
|
||||||
|
err += dx;
|
||||||
|
y0 += sy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useRender((ctx) => {
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
const renderHand = (
|
||||||
|
value: number,
|
||||||
|
color: string,
|
||||||
|
length: number,
|
||||||
|
width: number,
|
||||||
|
) => {
|
||||||
|
const angle = value * Math.PI * 2 - Math.PI / 2;
|
||||||
|
const endX = Math.round(CENTER_X + Math.cos(angle) * length);
|
||||||
|
const endY = Math.round(CENTER_Y + Math.sin(angle) * length);
|
||||||
|
ctx.fillStyle = color;
|
||||||
|
drawLine(ctx, CENTER_X, CENTER_Y, endX, endY, width);
|
||||||
|
};
|
||||||
|
|
||||||
|
renderHand(now.getMinutes() / 60, "#797979", 30, 2);
|
||||||
|
renderHand(
|
||||||
|
now.getHours() / 12 + now.getMinutes() / 60 / 12,
|
||||||
|
"#797979",
|
||||||
|
23,
|
||||||
|
2,
|
||||||
|
);
|
||||||
|
renderHand(now.getSeconds() / 60, "#49db8a", 35, 2);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#494949";
|
||||||
|
ctx.fillRect(CENTER_X - 2, CENTER_Y - 2, 5, 5);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
<Screen>
|
<Screen>
|
||||||
<TopScreenBackground />
|
<TopScreenBackground />
|
||||||
<TopScreenCalendar />
|
<TopScreenCalendar />
|
||||||
|
<TopScreenClock />
|
||||||
|
|
||||||
<slot />
|
<slot />
|
||||||
</Screen>
|
</Screen>
|
||||||
|
|||||||
Reference in New Issue
Block a user