‹ Building SuperCollider for piCore LinuxKeyboard Shortcuts ›

Motion Induced Blindness

2020-01-27 21:16:40 visuals

A fascinating illusion. Stare at the green dot for a bit.

More info here en.wikipedia.org/wiki/Motion-induced_blindness.

This is just a remake of the wikipedia GIF animation, but this JavaScript code and its variables/settings opens up for experimentation.

<div style="background-color:black;">
<canvas id="canvas" width="600" height="600"></canvas>
<script>
//motion-induced blindness after en.wikipedia.org/wiki/Motion-induced_blindness
(function() {
  let rotationRate= 0.1;  //rps
  let blinkRate= 2.5;  //Hz
  let numCrosses= 7;
  let numDots= 3;
  let dotRadius= 5;
  let crossWidth= 0.1;  //percent
  let crossWeight= 3;
  let colorBackground= '#000';
  let colorCrosses= '#00F';
  let colorCenter= '#0F0';
  let colorDots= '#FF0';
  let can= document.getElementById('canvas');  //EDIT name of canvas to draw to

  function draw() {
    let bottom= can.getBoundingClientRect().bottom;
    if(bottom>=0 && bottom<=(innerHeight+can.height)) {  //only draw when visible in browser
      let w2= can.width*0.5;
      let h2= can.height*0.5;
      let uw= can.width/3;

      let ctx= can.getContext('2d');
      ctx.fillStyle= colorBackground;
      ctx.fillRect(0, 0, can.width, can.height);

      //--crosses
      ctx.save();
      ctx.translate(w2, h2);
      ctx.lineWidth= crossWeight;
      ctx.strokeStyle= colorCrosses;
      ctx.rotate(Date.now()/1000*Math.PI*2*rotationRate%(Math.PI*2));
      ctx.beginPath();
      for(let i= 0; i<numCrosses; i++) {
        let y= i*(uw*2)/(numCrosses-1)-uw;
        for(let j= 0; j<numCrosses; j++) {
          let x= j*(uw*2)/(numCrosses-1)-uw;
          ctx.moveTo(x-(crossWidth*uw), y);
          ctx.lineTo(x+(crossWidth*uw), y);
          ctx.moveTo(x, y-(crossWidth*uw));
          ctx.lineTo(x, y+(crossWidth*uw));
        }
      }
      ctx.stroke();
      ctx.restore();

      //--center
      if ((Date.now()/1000*blinkRate)%1>0.5) {
        ctx.beginPath();
        ctx.fillStyle= colorCenter;
        ctx.ellipse(w2, h2, dotRadius, dotRadius, 0, 0, Math.PI*2);
        ctx.fill();
      }

      //--dots
      ctx.save();
      ctx.translate(w2, h2);
      ctx.fillStyle= colorDots;
      ctx.rotate(0.5*Math.PI);
      for (let i= 0; i<numDots; i++) {
        ctx.beginPath();
        ctx.ellipse(can.width/4, 0, dotRadius, dotRadius, 0, 0, Math.PI*2);
        ctx.fill();
        ctx.rotate(Math.PI*2/numDots);
      }
      ctx.restore();
    }
    window.requestAnimationFrame(draw);
  }
  window.requestAnimationFrame(draw);
})();
</script>
</div>

Also attached is the same code ported to Processing and SuperCollider.

Attachments:
motion_induced_blindness.pde
motion_induced_blindness.scd
‹ Building SuperCollider for piCore LinuxKeyboard Shortcuts ›