mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-03 23:14:13 +00:00 
			
		
		
		
	時計をSVG化
This commit is contained in:
		
							parent
							
								
									d05aee19f2
								
							
						
					
					
						commit
						95d0d0047a
					
				
					 1 changed files with 88 additions and 77 deletions
				
			
		| 
						 | 
				
			
			@ -1,24 +1,103 @@
 | 
			
		|||
<template>
 | 
			
		||||
<canvas class="mk-analog-clock" ref="canvas" width="256" height="256"></canvas>
 | 
			
		||||
<svg class="mk-analog-clock" viewBox="0 0 10 10" preserveAspectRatio="none">
 | 
			
		||||
	<line v-for="angle, i in graduations"
 | 
			
		||||
		:x1="5 + (Math.sin(angle) * (5 - graduationsPadding))"
 | 
			
		||||
		:y1="5 - (Math.cos(angle) * (5 - graduationsPadding))"
 | 
			
		||||
		:x2="5 + (Math.sin(angle) * ((5 - graduationsPadding) - (i % 5 == 0 ? longGraduationLength : shortGraduationLength)))"
 | 
			
		||||
		:y2="5 - (Math.cos(angle) * ((5 - graduationsPadding) - (i % 5 == 0 ? longGraduationLength : shortGraduationLength)))"
 | 
			
		||||
		:stroke="i % 5 == 0 ? longGraduationColor : shortGraduationColor"
 | 
			
		||||
		stroke-width="0.05"/>
 | 
			
		||||
 | 
			
		||||
	<line
 | 
			
		||||
		x1="5"
 | 
			
		||||
		y1="5"
 | 
			
		||||
		:x2="5 + (Math.sin(sAngle) * ((sHandLengthRatio * 5) - handsPadding))"
 | 
			
		||||
		:y2="5 - (Math.cos(sAngle) * ((sHandLengthRatio * 5) - handsPadding))"
 | 
			
		||||
		:stroke="sHandColor"
 | 
			
		||||
		stroke-width="0.05"/>
 | 
			
		||||
	<line
 | 
			
		||||
		x1="5"
 | 
			
		||||
		y1="5"
 | 
			
		||||
		:x2="5 + (Math.sin(mAngle) * ((mHandLengthRatio * 5) - handsPadding))"
 | 
			
		||||
		:y2="5 - (Math.cos(mAngle) * ((mHandLengthRatio * 5) - handsPadding))"
 | 
			
		||||
		:stroke="mHandColor"
 | 
			
		||||
		stroke-width="0.1"/>
 | 
			
		||||
	<line
 | 
			
		||||
		x1="5"
 | 
			
		||||
		y1="5"
 | 
			
		||||
		:x2="5 + (Math.sin(hAngle) * ((hHandLengthRatio * 5) - handsPadding))"
 | 
			
		||||
		:y2="5 - (Math.cos(hAngle) * ((hHandLengthRatio * 5) - handsPadding))"
 | 
			
		||||
		:stroke="hHandColor"
 | 
			
		||||
		stroke-width="0.1"/>
 | 
			
		||||
</svg>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import { themeColor } from '../../../config';
 | 
			
		||||
 | 
			
		||||
const Vec2 = function(this: any, x, y) {
 | 
			
		||||
	this.x = x;
 | 
			
		||||
	this.y = y;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			clock: null
 | 
			
		||||
			now: new Date(),
 | 
			
		||||
			clock: null,
 | 
			
		||||
 | 
			
		||||
			graduationsPadding: 0.5,
 | 
			
		||||
			longGraduationLength: 0.3,
 | 
			
		||||
			shortGraduationLength: 0.15,
 | 
			
		||||
			handsPadding: 1,
 | 
			
		||||
			hHandLengthRatio: 0.75,
 | 
			
		||||
			mHandLengthRatio: 1,
 | 
			
		||||
			sHandLengthRatio: 1,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	computed: {
 | 
			
		||||
		longGraduationColor(): string {
 | 
			
		||||
			return 'rgba(255, 255, 255, 0.3)';
 | 
			
		||||
		},
 | 
			
		||||
		shortGraduationColor(): string {
 | 
			
		||||
			return 'rgba(255, 255, 255, 0.2)';
 | 
			
		||||
		},
 | 
			
		||||
		sHandColor(): string {
 | 
			
		||||
			return 'rgba(255, 255, 255, 0.5)';
 | 
			
		||||
		},
 | 
			
		||||
		mHandColor(): string {
 | 
			
		||||
			return '#fff';
 | 
			
		||||
		},
 | 
			
		||||
		hHandColor(): string {
 | 
			
		||||
			return themeColor;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		s(): number {
 | 
			
		||||
			return this.now.getSeconds();
 | 
			
		||||
		},
 | 
			
		||||
		m(): number {
 | 
			
		||||
			return this.now.getMinutes();
 | 
			
		||||
		},
 | 
			
		||||
		h(): number {
 | 
			
		||||
			return this.now.getHours();
 | 
			
		||||
		},
 | 
			
		||||
		hAngle(): number {
 | 
			
		||||
			return Math.PI * (this.h % 12 + this.m / 60) / 6;
 | 
			
		||||
		},
 | 
			
		||||
		mAngle(): number {
 | 
			
		||||
			return Math.PI * (this.m + this.s / 60) / 30;
 | 
			
		||||
		},
 | 
			
		||||
		sAngle(): number {
 | 
			
		||||
			return Math.PI * this.s / 30;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		graduations(): any {
 | 
			
		||||
			const angles = [];
 | 
			
		||||
			for (let i = 0; i < 60; i++) {
 | 
			
		||||
				const angle = Math.PI * i / 30;
 | 
			
		||||
				angles.push(angle);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return angles;
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.tick();
 | 
			
		||||
		this.clock = setInterval(this.tick, 1000);
 | 
			
		||||
	},
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
| 
						 | 
				
			
			@ -26,75 +105,7 @@ export default Vue.extend({
 | 
			
		|||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		tick() {
 | 
			
		||||
			const canv = this.$refs.canvas as any;
 | 
			
		||||
 | 
			
		||||
			const now = new Date();
 | 
			
		||||
			const s = now.getSeconds();
 | 
			
		||||
			const m = now.getMinutes();
 | 
			
		||||
			const h = now.getHours();
 | 
			
		||||
 | 
			
		||||
			const ctx = canv.getContext('2d');
 | 
			
		||||
			const canvW = canv.width;
 | 
			
		||||
			const canvH = canv.height;
 | 
			
		||||
			ctx.clearRect(0, 0, canvW, canvH);
 | 
			
		||||
 | 
			
		||||
			{ // 背景
 | 
			
		||||
				const center = Math.min((canvW / 2), (canvH / 2));
 | 
			
		||||
				const lineStart =    center * 0.90;
 | 
			
		||||
				const shortLineEnd = center * 0.87;
 | 
			
		||||
				const longLineEnd =  center * 0.84;
 | 
			
		||||
				for (let i = 0; i < 60; i++) {
 | 
			
		||||
					const angle = Math.PI * i / 30;
 | 
			
		||||
					const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
 | 
			
		||||
					ctx.beginPath();
 | 
			
		||||
					ctx.lineWidth = 1;
 | 
			
		||||
					ctx.moveTo((canvW / 2) + uv.x * lineStart, (canvH / 2) + uv.y * lineStart);
 | 
			
		||||
					if (i % 5 == 0) {
 | 
			
		||||
						ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
 | 
			
		||||
						ctx.lineTo((canvW / 2) + uv.x * longLineEnd, (canvH / 2) + uv.y * longLineEnd);
 | 
			
		||||
					} else {
 | 
			
		||||
						ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
 | 
			
		||||
						ctx.lineTo((canvW / 2) + uv.x * shortLineEnd, (canvH / 2) + uv.y * shortLineEnd);
 | 
			
		||||
					}
 | 
			
		||||
					ctx.stroke();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			{ // 分
 | 
			
		||||
				const angle = Math.PI * (m + s / 60) / 30;
 | 
			
		||||
				const length = Math.min(canvW, canvH) / 2.6;
 | 
			
		||||
				const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
 | 
			
		||||
				ctx.beginPath();
 | 
			
		||||
				ctx.strokeStyle = '#ffffff';
 | 
			
		||||
				ctx.lineWidth = 2;
 | 
			
		||||
				ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
 | 
			
		||||
				ctx.lineTo(canvW / 2 + uv.x * length,     canvH / 2 + uv.y * length);
 | 
			
		||||
				ctx.stroke();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			{ // 時
 | 
			
		||||
				const angle = Math.PI * (h % 12 + m / 60) / 6;
 | 
			
		||||
				const length = Math.min(canvW, canvH) / 4;
 | 
			
		||||
				const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
 | 
			
		||||
				ctx.beginPath();
 | 
			
		||||
				ctx.strokeStyle = themeColor;
 | 
			
		||||
				ctx.lineWidth = 2;
 | 
			
		||||
				ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
 | 
			
		||||
				ctx.lineTo(canvW / 2 + uv.x * length,     canvH / 2 + uv.y * length);
 | 
			
		||||
				ctx.stroke();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			{ // 秒
 | 
			
		||||
				const angle = Math.PI * s / 30;
 | 
			
		||||
				const length = Math.min(canvW, canvH) / 2.6;
 | 
			
		||||
				const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
 | 
			
		||||
				ctx.beginPath();
 | 
			
		||||
				ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
 | 
			
		||||
				ctx.lineWidth = 1;
 | 
			
		||||
				ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
 | 
			
		||||
				ctx.lineTo(canvW / 2 + uv.x * length,     canvH / 2 + uv.y * length);
 | 
			
		||||
				ctx.stroke();
 | 
			
		||||
			}
 | 
			
		||||
			this.now = new Date();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue