<svg width='0' height='0'>
  <defs>
    <g id='coord-syst' class='coord-syst'>
      <line x1='0' x2='650' 
            y1='0' y2='0'/>
      <line x1='0' x2='0' 
            y1='0' y2='350'/>
      
      <circle cx='0' cy='0' r='2' />
    </g>
    
    <g id='box-guides' class='box-guides'>
      <line x1='0' x2='150' y1='40' y2='40'/>
      <line x1='75' x2='75' y1='0' y2='80' />
      
      <line x1='0' y1='0' x2='150' y2='80' />
      <line x1='0' y1='80' x2='150' y2='0' />
      
      <circle cx='75' cy='40' r='2' />
    </g>
  </defs>
</svg>
<section class='code'>
  <pre><span class='token token--angled-brackets'>&lt;</span><span class='token token--tag-name'>rect</span> <span class='token token--attr-name'>transform</span><span class='token token--equal'>=</span><span class='token token--quote'>'</span><span class='inf token token--attr-val'></span><span class='token token--quote'>'</span><span class='token token--angled-brackets'>&gt;</span></pre>
</section>
<section>
  <svg>
    <g class='box box--svg box--initial'>
      <rect x='-75' y='-40' width='150' height='80'/>
      <use xlink:href='#coord-syst'/>
      <use x='-75' y='-40' xlink:href='#box-guides'/>
    </g>
    <g class='box box--svg box--initial'>
      <rect x='65' y='65' width='150' height='80'/>
      <use xlink:href='#coord-syst'/>
      <use x='65' y='65' xlink:href='#box-guides'/>
    </g>
    <g class='box box--svg box--transforming'>
      <rect x='-75' y='-40' width='150' height='80'/>
      <use xlink:href='#coord-syst'/>
      <use x='-75' y='-40' xlink:href='#box-guides'/>
    </g>
  </svg>
  
  <div class='ctrls paused'>
    <button id='c1'>
      <div>play</div>
      <div>pause</div>
    </button>
    <button id='c2'>reset</button>
  </div>
</section>
@import "compass/css3";

$c: #be4c39;
$bg-c: #e18728;
$axes-c: #333;
$guides-c: #ddd;
$code-bg: #1d1f21;
$t: 6s;

body {
  margin: 0;
  
  > svg { display: none; }
}

section svg {
  overflow: hidden;
  width: 650px; height: 350px;
}

section {
  position: relative;
  width: 650px;
  margin: 0 auto;
}

.box {  
  &--svg {
    rect {
      fill: #e18728;
    }
  }
  
  &--initial {
    opacity: .5;
    
    svg & {      
      .coord-syst line {
        stroke-width: 4;
      }
    }
  }
  
  &--transforming {
    background: rgba($bg-c, .7);
    
    & rect {
      fill-opacity: .7;
      stroke: $bg-c;
      stroke-width: 2;
    }
  }
}

.coord-syst {
  line {
    stroke: $axes-c;
    stroke-width: 2;
  }
  
  circle {
    stroke: #9351a6;
    stroke-width: 4;
  }
}

.box-guides {
  line {
    //opacity: .65;
    stroke: $guides-c;
    stroke-dasharray: 9;
    stroke-width: 2;
  }
  
  circle {
    stroke: $c;
    stroke-width: 5;
  }
}

.meas {
  stroke: #222;
  
  line {
    stroke-dasharray: 7;
  }
  
  text {
    stroke: transparent;
    font: 900 italic 1em serif;
  }
}

.code {
  padding: 0 .5em;
  margin: .25em auto;
  background: $code-bg;
}

.token {
  line-height: 2;
  
  &--angled-brackets { color: #d49b00; }
  &--tag-name { color: #e18728; }
  &--attr-name { color: #be4c39; }
  &--attr-val { color: #4ca454; }
  &--equal { color: #4472b9; }
  &--quote { color: #f4e3dc; }
}

.ctrls {
  position: absolute;
  top: 6.5em; left: .5em;
  
  button {
    display: block;
    overflow: hidden;
    margin: .25em;
    border: solid 0;
    padding: 0;
    width: 3em; height: 2em;
    font: 1em/2 arial;
    text-align: center;
    cursor: pointer;
  }
  
  div {
    transition: .35s;
    pointer-events: none;
  }
  
  &:not(.paused) div {
    transform: translateY(-100%);
  }
  
  .cssgradients & button {
    width: 2em;
    color: transparent;
    
    &[id='c1'] {
      background: 
        linear-gradient(to right bottom, 
            $bg-c 50%, transparent 50%) 
          50% 1em, 
        linear-gradient(90deg, 
            $guides-c 35%, transparent 35%, 
            transparent 65%, $guides-c 65%) 
          50% 50%, 
        linear-gradient(to right top, 
            $bg-c 50%, transparent 50%) 
          left 50% bottom 1em 
        $axes-c;
      background-repeat: no-repeat;
      background-size: 0 0, 50% 1em;
      transition: .35s;
    }
    
    &[id='c2'] {
      box-shadow: inset 0 0 0 .5em $axes-c;
      background: $guides-c;
    }
  }
  
  .cssgradients &.paused [id='c1'] {
    background-size: 50% .5em, 0 0;
  }
}
Object.getOwnPropertyNames(Math).map(function(p) {
  window[p] = Math[p];
});

/* yeah, doing this is a bad idea... 
 * whatever... 
 * this thing checks whether a number is 
 * in the specified range, 
 * with flag dictating whether the limits are 
 * strict or not 
 * b = upper limit, defaults to 1 
 * a = lower limit, defaults to 0 
 * flag: 
 * strict limits if not specified or 0 
 * non-strict lower limit if divisible by 2 
 * non-strict upper limit if divisible by 3
 */
Number.prototype.ξ = function(b, a, flag) {
  var b = ((b - 1) || 0) + 1, 
      a = a || 0, 
      c1 = (flag && flag%2 === 0) 
  					? (this >= a) 
  					: (this > a), 
      c2 = (flag && flag%3 === 0) 
  					? (this <= b) 
  					: (this < b);
  
  return c1 && c2;
};

var sel1 = '.box--transforming', 
    sel2 = '.token--attr-val', 
    b = document.querySelector(sel1), 
    inf = document.querySelector(sel2), 
    ctrl = document.querySelector('.ctrls'), 
    d = { 'x': 140, 'y': 105 }, 
    rot = 45, 
    tu = 60, 
    t = tu, r_id = null;

var ani = function() {
  var t_val, rt, x, y, a;
  
  if(t.ξ(tu, 0, 3)) {
    t_val = 'translate(0 0)';
    b.setAttribute('transform', t_val);
    inf.textContent = '';
  }
  
  if(t.ξ(2*tu, tu, 3)) {
    rt = t - tu;
    x = rt*d.x/tu;
    y = rt*d.y/tu;
    t_val = 'translate(' + x + ' ' + y + ')';
    b.setAttribute('transform', t_val);
    t_val = 'translate(' + round(x) + ' ' + 
      										 round(y) + ')';
    inf.textContent = t_val;
  }
  
  if(t.ξ(4*tu, 3*tu, 3)) {
    rt = t - 3*tu;
    a = rt*rot/tu;
    t_val = 
      'translate(' + d.x + ' ' + d.y + ') ' + 
      'rotate(' + a + ')';
    b.setAttribute('transform', t_val);
    t_val = 
      'translate(' + d.x + ' ' + d.y + ') ' + 
      'rotate(' + round(a) + ')';
    inf.textContent = t_val;
  }
  
  if(t.ξ(5*tu, 4*tu, 3)) {
    t_val = 
      'translate(' + d.x + ' ' + d.y + ') ' + 
      'rotate(' + rot + ')';
    b.setAttribute('transform', t_val);
    inf.textContent = t_val;
  }
  
  if(t === 5*tu) { t = 0; }
    
  t++;
  
  r_id = requestAnimationFrame(ani);
};

ctrl.addEventListener('click', function(e) {
  var target = e.target;
    
  if(target.id === 'c1') {
    if(!ctrl.classList.contains('paused')) {
      cancelAnimationFrame(r_id);
      r_id = null;
      ctrl.classList.add('paused');
    }
    else {
      ctrl.classList.remove('paused');
      ani();
    }
  }
  
  if(target.id === 'c2') {
    cancelAnimationFrame(r_id);
    r_id = null;
    t = 100;
    b.setAttribute('transform', 
                   'translate(0 0)');
    inf.textContent = '';
    ctrl.classList.add('paused');
  }
}, false);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js