Chase Tyler Adams
Chase Tyler Adams

Reputation: 1

Changing shapes using addEventListener in HTML5

I'm trying to change the shape of the particles in this script so that every time you click, the shapes change to a random shape. The shapes I want to do are circles (which they already are), squares, triangles, pentagons, and a four-leaf clover shape without the stem. I want to use the addEventListener method, but i have no idea where to even start with that. Thanks in advance, and here's the code I have so far:

http://jsfiddle.net/eampkcrr/

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = window.innerWidth;
var height = window.innerHeight;
var xCirc;
var yCirc;
var rCirc;
var animate = true;

canvas.width = width;
canvas.height = height;

makeParticles();
makeShapes();


function makeParticles() {
    xCenter = canvas.width/2;
    yCenter = canvas.height/2;
    particles = [];
    for (var i = 0; i < 3000; i++){
        particles.push(new Particle());
    }
}

function makeShapes() {
    xCenter = canvas.width/2;
    yCenter = canvas.height/2;
    shapes = [];

    shapes.push(new Circle());
}

function Circle() {
    var r1 = 150;
    var r2 = 1000;
    var gradient1 = context.createRadialGradient(width/2, height/2, r1, width/2, height/2, r2);

    gradient1.addColorStop(0.2, "yellow");
    gradient1.addColorStop(0.8, "purple");
    context.fillStyle = gradient1;
    context.fillRect(0, 0, canvas.width, canvas.height);

    var gradient2 = context.createRadialGradient(width/2, height/2, 120, width/2, height/2, 150);
    gradient2.addColorStop(0, "black");
    gradient2.addColorStop(.75, "black");
    gradient2.addColorStop(1, "orange");

    context.beginPath();
    context.arc(width/2, height/2, 150, 0, 2 * Math.PI, true);
    context.fillStyle = gradient2;
    context.fill();
}

function start() {

    if(animate){
        window.requestAnimationFrame(start);
    }

    draw();
    moveParticles();
}



function Particle() {
    this.x = Math.floor((Math.random() * canvas.width) + 1);
    this.y = Math.floor((Math.random() * canvas.height) + 1);
    this.z = Math.floor((Math.random() * canvas.width));

    var grad = context.createRadialGradient(this.x, this.y, Math.floor((Math.random() * 10) + 1), this.x, this.y, Math.floor((Math.random() * 10) + 1));
    var colors = ["red", "green", "blue", "orange", "purple", "yellow", "white"];

    grad.addColorStop(0, colors[Math.floor(Math.random()*colors.length)]);
    grad.addColorStop(1, colors[Math.floor(Math.random()*colors.length)]);
    this.color = grad;
    this.radius = 1;
}

function draw() {   

    Circle();

    for (var i = 0; i < particles.length; i++){
        var p = particles[i];

        xP = (xCenter - p.x) * (canvas.width/p.z);
        xP += xCenter;
        yP = (yCenter - p.y) * (canvas.width/p.z);
        yP += yCenter;
        rP = (canvas.width/p.z);

        context.beginPath();
        context.arc(xP, yP, rP, 0, 2 * Math.PI, true);
        context.fillStyle = p.color;
        context.fill();

        xCirc -= p.x;
        yCirc -= p.y;
    }
}

function moveParticles() {
    for (var j = 0; j < particles.length; j++){
        var p = particles[j];
        p.z -= 2;
        if (p.z <= 0){
            p.z = canvas.width;
        } 
    }
}

start();

Upvotes: 0

Views: 59

Answers (1)

markE
markE

Reputation: 105025

You can listen for click events on the canvas like this:

canvas.onclick=function(){ ... }

To change the particle shape, you can add a draw method to Particle that draws the appropriate shape based on a particle's this.particleType.

function Particle(particleType) {
    this.particleType=particleType;

    this.x = Math.floor((Math.random() * canvas.width) + 1);
    this.y = Math.floor((Math.random() * canvas.height) + 1);
    this.z = Math.floor((Math.random() * canvas.width));

    var grad = context.createRadialGradient(this.x, this.y, Math.floor((Math.random() * 10) + 1), this.x, this.y, Math.floor((Math.random() * 10) + 1));
    var colors = ["red", "green", "blue", "orange", "purple", "yellow", "white"];

    grad.addColorStop(0, colors[Math.floor(Math.random()*colors.length)]);
    grad.addColorStop(1, colors[Math.floor(Math.random()*colors.length)]);
    this.color = grad;
    this.radius = 1;

    this.draw=function(){
        // update position
        var xP = (xCenter - this.x) * (canvas.width/this.z);
        xP += xCenter;
        var yP = (yCenter - this.y) * (canvas.width/this.z);
        yP += yCenter;
        var rP = (canvas.width/this.z);

        // set fillStyle
        context.fillStyle = this.color;

        // draw on context based on the particle's current shape
        switch (this.particleType){
            case 'circle':
                context.beginPath();
                context.arc(xP, yP, rP, 0, 2 * Math.PI, true);
                context.fill();       
                break;
            case 'square':
                context.fillRect(xP-rP, yP-rP, rP*2, rP*2);
                break;
        }

        // update 
        xCirc -= this.x;
        yCirc -= this.y;
    }
}

Then your external function draw simply requests each particle to draw itself:

function draw() {   
    Circle();
    for (var i = 0; i < particles.length; i++){
        // request each particle to draw itself
        var p = particles[i].draw();
    }
}

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = window.innerWidth;
var height = window.innerHeight;
var xCirc;
var yCirc;
var rCirc;
var xCenter,yCenter;
var animate = true;
var pTypes=['circle','square'];
var pTypeIndex=0;

canvas.width = width;
canvas.height = height;

makeParticles();
makeShapes();

canvas.onclick=function(){
  pTypeIndex++;
  if(pTypeIndex>pTypes.length-1){pTypeIndex=0;}
  var pType=pTypes[pTypeIndex];
  for(var i=0;i<particles.length;i++){
    particles[i].particleType=pType;
  }
};

start();

function makeParticles() {
  xCenter = canvas.width/2;
  yCenter = canvas.height/2;
  particles = [];
  for (var i = 0; i < 500; i++){
    particles.push(new Particle(pTypes[pTypeIndex]));
  }
}

function makeShapes() {
  xCenter = canvas.width/2;
  yCenter = canvas.height/2;
  shapes = [];

  shapes.push(new Circle());
}

function Circle() {
  var r1 = 150;
  var r2 = 1000;
  var gradient1 = context.createRadialGradient(width/2, height/2, r1, width/2, height/2, r2);

  gradient1.addColorStop(0.2, "yellow");
  gradient1.addColorStop(0.8, "purple");
  context.fillStyle = gradient1;
  context.fillRect(0, 0, canvas.width, canvas.height);

  var gradient2 = context.createRadialGradient(width/2, height/2, 120, width/2, height/2, 150);
  gradient2.addColorStop(0, "black");
  gradient2.addColorStop(.75, "black");
  gradient2.addColorStop(1, "orange");

  context.beginPath();
  context.arc(width/2, height/2, 150, 0, 2 * Math.PI, true);
  context.fillStyle = gradient2;
  context.fill();
}

function start() {

  if(animate){
    window.requestAnimationFrame(start);
  }

  draw();
  moveParticles();
}



function Particle(particleType) {
  this.particleType=particleType;

  this.x = Math.floor((Math.random() * canvas.width) + 1);
  this.y = Math.floor((Math.random() * canvas.height) + 1);
  this.z = Math.floor((Math.random() * canvas.width));

  var grad = context.createRadialGradient(this.x, this.y, Math.floor((Math.random() * 10) + 1), this.x, this.y, Math.floor((Math.random() * 10) + 1));
  var colors = ["red", "green", "blue", "orange", "purple", "yellow", "white"];

  grad.addColorStop(0, colors[Math.floor(Math.random()*colors.length)]);
  grad.addColorStop(1, colors[Math.floor(Math.random()*colors.length)]);
  this.color = grad;
  this.radius = 1;

  this.draw=function(){
    // update position
    var xP = (xCenter - this.x) * (canvas.width/this.z);
    xP += xCenter;
    var yP = (yCenter - this.y) * (canvas.width/this.z);
    yP += yCenter;
    var rP = (canvas.width/this.z);

    // set fillStyle
    context.fillStyle = this.color;

    // draw on context
    switch (this.particleType){
      case 'circle':
        context.beginPath();
        context.arc(xP, yP, rP, 0, 2 * Math.PI, true);
        context.fill();       
        break;
      case 'square':
        context.fillRect(xP-rP, yP-rP, rP*2, rP*2);
        break;
    }

    // update 
    xCirc -= this.x;
    yCirc -= this.y;
  }

}

function draw() {   
  Circle();
  for (var i = 0; i < particles.length; i++){
    var p = particles[i].draw();
  }
}

function moveParticles() {
  for (var j = 0; j < particles.length; j++){
    var p = particles[j];
    p.z -= 2;
    if (p.z <= 0){
      p.z = canvas.width;
    } 
  }
}
<h4>Click to change shapes.</h4>
<canvas id="canvas" width=300 height=300></canvas>

[ Fixed "yip" in circle <--> square conversion -- Thanks @Kaiido ]

Upvotes: 1

Related Questions