Reputation: 1
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:
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
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