我正在尝试在时钟代码的秒数滴答中使用转换,使其像自动监视一样工作,如watch中的秒数滴答,这是codepen.io中的演示和代码
function setAttributes(el, attrs) {
for(var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
function setAttrib(id, val) {
// body...
var v = 'rotate('+val+',220,220)';
if(id==='sec') {
setAttributes(document.getElementById(id), {"transform": v, "transition": "transform 13s ease"});
} else {
document.getElementById(id).setAttribute('transform', v);
}
};
我试图在秒刻度上使用毫秒',但它不起作用。我只想设置动画秒刻度'以像自动时钟一样工作,我测试了其中的其他过渡,但我认为没有效果。我不知道这段代码有什么问题?帮助
答案 0 :(得分:3)
使用CSS过渡(不推荐用于下面提到的原因)
正如我在评论中提到的那样,您使用https://jsfiddle.net/fpwo8e7e/1/来轮换line
,因此transition
设置不会对其产生任何影响。您必须通过style
属性使用CSS转换才能使用transition
。以下是SVG's transform
attribute:
'transition-property'属性指定应用转换的CSS属性的 名称 。
(重点是我的)
与SVG transform-origin
属性不同,您还必须单独设置transform
。
使用这种方法的问题是从59s到0s / 60s的旋转是旋转角度从354deg变为0deg,它将反向运动,从而破坏时钟效应。
function clock() {
// body...
var d, h, m, s;
d = new Date;
h = 30 * ((d.getHours() % 12) + d.getMinutes() / 60);
m = 6 * d.getMinutes();
s = 6 * d.getSeconds();
setAttrib('h', h);
setAttrib('m', m);
setAttrib('s', s);
setAttrib('st', s + 180);
h = d.getHours();
m = d.getMinutes();
s = d.getSeconds();
(h >= 12) ? setText('suffix', 'PM'): setText('suffix', 'AM');
if (h != 12) {
h %= 12;
}
setText('hr', h);
setText('min', m);
setText('sec', s);
setTimeout(clock, 1);
};
function setAttributes(el, attrs) {
for (var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
function setAttrib(id, val) {
// body...
var v = 'rotate(' + val + 'deg)';
if (id === 's') {
setAttributes(document.getElementById(id), {
"style": "transform:" + v + "; transform-origin: 220px 220px"
});
} else {
document.getElementById(id).setAttribute('style', "transform:" + v + "; transform-origin: 220px 220px");
}
};
function setText(id, val) {
// body...
if (val < 10) {
val = "0" + val;
}
document.getElementById(id).innerHTML = val;
};
window.onload = clock;
* {
margin: 0;
padding: 0;
font-size: 36px;
}
.analog-clock {
position: relative;
display: flex;
align-items: center;
text-align: center;
border: solid green 2px;
flex-direction: column;
box-sizing: border-box;
justify-content: center;
}
#clock {
stroke: red;
stroke-width: 2px;
fill: white;
}
#h,
#m,
#s,
#st {
stroke: black;
stroke-linecap: round;
/**/
}
#h {
stroke-width: 5.5px;
}
#m {
stroke-width: 3px;
}
#s {
stroke-width: 1.5px;
}
#st {
stroke-width: 1.5px;
}
.time-text {
text-align: center;
}
#s,
#st {
transition: transform 1s ease;
}
<div class="analog-clock">
<svg width='440' height='440'>
<circle id='clock' cx="220" cy='220' r='218' />
<line id='h' x1='220' x2='220' y1='220' y2='38' />
<line id='m' x1='220' x2='220' y1='220' y2='20' />
<line id='s' x1='220' x2='220' y1='220' y2='12' />
<line id='st' x1='220' x2='220' y1='220' y2='166' />
<text x='204' y='30'>12</text>
<text x='420' y='232'>3</text>
<text x='210' y='435'>6</text>
<text x='3' y='232'>9</text>
</svg>
<div class="time-text">
<span id="hr">00</span>
<span>:</span>
<span id="min">00</span>
<span>:</span>
<span id="sec">00</span>
<span id="suffix">--</span>
</div>
</div>
使用更高的刷新率:(推荐)
要克服CSS过渡的问题,但仍然有动画效果,可以通过减少超时持续时间来增加刷新率,并使用毫秒也可以计算。
由于缓和效果,CSS输出会更令人赏心悦目,但据我所知,用JS实现它是不可能的。
function clock() {
// body...
var d, h, m, s, ms;
d = new Date;
h = 30 * ((d.getHours() % 12) + d.getMinutes() / 60);
m = 6 * d.getMinutes();
s = 6 * d.getSeconds();
ms = 6 * d.getMilliseconds();
setAttrib('h', h);
setAttrib('m', m);
setAttrib('s', s + (ms == 0 ? 1 : ms / 1000));
setAttrib('st', s + (ms == 0 ? 1 : ms / 1000) + 180);
h = d.getHours();
m = d.getMinutes();
s = d.getSeconds();
ms = d.getMilliseconds();
(h >= 12) ? setText('suffix', 'PM'): setText('suffix', 'AM');
if (h != 12) {
h %= 12;
}
setText('hr', h);
setText('min', m);
setText('sec', s + '.' + ms);
setTimeout(clock, 1);
};
function setAttributes(el, attrs) {
for (var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
function setAttrib(id, val) {
// body...
var v = 'rotate(' + val + 'deg)';
if (id === 's') {
setAttributes(document.getElementById(id), {
"style": "transform:" + v + "; transform-origin: 220px 220px"
});
} else {
document.getElementById(id).setAttribute('style', "transform:" + v + "; transform-origin: 220px 220px");
}
};
function setText(id, val) {
// body...
if (val < 10) {
val = "0" + val;
}
document.getElementById(id).innerHTML = val;
};
window.onload = clock;
* {
margin: 0;
padding: 0;
font-size: 36px;
}
.analog-clock {
position: relative;
display: flex;
align-items: center;
text-align: center;
border: solid green 2px;
flex-direction: column;
box-sizing: border-box;
justify-content: center;
}
#clock {
stroke: red;
stroke-width: 2px;
fill: white;
}
#h,
#m,
#s,
#st {
stroke: black;
stroke-linecap: round;
/**/
}
#h {
stroke-width: 5.5px;
}
#m {
stroke-width: 3px;
}
#s {
stroke-width: 1.5px;
}
#st {
stroke-width: 1.5px;
}
.time-text {
text-align: center;
}
<div class="analog-clock">
<svg width='440' height='440'>
<circle id='clock' cx="220" cy='220' r='218' />
<line id='h' x1='220' x2='220' y1='220' y2='38' />
<line id='m' x1='220' x2='220' y1='220' y2='20' />
<line id='s' x1='220' x2='220' y1='220' y2='12' />
<line id='st' x1='220' x2='220' y1='220' y2='166' />
<text x='204' y='30'>12</text>
<text x='420' y='232'>3</text>
<text x='210' y='435'>6</text>
<text x='3' y='232'>9</text>
</svg>
<div class="time-text">
<span id="hr">00</span>
<span>:</span>
<span id="min">00</span>
<span>:</span>
<span id="sec">00</span>
<span id="suffix">--</span>
</div>
</div>
也许使用W3C spec on transitions也可以产生缓和效果而不会出现反向旋转问题,但它在Chrome中至少不会起作用,因为他们已经弃用了SMIL动画。