Image Transformation SVG

Image transformation using SVG

by João Gouveia

HTML

<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://www.numericjs.com/lib/numeric-1.2.6.js"></script>
<div id="screen">
    <div id="buttons">
      <button class="transform" data-targets="[[492,329],[542,330],[569,434],[424,424]]">Transform</button>
      <button class="reset" data-targets="[[0,0],[400,0],[400,400],[0,400]]">Reset</button>
    </div>
    <div id="background"></div>
    <div id="vis"></div>
</div>

CSS

#screen {
    position: relative;
}

#buttons {
  position: absolute;
  top: 20px;
  left: 750px;
  z-index: 2;
}

button {
  display: block;
  width: 10em;
}

button:focus {
  outline: none;
}

#background {
    position: absolute;
    top: 0;
    left: 0;
    background-image: url("http://i.imgur.com/gtvs1CJ.png");
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
    height: 200px;
    width: 300px;
    z-index: -2;
}

#vis {
    width: 700px;
    height: 500px;    
}

svg {
    position: absolute;
    top: 0;
    left: 0;    
}

JavaScript

var margin = {top: 152.5, right: 200, bottom: 152.5, left: 200},
    width = 700 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;
//var width = 300;//500;
//var height = 195;//325;

var sourcePoints = [[0, 0], [width, 0], [width, height], [0, height]],
    targetPoints = [[225.201, 48.411], [1188.39, 185.159], [1869.12, 892.339], [217.525, 231.14]];

var svgTransform;
var svgClick;

var transform = ["", "-webkit-", "-moz-", "-ms-", "-o-"].reduce(function(p, v) { 
        return v + "transform" in document.body.style ? v : p; 
    }) + "transform";

function transformed() {  
  for (var a = [], b = [], i = 0, n = sourcePoints.length; i < n; ++i) {
    var s = sourcePoints[i], t = targetPoints[i];
    a.push([s[0], s[1], 1, 0, 0, 0, -s[0] * t[0], -s[1] * t[0]]), b.push(t[0]);
    a.push([0, 0, 0, s[0], s[1], 1, -s[0] * t[1], -s[1] * t[1]]), b.push(t[1]);
  }

  var X = numeric.solve(a, b, true), matrix = [
    X[0], X[3], 0, X[6],
    X[1], X[4], 0, X[7],
       0,    0, 1,    0,
    X[2], X[5], 0,    1
  ].map(function(x) {
    return d3.round(x, 6);
  });

  svgTransform.style(transform, "matrix3d(" + matrix + ")");
}

/*function transform() { 
    //$("#image").css("top", 0); 
    transformed();  
}*/

function reset() {
    //$("#image").css("top", "250px");
    targetPoints = [[0, 0], [width, 0], [width, height], [0, height]];
    transformed();
    targetPoints = [[225.201, 48.411], [1188.39, 185.159], [1869.12, 892.339], [217.525, 231.14]];
    pointsCounter = 0;
}

var pointsCounter = 0;
function printPoints(evt) {
    /*console.log("PageX: " + evt.pageX + " PageY: " + evt.pageY);
    console.log("LayerX: " + evt.layerX + " LayerY: " + evt.layerY);
    console.log("------------");*/
    
    if(pointsCounter > 3) pointsCounter = 0;
    targetPoints[pointsCounter] = [d3.event.x, d3.event.y];
    if(pointsCounter == 3) transformed();
    pointsCounter++;
    
}

function initialize() {
    svgTransform =...