Created
August 1, 2020 19:02
-
-
Save zackexplosion/674880ebe3ee63d42be9193c3e839351 to your computer and use it in GitHub Desktop.
Canvas Clock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<canvas id="clock" width="800" height="800"></canvas> | |
<div id="app"> | |
<template> | |
<el-switch v-model="hourFormat12" active-text="12" inactive-text="24"> | |
</el-switch> | |
</template> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var canvas = document.getElementById("clock"); | |
var ctx = canvas.getContext("2d"); | |
const CENTER_X = 400; | |
const CENTER_Y = 400; | |
function angleToRadian(angle) { | |
return (angle * Math.PI) / 180; | |
} | |
// 1 ~ 12 | |
function drawNumbers() { | |
ctx.fillStyle = "white"; | |
ctx.textAlign = "center"; | |
ctx.textBaseline = "middle"; | |
ctx.font = "40px Helvetica"; | |
for (let i = 1; i <= clockProps.HOUR_FORMAT; i++) { | |
var angle = angleToRadian((i * 360) / clockProps.HOUR_FORMAT); | |
ctx.fillText( | |
i.toString(), | |
CENTER_X + | |
(clockProps.CLOCK_R - clockProps.NUMBER_POS_FROM_EDGE) * | |
Math.sin(angle), | |
CENTER_Y - | |
(clockProps.CLOCK_R - clockProps.NUMBER_POS_FROM_EDGE) * Math.cos(angle) | |
); | |
} | |
} | |
function drawHand(type, time) { | |
var color, scale, width, length; | |
switch (type) { | |
case "second": | |
color = "red"; | |
scale = 60; | |
width = 5; | |
length = clockProps.SECOND_HAND_LENGTH; | |
time = time.getSeconds(); | |
break; | |
case "minute": | |
color = "white"; | |
scale = 60; | |
width = 8; | |
length = clockProps.MINUTE_HAND_LENGTH; | |
time = time.getMinutes(); | |
break; | |
case "hour": | |
color = "white"; | |
scale = clockProps.HOUR_FORMAT; | |
width = 10; | |
length = clockProps.HOUR_HAND_LENGTH; | |
time = time.getHours(); | |
break; | |
} | |
ctx.strokeStyle = color; | |
// draw minute hand | |
var rad = angleToRadian((time * 360) / scale); | |
ctx.beginPath(); | |
ctx.lineWidth = 8; | |
ctx.moveTo(CENTER_X, CENTER_Y); | |
ctx.lineTo( | |
CENTER_X + clockProps.CLOCK_R * length * Math.sin(rad), | |
CENTER_Y - clockProps.CLOCK_R * length * Math.cos(rad) | |
); | |
ctx.stroke(); | |
} | |
function drawScales() { | |
ctx.strokeStyle = "white"; | |
for (let i = 0; i < 60; i++) { | |
var angle = i * 6; | |
var length = 20; | |
// if ((angle & (5 - 1)) === 0) { | |
if (i % 5 === 0) { | |
length = 40; | |
} | |
var rad = angleToRadian(angle); | |
ctx.beginPath(); | |
ctx.moveTo( | |
CENTER_X + clockProps.CLOCK_R * Math.sin(rad), | |
CENTER_Y - clockProps.CLOCK_R * Math.cos(rad) | |
); | |
ctx.lineTo( | |
CENTER_X + (clockProps.CLOCK_R - length) * Math.sin(rad), | |
CENTER_Y - (clockProps.CLOCK_R - length) * Math.cos(rad) | |
); | |
ctx.stroke(); | |
} | |
} | |
function update() { | |
// the black background | |
ctx.fillStyle = "black"; | |
ctx.fillRect(0, 0, canvas.width, canvas.height); | |
// draw the clock frame | |
ctx.lineWidth = 10; | |
ctx.strokeStyle = "white"; | |
ctx.beginPath(); | |
ctx.arc(CENTER_X, CENTER_X, clockProps.CLOCK_R, 0, 2 * Math.PI); | |
ctx.stroke(); | |
drawScales(); | |
drawNumbers(); | |
var time = new Date(); | |
drawHand("second", time); | |
drawHand("minute", time); | |
drawHand("hour", time); | |
// draw center dot | |
ctx.beginPath(); | |
ctx.strokeStyle = "white"; | |
ctx.fillStyle = "white"; | |
ctx.arc(CENTER_X, CENTER_X, 10, 0, 2 * Math.PI); | |
ctx.fill(); | |
} | |
function ClockProps() { | |
this.CLOCK_R = 380; | |
this.HOUR_FORMAT_12 = true; | |
this.SECOND_HAND_LENGTH = 0.85; | |
this.MINUTE_HAND_LENGTH = 0.7; | |
this.HOUR_HAND_LENGTH = 0.6; | |
this.NUMBER_POS_FROM_EDGE = 65; | |
this.set_HOUR_FORMAT = () => { | |
this.HOUR_FORMAT = this.HOUR_FORMAT_12 ? 12 : 24; | |
}; | |
this.set_HOUR_FORMAT(); | |
} | |
// setup gui controller | |
var clockProps = new ClockProps(); | |
var gui = new dat.GUI(); | |
gui.add(clockProps, "CLOCK_R", 100, 400).onChange(update); | |
gui.add(clockProps, "NUMBER_POS_FROM_EDGE", 40, 300).onChange(update); | |
gui.add(clockProps, "SECOND_HAND_LENGTH", 0, 1).onChange(update); | |
gui.add(clockProps, "MINUTE_HAND_LENGTH", 0, 1).onChange(update); | |
gui.add(clockProps, "HOUR_HAND_LENGTH", 0, 1).onChange(update); | |
gui.add(clockProps, "HOUR_FORMAT_12").onChange((e) => { | |
clockProps.set_HOUR_FORMAT(); | |
update(); | |
}); | |
// monitor FPS | |
var stats = new Stats(); | |
stats.showPanel(0); | |
document.body.appendChild(stats.dom); | |
(function main() { | |
window.requestAnimationFrame(function step(now) { | |
stats.begin(); | |
update(); | |
stats.end(); | |
window.requestAnimationFrame(step); | |
}); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/element-ui/2.13.2/index.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.min.js"></script> | |
<script src="https://rawgit.com/mrdoob/stats.js/master/build/stats.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
canvas { | |
display: block; | |
margin: 0 auto; | |
} | |
@media only screen and (max-width: 720px) { | |
canvas { | |
width: 100%; | |
} | |
} | |
html, | |
body { | |
margin: 0; | |
padding: 0; | |
background: #000; | |
} | |
#app { | |
text-align: center; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment