Unreveal animation canvas - javascript

Can anyone help me how to do the reverse the animation of this?
var $ = function(id) { return document.getElementById(id); }
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var cvs = $('cvs');
var ctx = cvs.getContext('2d');
var x = 0, y = 0, r = 0, count = 0;
x = cvs.width / 2;
y = cvs.height / 2;
time = Math.sqrt( Math.pow(cvs.width, 2) +
Math.pow(cvs.height, 2) ) / 2;
ctx.fillStyle = 'red';
ctx.rect(0, 0, cvs.width, cvs.height);
ctx.fill();
ctx.globalCompositeOperation = "destination-out";
(function animate() {
if( count >= time ) {
return false;
}else {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
r++;
count++;
window.requestAnimFrame(animate, 0);
}
})();
http://jsfiddle.net/j57msxr5/10/
I can't find a way to make the circle shrink. From big to small/dot/gone.

I recommend taking a different approach. I'd start with objects that represent what's going to be drawn on canvas, and maintain the state within those objects. Then to stop the animation you can check if the radius is more than zero:
var $ = document.getElementById.bind(document);
var cvs = $('cvs');
var ctx = cvs.getContext('2d');
var circle = {
x: cvs.height/2,
y: cvs.width/2,
radius: cvs.width/2,
color: 'white',
animate: function() {
if (this.radius > 0) {
this.radius--;
}
return this;
},
draw: function(ctx) {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2*Math.PI, false);
ctx.fillStyle = this.color;
ctx.fill();
return this;
}
};
var bg = {
x: 0,
y: 0,
w: cvs.width,
h: cvs.height,
color: 'red',
draw: function(ctx) {
ctx.fillStyle = this.color;
ctx.rect(this.x, this.y, this.w, this.h);
ctx.fill();
}
};
(function frame() {
// If you draw your objects in order
// you don't need to set globalCompositeOperation
bg.draw(ctx);
circle.draw(ctx).animate();
requestAnimationFrame(frame);
}());
DEMO: http://jsfiddle.net/9uLrL6d6/

Related

Animating circle in html canvas with javascript

I need to animate a circle moving in a html canvas. For this purpose, I decided to use a typical sprite animation technique which consist in the following general steps:
Initialize the background (in this case, just a gray rectangle)
Calculate new sprite's coordinates
Draw the sprite (the circle)
Reset the backgound
Goto 2
My problem is that the result looks like all the old circles seem to be redrawn each time I call ctx.fill() despite I am reseting the canvas.
What am I doing wrong? Any suggestion?
var canvas;
var ctx;
var canvasPos;
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
function init() {
canvas = document.getElementById("target_temp");
ctx = canvas.getContext("2d");
canvasPos = { x: canvas.offsetLeft, y: canvas.offsetTop };
drawSlider();
}
var y = 7;
function animate() {
y = y + 1;
knob.setPosition(8, y);
knob.clear();
knob.draw();
if (y < 93) {
setTimeout(animate, 10);
}
}
function drawSlider() {
ctx = canvas.getContext("2d");
ctx.fillStyle = "#d3d3d3";
ctx.fillRect(0, 0, 16, 100);
}
var knob = {
position: { x: 8, y: 7 },
oldPosition: { x: 8, y: 7 },
setPosition(_x, _y) {
this.oldPosition = this.position;
this.position.x = _x;
this.position.y = _y
},
clear() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawSlider();
},
draw() {
ctx.fillStyle = rgbToHex(0, 0, 112);
ctx.arc(8, this.position.y, 7, 0, 2 * Math.PI);
ctx.fill();
}
}
window.onload = function () { init(); animate(); };
<!DOCTYPE html>
<html>
<boyd>
<canvas id="target_temp" width="16px" height="100px"></canvas>
</boyd>
</html>
I see you already figured out to use the beginPath but I will disagree with the location I will put that at the very beginning of the function animate, take a look at the code below, I refactored your code, got rid of some unused variables, and made the slider an object just like you have for the knob
var canvas = document.getElementById("target_temp");
var ctx = canvas.getContext("2d");
var slider = {
width: 16,
height: 100,
draw() {
ctx.fillStyle = "#d3d3d3";
ctx.fillRect(0, 0, this.width, this.height);
}
}
var knob = {
position: {x: 8, y: 7},
radius: 8,
draw() {
ctx.fillStyle = "#00D";
ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
ctx.fill();
}
}
function animate() {
ctx.beginPath()
ctx.clearRect(0, 0, canvas.width, canvas.height);
slider.draw();
if (knob.position.y + knob.radius < slider.height)
knob.position.y++;
knob.draw();
setTimeout(animate, 10);
}
window.onload = function() {
animate()
};
<canvas id="target_temp"></canvas>
Ok, I found the cause: the arc() method stacks the circle as part of the path, so, for it to work, we need to reset the path like this:
draw() {
ctx.fillStyle = rgbToHex(0, 2*y, 107);
ctx.beginPath();
ctx.arc(8, this.position.y, 7, 0, 2 * Math.PI);
ctx.fill();
}

Canvas using high CPU in chrome

I am using a Codepen demo but after checking the CPU usage in chrome, it is using approx 100% of CPU. After trying hard, I am not able to figure out the problem as I am not an expert in javascript and canvas. What modifications do I need to make it use less CPU.
Codepen Link
As per my understanding, the problem is in animating particles or maybe I am wrong.
// Global Animation Setting
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000/60);
};
// Global Canvas Setting
var canvas = document.getElementById('particle');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Particles Around the Parent
function Particle(x, y, distance) {
this.angle = Math.random() * 2 * Math.PI;
this.radius = Math.random() ;
this.opacity = (Math.random()*5 + 2)/10;
this.distance = (1/this.opacity)*distance;
this.speed = this.distance*0.00003;
this.position = {
x: x + this.distance * Math.cos(this.angle),
y: y + this.distance * Math.sin(this.angle)
};
this.draw = function() {
ctx.fillStyle = "rgba(255,255,255," + this.opacity + ")";
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI*2, false);
ctx.fill();
ctx.closePath();
}
this.update = function() {
this.angle += this.speed;
this.position = {
x: x + this.distance * Math.cos(this.angle),
y: y + this.distance * Math.sin(this.angle)
};
this.draw();
}
}
function Emitter(x, y) {
this.position = { x: x, y: y};
this.radius = 30;
this.count = 3000;
this.particles = [];
for(var i=0; i< this.count; i ++ ){
this.particles.push(new Particle(this.position.x, this.position.y, this.radius));
}
}
Emitter.prototype = {
draw: function() {
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI*2, false);
ctx.fill();
ctx.closePath();
},
update: function() {
for(var i=0; i< this.count; i++) {
this.particles[i].update();
}
this.draw();
}
}
var emitter = new Emitter(canvas.width/2, canvas.height/2);
function loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
emitter.update();
requestAnimFrame(loop);
}
loop();
body{background:#000;}
<canvas id="particle"></canvas>
Avoid semi-transparency as much as possible.
Painting with alpha is a CPU killer, avoid blending as much as possible by using solid colors:
// Global Animation Setting
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000/60);
};
// Global Canvas Setting
var canvas = document.getElementById('particle');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Particles Around the Parent
function Particle(x, y, distance) {
this.angle = Math.random() * 2 * Math.PI;
this.radius = Math.random() ;
this.opacity = (Math.random()*5 + 2)/10;
// convert to solid color '#nnnnnn'
this.color = '#' + Math.floor((this.opacity * 255)).toString(16).padStart(2, 0).repeat(3);
this.distance = (1/this.opacity)*distance;
this.speed = this.distance*0.00003;
this.position = {
x: x + this.distance * Math.cos(this.angle),
y: y + this.distance * Math.sin(this.angle)
};
this.draw = function() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI*2, false);
ctx.fill();
ctx.closePath();
}
this.update = function() {
this.angle += this.speed;
this.position = {
x: x + this.distance * Math.cos(this.angle),
y: y + this.distance * Math.sin(this.angle)
};
this.draw();
}
}
function Emitter(x, y) {
this.position = { x: x, y: y};
this.radius = 30;
this.count = 3000;
this.particles = [];
for(var i=0; i< this.count; i ++ ){
this.particles.push(new Particle(this.position.x, this.position.y, this.radius));
}
}
Emitter.prototype = {
draw: function() {
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI*2, false);
ctx.fill();
ctx.closePath();
},
update: function() {
for(var i=0; i< this.count; i++) {
this.particles[i].update();
}
this.draw();
}
}
var emitter = new Emitter(canvas.width/2, canvas.height/2);
function loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
emitter.update();
requestAnimFrame(loop);
}
loop();
body{background:#000;}
<canvas id="particle"></canvas>
But that's still not enough,
Avoid painting as much as possible.
The paint operations are really slow on a canvas (compared to non-paint ones) and should be avoided as much as possible. To do this, you can sort your particles by color and draw them by stack of single Path objects, but this requires that we round up a bit the opacity value (done when solidifying the color).
// Global Animation Setting
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000/60);
};
// Global Canvas Setting
var canvas = document.getElementById('particle');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Particles Around the Parent
function Particle(x, y, distance) {
this.angle = Math.random() * 2 * Math.PI;
this.radius = Math.random() ;
this.opacity = (Math.random()*5 + 2)/10;
// convert to solid color '#nnnnnn'
this.color = '#' + Math.floor((this.opacity * 255)).toString(16).padStart(2, 0).repeat(3);
this.distance = (1/this.opacity)*distance;
this.speed = this.distance*0.00003;
this.position = {
x: x + this.distance * Math.cos(this.angle),
y: y + this.distance * Math.sin(this.angle)
};
this.draw = function() {
// here we remove everything but the 'arc' operation and a moveTo
// no paint
ctx.moveTo(this.position.x + this.radius, this.position.y);
ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI*2, false);
}
this.update = function() {
this.angle += this.speed;
this.position = {
x: x + this.distance * Math.cos(this.angle),
y: y + this.distance * Math.sin(this.angle)
};
// 'update' should not 'draw'
// this.draw();
}
}
function Emitter(x, y) {
this.position = { x: x, y: y};
this.radius = 30;
this.count = 3000;
this.particles = [];
for(var i=0; i< this.count; i ++ ){
this.particles.push(new Particle(this.position.x, this.position.y, this.radius));
}
// sort our particles by color (opacity = color)
this.particles.sort(function(a, b) {
return a.opacity - b.opacity;
});
}
Emitter.prototype = {
draw: function() {
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI*2, false);
ctx.fill();
// draw our particles in batches
var particle, color;
ctx.beginPath();
for(var i=0; i<this.count; i++) {
particle = this.particles[i];
if(color !== particle.color) {
ctx.fill();
ctx.beginPath();
ctx.fillStyle = color = particle.color;
}
particle.draw();
}
ctx.fill(); // fill the last batch
},
update: function() {
for(var i=0; i< this.count; i++) {
this.particles[i].update();
}
this.draw();
}
}
var emitter = new Emitter(canvas.width/2, canvas.height/2);
function loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
emitter.update();
requestAnimFrame(loop);
}
loop();
body{background:#000;}
<canvas id="particle"></canvas>
That's better but not yet perfect...
Finally, be clever about YOUR animation.
In your animation, the opacity defines the distance. That is, the particles that are farther from the center are the most transparent ones. This exactly defines what a radial gradient is.
We can thus reduce our paint operations to two. Yes, only two paints for 3000 particles, using a radial-gradient and a bit of compositing, we can first draw all the particles in a single shot, and then apply the gradient as a mask which will apply its color only where there were already something painted. We can even keep the transparency.
// Global Animation Setting
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000/60);
};
// Global Canvas Setting
var canvas = document.getElementById('particle');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Particles Around the Parent
function Particle(x, y, distance) {
this.angle = Math.random() * 2 * Math.PI;
this.radius = Math.random() ;
this.opacity = (Math.random()*5 + 2)/10;
this.distance = (1/this.opacity)*distance;
this.speed = this.distance*0.00003;
this.position = {
x: x + this.distance * Math.cos(this.angle),
y: y + this.distance * Math.sin(this.angle)
};
this.draw = function() {
// still no paint here
ctx.moveTo(this.position.x + this.radius, this.position.y);
ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI*2, false);
}
this.update = function() {
this.angle += this.speed;
this.position = {
x: x + this.distance * Math.cos(this.angle),
y: y + this.distance * Math.sin(this.angle)
};
this.draw();
}
}
function Emitter(x, y) {
this.position = { x: x, y: y};
this.radius = 30;
this.count = 3000;
this.particles = [];
for(var i=0; i< this.count; i ++ ){
this.particles.push(new Particle(this.position.x, this.position.y, this.radius));
}
// a radial gradient that we will use as mask
// in particle.constructor
// opacities go from 0.2 to 0.7
// with a distance range of [radius, 1 / 0.2 * this.radius]
this.grad = ctx.createRadialGradient(x, y, this.radius, x, y, 1 / 0.2 * this.radius);
this.grad.addColorStop(0, 'rgba(255,255,255,0.7)');
this.grad.addColorStop(1, 'rgba(255,255,255,0.2)');
}
Emitter.prototype = {
draw: function() {
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI*2, false);
ctx.fill();
ctx.closePath();
},
update: function() {
ctx.beginPath(); // one Path
ctx.fillStyle = 'black'; // a solid color
for(var i=0; i< this.count; i++) {
this.particles[i].update();
}
ctx.fill(); // one paint
// prepare the composite operation
ctx.globalCompositeOperation = 'source-in';
ctx.fillStyle = this.grad; // our gradient
ctx.fillRect(0,0,canvas.width, canvas.height); // cover the whole canvas
// reset for next paints (center arc and next frame's clearRect)
ctx.globalCompositeOperation = 'source-over';
this.draw();
}
}
var emitter = new Emitter(canvas.width/2, canvas.height/2);
function loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
emitter.update();
requestAnimFrame(loop);
}
loop();
body{background:#000;}
<canvas id="particle"></canvas>

Use image to fill in arc in canvas using javascript

So I am totally new to canvas and trying a project in which I need to make small balls move around with their background as images. Following code is what I am trying right now.
ctx.beginPath();
ctx.arc(
this.pos[0], this.pos[1], this.radius, 0, 2 * Math.PI, true
);
let tempCanvas = document.createElement("canvas"),
tCtx = tempCanvas.getContext("2d");
let ballbackground = new Image();
if (this.color === "green") {
ballbackground.src = "https://s26.postimg.cc/fl2vwj1mh/greenball.png";
}
else if (this.color === "yellow") {
ballbackground.src = "https://s26.postimg.cc/if61a18yh/yellowball.png";
}
else if (this.color === "blue") {
ballbackground.src = "https://s26.postimg.cc/xb4khn7ih/blueball.jpg";
}
tempCanvas.width = 50;
tempCanvas.height = 50;
tCtx.drawImage(ballbackground,0,0,ballbackground.width, ballbackground.height,0,0,50,50);
ctx.fillStyle = ctx.createPattern(tempCanvas, "repeat");
And for moving those balls I do as follows:
const velocityScale = timeDelta / NORMAL_FRAME_TIME_DELTA,
offsetX = this.vel[0] * velocityScale * this.speed,
offsetY = this.vel[1] * velocityScale * this.speed;
this.pos = [this.pos[0] + offsetX, this.pos[1] + offsetY];
However, the problem is when objects move they seem like sliding over background image like so:
If I try "no-repeat" with createPattern, the balls won't display at all.
What I want is those balls with background images moving on the canvas?
move the balls by using the canvas transform?
const ctx = document.querySelector("canvas").getContext("2d");
const pattern = createPattern(ctx);
function drawCircleByPosition(ctx, x, y) {
ctx.beginPath();
ctx.arc(x, y, 50, 0, Math.PI * 2, true);
ctx.fill();
}
function drawCircleByTransform(ctx, x, y) {
ctx.save();
ctx.translate(x, y);
ctx.beginPath();
ctx.arc(0, 0, 50, 0, Math.PI * 2, true);
ctx.fill();
ctx.restore();
}
function render(time) {
time *= 0.001;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillStyle = pattern;
drawCircleByPosition(ctx, 90, 75 + Math.sin(time) * 50);
drawCircleByTransform(ctx, 210, 75 + Math.sin(time) * 50);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
function createPattern(ctx) {
const tCtx = document.createElement("canvas").getContext("2d");
tCtx.canvas.width = 50;
tCtx.canvas.height = 50;
tCtx.fillStyle = "yellow";
tCtx.fillRect(0, 0, 50, 50);
for (let x = 0; x < 50; x += 20) {
tCtx.fillStyle = "red";
tCtx.fillRect(x, 0, 10, 50);
tCtx.fillStyle = "blue";
tCtx.fillRect(0, x, 50, 10);
}
return ctx.createPattern(tCtx.canvas, "repeat");
}
canvas { border: 1px solid black; }
<canvas></canvas>
note that rather than call save and restore you can also just set the transform with setTransform which is probably faster since save and restore saves all state (fillStyle, strokeStyle, font, globalCompositeOperation, lineWidth, etc...).
You can either pass in your own matrix. Example
ctx.setTransform(1, 0, 0, 1, x, y); // for translation
and/or you can reset it to the default whenever and then use the standard transform manipulation functions
ctx.setTransform(1, 0, 0, 1, 0, 0); // the default
ctx.translate(x, y);
or whatever combination of things you want to do.

Limit values between two points on an arc?

I'm trying to adapt the code from a previous question on circular dial controls. The concept is pretty similar to this one, except I would like to define a range in which the dial cannot be selected. Consider the volume controls/dials in hardware; they often have these 'dead zones' where they can't be turned:
How can I replicate this in JavaScript? Here's the adapted code so far:
function Dial(size) {
var dial = this;
var canvas = document.querySelector('#c');
var ctx = canvas.getContext("2d");
var pi2 = Math.PI*2;
this.from = 0.75 * Math.PI;
this.to = 0.25 * Math.PI;
this.value = this.from;
var radius = size / 2 - 10;
this.draw = function() {
ctx.save();
ctx.clearRect(0,0,size,size);
ctx.translate(size/2,size/2);
ctx.beginPath();
ctx.strokeStyle = "silver";
ctx.lineWidth = 2;
ctx.arc(0, 0, radius, this.from, this.to);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.fillStyle = "green";
ctx.strokeStyle = "black";
ctx.arc(-radius*Math.sin(this.value),
-radius*Math.cos(this.value),
8, 0, 2*Math.PI);
ctx.fill();
ctx.stroke();
ctx.restore();
};
var getMousePos = function(canvas, evt) {
return {
x: event.pageX - canvas.offsetLeft,
y: event.pageY - canvas.offsetTop
};
};
var inBounds = function(pos) {
return Math.hypot(
size / 2 - radius * Math.sin(dial.value) - pos.x,
size / 2 - radius * Math.cos(dial.value) - pos.y
) <= 8;
};
canvas.addEventListener("mousemove", function(evt) {
var pos = getMousePos(canvas, evt);
if (dial.markerMoving) {
if (pos.x == size/2 && pos.y == size/2)
return;
dial.value = Math.atan2(size/2-pos.x,size/2-pos.y);
}
dial.draw();
}, false);
canvas.addEventListener("mousedown", function(evt) {
var pos = getMousePos(canvas, evt);
dial.markerMoving = inBounds(pos);
}, false);
canvas.addEventListener("mouseup", function(evt) {
dial.markerMoving = false;
}, false);
this.draw();
};
new Dial(150);
<canvas id="c"></canvas>
Bonus points if you can work out how to display a 'range' on the selection - from the starting point on the dial to the selection point.
Turns out it was pretty straightforward, using Math.abs.
function Dial(size) {
var dial = this;
var canvas = document.querySelector('#c');
var ctx = canvas.getContext("2d");
var pi2 = Math.PI*2;
this.from = 0.75 * Math.PI;
this.to = 0.25 * Math.PI;
this.value = this.from;
var radius = size / 2 - 10;
this.draw = function() {
ctx.save();
ctx.clearRect(0,0,size,size);
ctx.translate(size/2,size/2);
ctx.beginPath();
ctx.strokeStyle = "silver";
ctx.lineWidth = 2;
ctx.arc(0, 0, radius, this.from, this.to);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.fillStyle = "green";
ctx.strokeStyle = "black";
ctx.arc(-radius*Math.sin(this.value),
-radius*Math.cos(this.value),
8, 0, 2*Math.PI);
ctx.fill();
ctx.stroke();
ctx.restore();
};
var getMousePos = function(canvas, evt) {
return {
x: event.pageX - canvas.offsetLeft,
y: event.pageY - canvas.offsetTop
};
};
var inBounds = function(pos) {
return Math.hypot(
size / 2 - radius * Math.sin(dial.value) - pos.x,
size / 2 - radius * Math.cos(dial.value) - pos.y
) <= 8;
};
canvas.addEventListener("mousemove", function(evt) {
var pos = getMousePos(canvas, evt);
if (dial.markerMoving) {
if (pos.x == size/2 && pos.y == size/2) {
return;
}
var radians = Math.atan2(size/2-pos.x,size/2-pos.y);
if (Math.abs(radians) < dial.from) {
dial.value = radians;
dial.draw();
}
}
}, false);
canvas.addEventListener("mousedown", function(evt) {
var pos = getMousePos(canvas, evt);
dial.markerMoving = inBounds(pos);
}, false);
canvas.addEventListener("mouseup", function(evt) {
dial.markerMoving = false;
}, false);
this.draw();
};
new Dial(150);
<canvas id="c"></canvas>

html canvas - drawing circle with animation & number

i'm totally new in javascript and css3. What I would like to achieve is to have an animation of drawing circle (in fact four of them). Everything should work like that:
1. animation of circle #1 and after animation put number 78 inside
2. animation of circle #2 and after animation put number 460 inside
3. the same but with number 20 inside
4. same but with 15 inside.
I've find a piece of code here:
http://jsfiddle.net/uhVj6/100/
// requestAnimationFrame Shim
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})();
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 75;
var endPercent = 101;
var curPerc = 0;
var counterClockwise = false;
var circ = Math.PI * 2;
var quart = Math.PI / 2;
context.lineWidth = 10;
context.strokeStyle = '#ad2323';
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
function animate(current) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.arc(x, y, radius, -(quart), ((circ) * current) - quart, false);
context.stroke();
curPerc++;
if (curPerc < endPercent) {
requestAnimationFrame(function () {
animate(curPerc / 100)
});
}
}
animate();
and I added few lines. But being honest I have to idea how to load four of them (one by one with animation) and then show those numbers inside (usually numbers puted in show under the circle.
Any ideas? thank you!
Here's how I'd do it :
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
}());
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var circles = [];
createCircle(100,100,'78', function() {
createCircle(270,100,'460', function() {
createCircle(440,100,'20', function() {
createCircle(610,100,'15', null);
});
});
});
function createCircle(x,y,text,callback) {
var radius = 75;
var endPercent = 101;
var curPerc = 0;
var counterClockwise = false;
var circ = Math.PI * 2;
var quart = Math.PI / 2;
context.lineWidth = 10;
context.strokeStyle = '#ad2323';
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
function doText(context,x,y,text) {
context.lineWidth = 1;
context.fillStyle = "#ad2323";
context.lineStyle = "#ad2323";
context.font = "28px sans-serif";
context.fillText(text, x-15, y+5);
}
function animate(current) {
context.lineWidth = 10;
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.arc(x, y, radius, -(quart), ((circ) * current) - quart, false);
context.stroke();
curPerc++;
if (circles.length) {
for (var i=0; i<circles.length; i++) {
context.lineWidth = 10;
context.beginPath();
context.arc(circles[i].x, circles[i].y, radius, -(quart), ((circ) * circles[i].curr) - quart, false);
context.stroke();
doText(context,circles[i].x,circles[i].y,circles[i].text);
}
}
if (curPerc < endPercent) {
requestAnimationFrame(function () {
animate(curPerc / 100)
});
}else{
var circle = {x:x,y:y,curr:current,text:text};
circles.push(circle);
doText(context,x,y,text);
if (callback) callback.call();
}
}
animate();
}
FIDDLE

Categories

Resources