> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://p5js.sketchpad.cc/sp/pad/view/ro.80gqevzuan$/rev.47
 * 
 * authors: 
 *   GoToLoop

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



/**
 * Exploding Image (v2.51)
 * by BlindFish
 * mod GoToLoop (2015-Dec-11)
 *
 * forum.Processing.org/two/discussion/13845/
 * continual-restful-request-to-json-on-server-
 * parse-on-the-fly-render-data-inside-p5js-draw-loop
 *
 * p5js.ProcessingTogether.com/sp/pad/export/ro.C7yI5n-rAMHkBH
 * blindfish3.GitHub.io/p5-playground/exploding-image/
 */

'use strict';

var img, particles;

const DIAM = 6,
      RAD  = DIAM>>1,
      FPS  = 60,
      PATH = 'static/uploaded_resources/p.19392/',
      FILE = 'elephant.jpg',
      IS_LOCAL = false;

function preload() {
  img = loadImage((IS_LOCAL? '' :  PATH) + FILE);
}

function setup() {
  const renderer = confirm('WebGL?')? 'webgl' : 'p2d';
  Object.seal(createCanvas(img.width, img.height, renderer));
  frameRate(FPS).imageMode(CENTER);

  const rw = round(img.width / DIAM), rh = round(img.height / DIAM);
  particles = Array(rw*rh);
  console.info(particles.length, rw, rh, img.width, img.height);

  for (var block, yrw, yd, x, y = 0; y !== rh; ++y)
    for (yrw = y*rw, yd = y*DIAM, x = 0; x !== rw; ++x) {
      block = img.get(x*DIAM, yd, DIAM, DIAM);
      particles[yrw + x] = new Particle(x*DIAM + RAD, yd + RAD, block);
    }

  Object.freeze(particles);
  mouseX = mouseY = width << 1;
}

function draw() {
  background(0);
  for (var i = 0; i !== particles.length; particles[i++].display());
}

function Particle(x, y, img) {
  Object.seal(Object.defineProperties(this, {
    'ox':  { value: this.x = x, enumerable: true },
    'oy':  { value: this.y = y, enumerable: true },
    'img': { value: Object.freeze(img), enumerable: true }
  }));
}

Particle.AREA_SQ  = 1000;
Particle.FRICTION = .99;
Particle.SPRING   = .05;
Particle.FRICTION_SPRING = Particle.FRICTION * Particle.SPRING;

Particle.prototype.display = Object.freeze(function () {
  const dx = mouseX - this.x, dy = mouseY - this.y,
        Δ2 = dx*dx + dy*dy;
  var   νx = 0, νy = 0;

  if (Δ2 > Particle.AREA_SQ<<1) {
    νx = (this.ox - this.x) * Particle.FRICTION_SPRING;
    νy = (this.oy - this.y) * Particle.FRICTION_SPRING;
  } else if (Δ2 < Particle.AREA_SQ) {
    const θ = atan2(dy, dx);
    νx = -Δ2 * cos(θ), νy = -Δ2 * sin(θ);
  }

  image(this.img, this.x += νx, this.y += νy);
});

Object.freeze(Object.freeze(Particle).prototype);