Circular Path Animation not working with Pulsating Movement - javascript

I'm trying to achieve a kind of pulsating moon effect with canvas in HTML5. I have the pulsating effect, but my requestAnimation function does not seem to be updating the frame along the circular path that I have defined. Here's the javascript.
window.requestAnimFrame = function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame
||
window.mozRequestAnimationFrame || window.oRequestAnimationFrame
|| window.msRequestAnimationFrame ||
function(a) {
window.setTimeout(a, 1E3 / 60)
}
}();
var canvas = document.getElementById('canvas');       
var context = canvas.getContext('2d');
function Ball(radius, color) {
if (radius === undefined) {
radius = 40;
}
if (color === undefined) {
color = "#ff0000";
}
this.x = 0;
this.y = 0;
this.radius = radius;
this.rotation = 0;
this.scaleX = 1;
this.scaleY = 1;
this.lineWidth = 1;
}
Ball.prototype.draw = function(context) {
context.save();
context.translate(this.x, this.y);
context.rotate(this.rotation);
context.scale(this.scaleX, this.scaleY);
context.lineWidth = this.lineWidth;
context.fillStyle = "#e50000";
context.beginPath();
//x, y, radius, start_angle, end_angle, anti-clockwise
context.arc(0, 0, this.radius, 0, (Math.PI * 2), true);
context.closePath();
context.fill();
if (this.lineWidth > 0) {
context.stroke();
}
context.restore();
};
window.onload = function() {    
var canvas = document.getElementById('canvas'),
        context = canvas.getContext('2d'),
        ball = new Ball(),
        angle = 0,
        centerScale = 1,
        range = 0.5,
        speed = 0.02,
 
pathX = canvas.width / 2,
pathY = canvas.height / 2,
pathRadius = 150,
pathAngle = 0;
ball.x = Math.cos(pathAngle) * pathRadius + pathX;
ball.y = Math.sin(pathAngle) * pathRadius + pathY;  
(function drawFrame() {      
window.requestAnimationFrame(drawFrame, canvas);      
context.clearRect(0, 0, canvas.width, canvas.height);      
ball.scaleX = ball.scaleY = centerScale + Math.sin(angle) * range;  
angle += speed;    
pathAngle += speed;
ball.draw(context);    
}());  
};

You're rotating a circle around it's own centerpoint so it's not orbiting relative to it's centerpoint.
// offset the circles rotation by 100px off its centerpoint
context.arc(100, 0, this.radius, 0, (Math.PI * 2), true);
Example code ad a demo:
window.requestAnimFrame = function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame
||
window.mozRequestAnimationFrame || window.oRequestAnimationFrame
|| window.msRequestAnimationFrame ||
function(a) {
window.setTimeout(a, 1E3 / 60)
}
}();
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
function Ball(radius, color) {
if (radius === undefined) {
radius = 40;
}
if (color === undefined) {
color = "#ff0000";
}
this.x = 0;
this.y = 0;
this.radius = radius;
this.rotation = 0;
this.scaleX = 1;
this.scaleY = 1;
this.lineWidth = 1;
}
Ball.prototype.draw = function(context) {
context.save();
context.translate(this.x, this.y);
context.rotate(this.rotation);
context.scale(this.scaleX, this.scaleY);
context.lineWidth = this.lineWidth;
context.fillStyle = "#e50000";
context.beginPath();
//x, y, radius, start_angle, end_angle, anti-clockwise
context.arc(50, 0, this.radius, 0, (Math.PI * 2), true);
context.closePath();
context.fill();
if (this.lineWidth > 0) {
context.stroke();
}
context.restore();
};
window.onload = function() {
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
ball = new Ball(),
angle = 0,
centerScale = 1,
range = 0.5,
speed = 0.02,
pathX = canvas.width / 2,
pathY = canvas.height / 2,
pathRadius = 50,
pathAngle = 0;
ball.x = canvas.width/2; // Math.cos(pathAngle) * pathRadius + pathX;
ball.y = canvas.height/2; //Math.sin(pathAngle) * pathRadius + pathY;
(function drawFrame() {
window.requestAnimationFrame(drawFrame, canvas);
context.clearRect(0, 0, canvas.width, canvas.height);
ball.scaleX = ball.scaleY = centerScale + Math.sin(angle) * range;
angle += speed;
pathAngle += speed;
ball.rotation+=Math.PI/180;
ball.draw(context);
}());
};
body{ background-color:white; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

Related

adding mouse movement to a canvas animation

i have made a an animations in canvas html but now i want to make the origin from where the balls originate move around the canvas according to my mouse position. i want to add mouse event function but i can't seem to get the logic straightand add added to the code , any help would be appreciated !
function runParticles () {
var canvas = document.createElement("canvas");
c = canvas.getContext("2d");
var particles = {};
var particleIndex = 0;
var particleNum = 15;
// set canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// add canvas to body
document.body.appendChild(canvas);
// style the canvas
c.fillStyle = "black";
c.fillRect(0, 0, canvas.width, canvas.height);
function Particle() {
this.x = canvas.width / 2;
this.y = canvas.height / 2;
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = 0.3;
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
this.life = 0;
this.maxLife = Math.random() * 30 + 60;
this.color = "hsla(" + parseInt(Math.random() * 360, 10) + ",90%,60%,0.5";
}
Particle.prototype.draw = function() {
this.x += this.vx;
this.y += this.vy;
if (Math.random() < 0.1) {
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
}
this.life++;
if (this.life >= this.maxLife) {
delete particles[this.id];
}
c.fillStyle = this.color;
//c.fillRect(this.x, this.y, 5, 10);
c.beginPath();
c.arc(this.x, this.y, 2.5, degToRad(0), degToRad(360));
c.fill();
};
setInterval(function() {
//normal setting before drawing over canvas w/ black background
c.globalCompositeOperation = "source-over";
c.fillStyle = "rgba(0,0,0,0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < particleNum; i++) {
new Particle();
}
// c.globalCompositeOperation = "darken";
for (var i in particles) {
particles[i].draw();
}
}, 30);
}
function degToRad(deg) {
var radians = (deg * Math.PI / 180) - Math.PI / 2;
return radians;
}
<!DOCTYPE html5>
<html>
<head>
<title>disturbed</title>
<script src="toto.js" type="text/javascript"></script>
<script>
window.onload = () => runParticles();
</script>
</head>
<body>
</body>
</html>
I've added a function to detect the mouse position:
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}
I've declared a variable m (the mouse).
var m = {x:canvas.width/2,y:canvas.height/2};
and I've changed the origin of the particles from this.x = canvas.width / 2;
this.y = canvas.height / 2;to this.x = m.x; this.y = m.y;
This is the position when the mouse do not move over the canvas
I've added an event "mousemove". When the mouse move over the canvas it's position change.
canvas.addEventListener("mousemove", (evt)=>{
m = oMousePos(canvas, evt);
})
I've also added an event "mouseleave". When the mouse leaves the canvas, the mouse goes back in the center.
canvas.addEventListener("mouseleave", (evt)=>{
m = {x:canvas.width/2,y:canvas.height/2};
})
Also I've changed the setInterval for requestAnimationFrame ( much more efficient ). The code inside is your code.
function runParticles () {
var canvas = document.createElement("canvas");
c = canvas.getContext("2d");
var particles = {};
var particleIndex = 0;
var particleNum = 8;
// set canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var m = {x:canvas.width/2,y:canvas.height/2};///////
// add canvas to body
document.body.appendChild(canvas);
// style the canvas
c.fillStyle = "black";
c.fillRect(0, 0, canvas.width, canvas.height);
function Particle() {
this.x = m.x;//////////
this.y = m.y;//////////
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = 0.3;
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
this.life = 0;
this.maxLife = Math.random() * 30 + 60;
this.color = "hsla(" + parseInt(Math.random() * 360, 10) + ",90%,60%,0.5";
}
Particle.prototype.draw = function() {
this.x += this.vx;
this.y += this.vy;
if (Math.random() < 0.1) {
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
}
this.life++;
if (this.life >= this.maxLife) {
delete particles[this.id];
}
c.fillStyle = this.color;
//c.fillRect(this.x, this.y, 5, 10);
c.beginPath();
c.arc(this.x, this.y, 2.5, degToRad(0), degToRad(360));
c.fill();
};
function Draw() {
window.requestAnimationFrame(Draw);
c.globalCompositeOperation = "source-over";
c.fillStyle = "rgba(0,0,0,0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < particleNum; i++) {
new Particle();
}
// c.globalCompositeOperation = "darken";
for (var i in particles) {
particles[i].draw();
}
}
Draw();
///////////////////
canvas.addEventListener("mousemove", (evt)=>{
m = oMousePos(canvas, evt);
})
canvas.addEventListener("mouseleave", (evt)=>{
m = {x:canvas.width/2,y:canvas.height/2};
})
///////////////////
}
function degToRad(deg) {
var radians = (deg * Math.PI / 180) - Math.PI / 2;
return radians;
}
runParticles();
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}
body,canvas{margin:0;padding:0;}
I hope this helps.

Canvas spark lines

I would like to create a spark lines with the various lengths and animate them by moving them from center to end of the canvas and the process has to loop on a canvas. To achieve this i started with a particle system.
Please check the below code and here is the codepen link https://codepen.io/yesvin/pen/XPKNYW
window.onload = function() {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
centerX = w / 2,
centerY = h / 2,
speed = 0,
time = 0,
numObjects = 5,
x, y, vx, vy, life, maxLife;
var lines = {},
lineIndex = 0;
function Line() {
this.x = centerX;
this.y = centerY;
this.vx = Math.random() * 16 - 8;
this.vy = Math.random() * 16 - 8;
this.life = 0;
this.maxLife = Math.random() * 10 + 20;
lineIndex++;
lines[lineIndex] = this;
this.id = lineIndex;
}
Line.prototype.draw = function() {
this.x += this.vx;
this.y += this.vy;
this.life++;
if (this.life >= this.maxLife) {
delete lines[this.id];
}
context.fillStyle = "#000";
context.fillRect(this.x, this.y, 3, 3)
}
setInterval(function() {
context.fillStyle = 'rgba(255,255,255,.05)';
context.fillRect(0, 0, w, h);
new Line();
for (var i in lines) {
lines[i].draw();
}
}, 30)
};
body {
overflow: hidden;
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
So, How do we create this same effect using the lineTo(), and moveTo() methods? I tried with the following code (which is commented in a codepen)
context.beginPath();
context.moveTo(centerX, centerY);
context.lineTo(this.x * Math.random() * w, this.y * Math.random() * h);
context.lineWidth = 1;
context.stroke();
context.strokeStyle = "#000";
Sample GIF
Thanks in advance.
Here is one approach...
With lines you will get a more continuous effect:
The change I'm making to your code is to keep track of the start and end points.
window.onload = function() {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
centerX = w / 2,
centerY = h / 2;
var lines = {},
lineIndex = 0;
function Line() {
this.start = { x: centerX, y: centerY };
this.end = { x: centerX, y: centerY };
this.vx = Math.random() * 16 - 8;
this.vy = Math.random() * 16 - 8;
this.life = 0;
this.maxLife = Math.random() * 10 + 20;
lineIndex++;
lines[lineIndex] = this;
this.id = lineIndex;
}
Line.prototype.draw = function() {
this.end.x += this.vx;
this.end.y += this.vy;
this.life++;
if (this.life >= this.maxLife) {
delete lines[this.id];
}
//context.fillStyle = "#000";
//context.fillRect(this.x, this.y, 1, 1)
context.beginPath();
context.moveTo(this.start.x, this.start.y);
context.lineTo(this.end.x, this.end.y);
context.lineWidth = 1;
context.stroke();
context.strokeStyle = "#000";
}
setInterval(function() {
context.fillStyle = 'rgba(255,255,255,.05)';
context.fillRect(0, 0, w, h);
new Line();
for (var i in lines) {
lines[i].draw();
}
}, 30)
};
body {
overflow: hidden;
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>

Canvas Fade Out Particles

I'm a canvas beginner, sorry if this is a trivial question. How can I make the fireworks in my work fade out once they've exploded?
https://jsfiddle.net/ccwhryvv/
var SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight,
mousePos = {
x: 400,
y: 300
},
// create canvas
canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
particles = [],
rockets = [],
MAX_PARTICLES = 400,
colorCode = 0;
// init
$(document).ready(function() {
$('#content')[0].appendChild(canvas);
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
setInterval(launch, 800);
setInterval(loop, 1000 / 50);
});
// update mouse position
$(document).mousemove(function(e) {
e.preventDefault();
mousePos = {
x: e.clientX,
y: e.clientY
};
});
// launch more rockets!!!
$(document).mousedown(function(e) {
for (var i = 0; i < 5; i++) {
launchFrom(Math.random() * SCREEN_WIDTH * 2 / 3 + SCREEN_WIDTH / 6);
}
});
function launch() {
launchFrom(SCREEN_WIDTH / 2);
}
function launchFrom(x) {
if (rockets.length < 10) {
var rocket = new Rocket(x);
rocket.explosionColor = Math.floor(Math.random() * 360 / 10) * 10;
rocket.vel.y = Math.random() * -3 - 4;
rocket.vel.x = Math.random() * 6 - 3;
rocket.size = 8;
rocket.shrink = 0.999;
rocket.gravity = 0.01;
rockets.push(rocket);
}
}
function loop() {
// update screen size
if (SCREEN_WIDTH != window.innerWidth) {
canvas.width = SCREEN_WIDTH = window.innerWidth;
}
if (SCREEN_HEIGHT != window.innerHeight) {
canvas.height = SCREEN_HEIGHT = window.innerHeight;
}
// clear canvas
context.fillStyle = "rgba(0, 0, 0, 0.0)";
context.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
var existingRockets = [];
for (var i = 0; i < rockets.length; i++) {
// update and render
rockets[i].update();
rockets[i].render(context);
// calculate distance with Pythagoras
var distance = Math.sqrt(Math.pow(mousePos.x - rockets[i].pos.x, 2) + Math.pow(mousePos.y - rockets[i].pos.y, 2));
// random chance of 1% if rockets is above the middle
var randomChance = rockets[i].pos.y < (SCREEN_HEIGHT * 2 / 3) ? (Math.random() * 100 <= 1) : false;
/* Explosion rules
- 80% of screen
- going down
- close to the mouse
- 1% chance of random explosion
*/
if (rockets[i].pos.y < SCREEN_HEIGHT / 5 || rockets[i].vel.y >= 0 || distance < 50 || randomChance) {
rockets[i].explode();
} else {
existingRockets.push(rockets[i]);
}
}
rockets = existingRockets;
var existingParticles = [];
for (var i = 0; i < particles.length; i++) {
particles[i].update();
// render and save particles that can be rendered
if (particles[i].exists()) {
particles[i].render(context);
existingParticles.push(particles[i]);
}
}
// update array with existing particles - old particles should be garbage collected
particles = existingParticles;
while (particles.length > MAX_PARTICLES) {
particles.shift();
}
}
function Particle(pos) {
this.pos = {
x: pos ? pos.x : 0,
y: pos ? pos.y : 0
};
this.vel = {
x: 0,
y: 0
};
this.shrink = .97;
this.size = 2;
this.resistance = 1;
this.gravity = 0;
this.flick = false;
this.alpha = 1;
this.fade = 0;
this.color = 0;
}
Particle.prototype.update = function() {
// apply resistance
this.vel.x *= this.resistance;
this.vel.y *= this.resistance;
// gravity down
this.vel.y += this.gravity;
// update position based on speed
this.pos.x += this.vel.x;
this.pos.y += this.vel.y;
// shrink
this.size *= this.shrink;
// fade out
this.alpha -= this.fade;
};
Particle.prototype.render = function(c) {
if (!this.exists()) {
return;
}
c.save();
c.globalCompositeOperation = 'lighter';
var x = this.pos.x,
y = this.pos.y,
r = this.size / 2;
var gradient = c.createRadialGradient(x, y, 0.1, x, y, r);
gradient.addColorStop(0.1, "rgba(255,255,255," + this.alpha + ")");
gradient.addColorStop(0.8, "hsla(" + this.color + ", 100%, 50%, " + this.alpha + ")");
gradient.addColorStop(1, "hsla(" + this.color + ", 100%, 50%, 0.1)");
c.fillStyle = gradient;
c.beginPath();
c.arc(this.pos.x, this.pos.y, this.flick ? Math.random() * this.size : this.size, 0, Math.PI * 2, true);
c.closePath();
c.fill();
c.restore();
};
Particle.prototype.exists = function() {
return this.alpha >= 0.1 && this.size >= 1;
};
function Rocket(x) {
Particle.apply(this, [{
x: x,
y: SCREEN_HEIGHT}]);
this.explosionColor = 0;
}
Rocket.prototype = new Particle();
Rocket.prototype.constructor = Rocket;
Rocket.prototype.explode = function() {
var count = Math.random() * 10 + 80;
for (var i = 0; i < count; i++) {
var particle = new Particle(this.pos);
var angle = Math.random() * Math.PI * 2;
// emulate 3D effect by using cosine and put more particles in the middle
var speed = Math.cos(Math.random() * Math.PI / 2) * 15;
particle.vel.x = Math.cos(angle) * speed;
particle.vel.y = Math.sin(angle) * speed;
particle.size = 10;
particle.gravity = 0.2;
particle.resistance = 0.92;
particle.shrink = Math.random() * 0.05 + 0.93;
particle.flick = true;
particle.color = this.explosionColor;
particles.push(particle);
}
};
Rocket.prototype.render = function(c) {
if (!this.exists()) {
return;
}
c.save();
c.globalCompositeOperation = 'lighter';
var x = this.pos.x,
y = this.pos.y,
r = this.size / 2;
var gradient = c.createRadialGradient(x, y, 0.1, x, y, r);
gradient.addColorStop(0.1, "rgba(255, 255, 255 ," + this.alpha + ")");
// gradient.addColorStop(1, "rgba(255, 255, 255, " + this.alpha + ")");
gradient.addColorStop(1, "rgba(255, 255, 255, 0)");
c.fillStyle = gradient;
c.beginPath();
c.arc(this.pos.x, this.pos.y, this.flick ? Math.random() * this.size / 2 + this.size / 2 : this.size, 0, Math.PI * 2, true);
c.closePath();
c.fill();
c.restore();
};
Thank you!
Creating gradients is expensive -- especially inside an animation loop.
It's more efficient is to pre-create a spritesheet of gradient exploding sprites before your app starts:
Create an in-memory canvas to act as a spritesheet,
Choose a dozen standard colors for you explosions.
Create gradient sprites in sequential order of exploding.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var ss=makeSpritesheet(10,15);
ctx.fillStyle='navy';
ctx.fillRect(0,0,cw,ch);
ctx.drawImage(ss,0,0);
function makeSpritesheet(maxRadius,colorCount){
var c=document.createElement('canvas');
var ctx=c.getContext('2d');
var spacing=maxRadius*2.5;
c.width=spacing*maxRadius;
c.height=spacing*(colorCount+1);
for(var colors=0;colors<colorCount;colors++){
var y=(colors)*spacing+spacing/2;
var color = parseInt(colors/colorCount*360);
for(r=2;r<=maxRadius;r++){
var x=(r-1)*spacing;
var gradient = ctx.createRadialGradient(x, y, 0, x, y, r);
gradient.addColorStop(0.2, "white");
gradient.addColorStop(0.7, 'hsla('+color+', 100%, 50%, 1)');
gradient.addColorStop(1.0, "rgba(0,0,0,0)");
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(x,y,r,0,Math.PI*2);
ctx.closePath();
ctx.fill();
}
}
return(c);
}
body{ background-color:white; }
#canvas{border:1px solid red; }
<canvas id="canvas" width=640 height=512></canvas>
During Animation, draw the sprites from the spritesheet to your canvas.
Fade the opacity of each sprite by setting context.globalAlpha before drawing each sprite.

How to smooth out edges of circles drawn in canvas with arc?

I am drawing circles in a html5 canvas using arc but the edges are rough and not smooth. I am looking to smooth them out. Stacked overflow requires me to write more so my code to text ratio is better
Code
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
}());
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
createCircle(100, 150, '85', '675');
createCircle(300, 150, '70', '479');
createCircle(500, 150, '91', '715');
createCircle(700, 150, '58', '334');
function createCircle(x, y, temp, hash, callback) {
var radius = 75;
var endPercent = parseInt(temp, 10);
var curPerc = 0;
var counterClockwise = false;
var circ = Math.PI * 2;
var quart = Math.PI / 2;
context.strokeStyle ='#006600';
context.lineWidth = 10;
context.lineCap = "round";
var offset = quart;
function doText(context, x, y, temp, hash) {
context.lineWidth = 10;
if(parseInt(temp, 10) > 90)
context.fillStyle = '#ad2323';
else if(parseInt(temp, 10) > 82)
context.fillStyle = '#ffcc33';
else
context.fillStyle = '#006600';
context.font = "28px sans-serif";
context.fillText(temp + 'º', x - 20, y + 10);
context.fillText(hash + 'KH/s', x - 50, y - 90);
}
function animate(current) {
context.lineWidth = 10;
if(curPerc > 89)
context.strokeStyle = '#ad2323';
else if(curPerc > 81)
context.strokeStyle = '#ffcc33';
context.beginPath();
context.arc(x, y, radius, offset, ((circ) * current) + offset , false);
context.stroke();
context.closePath();
curPerc++;
if (curPerc < endPercent) {
requestAnimationFrame(function () {
animate(curPerc / 100);
});
}
else {
doText(context, x, y, temp, hash);
if (callback) callback.call();
}
}
animate();
}
JSFiddle = http://jsfiddle.net/uhVj6/712/
You are drawing strokes multiple times so they are drawing over one another. You need to clear the area where the old arc stroke was and then draw the new one
context.clearRect(x - radius - context.lineWidth,
y - radius - context.lineWidth,
radius * 2 + (context.lineWidth*2),
radius * 2 + (context.lineWidth*2));
context.beginPath();
context.arc(x, y, radius, offset, ((circ) * current) + offset , false);
context.stroke();
context.closePath();
JSFiddle

HTML5 Canvas - Adding more circles rotate in circular motion

I am trying to add a few more circles in the circular loop using HTML5 canvas but it doesn't seem to work. I want the other circles to kind of trail the circle is already rotating there. I am also wondering how to make the circular motion non-linear (that is, it moves in varying speed like it has easing).
Can you guys help? :/ Thanks heaps. Below is my code.
<canvas id="canvas" width="450" height="450"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
var dd = 4;
var angle = 0;
/*var cx = 197;
var cy = 199;
var radius = 200;*/
var cx = w/2;
var cy = h/2;
var radius = 200;
function draw(x, y) {
ctx.fillStyle = "rgb(38,161,220)";
ctx.strokeStyle = "rgb(38,161,220)";
ctx.clearRect(0, 0, w, h);
ctx.save();
ctx.beginPath();
ctx.beginPath();
//ctx.rect(x - 30 / 2, y - 30 / 2, 50, 30);
// Circle 1
ctx.arc(x-1/2, y-1/2, 10, 0, 2 * Math.PI, false);
ctx.fill();
ctx.stroke();
ctx.restore();
};
/** context.beginPath();
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke(); **/
var fps = 120;
window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / fps);
};
})();
function animate() {
setTimeout(function () {
requestAnimFrame(animate);
// increase the angle of rotation
//angle += Math.acos(1-Math.pow(dd/radius,2)/2);
angle += Math.acos(1-Math.pow(dd/radius,2)/2);
// calculate the new ball.x / ball.y
var newX = cx + radius * Math.cos(angle);
var newY = cy + radius * Math.sin(angle);
// draw
draw(newX, newY);
// draw the centerpoint
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, Math.PI * 2, false);
ctx.closePath();
ctx.stroke();
}, 1000 / fps );
}
animate();
</script>
Easing between where and where?
Heres some non-linear angular velocities:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<canvas id="canvas" width="450" height="450"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
var dd = 4;
var angle = 0;
var cx = w/2;
var t = 0;
var velocity = 0.01;
var cy = h/2;
var radius = 200;
function draw(x, y) {
ctx.fillStyle = "rgb(38,161,220)";
ctx.strokeStyle = "rgb(38,161,220)";
ctx.clearRect(0, 0, w, h);
ctx.save();
ctx.beginPath();
ctx.beginPath();
ctx.arc(x-1/2, y-1/2, 10, 0, 2 * Math.PI, false);
ctx.fill();
ctx.stroke();
ctx.restore();
};
var fps = 120;
window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / fps);
};
})();
function animate() {
setTimeout(function () {
// increase the angle of rotation
angle += velocity;
//sinusoidal velocity
velocity += 0.005 * (Math.sin(t));
t += 0.1;
// randomzed velocity:
//velocity += 0.001 * (Math.random() - 1);
// draw
// calculate the new ball.x / ball.y
var newX = cx + radius * Math.cos(angle);
var newY = cy + radius * Math.sin(angle);
draw(newX, newY);
// draw the centerpoint
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, Math.PI * 2, false);
ctx.closePath();
ctx.stroke();
requestAnimFrame(animate);
}, 1000 / fps );
}
animate();
</script>
</body>
</html>
You can make a circle class like this:
var Circle = function(radius,velocity,etc){
this.radius = radius
this.velocity = velocity
this.etc = etc
// and whatever other properties you think you need
}
then
var circleArray = []
for(var i = 0; i < circleCount; i++){
circleArray.push(new Circle(2,0.1,"some_property"))
}
then inside animate():
circleArray.forEach(function(circle){
//drawing code
})
Until you ask a more specific question, thats all I can give you

Categories