diff --git a/src/client/app/desktop/views/components/analog-clock.vue b/src/client/app/desktop/views/components/analog-clock.vue
index 81eec81598..7b5caf9f27 100644
--- a/src/client/app/desktop/views/components/analog-clock.vue
+++ b/src/client/app/desktop/views/components/analog-clock.vue
@@ -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();
 		}
 	}
 });