マウスポインターに追従する『(カレンダー機能付き)アナログ時計』の体裁が崩れる原因について
下記のコードは、マウスポインターに追従する"(カレンダー機能付き)アナログ時計"のものですが、
1点だけ気になるところがあるのです。
それは、コード内にある"const SPEED = 0.6,"の値を0.6以下に設定すると、face(文字盤)の
体裁が崩れるのです。コード全体を見ても、どこに原因があるのか分かりません。分かる方がいましたら、
教えていただけませんでしょうか。
ブラウザはIEで、バージョンは11.0.9600.8977です。クロームでも同様です。
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: Helvetica, Arial, sans-serif;
}
.Face {
position: absolute;
height: 10;
widdth: 10;
text-align: center;
font-size: 1em;
color: #0000ff;
}
.Hours {
position: absolute;
width: 16px;
height: 16px;
font-family: Arial;
font-size: 16px;
color: #000000;
text-align: center;
font-weight: bold;
}
.Minutes {
position: absolute;
width: 16px;
height: 16px;
font-family: Arial;
font-size: 16px;
color: #000000;
text-align: center;
font-weight: bold;
}
.Seconds {
position: absolute;
width: 16px;
height: 16px;
font-family: Arial;
font-size: 16px;
color: #ff0000;
text-align: center;
font-weight: bold;
}
.Date {
position: absolute;
height: 10;
width: 10;
font-size: 1em;
color: #00ff00;
}
</style>
<script src="/scripts/snippet-javascript-console.min.js?v=1"></script>
</head>
<body>
<div id="clock">
<div id="Od" style="position:absolute;top:0px;left:0px">
<div style="position:relative">
</div>
</div>
<div id="Of" style="position:absolute;top:0px;left:0px">
<div style="position:relative">
</div>
</div>
<div id="Oh" style="position:absolute;top:0px;left:0px">
<div style="position:relative">
</div>
</div>
<div id="Om" style="position:absolute;top:0px;left:0px">
<div style="position:relative">
</div>
</div>
<div id="Os" style="position:absolute;top:0px;left:0px">
<div style="position:relative">
</div>
</div>
</div>
<script type="text/javascript">
"use strict";
function $(sel) {
return document.getElementById(sel);
}
function $$(sel) {
return document.getElementsByClassName(sel);
}
function setPosition(element, y, x) {
element.style.top = y + 'px';
element.style.left = x + 'px';
}
const CLOCK_HEIGHT = 40,
CLOCK_WIDTH = 40,
CLOCK_FROM_MOUSE_Y = 0,
CLOCK_FROM_MOUSE_X = 100;
const H = '...'.split('');
const M = '....'.split('');
const S = '.....'.split('');
const SPEED = 0.6,
FACES = '1 2 3 4 5 6 7 8 9 10 11 12'.split(' ');
const HAND_HEIGHT = CLOCK_HEIGHT / 4.5;
const HAND_WIDTH = CLOCK_WIDTH / 4.5;
const HAND_Y = -7,
HAND_X = -2.5,
STEP = 0.06;
var ymouse = 0,
xmouse = 0;
var currStep = 0;
var lastBasePositions = [];
function initialize() {
for (var i = 0; i < FACES.length; ++i) {
lastBasePositions[i] = {x:0, y:0};
}
var html = '';
// Face wrapper
html = '';
for (var i = 0; i < FACES.length; ++i) {
html += '<div class="Face">' + FACES[i] + '</div>';
}
$('Of').children[0].innerHTML = html;
// Hours wrapper
html = '';
for (var i = 0; i < H.length; ++i) {
html += '<div class="Hours">' + H[i] + '</div>';
}
$('Oh').children[0].innerHTML = html;
// Minute wrapper
html = '';
for (var i = 0; i < M.length; ++i) {
html += '<div class="Minutes">' + M[i] + '</div>';
}
$('Om').children[0].innerHTML = html;
// Seconds wrapper
html = '';
for (var i = 0; i < S.length; ++i) {
html += '<div class="Seconds">' + S[i] + '</div>';
}
$('Os').children[0].innerHTML = html;
// Mouse move event handler
document.onmousemove = function(evnt) {
ymouse = evnt.clientY + CLOCK_FROM_MOUSE_Y;
xmouse = evnt.clientX + CLOCK_FROM_MOUSE_X;
};
requestAnimationFrame(ClockAndAssign);
}
var lastYearPositions = [{x:0, y:0}];
var lastYearString = ' ';
var lastYearLocale = '';
function updateYear(currentDate, scrll) {
var yearString = lastYearString;
if (currentDate.getMinutes() % 2 == 0) {
if (lastYearLocale != 'ja')
yearString = currentDate.toLocaleDateString("ja-JP-u-ca-japanese", { era: "long", year: "numeric" }).
replace(/\u200e/g, "").replace(" ", "");
lastYearLocale = 'ja';
} else {
if (lastYearLocale != 'en')
yearString = currentDate.toLocaleDateString("en-US", { era: "long", year: "numeric" }).
replace(/\u200e/g, "") + "年";
lastYearLocale = 'en';
}
var yearLength = lastYearPositions.length;
if (yearString != lastYearString) {
lastYearString = yearString;
var yearCharacters = yearString.split('');
yearLength = yearCharacters.length;
// Date wrapper
var html = '';
for (var i = 0; i < yearLength; ++i) {
html += '<div class="Date">' + yearCharacters[i] + '</div>';
}
$('Od').children[0].innerHTML = html;
}
var positions = [{}];
var lastPosition = lastYearPositions[0];
positions[0].y = lastPosition.y + ((ymouse) - lastPosition.y) * SPEED;
positions[0].x = lastPosition.x + ((xmouse) - lastPosition.x) * SPEED;
for (var i = 1; i < yearLength; ++i) {
lastPosition = i < lastYearPositions.length ?
lastYearPositions[i] :
lastYearPositions[lastYearPositions.length - 1];
positions[i] = {};
positions[i].y = lastPosition.y + (positions[i-1].y - lastPosition.y) * SPEED;
positions[i].x = lastPosition.x + (positions[i-1].x - lastPosition.x) * SPEED;
}
for (var i = 0; i < yearLength; ++i) {
var radian = currStep + i * (360 / yearLength) * Math.PI / 180;
setPosition($$('Date')[i],
Math.round(positions[i].y) + CLOCK_HEIGHT * 1.5 * Math.sin(radian) + scrll,
Math.round(positions[i].x) + CLOCK_WIDTH * 1.5 * Math.cos(radian));
}
lastYearPositions = positions;
currStep -= STEP;
}
function ClockAndAssign() {
var date = new Date();
var secs = date.getSeconds();
var sec = -1.57 + Math.PI * secs / 30;
var mins = date.getMinutes();
var min = -1.57 + Math.PI * mins / 30;
var hr = date.getHours();
var hrs = -1.575 + Math.PI * hr / 6 + Math.PI * parseInt(date.getMinutes(), 10) / 360;
$('Od').style.top = window.document.body.scrollTop;
$('Of').style.top = window.document.body.scrollTop;
$('Oh').style.top = window.document.body.scrollTop;
$('Om').style.top = window.document.body.scrollTop;
$('Os').style.top = window.document.body.scrollTop;
var scrll = 0;
var positions = [{}];
var lastPosition = lastBasePositions[0];
positions[0].y = Math.round(lastPosition.y + (ymouse - lastPosition.y) * SPEED);
positions[0].x = Math.round(lastPosition.x + (xmouse - lastPosition.x) * SPEED);
for (var i = 1; i < FACES.length; ++i) {
lastPosition = lastBasePositions[i];
positions[i] = {};
positions[i].y = Math.round(lastPosition.y + (positions[i - 1].y - lastPosition.y) * SPEED);
positions[i].x = Math.round(lastPosition.x + (positions[i - 1].x - lastPosition.x) * SPEED);
}
lastBasePositions = positions;
var split = 360 / FACES.length;
for (var i = 0; i < FACES.length; ++i) {
var radian = -1.0471 + i * split * Math.PI / 180;
setPosition($$('Face')[i],
positions[i].y + CLOCK_HEIGHT * Math.sin(radian) + scrll,
positions[i].x + CLOCK_WIDTH * Math.cos(radian));
}
for (var i = 0; i < H.length; ++i) {
setPosition($$('Hours')[i],
positions[i].y + HAND_Y + (i * HAND_HEIGHT) * Math.sin(hrs) + scrll,
positions[i].x + HAND_X + (i * HAND_WIDTH) * Math.cos(hrs));
}
for (var i = 0; i < M.length; ++i) {
setPosition($$('Minutes')[i],
positions[i].y + HAND_Y + (i * HAND_HEIGHT) * Math.sin(min) + scrll,
positions[i].x + HAND_X + (i * HAND_WIDTH) * Math.cos(min));
}
for (var i = 0; i < S.length; ++i) {
setPosition($$('Seconds')[i],
positions[i].y + HAND_Y + (i * HAND_HEIGHT) * Math.sin(sec) + scrll,
positions[i].x + HAND_X + (i * HAND_WIDTH) * Math.cos(sec));
}
updateYear(date, scrll);
requestAnimationFrame(ClockAndAssign);
}
initialize();
</script>
</body>
</html>