block by EE2dev 78c0c87a094967564a97d7f470249521

affine transformations

Full Screen

This block illustrate basic affine transformations with canvas.

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <style>
    body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
    div#canvas {background: #000;}
  </style>
</head>

<body>
  <div id="canvas"></div>
  <aside style="display:none">
            <img id="star-texture" src="https://ee2dev.github.io/startext/lib/stars-02.png">
  </aside> 

  <script>
    const canvasWidth = 200;
    const canvasHeight = 200;
    const transforms = ["rotate","fade","scale","translate"];

    let canvas = d3.select("div#canvas").selectAll("canvas")
      .data(transforms)
      .enter()
      .append("canvas")
      .attr("class", (d) => d)
      .attr("width", canvasWidth)
      .attr("height", canvasHeight);

    let props = getProps(transforms); 

    setInterval(rotate, 50);
    setInterval(fade, 50);
    setInterval(translate, 50);
    setInterval(scale, 50);

    function getProps(_transforms) {
      const arrayLength = _transforms.length;
      let allProps = [];
      for (let i = 0; i < arrayLength; i++) {
        let prop = {};
        prop.name = _transforms[i];
        prop.texture = getStar(i);
        prop.change = 1;
        prop.sign = 1;
        prop.center = {x: canvasWidth/2 - prop.texture.width/2, y: canvasHeight/2 - prop.texture.height/2};
        allProps.push(prop);
      }
      return allProps;
    }

    function getStar(num) {
      const texture = { 
        t: document.querySelector("#star-texture"),
        x: 80*num, 
        y: 0, 
        width: 80, 
        height: 80};
      return texture;
    }

    function rotate() {
      let context = d3.select("canvas.rotate").node().getContext('2d');
      context.clearRect(0, 0, canvasWidth, canvasHeight);
      context.translate(canvasWidth/2, canvasHeight/2);
      context.rotate(1 * Math.PI / 180);
      context.translate(-canvasWidth/2, -canvasHeight/2);
      context.drawImage(props[0].texture.t, props[0].texture.x, props[0].texture.y, 
        props[0].texture.width, props[0].texture.height, props[0].center.x, props[0].center.y, 
        props[0].texture.width, props[0].texture.height);
    }

    function translate() {
      let context = d3.select("canvas.translate").node().getContext('2d');
      props[1].change = (props[1].sign === 1) ? props[1].change + 1 : props[1].change - 1;
      if (Math.abs(props[1].change) > (canvasWidth - props[1].texture.width) / 2) {
        props[1].sign = props[1].sign * -1;
        props[1].change = 0;
      }
      context.clearRect(0, 0, canvasWidth, canvasHeight);
      context.translate(props[1].sign, 0);
      context.drawImage(props[1].texture.t, props[1].texture.x, props[1].texture.y, 
        props[1].texture.width, props[1].texture.height, props[1].center.x, props[1].center.y, 
        props[1].texture.width, props[1].texture.height);
    }

    function fade() {
      let context = d3.select("canvas.fade").node().getContext('2d');
      props[2].change = (props[2].sign === 1) ? props[2].change - 0.05 : props[2].change + 0.05;
      if (props[2].change < 0 || props[2].change > 1) {props[2].sign = props[2].sign * -1;}
      context.clearRect(0, 0, canvasWidth, canvasHeight);
      context.globalAlpha = props[2].change;
      context.drawImage(props[2].texture.t, props[2].texture.x, props[2].texture.y, 
        props[2].texture.width, props[2].texture.height, props[2].center.x, props[2].center.y, 
        props[2].texture.width, props[2].texture.height);
    }

    function scale() {
      let context = d3.select("canvas.scale").node().getContext('2d');
      props[3].change = (props[3].sign === 1) ? props[3].change + 1 : props[3].change - 1;
      let sg = props[3].sign * props[3].change;
      if (Math.pow(0.97, sg) < 0.05 || Math.pow(0.97, sg) > 1) {
        props[3].sign = props[3].sign * -1;
        props[3].change = 0;
      }
      let s = Math.pow(0.97, props[3].sign);
      context.clearRect(0, 0, canvasWidth, canvasHeight);
      context.translate(canvasWidth/2, canvasHeight/2);
      context.scale(s,s);
      context.translate(-canvasWidth/2, -canvasHeight/2);
      context.drawImage(props[3].texture.t, props[3].texture.x, props[3].texture.y, 
        props[3].texture.width, props[3].texture.height, props[3].center.x, props[3].center.y, 
        props[3].texture.width, props[3].texture.height);
    }
  </script>
</body>
</html>