Last active
March 25, 2019 06:12
-
-
Save Deliaz/9710761 to your computer and use it in GitHub Desktop.
На основании идеи с http://www.artlebedev.ru/everything/brain/2014/03/20/
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
<html lang="ru"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
<style> | |
#canv { | |
border: 2px solid #eee; | |
margin: 20px auto; | |
display: block; | |
color: #7a93b4; | |
} | |
</style> | |
<script> | |
"use strict"; | |
var app = { | |
conf: { | |
idCanv: 'canv', // ID Canvas | |
R: 240, // Радиус циферблата | |
hourL: 70, // Длина часовой | |
minL: 100, // Длина минутной | |
secL: 110, // Дина секундной | |
hourW: 4, // Толщина часовой | |
minW: 3, // Толщина минутной | |
secW: 2, // Толщина секундной | |
armClr: '#000', // Цвет стрелок | |
vectorClr: '#999', // Цвет векторов | |
clockClr: '#5E7490',// Цвет циферблата | |
numberClr: '#777', // Цвет чисел | |
intervalMs: 30 // Интервал отрисовки в миллисекундах | |
}, | |
centerX: 0, // Центр по X | |
centerY: 0, // Центр по Y | |
canv: {}, // DOM элемент канвы | |
ctx: {}, // Контекст канвы | |
tau: 2 * Math.PI, // Константа для упрощения расчетов | |
/** | |
* Исходная точка приложения | |
*/ | |
start: function () { | |
this.setCanvas(); | |
this.startClock() | |
}, | |
/** | |
* Настройка канвы для отрисовки | |
*/ | |
setCanvas: function () { | |
this.canv = document.getElementById(this.conf.idCanv); | |
this.ctx = this.canv.getContext('2d'); | |
this.centerX = this.canv.width / 2; | |
this.centerY = this.canv.height / 2; | |
}, | |
/** | |
* Запуск основного цикла | |
*/ | |
startClock: function () { | |
var self = this; | |
setInterval(function () { | |
// Очистка | |
self.ctx.clearRect(0, 0, self.canv.width, self.canv.height); | |
// Получение времени | |
var date = new Date(), | |
h = date.getHours(), | |
m = date.getMinutes(), | |
s = date.getSeconds(), | |
ms = date.getMilliseconds(); | |
// Корректировка движения стрелок | |
s += ms / 1000; | |
m += s / 60; | |
h += m / 60; | |
self.drawClockface(); | |
self.drawArms(h, m, s); | |
}, this.intervalMs); | |
}, | |
/** | |
* Отрисовка циферблата | |
*/ | |
drawClockface: function () { | |
// Окружность | |
this.ctx.beginPath(); | |
this.ctx.arc(this.centerX, this.centerY, this.conf.R, 0, Math.PI * 2, true); | |
this.ctx.lineWidth = 4; | |
this.ctx.strokeStyle = this.conf.clockClr; | |
this.ctx.stroke(); | |
this.ctx.closePath(); | |
// Цифры | |
this.ctx.beginPath(); | |
this.ctx.fillStyle = this.conf.numberClr; | |
this.ctx.font = "30pt Arial"; | |
this.ctx.textAlign = "center"; | |
this.ctx.textBaseline = "middle"; | |
this.ctx.fillText("12", this.centerX, this.centerY - this.conf.R * 0.9); | |
this.ctx.fillText("3", this.centerX + this.conf.R * 0.9, this.centerY); | |
this.ctx.fillText("6", this.centerX, this.centerY + this.conf.R * 0.9); | |
this.ctx.fillText("9", this.centerX - this.conf.R * 0.9, this.centerY); | |
this.ctx.closePath(); | |
}, | |
/** | |
* Отрисовка стрелок | |
* @param h часы | |
* @param m минуты | |
* @param s секунды | |
*/ | |
drawArms: function (h, m, s) { | |
/* Отрисовка стрелок */ | |
// Часы | |
var hArmRadians = (this.tau * h / 12) - (this.tau / 4), | |
hTargetX = this.centerX + Math.cos(hArmRadians) * this.conf.hourL, | |
hTargetY = this.centerY + Math.sin(hArmRadians) * this.conf.hourL; | |
drawArm.apply(this, [hTargetX, hTargetY, this.conf.hourW]); | |
// Минуты | |
var mArmRadians = (this.tau * m / 60) - (this.tau / 4), | |
mTargetX = this.centerX + Math.cos(mArmRadians) * this.conf.minL, | |
mTargetY = this.centerY + Math.sin(mArmRadians) * this.conf.minL; | |
drawArm.apply(this, [mTargetX, mTargetY, this.conf.minW]); | |
// Секунды | |
var sArmRadians = (this.tau * s / 60) - (this.tau / 4), | |
sTargetX = this.centerX + Math.cos(sArmRadians) * this.conf.secL, | |
sTargetY = this.centerY + Math.sin(sArmRadians) * this.conf.secL; | |
drawArm.apply(this, [sTargetX, sTargetY, this.conf.secW]); | |
/* Отрисовка векторов */ | |
// Вектор между часами и минутами | |
var hmVectorX = (hTargetX + mTargetX) - this.centerX, | |
hmVectorY = (hTargetY + mTargetY) - this.centerY; | |
drawVector.apply(this, [hTargetX, hTargetY, hmVectorX, hmVectorY, mTargetX, mTargetY]); | |
// Вектор между минутыми и секундами | |
var msVectorX = (mTargetX + sTargetX) - this.centerX, | |
msVectorY = (mTargetY + sTargetY) - this.centerY; | |
drawVector.apply(this, [mTargetX, mTargetY, msVectorX, msVectorY, sTargetX, sTargetY]); | |
// Вектор между часами и секундами | |
var hsVectorX = (hTargetX + sTargetX) - this.centerX, | |
hsVectorY = (hTargetY + sTargetY) - this.centerY; | |
drawVector.apply(this, [hTargetX, hTargetY, hsVectorX, hsVectorY, sTargetX, sTargetY]); | |
// Результирующий вектор | |
this.ctx.beginPath(); | |
var hmsVectorX = (hTargetX + mTargetX + sTargetX) - this.centerX * 2, | |
hmsVectorY = (hTargetY + mTargetY + sTargetY) - this.centerY * 2; | |
this.ctx.moveTo(hsVectorX, hsVectorY); | |
this.ctx.lineTo(hmsVectorX, hmsVectorY); | |
this.ctx.moveTo(hmVectorX, hmVectorY); | |
this.ctx.lineTo(hmsVectorX, hmsVectorY); | |
this.ctx.moveTo(msVectorX, msVectorY); | |
this.ctx.lineTo(hmsVectorX, hmsVectorY); | |
this.ctx.lineWidth = 1; | |
this.ctx.strokeStyle = this.conf.vectorClr; | |
this.ctx.stroke(); | |
this.ctx.closePath(); | |
/** | |
* Отрисовка самой стрелки-палки. | |
* Использовать в контексте. | |
* @param x Координата X | |
* @param y Координата Y | |
* @param w Толщина линии | |
*/ | |
function drawArm(x, y, w) { | |
this.ctx.beginPath(); | |
this.ctx.moveTo(this.centerX, this.centerY); | |
this.ctx.lineTo(x, y); | |
this.ctx.lineWidth = w; | |
this.ctx.strokeStyle = this.conf.armClr; | |
this.ctx.stroke(); | |
this.ctx.closePath(); | |
} | |
/** | |
* Отрисовка векторов. | |
* Рисует ломаную, состоящую из 2-х векторов. | |
* Использовать в контексте. | |
* @param startX X-координата начала | |
* @param startY Y-координата начала | |
* @param line1X X-координата конца 1-го вектора, начало 2-го | |
* @param line1Y Y-координата конца 1-го вектора, начало 2-го | |
* @param line2X X-координата конца 2-го вектора | |
* @param line2Y Y-координата конца 2-го вектора | |
*/ | |
function drawVector(startX, startY, line1X, line1Y, line2X, line2Y) { | |
this.ctx.beginPath(); | |
this.ctx.moveTo(startX, startY); | |
this.ctx.lineTo(line1X, line1Y); | |
this.ctx.lineTo(line2X, line2Y); | |
this.ctx.lineWidth = 1; | |
this.ctx.strokeStyle = this.conf.vectorClr; | |
this.ctx.stroke(); | |
this.ctx.closePath(); | |
} | |
} | |
}; | |
// Запуск приложения при загрузке страницы | |
window.onload = function () { | |
app.start(); | |
}; | |
</script> | |
</head> | |
<body> | |
<canvas width="900" height="800" id='canv'></canvas> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment