title: Dynamically changing CSS keyframe values to create a clock
body: <p>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. </p>
  
  <p>I Googled around a bit to find it 'can' be done but with a lot of fiddly work finding, removing and replacing parts of or whole stylesheets.</p>
  
  <p>Anyway, here's my effort. The eventual goal of this particular script is to be the bounce of clock hand. I can already do this with transition and cubic bezier but can only get one bounce in. I've seen this effect using various js libraries etc but you know how it is - you like to roll your own.</p>
  
  <p>My question is - Is there anything glaringly wrong with my method below. Ignore the trivia, it's just a test. What I want looking at is my GenerateKeyFrames() function and the two methods of calling it.</p>
  
  <p>Thanks for any info.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>    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();</code></pre>
  </div>
  </div>
  </p>