使用 setInterval 控制 svg 时钟



我做了一个svg时钟:

<svg baseProfile="basic" viewBox="0 0 200 200" preserveAspectRatio="xMidYMin" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="aiguilles">
<g id="heures" visibility="hidden">
<path fill="#555" d="M94.9,38.8v11l-6,8.2l6.3,9.3L95,92.9c-2.2,1.6-3.7,4.2-3.7,7.1s1.4,5.5,3.6,7l-0.1,12.7l5.3,3.5v-14.5 c0-4.6,0-13.1,0-17.5V33.9L94.9,38.8z"/>
<path fill="#bbb" d="M105,92.9l-0.2-25.6l6.3-9.3l-6-8.2v-11l-5.1-5v57.4c0,5.7,0,12,0,17.5v14.5l5.3-3.5l-0.1-12.7 c2.2-1.6,3.6-4.1,3.6-7C108.7,97.1,107.3,94.5,105,92.9z"/>
<polygon fill="#fff" points="100,69.7 92.6,58.1 100,47.5 107.4,58.1 "/>
</g>
<g id="minutes" visibility="hidden">
<path fill="#777" d="M95.6,9.7v84.9c-1.6,1.3-2.5,3.2-2.5,5.4s1,4.1,2.5,5.4v14.8l4.4,2.6V5.3L95.6,9.7z"/>
<path fill="#ddd" d="M106.9,100c0-2.1-1-4.1-2.5-5.3v-85L100,5.3V93l0,0c0,3,0,10.4,0,13.9l0,0v15.9l4.4-2.6v-14.9 C105.9,104.1,106.9,102.2,106.9,100z"/>
<polygon fill="#fff" points="97.7,17.5 97.7,69.4 100,71.9 102.3,69.4 102.3,17.5 100,15.4 "/>
</g>
<g id="secondes" visibility="hidden">
<path fill="#bbb" d="M101,95.5c0-33.1,0-54.1,0-67.4c2.5-0.5,4.4-2.7,4.4-5.3s-1.9-4.8-4.4-5.3c0-12.4,0-12.7,0-13.3 c0-0.8-0.5-1.8-1-2c-0.6,0.3-1,1.2-1,2c0,0.6,0,0.9,0,13.3c-2.5,0.5-4.4,2.7-4.4,5.3s1.9,4.8,4.4,5.3c0,13.3,0,34.3,0,67.4 c-2.2,0.5-3.8,2.4-3.8,4.7c0,1.2,0.5,2.3,1.2,3.1V122l3.7,3.3l3.7-3.3v-18.7c0.7-0.8,1.2-1.9,1.2-3.1 C104.8,97.9,103.2,95.9,101,95.5z"/>
<circle fill="#FFF" cx="100" cy="22.7" r="3.7"/>
</g>
</g>
</svg>

我成功地为手制作了动画,以便它们首先使用"toTimeNow"函数从 12:00 转到当前时间,然后使用"timeNow"函数连续显示时间:

var tailleAiguilles = 2;
var aiguillesGauche = 250;
var aiguillesHaut = 250;
var aiguilles = document.getElementById("aiguilles");
function transformSvg() {
aiguilles.setAttribute("transform", "matrix(" + tailleAiguilles + " 0 0 " + tailleAiguilles + " " + aiguillesGauche + " " + aiguillesHaut + ")");
}
function toTimeNow() {
var hr = 0;
var mn = 0;
var sc = 0;
var interval = setInterval(function() {
var maintenant = new Date();
var heures = maintenant.getHours();
var minutes = maintenant.getMinutes();
var secondes = maintenant.getSeconds();
var milliSecondes = maintenant.getMilliseconds();
var secondes2 = 6 * secondes;
if  (heures * 30 + minutes * 0.5 > 359) {
var angleHeures = heures * 30 + minutes * 0.5 - 359;
}
else {
var angleHeures = heures * 30 + minutes * 0.5;
}
var angleMinutes = minutes * 6 + (0.1 * secondes);
var angleSecondes = secondes2 += 0.006 * milliSecondes;
var max = Math.max(angleHeures, angleMinutes, angleSecondes)
if  (hr < angleHeures) {
hr += angleHeures / max * 2;
rotation('heures', hr, 100);
}
if  (mn < angleMinutes) {
mn += angleMinutes / max * 2;
rotation('minutes', mn, 100);
}
if  (sc < angleSecondes) {
sc += angleSecondes / max * 2;
rotation('secondes', sc, 100);
}
else  {
clearInterval(interval);
timeNow();
}
}, 5);
}
function timeNow() {
setInterval(function() {
var maintenant = new Date();
var heures = maintenant.getHours();
var minutes = maintenant.getMinutes();
var secondes = maintenant.getSeconds();
var milliSecondes = maintenant.getMilliseconds();
var secondes2 = 6 * secondes;
rotation('heures', heures * 30 + minutes * 0.5, 100);
rotation('minutes', minutes * 6 + (0.1 * secondes), 100);
rotation('secondes', secondes2 += 0.006 * milliSecondes, 100);
}, 50);
}
function rotation(id, angle, centre) {
var element = document.getElementById(id);
if (element) {
element.setAttribute('transform', 'rotate(' + angle + ', ' + centre + ', ' + centre + ')');
if (element.getAttribute('visibility') == 'hidden') {
element.setAttribute('visibility', 'visible');
}
}
}
window.addEventListener('load', toTimeNow, false);

但我注意到,就在第二个功能接管之前,手会稍微向后移动。如果有人能告诉我为什么我会感激它。

几乎可以肯定是因为这段代码:

if  (mn < angleMinutes) {
mn += angleMinutes / max * 2;
rotation('minutes', mn, 100);
}

如果mn略小于angleMinutes,则此代码可能导致它远远超过它。 您应该在递增后检查mn

if  (mn < angleMinutes) {
mn = Math.min(angleMinutes, mn + angleMinutes / max * 2);
rotation('minutes', mn, 100);
}

最新更新