egirlskey/src/web/app/desktop/views/components/analog-clock.vue

109 lines
2.9 KiB
Vue
Raw Normal View History

2018-02-12 13:07:28 +00:00
<template>
<canvas class="mk-analog-clock" ref="canvas" width="256" height="256"></canvas>
</template>
<script lang="ts">
import Vue from 'vue';
import { themeColor } from '../../../config';
2017-02-20 11:13:42 +00:00
2018-02-12 13:07:28 +00:00
const Vec2 = function(x, y) {
this.x = x;
this.y = y;
};
2016-12-28 22:49:51 +00:00
2018-02-12 13:07:28 +00:00
export default Vue.extend({
data() {
return {
clock: null
};
},
mounted() {
this.tick();
this.clock = setInterval(this.tick, 1000);
},
beforeDestroy() {
clearInterval(this.clock);
},
methods: {
tick() {
const canv = this.$refs.canvas as any;
2016-12-28 22:49:51 +00:00
2017-02-20 02:02:43 +00:00
const now = new Date();
2017-02-20 11:13:42 +00:00
const s = now.getSeconds();
const m = now.getMinutes();
const h = now.getHours();
2016-12-28 22:49:51 +00:00
2018-02-12 13:07:28 +00:00
const ctx = canv.getContext('2d');
const canvW = canv.width;
const canvH = canv.height;
2017-02-20 11:13:42 +00:00
ctx.clearRect(0, 0, canvW, canvH);
2016-12-28 22:49:51 +00:00
2017-02-20 11:13:42 +00:00
{ // 背景
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;
2017-02-21 17:05:44 +00:00
ctx.moveTo((canvW / 2) + uv.x * lineStart, (canvH / 2) + uv.y * lineStart);
2017-02-20 11:13:42 +00:00
if (i % 5 == 0) {
ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
2017-02-21 17:05:44 +00:00
ctx.lineTo((canvW / 2) + uv.x * longLineEnd, (canvH / 2) + uv.y * longLineEnd);
2017-02-20 11:13:42 +00:00
} else {
ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
2017-02-21 17:05:44 +00:00
ctx.lineTo((canvW / 2) + uv.x * shortLineEnd, (canvH / 2) + uv.y * shortLineEnd);
2017-02-20 11:13:42 +00:00
}
ctx.stroke();
}
}
2016-12-28 22:49:51 +00:00
2017-02-20 11:13:42 +00:00
{ // 分
const angle = Math.PI * (m + s / 60) / 30;
const length = Math.min(canvW, canvH) / 2.6;
2017-02-21 17:05:44 +00:00
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
2017-02-20 11:13:42 +00:00
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();
}
2016-12-28 22:49:51 +00:00
2017-02-20 11:13:42 +00:00
{ // 時
const angle = Math.PI * (h % 12 + m / 60) / 6;
const length = Math.min(canvW, canvH) / 4;
2017-02-21 17:05:44 +00:00
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
2017-02-20 11:13:42 +00:00
ctx.beginPath();
2018-02-12 13:07:28 +00:00
ctx.strokeStyle = themeColor;
2017-02-20 11:13:42 +00:00
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();
}
2016-12-28 22:49:51 +00:00
2017-02-20 11:13:42 +00:00
{ // 秒
const angle = Math.PI * s / 30;
const length = Math.min(canvW, canvH) / 2.6;
2017-02-21 17:05:44 +00:00
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
2017-02-20 11:13:42 +00:00
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();
}
2018-02-12 13:07:28 +00:00
}
}
});
</script>
<style lang="stylus" scoped>
.mk-analog-clock
display block
width 256px
height 256px
</style>