这是我对关键帧动画的'第一次'尝试。由于无法通过JavaScript动态更改硬编码的CSS值,我之前被推迟了。
我用Google搜索了一下,发现它“可以”完成,但需要进行大量繁琐的工作,删除并更换部分或整个样式表。
无论如何,这是我的努力。这个特定剧本的最终目标是成为时钟之手的反弹。我已经可以用过渡和立方贝塞尔来做这个但只能得到一次反弹。我已经看到了这种效果使用各种js库等但你知道它是怎么回事 - 你喜欢自己动手。
我的问题是 - 我的方法下面有什么明显的错误。忽略琐事,这只是一个考验。我想看的是我的GenerateKeyFrames()函数和两种调用它的方法。
感谢您的任何信息。
var d = document;
var incr = 1;
var step = -6; //Initial start pos.
var coreCss = 'display: block;position: absolute;'
+'left: 100px;top: 10px;height: 95px;'
+'width: 4px;background-color: #000;'
+'transform-origin: center bottom;';
var initialAniCss = 'animation: reGen'+incr+' 1s 1 forwards;';
coreCss += initialAniCss;
var elementToAnimate = d.createElement('div');
elementToAnimate.setAttribute('style', coreCss);
d.body.appendChild(elementToAnimate);
function GenerateKeyFrames() {
/* Remove previous 'tmpSheet' stylesheet */
var currSheet = (d.getElementById('tmpSheet'));
if (currSheet) {
//currSheet.parentNode.removeChild(currSheet);// Doesn't seem as smooth as other 2 below!
//currSheet.remove(); - Not IE, shame.
currSheet.outerHTML = '';
}
/* Movement in degrees */
var p1 = step;
var p2 = step+6;
var p3 = step+4;
var p4 = step+6;
var p5 = step+5;
var p6 = step+6;
/* Create new keyframe. Must have new name! Adding an incrementing var to name does ok */
var frames = '@keyframes reGen'+incr+' { '
+'0% { transform: rotate('+p1+'deg) translateZ(0); animation-timing-function: ease-in;}'
+'25% { transform: rotate('+p2+'deg) translateZ(0); animation-timing-function: ease-out;}'
+'45% { transform: rotate('+p3+'deg) translateZ(0); animation-timing-function: ease-in;}'
+'65% { transform: rotate('+p4+'deg) translateZ(0); animation-timing-function: ease-out;}'
+'75% { transform: rotate('+p5+'deg) translateZ(0); animation-timing-function: ease-in;}'
+'85%,100% { transform: rotate('+p6+'deg) translateZ(0);animation-timing-function: ease-out;}}';
/* Create new tmpSheet style sheet to head */
var s = document.createElement( 'style' );
s.setAttribute("id", "tmpSheet");
s.innerHTML = frames;
document.getElementsByTagName('head')[0].appendChild(s);
/* Put it all together and it's ready to go */
var newAni = 'animation: reGen'+incr+' 1s 1 forwards;';
coreCss += newAni;
elementToAnimate.setAttribute('style', coreCss);
d.body.appendChild(elementToAnimate);
}
GenerateKeyFrames();
/* Can be called on animation end - or timed function rep().
elementToAnimate.addEventListener("animationend",function(e) {
incr++;
step += 6;
elementToAnimate.removeAttribute("style");
GenerateKeyFrames();
},false);
*/
function rep() {
incr++;
step += 6;
elementToAnimate.removeAttribute("style");
GenerateKeyFrames();
setTimeout(rep, 2000);
}
rep();
答案 0 :(得分:2)
我真的不喜欢用唯一名称动态插入所有这些关键帧的想法。如果我这样做并尝试使用CSS关键帧动画,我会创建两个动画,一个提供“双反弹”效果,另一个旋转包装围绕中心。
只使用HTML和CSS,你可以几乎创建一个完整的工作时钟,虽然没有任何方法可以在没有JavaScript的情况下在适当的时间启动它。
这是一个有趣的练习,我能够使用关键帧动画和一小部分JavaScript重新创建整个时钟效果,以确定动画的开始时间并提供负animation-delay
来抵消动画到适当的时间范围。
时间可以稍微徘徊,但实际上没有你想象的那么多。我让动画片在Chrome,FF和IE中一夜之间运行,并允许我的电脑进入睡眠状态,9小时后,时钟仍保持完美时间。然而,当我让它在我的手机的背景标签中运行一夜之后,时钟在早上完全被打破了。虽然看到整个目的是如何在网页上显示时钟,但页面不太可能长时间停留以使时钟明显关闭。
无论如何,这是片段:
window.addEventListener("load", function() {
var now = new Date();
var secondsDelay = now.getSeconds();
var minutesDelay = now.getMinutes() * 60 + secondsDelay;
var hoursDelay = (now.getHours() % 12) * 3600 + minutesDelay;
var minuteHand = document.querySelector(".minute .hand");
var minuteWrapper = document.querySelector(".minute");
var secondWrapper = document.querySelector(".second");
var hourWrapper = document.querySelector(".hour");
//set animation offsets with negative delay
minuteHand.style.animation = "minuteTick 60s -" + secondsDelay + "s infinite";
secondWrapper.style.animation = "rotateHolder steps(60) 60s -" + secondsDelay + "s infinite";
minuteWrapper.style.animation = "rotateHolder steps(60) 3600s -" + minutesDelay + "s infinite";
hourWrapper.style.animation = "rotateHolder steps(43200) 43200s -" + hoursDelay + "s infinite";
//start running
document.querySelector(".clock").classList.add("running");
});
.clock {
width: 200px;
height: 200px;
background-color: gray;
border-radius: 50%;
}
.sectionWrapper {
width: 200px;
height: 200px;
position: absolute;
transform: rotate(0deg);
}
.clock.running .second {
animation: rotateHolder 60s steps(60) infinite;
}
.clock.running .second .hand {
animation: secondTick 1s 0s infinite;
}
.clock.running .minute {
animation: rotateHolder 3600s steps(60) infinite;
}
.clock.running .minute .hand {
animation: minuteTick 60s 0s infinite;
}
.clock.running .hour {
animation: rotateHolder 43200s steps(43200) infinite;
}
.hand {
display: block;
position: absolute;
background-color: #000;
transform-origin: center bottom;
}
.second .hand {
left: 99px;
top: 5px;
height: 95px;
width: 2px;
background-color: red;
}
.minute .hand {
left: 98px;
top: 15px;
height: 85px;
width: 4px;
}
.hour .hand {
left: 97px;
top: 45px;
height: 55px;
width: 6px;
}
@keyframes secondTick {
0% { transform: rotate(0deg); animation-timing-function: ease-in; }
25% { transform: rotate(6deg); animation-timing-function: ease-out; }
45% { transform: rotate(4deg); animation-timing-function: ease-in; }
65% { transform: rotate(6deg); animation-timing-function: ease-out; }
75% { transform: rotate(5deg); animation-timing-function: ease-in; }
85%,100% { transform: rotate(6deg);animation-timing-function: ease-out; }
}
@keyframes minuteTick {
0%,98.3% { transform: rotate(0deg); animation-timing-function: ease-in; }
98.8% { transform: rotate(6deg); animation-timing-function: ease-out; }
99.1% { transform: rotate(4deg); animation-timing-function: ease-in; }
99.4% { transform: rotate(6deg); animation-timing-function: ease-out; }
99.6% { transform: rotate(5deg); animation-timing-function: ease-in; }
99.8%,100% { transform: rotate(6deg);animation-timing-function: ease-out; }
}
@keyframes rotateHolder {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
<div class="clock">
<div class="hour sectionWrapper">
<div class="hand"></div>
</div>
<div class="minute sectionWrapper">
<div class="hand"></div>
</div>
<div class="second sectionWrapper">
<div class="hand"></div>
</div>
</div>
答案 1 :(得分:1)
这似乎太复杂了。每当我使用复杂的动画时,我都会使用GSAP。 Here's a simplied demo that I made。它使用基本的JQuery和GSAP动画引擎TweenMax。
您可以通过ease visualizer
轻松地使用GSAP调整宽松度$(document).ready(function() {
var clock = $('.clock'); // clock container
var arm = $('.arm'); // seconds arm
var log = $('.log'); // log beneath clock
var position = 90; // starting position at 0 seconds
var time = 0;
setInterval(function(){
position += 6; // 360 / 60 = +6 deg per second
time ++;
TweenLite.to(arm, 0.3, {rotation:position, transformOrigin:"right bottom", ease: Back.easeOut.config(2), y: 0 });
log.text(time + " seconds and " + position + " degs");
}, 1000);
});
答案 2 :(得分:1)
只关注代码,我发现它非常好。
我唯一关心的是
/* Put it all together and it's ready to go */
var newAni = 'animation: reGen'+incr+' 1s 1 forwards;';
coreCss += newAni;
请注意,coreCss最终会有很多动画(在开发工具中验证)
你应该清除它。
但鉴于动画是通过前锋设置位置,可能会出现问题......
如果是这种情况,可能只玩2个动画??
如果您想获得有关如何获得该效果的建议,我将设置2个嵌套元素,一个具有您精心设计的关键帧,并且每秒运行一次。而另一个完整的圆圈,步了60次......
答案 3 :(得分:1)
完成时钟。
(function () {
/* Station Style Clock - kurt.grigg@yahoo.co.uk */
/* ^^^^^^^^^^^^^^^ Config below ^^^^^^^^^^^^^^^ */
var clockSize = 400;
var clockColour = 'rgb(255,255,255)';
var secHandColour = 'rgb(255,255,255)';
/* ^^^^^^^^^^^^^^^^^ End config ^^^^^^^^^^^^^^^^ */
var d = document;
var mcon = [];
var mrkrs = [];
var e = 360/60;
var degr = -6;
var mls = 100;
var prev = performance.now();
var radi = Math.PI / 180;
var offs = 90 * radi;
var rndId = 'id'+Math.random() * 1;
var secSpan = '.8s';
var minSpan = '1s';
var houSpan = '1s';
var secIncr = 0;
var minIncr = 0;
var houIncr = 0;
var secDeg, minDeg, houDeg, preSec, preMin, preHou;
var idx = d.getElementsByTagName('div').length;
var shdcol = 'rgba(0,0,0,0.6)';
var eiatf = ' translateZ(0); animation-timing-function: ease-in';
var eoatf = ' translateZ(0); animation-timing-function: ease-out';
d.write('<div id = "'+rndId+'" style="display:inline-block;line-height:0px;"></div>');
function xy (a) {
return (a * (clockSize * 2) / 100);
}
function shdw(s, h) {
var depth = xy(h);
var angle = s * radi;
var vsa = depth * Math.cos(angle);
var hsa = depth * Math.sin(angle);
return {vsa:vsa, hsa:hsa}
}
var dial = d.createElement('div');
dial.setAttribute('style', 'display: inline-block;'
+'position: relative;'
+'height: '+xy(100)+'px;'
+'width: '+xy(100)+'px;'
+'background-color:transparent;'
+'border-radius: 50%;'
+'margin: -'+xy(24)+'px -'+xy(24)+'px -'+xy(24)+'px -'+xy(24)+'px;');
d.getElementById(rndId).style.transform = 'scale3d(.5,.5,1)';
d.getElementById(rndId).appendChild(dial);
for (var i = 0; i < 60; i++) {
var mky = shdw(i * 6, 0.5).vsa;
var mkx = shdw(i * 6, 0.5).hsa;
var len = (i % 5) ? 4 : 8;
var wid = (i % 5) ? .8 : 4;
mcon[i] = d.createElement('div');
mcon[i].setAttribute('style', 'display: block;'
+'position: absolute;'
+'width: '+xy(4)+'px;'
+'height: '+xy(8)+'px;'
+'margin: auto; top: 0;bottom: 0;left: 0;right: 0;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'color: '+clockColour+';');
mrkrs[i] = d.createElement('div');
mrkrs[i].setAttribute('style', 'display: block;'
+'position: absolute;'
+'width: '+xy(wid)+'px;'
+'height: '+xy(len)+'px;'
+'margin: auto; top: 0;left: 0;right: 0;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'box-shadow:'+mkx+'px '+mky+'px 0px 0px rgba(0,0,0,0.7);'
+'background-color:'+clockColour+';');
mcon[i].appendChild(mrkrs[i]);
dial.appendChild(mcon[i]);
degr += 6;
mcon[i].style.top = xy(0) + xy(86) * Math.sin(-offs + e * i * radi) + 'px';
mcon[i].style.left= xy(0) + xy(86) * Math.cos(-offs + e * i * radi) + 'px';
mcon[i].style.transform = 'rotate(' + (degr) + 'deg)';
mcon[i].style.transformOrigin = 'center center';
}
/* Generic container div for all hands */
var handContainers = 'display: block;'
+'position: absolute;'
+'height: '+xy(100)+'px;'
+'width: '+xy(16)+'px;'
+'font-size: 0px; line-height: 0px; padding: 0;'
+'margin: auto; top: 0;bottom: 0; left: 0; right: 0;'
+'transform-origin: center center;';
/* Hour hand CSS */
var houClone = handContainers;
var houHand = d.createElement('div');
houHand.setAttribute('style', houClone);
dial.appendChild(houHand);
var hh = d.createElement('div');
hh.setAttribute('style', 'display: block;'
+'position: absolute;'
+'height: '+xy(48)+'px;'
+'width: '+xy(5)+'px;'
+'top: '+xy(15)+'px;'
+'margin: auto; left: 0; right: 0;'
+'outline: 1px solid transparent;'
+'background-color: '+clockColour+';');
houHand.appendChild(hh);
var houShad = houHand.cloneNode(true);
houShad.childNodes[0].style.backgroundColor = shdcol;
/* Minute hand CSS */
var minClone = handContainers;
var minHand = d.createElement('div');
minHand.setAttribute('style', minClone);
dial.appendChild(minHand);
var mh = d.createElement('div');
mh.setAttribute('style', 'display:block;'
+'position: absolute;'
+'height: '+xy(58)+'px;'
+'width: '+xy(3)+'px;'
+'top: '+xy(5)+'px;'
+'margin: auto; left: 0; right: 0;'
+'outline: 1px solid transparent;'
+'background-color: '+clockColour+';');
minHand.appendChild(mh);
var minShad = minHand.cloneNode(true);
minShad.childNodes[0].style.backgroundColor = shdcol;
/* Seconds hand CSS */
var secClone = handContainers;
var secHand = d.createElement('div');
secHand.setAttribute('style', secClone);
dial.appendChild(secHand);
var sh = d.createElement('div');
var svgsec = '<svg height="'+xy(100)+'" width="'+xy(16)+'">'
+'<g>'
+'<rect id="hd" x="'+xy(7.45)+'" y="'+xy(3)+'" width="'+xy(1)+'" height="'+xy(60)+'" stroke-width="0" fill="'+secHandColour+'"/>'
+'<circle id="cw" cx="50%" cy="'+xy(67)+'" r="'+xy(4)+'" stroke-width="0" stroke="'+secHandColour+'" fill="'+secHandColour+'"/>'
+'</g>'
+'</svg>';
sh.innerHTML = svgsec;
secHand.appendChild(sh);
var secShad = secHand.cloneNode(true);
var newColor = '"'+shdcol+'"';
var clnshd = svgsec.split(secHandColour).join("");
clnshd = clnshd.replace(/""/g, newColor);
secShad.innerHTML = clnshd;
var nut = d.createElement('div');
nut.setAttribute('style', 'display: block;'
+'position: absolute;'
+'height: '+xy(4)+'px;'
+'width: '+xy(4)+'px;'
+'border-radius: 50%;'
+'margin: auto;top: 0;bottom: 0;left: 0;right: 0;'
+'background-color: '+secHandColour+';'
+'box-shadow:'+xy(0)+'px '+xy(0.5)+'px 0px 0px rgba(0,0,0,0.7);'
+'z-index: 105;');
dial.appendChild(nut);
function houKeyFrames() {
var houSheet = (d.getElementById('tmphouSheet'+idx));
if (houSheet) {
houSheet.parentNode.removeChild(houSheet);
}
houClone = handContainers;
var p1 = houDeg;
var p2 = houDeg+1;
var p3 = houDeg+0.4;
var p4 = houDeg+1;
var p5 = houDeg+0.5;
var p6 = houDeg+1;
var houframes = '@keyframes hou'+idx+'gen'+houIncr+' { '
+'0% { transform: rotate('+p1+'deg) '+eiatf+';}'
+'30% { transform: rotate('+p2+'deg) '+eoatf+';}'
+'45% { transform: rotate('+p3+'deg) '+eiatf+';}'
+'60% { transform: rotate('+p4+'deg) '+eoatf+';}'
+'70% { transform: rotate('+p5+'deg) '+eiatf+';}'
+'80%,100% { transform: rotate('+p6+'deg) '+eoatf+';}}';
var hs = document.createElement( 'style' );
hs.setAttribute('id', 'tmphouSheet'+idx);
hs.innerHTML = houframes;
d.getElementsByTagName('head')[0].appendChild(hs);
var houAni = 'animation: hou'+idx+'gen'+houIncr+' '+houSpan+' 1 forwards;';
houClone += houAni;
houHand.setAttribute('style', houClone);
houHand.style.zIndex = 100;
dial.appendChild(houHand);
houShad.setAttribute('style', houClone);
houShad.style.top = xy(2.5)+'px';
houShad.style.zIndex = 99;
dial.appendChild(houShad);
}
function minKeyFrames() {
var minSheet = (d.getElementById('tmpMinSheet'+idx));
if (minSheet) {
minSheet.parentNode.removeChild(minSheet);
}
minClone = handContainers;
var p1 = minDeg;
var p2 = minDeg+6;
var p3 = minDeg+4;
var p4 = minDeg+6;
var p5 = minDeg+5;
var p6 = minDeg+6;
var minframes = '@keyframes min'+idx+'gen'+minIncr+' { '
+'0% { transform: rotate('+p1+'deg) '+eiatf+';}'
+'30% { transform: rotate('+p2+'deg) '+eoatf+';}'
+'45% { transform: rotate('+p3+'deg) '+eiatf+';}'
+'60% { transform: rotate('+p4+'deg) '+eoatf+';}'
+'70% { transform: rotate('+p5+'deg) '+eiatf+';}'
+'80%,100% { transform: rotate('+p6+'deg) '+eoatf+';}}';
var ms = document.createElement( 'style' );
ms.setAttribute('id', 'tmpMinSheet'+idx);
ms.innerHTML = minframes;
d.getElementsByTagName('head')[0].appendChild(ms);
var minAni = 'animation: min'+idx+'gen'+minIncr+' '+minSpan+' 1 forwards;';
minClone += minAni;
minHand.setAttribute('style', minClone);
minHand.style.zIndex = 102;
dial.appendChild(minHand);
minShad.setAttribute('style', minClone);
minShad.style.top = xy(3)+'px';
minShad.style.zIndex = 101;
dial.appendChild(minShad);
}
function secKeyFrames() {
var secSheet = (d.getElementById('tmpSecSheet'+idx));
if (secSheet) {
secSheet.parentNode.removeChild(secSheet);
}
secClone = handContainers;
var p1 = secDeg;
var p2 = secDeg+6;
var p3 = secDeg+4;
var p4 = secDeg+6;
var p5 = secDeg+5;
var p6 = secDeg+6;
var secframes = '@keyframes sec'+idx+'gen'+secIncr+' { '
+'0% { transform: rotate('+p1+'deg) '+eiatf+';}'
+'30% { transform: rotate('+p2+'deg) '+eoatf+';}'
+'45% { transform: rotate('+p3+'deg) '+eiatf+';}'
+'60% { transform: rotate('+p4+'deg) '+eoatf+';}'
+'70% { transform: rotate('+p5+'deg) '+eiatf+';}'
+'80%,100% { transform: rotate('+p6+'deg) '+eoatf+';}}';
var ss = document.createElement( 'style' );
ss.setAttribute('id', 'tmpSecSheet'+idx);
ss.innerHTML = secframes;
document.getElementsByTagName('head')[0].appendChild(ss);
var secAni = 'animation: sec'+idx+'gen'+secIncr+' '+secSpan+' 1 forwards;';
secClone += secAni;
secHand.setAttribute('style', secClone);
secHand.style.zIndex = 104;
dial.appendChild(secHand);
secShad.setAttribute('style', secClone);
secShad.style.top = xy(3.5)+'px';
secShad.style.zIndex = 103;
dial.appendChild(secShad);
}
function clock() {
var x = new Date();
var seconds = x.getSeconds();
var minutes = x.getMinutes();
var hours = (x.getHours() * 30) + (x.getMinutes() / 2);
if (seconds !== preSec) {
secIncr++;
secDeg = (seconds-1) * 6;
secHand.removeAttribute('style');
secKeyFrames();
if (secIncr > 59) {
secIncr = 0;
}
}
if (minutes !== preMin) {
minIncr++;
minDeg = (minutes-1) * 6;
minHand.removeAttribute('style');
minKeyFrames();
if (minIncr > 59) {
minIncr = 0;
}
}
if (hours !== preHou) {
houIncr++;
houDeg = (hours-1) * 1;
houHand.removeAttribute('style');
houKeyFrames();
if (houIncr > 59) {
houIncr = 0;
}
}
preSec = seconds;
preMin = minutes;
preHou = hours;
}
function cyc() {
var pres = performance.now();
if ((pres - prev) > mls) {
clock();
prev = performance.now();
}
window.requestAnimationFrame(cyc);
}
window.addEventListener('load', cyc, false);
})();
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Clock</title>
<style type="text/css">
html {
height: 100%;
}
body {
background-color: #ffff00;
text-align: center;
}
</style>
</head>
<body>
</body>
</html>
答案 4 :(得分:0)
Dave的BBC时钟示例。
(function () {
/* The BBC Analogue Clock - kurt.grigg@yahoo.co.uk */
/* ^^^^^^^^^^^^^^^^^^^ Config below ^^^^^^^^^^^^^^^^^^^ */
var clockSize = 300;
var dialcol = 'rgba(0,0,255,0.9)';
var handcol = 'rgb(230,230,230)';
/* ^^^^^^^^^^^^^^^^^^^ End config ^^^^^^^^^^^^^^^^^^^ */
var d = document;
var mrkrs = [];
var e = (360 / 12);
var degr = 0;
var mls = 100;
var prev = performance.now();
var radi = Math.PI / 180;
var offs = 60 * radi;
var rndId = 'id'+Math.random() * 1;
var sSpan = '.9s';
var mSpan = '1s';
var hSpan = '1s';
var sIncr = 0;
var mIncr = 0;
var hIncr = 0;
var sDeg, mDeg, hDeg, sPre, mPre, hPre;
var idx = d.getElementsByTagName('div').length;
d.write('<div id = "'+rndId+'" style="display:inline-block;line-height:0px;"></div>');
function xy(a) {
return (a * clockSize / 100);
}
var dial = d.createElement('div');
dial.setAttribute('style', 'display: inline-block;'
+'position: relative;'
+'height: '+clockSize+'px;'
+'width: '+clockSize+'px;'
+'margin: 0px;padding: 0px;'
+'border-radius: 5%;z-index: 1;'
+'background-color: '+dialcol+';');
d.getElementById(rndId).appendChild(dial);
for (var i = 0; i < 12; i++) {
var incr = xy(2.0) + (i * xy(0.2));
mrkrs[i] = d.createElement('div');
mrkrs[i].setAttribute('style', 'display: block;'
+'position: absolute;'
+'width: '+xy(14)+'px;'
+'height: '+xy(14)+'px;'
+'margin: auto; top: 0;bottom: 0;left: 0;right: 0;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'text-align: center !important;'
+'background-color: transparent;');
mrkrs[i].innerHTML = '<div style = "display: inline-block;'
+'position: relative;width: '+incr+'px;height: '+xy(14)+'px;'
+'font-size: 0px;background-color:'+handcol+';'
+'margin-right: '+xy(0.6)+'px;"></div>'
+'<div style = "display:inline-block;position: relative;'
+'width: '+incr+'px;height: '+xy(14)+'px;font-size: 0px;'
+'margin-left: '+xy(0.6)+'px;'
+'background-color:'+handcol+';"></div>';
dial.appendChild(mrkrs[i]);
degr += 30;
mrkrs[i].style.top = xy(0) + xy(77) *
Math.sin(-offs + e * i * radi) + 'px';
mrkrs[i].style.left= xy(0) + xy(77) *
Math.cos(-offs + e * i * radi) + 'px';
mrkrs[i].style.transform = 'rotate(' + (degr) + 'deg)';
mrkrs[i].style.transformOrigin = 'center center';
}
/* Hour CSS */
var hCss = 'display: block;'
+'position: absolute;'
+'height: '+xy(56)+'px;'
+'width: '+xy(6)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0;bottom: 0; left: 0; right: 0;'
+'transform-origin: center center 0;'
+'z-index: 2;';
var hClone = hCss;
var houHand = d.createElement('div');
houHand.setAttribute('style', hClone);
dial.appendChild(houHand);
var hh = d.createElement('div');
hh.setAttribute('style', 'display: block;'
+'position: absolute;'
+'height: '+xy(21)+'px;'
+'width: '+xy(6)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0; left: 0; right: 0;'
+'background-color: '+handcol+';');
houHand.appendChild(hh);
/* Minute CSS */
var mCss = 'display: block;'
+'position: absolute;'
+'height: '+xy(86)+'px;'
+'width: '+xy(4)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0; bottom: 0; left: 0; right: 0;'
+'transform-origin: center center;'
+'z-index: 3;';
var mClone = mCss;
var minHand = d.createElement('div');
minHand.setAttribute('style', mClone);
dial.appendChild(minHand);
var mh = d.createElement('div');
mh.setAttribute('style', 'display: block;'
+'position: absolute;'
+'height: '+xy(36)+'px;'
+'width: '+xy(4)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0; left: 0; right: 0;'
+'background-color: '+handcol+';');
minHand.appendChild(mh);
/* Second CSS */
var sCss = 'display: block;'
+'position: absolute;'
+'height: '+xy(90)+'px;'
+'width: '+xy(2)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0;bottom: 0; left: 0; right: 0;'
+'transform-origin: center center;'
+'z-index: 4;';
var sClone = sCss;
var secHand = d.createElement('div');
secHand.setAttribute('style', sClone);
dial.appendChild(secHand);
var sh = d.createElement('div');
sh.setAttribute('style', 'display: block;'
+'position: absolute;'
+'height: '+xy(39)+'px;'
+'width: '+xy(2)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0; left: 0; right: 0;'
+'background-color: '+handcol+';');
secHand.appendChild(sh);
var sectail = d.createElement('div');
sectail.setAttribute('style', 'display: block;'
+'position: absolute;'
+'height: '+xy(12)+'px;'
+'width: '+xy(2)+'px;'
+'margin: auto; left: 0; right: 0;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'top: '+xy(52)+'px;'
+'background-color: '+handcol+';');
secHand.appendChild(sectail);
/* Centre nut & optional glass front CSS */
var nut = d.createElement('div');
nut.setAttribute('style', 'display: inline-block;'
+'position: absolute;'
+'height: '+xy(10)+'px;'
+'width: '+xy(10)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'border: '+xy(3)+'px solid '+handcol+';'
+'border-radius: 50%;'
+'margin: auto;top: 0;bottom: 0;left: 0;right: 0;'
+'background-color: transparent;'
+'z-index: 5;');
dial.appendChild(nut);
var glass = d.createElement('div');
glass.setAttribute('style', 'display: block;'
+'height:'+clockSize+'px;'
+'width: '+clockSize+'px;'
+'border-radius:'+xy(5)+'px;'
+'margin: auto;top: 0;bottom: 0;left: 0;right: 0;'
+'z-index: 6;box-shadow:'
+'0 '+xy(1)+'px '+xy(1)+'px rgba(0,0,0,0.5),'
+'inset 0 '+xy(1)+'px rgba(255,255,255,0.3),'
+'inset 0 '+xy(10)+'px rgba(255,255,255,0.2),'
+'inset 0 '+xy(10)+'px '+xy(20)+'px rgba(255,255,255,0.25),'
+'inset 0 -'+xy(15)+'px '+xy(30)+'px rgba(0,0,0,0.3);');
dial.appendChild(glass);
var eiatf = 'translateZ(0); animation-timing-function: ease-in';
var eoatf = 'translateZ(0); animation-timing-function: ease-out';
function secKeyFrames() {
var secSheet = (d.getElementById('tmpSecSheet'+idx));
if (secSheet) {
secSheet.outerHTML = '';
}
sClone = sCss;
var p1 = sDeg;
var p2 = sDeg+6;
var p3 = sDeg+4;
var p4 = sDeg+6;
var p5 = sDeg+5;
var p6 = sDeg+6;
var secframes = '@keyframes reGen'+sIncr+' { '
+'0% { transform: rotate('+p1+'deg) '+eiatf+';}'
+'30% { transform: rotate('+p2+'deg) '+eoatf+';}'
+'45% { transform: rotate('+p3+'deg) '+eiatf+';}'
+'60% { transform: rotate('+p4+'deg) '+eoatf+';}'
+'70% { transform: rotate('+p5+'deg) '+eiatf+';}'
+'80%,100% { transform: rotate('+p6+'deg) '+eoatf+';}}';
var ss = document.createElement( 'style' );
ss.setAttribute('id', 'tmpSecSheet'+idx);
ss.innerHTML = secframes;
document.getElementsByTagName('head')[0].appendChild(ss);
var secAni = 'animation: reGen'+sIncr+' '+sSpan+' 1 forwards;';
sClone += secAni;
secHand.setAttribute('style', sClone);
dial.appendChild(secHand);
}
function minKeyFrames() {
var minSheet = (d.getElementById('tmpMinSheet'+idx));
if (minSheet) {
minSheet.outerHTML = '';
}
mClone = mCss;
var p1 = mDeg;
var p2 = mDeg+6;
var p3 = mDeg+4;
var p4 = mDeg+6;
var p5 = mDeg+5;
var p6 = mDeg+6;
var minframes = '@keyframes minGen'+mIncr+' { '
+'0% { transform: rotate('+p1+'deg) '+eiatf+';}'
+'30% { transform: rotate('+p2+'deg) '+eoatf+';}'
+'45% { transform: rotate('+p3+'deg) '+eiatf+';}'
+'60% { transform: rotate('+p4+'deg) '+eoatf+';}'
+'70% { transform: rotate('+p5+'deg) '+eiatf+';}'
+'80%,100% { transform: rotate('+p6+'deg) '+eoatf+';}}';
var ms = document.createElement( 'style' );
ms.setAttribute('id', 'tmpMinSheet'+idx);
ms.innerHTML = minframes;
d.getElementsByTagName('head')[0].appendChild(ms);
var minAni = 'animation: minGen'+mIncr+' '+mSpan+' 1 forwards;';
mClone += minAni;
minHand.setAttribute('style', mClone);
dial.appendChild(minHand);
}
function houKeyFrames() {
var houSheet = (d.getElementById('tmphouSheet'+idx));
if (houSheet) {
houSheet.outerHTML = '';
}
hClone = hCss;
var p1 = hDeg;
var p2 = hDeg+1;
var p3 = hDeg+0.4;
var p4 = hDeg+1;
var p5 = hDeg+0.5;
var p6 = hDeg+1;
var houframes = '@keyframes houGen'+hIncr+' { '
+'0% { transform: rotate('+p1+'deg) '+eiatf+';}'
+'30% { transform: rotate('+p2+'deg) '+eoatf+';}'
+'45% { transform: rotate('+p3+'deg) '+eiatf+';}'
+'60% { transform: rotate('+p4+'deg) '+eoatf+';}'
+'70% { transform: rotate('+p5+'deg) '+eiatf+';}'
+'80%,100% { transform: rotate('+p6+'deg) '+eoatf+';}}';
var hs = document.createElement( 'style' );
hs.setAttribute('id', 'tmphouSheet'+idx);
hs.innerHTML = houframes;
d.getElementsByTagName('head')[0].appendChild(hs);
var houAni = 'animation: houGen'+hIncr+' '+hSpan+' 1 forwards;';
hClone += houAni;
houHand.setAttribute('style', hClone);
dial.appendChild(houHand);
}
function animate() {
var x = new Date();
var seconds = x.getSeconds();
var minutes = x.getMinutes();
var hours = (x.getHours() * 30) + (x.getMinutes() / 2);
if (seconds !== sPre) {
sIncr++;
sDeg = (seconds-1) * 6;
secHand.removeAttribute('style');
secKeyFrames();
if (sIncr > 59) {
sIncr = 0;
}
}
if (minutes !== mPre) {
mIncr++;
mDeg = (minutes-1) * 6;
minHand.removeAttribute('style');
minKeyFrames();
if (mIncr > 59) {
mIncr = 0;
}
}
if (hours !== hPre) {
hIncr++;
hDeg = (hours-1) * 1;
houHand.removeAttribute('style');
houKeyFrames();
if (hIncr > 59) {
hIncr = 0;
}
}
sPre = seconds;
mPre = minutes;
hPre = hours;
}
function cyc() {
var pres = performance.now();
if ((pres - prev) > mls) {
animate();
prev = performance.now();
}
window.requestAnimationFrame(cyc);
}
window.addEventListener('load', cyc, false);
})();
&#13;