Skip to content Skip to sidebar Skip to footer

Dynamically Changing Css Keyframe Values To Create A Clock

This is my 'very first' foray into keyframe animation. I was put off before by the alleged inability to dynamically change hard coded CSS values on the fly via JavaScript. I Googl

Solution 1:

I don't really like the idea of inserting all those keyframes dynamically with unique names. If I were doing this and trying to use CSS keyframe animations, I'd create two animations, one that provides your "double-bounce" effect, and one that rotates a wrapper around the center.

Using just HTML and CSS, you can almost create a full working clock, although you don't have any way to start it at the right time without JavaScript.

This was a fun exercise though, and I was able to recreate the whole clock effect using just keyframe animations with a tiny bit of JavaScript to determine the starting time of the animation and supply a negative animation-delay to offset the animations to the proper timeframes.

The time can wander a bit, but really not as much as you might think. I left the animations running overnight in Chrome, FF, and IE, and allowed my computer to go to sleep, and 9 hours later the clocks were still keeping perfect time. However, when I left it running in a background tab of my phone overnight, the clock was completely broken in the morning. Though, seeing as how the whole purpose is to display a clock on a webpage, it's unlikely that the page would stick around long enough for the clock to be noticeably off.

Anyway, here's the snippet:

window.addEventListener("load", function() {
  var now = newDate();
  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 runningdocument.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 60ssteps(60) infinite;
}
.clock.running.second.hand {
  animation: secondTick 1s0s infinite;
}
.clock.running.minute {
  animation: rotateHolder 3600ssteps(60) infinite;
}
.clock.running.minute.hand {
  animation: minuteTick 60s0s infinite;
}
.clock.running.hour {
  animation: rotateHolder 43200ssteps(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); }
}
<divclass="clock"><divclass="hour sectionWrapper"><divclass="hand"></div></div><divclass="minute sectionWrapper"><divclass="hand"></div></div><divclass="second sectionWrapper"><divclass="hand"></div></div></div>

Solution 2:

Finished clock.

(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>');

    functionxy (a) {
        return (a * (clockSize * 2) / 100);
    }

    functionshdw(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);

    functionhouKeyFrames() {
        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);
    }

    functionminKeyFrames() {
        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);
    }

    functionsecKeyFrames() {
        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);
    }

    functionclock() {
        var x = newDate();
        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;
    }

    functioncyc() {
        var pres = performance.now(); 
        if ((pres - prev) > mls) {
            clock();
            prev = performance.now();
        }
        window.requestAnimationFrame(cyc);
    } 

    window.addEventListener('load', cyc, false);
})();
<!doctype html><html><head><metacharset="UTF-8"><title>Clock</title><styletype="text/css">html {
            height: 100%;
        }
        
        body {
            background-color: #ffff00;
            text-align: center;
        }
    </style></head><body></body></html>

Solution 3:

This seems way too complicated. Whenever I'm working with complex animations, I use GSAP. Here's a simplied demo that I made. It uses basic JQuery and the GSAP animation engine, TweenMax.

You can easily adjust the easing with GSAP via their ease visualizer

$(document).ready(function() {
  var clock = $('.clock'); // clock containervar arm = $('.arm'); // seconds armvar log = $('.log'); // log beneath clockvar position =  90; // starting position at 0 secondsvar 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);

});

Solution 4:

Focusing just in the code, I find it quite good.

my only concern would be

/* Put it all together and it's ready to go */var newAni = 'animation: reGen'+incr+' 1s 1 forwards;';
coreCss += newAni;

Note that coreCss will at the end have lots of animations (verified in dev tools)

You should just clear it.

But given that the animation is setting the position via forwards, may be that can give problems ...

If this is the case, may be playing with just 2 animations ??

In case that you want advice about how I would get that effect, I would set 2 nested elements, one with the elaborate keyframes that you have , and running every second. And the other making the full circle, stepped 60 times ...

Solution 5:

BBC clock example for Dave.

(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>');

functionxy(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';

functionsecKeyFrames() {
    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);
}

functionminKeyFrames() {
    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);
}

functionhouKeyFrames() {
    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);
}

functionanimate() {
    var x = newDate();
    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;
}

functioncyc() {
    var pres = performance.now(); 
    if ((pres - prev) > mls) {
        animate();
        prev = performance.now();
    }
    window.requestAnimationFrame(cyc);
} 

window.addEventListener('load', cyc, false);
})();

Post a Comment for "Dynamically Changing Css Keyframe Values To Create A Clock"