I am doing some work with HTML canvases. Unfortunately I have ran into a very weird problem. At some point during development of the code the web page started to hang the browser. There were no tight loops apart from the requestAnimFrame shim so I took it back to basics and have found a very odd thing.
The code below will animate a circle across the screen. This works perfectly fine. If I comment out the code to draw the circle (marked in the code) it then grinds the browser to a halt. What is happening?
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function animate(lastTime, myCircle) {
//return;
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
// update
var date = new Date();
var time = date.getTime();
var timeDiff = time - lastTime;
var linearSpeed = 100;
// pixels / second
var linearDistEachFrame = linearSpeed * timeDiff / 1000;
var currentX = myCircle.x;
if(currentX < canvas.width - myCircle.width - myCircle.borderWidth / 2) {
var newX = currentX + linearDistEachFrame;
myCircle.x = newX;
}
lastTime = time;
// clear
drawGrid();
//draw a circle
context.beginPath();
context.fillStyle = "#8ED6FF";
context.arc(myCircle.x, myCircle.y, myCircle.width, 0, Math.PI*2, true);
context.closePath();
context.fill();
context.lineWidth = myCircle.borderWidth;
context.strokeStyle = "black";
context.stroke();
// request new frame
requestAnimFrame(function() {
animate(lastTime, myCircle);
});
}
$(document).ready(function() {
var myCircle = {
x: 50,
y: 50,
width: 30,
height: 50,
borderWidth: 2
};
//drawGrid();
var date = new Date();
var time = date.getTime();
animate(time, myCircle);
});
function drawGrid(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.clearRect(0, 0, canvas.width, canvas.height);
context.lineWidth = 1;
for (var x = 0; x <= canvas.width; x += 40) {
context.moveTo(0 + x, 0);
context.lineTo(0 + x, canvas.height);
}
for (var x = 0; x <= canvas.height; x += 40) {
context.moveTo(0, 0 + x);
context.lineTo(canvas.width, 0 + x);
}
context.strokeStyle = "#ddd";
context.stroke();
}
And my canvas is declared like so:
<canvas id="myCanvas" width="700" height="400"></canvas>
Turns out that the reason it worked when I draw the circle was because that code contained a closePath function. Adding that to the drawGrid function below fixes the issue.
function drawGrid(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.clearRect(0, 0, canvas.width, canvas.height);
context.lineWidth = 1;
context.beginPath();
for (var x = 0; x <= canvas.width; x += 40) {
context.moveTo(0 + x, 0);
context.lineTo(0 + x, canvas.height);
}
for (var x = 0; x <= canvas.height; x += 40) {
context.moveTo(0, 0 + x);
context.lineTo(canvas.width, 0 + x);
}
context.closePath();
context.strokeStyle = "#ddd";
context.stroke();
}
Related
I am working on a canvas. I want to draw an arc with a different two-color, like first half will be green second half will be red.
sample code
// CANVAS
const canvas = document.getElementById('bar'),
width = canvas.width,
height = canvas.height;
// CANVAS PROPERTIES
const ctx = canvas.getContext('2d');
ctx.lineWidth = 6;
ctx.strokeStyle = 'green';
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
const x = width / 2,
y = height / 2,
radius = 41,
circum = Math.PI * 2,
start = 2.37,
finish = 75;
let curr = 0;
const raf =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
window.requestAnimationFrame = raf;
function animate(draw_to) {
//ctx.clearRect(0, 0, width, height);
ctx.beginPath();
ctx.arc(x, y, radius, start, draw_to, false);
ctx.stroke();
curr++;
if (curr < finish + 1) {
requestAnimationFrame(function () {
animate(circum * curr / 100 + start);
});
}
}
animate();
code link https://jsfiddle.net/gowtham25/bp0myt21/11/
Something like this?
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
const x = canvas.width / 2
const y = canvas.height / 2
const radius = 41
const start = -25
const end = 75
const width = 6
function DrawArc(x, y, radius, start, end, width, color) {
ctx.beginPath()
ctx.lineWidth = width
ctx.strokeStyle = color
ctx.arc(x, y, radius, start, end, false)
ctx.stroke()
}
function DrawGauge(percentage) {
const rotation = Math.PI * 0.75
const angle = Math.PI * 1.5
const current = angle * percentage / 100
DrawArc(x, y, radius, rotation, rotation + current, width, 'green')
DrawArc(x, y, radius, rotation + current, rotation + angle, width, 'red')
}
function Animate(percent = 0) {
if (percent < 0) return
if (percent > 100) return
DrawGauge(percent)
requestAnimationFrame(() => Animate(++percent))
}
Animate()
<canvas></canvas>
I recommend breaking down the things you want to draw into functions at the very least so you can easily draw the item by passing in the parameters each time and can reuse the function to draw multiple different versions of that item.
Personally I'd create a class for the arc drawing and a class for the gauge drawing and then the gauge would draw two arcs based on the value of its percentage property. That way the drawing is separated from your data logic which is extremely important as you start doing more complex things with more draw calls.
You need to change the startAngle parameter in
ctx.arc(x, y, radius, startAngle, endAngle [, anticlockwise]);
Currently, if you modify the strokeStyle without changing the startAngle it will just draw on the same path.
https://jsfiddle.net/97ogkwas/4/
// CANVAS
const canvas = document.getElementById('bar'),
width = canvas.width,
height = canvas.height;
// CANVAS PROPERTIES
const ctx = canvas.getContext('2d');
ctx.lineWidth = 6;
ctx.strokeStyle = 'green';
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
let x = width / 2,
y = height / 2,
radius = 41,
circum = Math.PI * 2
start = 0.5* Math.PI
finish = 75;
let curr = 0;
const raf =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
window.requestAnimationFrame = raf;
function animate(draw_to) {
//ctx.clearRect(0, 0, width, height);
ctx.beginPath();
if(curr>45){
ctx.strokeStyle = 'red';
start = 1* Math.PI;
}
ctx.arc(x, y, radius, start, draw_to, false);
ctx.stroke();
curr++;
if (curr < finish + 1) {
requestAnimationFrame(function () {
animate(circum * curr / 100 + start);
});
}
}
animate();
#bar {
position: absolute;
top: 0;
left: 0;
}
<canvas id="bar" width="100" height="100"></canvas>
https://jsfiddle.net/97ogkwas/4/
// CANVAS
const canvas = document.getElementById('bar'),
width = canvas.width,
height = canvas.height;
// CANVAS PROPERTIES
const ctx = canvas.getContext('2d');
ctx.lineWidth = 1;
ctx.strokeStyle = 'green';
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// CANVAS PROPERTIES
const ctx2 = canvas.getContext('2d');
ctx2.lineWidth = 1;
ctx2.shadowOffsetX = 0;
ctx2.shadowOffsetY = 0;
var x = width / 2,
y = height / 2,
radius = 40,
circum = Math.PI * 2,
start = 2.37,
finish = 50;
let curr = 0;
const raf = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
window.requestAnimationFrame = raf;
function animate(draw_to) {
//ctx.clearRect(0, 0, width, height);
ctx.beginPath();
ctx.arc(x, y, radius, start, draw_to, false);
ctx.stroke();
curr++;
if (curr < finish + 5) {
requestAnimationFrame(function () {
animate(circum * curr / 100 + start);
});
}
}
function animate2(draw_to) {
//ctx.clearRect(0, 0, width, height);
ctx2.beginPath();
ctx2.arc(x, y, radius, start, draw_to, false);
ctx2.stroke();
curr++;
if (curr < finish + 5) {
requestAnimationFrame(function () {
animate2(circum * curr / 100 + start);
});
}
}
animate();
setTimeout(function(){
finish = 52;
start = 5.5;
ctx2.strokeStyle = 'red';
animate2();
}, 2000);
#bar {
position: absolute;
top: 0;
left: 0;
}
<canvas id="bar" width="100" height="100"></canvas>
The question is not clear at all! I am not sure but maybe someting like this:
https://jsfiddle.net/15srnh4w/
I have eyesore flickering in my canvas animation. I have no idea what causes the flicker and the Google is not offering help on the transition global element I added to my text. On separate canvases, they work fine. It's only when I add them to the main code do I run into the flicker.
var canvas,
context,
ox = 60,
oy = 60,
ux = Math.random(),
uy = Math.random();
var drops = [];
var squares = [];
var clouds = [];
var text, step = 190, steps = 255;
delay = 180;
var rgbstep = 120;
function Drop(x,y,color){
this.x = x;
this.y = y;
this.color = color;
this.dy = Math.random();
}
function Square(x,y,w,color){
this.sx = x;
this.sy = y;
this.sw = w;
this.color = color;
this.qy = Math.random();
}
function init(){
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
//alert("Hello!\nClick on the screen for rain drops!");
window.addEventListener('resize', resizeCanvas, false);
window.addEventListener('orientationchange', resizeCanvas, false);
resizeCanvas()
Textfadeup();
canvas.onclick = function(event){
handleClick(event.clientX, event.clientY);
};
setInterval(handleClick,50);
setInterval(draw, 1);
}
addEventListener("keydown", function(event) {
if (event.keyCode == 32)
document.body.style.background = "yellow";
});
addEventListener("keyup", function(event) {
if (event.keyCode == 32)
document.body.style.background = "";
});
function handleClick(x,y,w){
var found = false;
for(var i = 0; i<drops.length; i++){
d = Math.sqrt((drops[i].x-x)*(drops[i].x-x) + (drops[i].y-y)*(drops[i].y-y));
if(d<=5){
drops.splice(i,1);
found = true;
}
}
fillBackgroundColor();
if(!found){
var colors = ["#000080", "#add8e6", "blue"];
var color = colors[Math.floor(Math.random()*colors.length)];
drops.push(new Drop(x,y,color));
squares.push(new Square(x,y,w,color));
}
for(var i = 0; i<drops.length; i++){
drawDrop(drops[i]);
}
for(var i = 0; i<squares.length; i++){
drawSquare(squares[i]);
}
}
function Textfadeup() {
rgbstep++;
//context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgb(" + rgbstep + "," + rgbstep + "," + rgbstep + ")"
context.fillText("Drip, drip, drop, little April shower...", 500, canvas.height);
context.font= "40px Arial";
if (rgbstep < 255)
var t = setTimeout('Textfadeup()', 10);
if (rgbstep == 255) {
Textfadedown();
}
}
function Textfadedown() {
rgbstep=rgbstep-1;
// context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgb(" + rgbstep + "," + rgbstep + "," + rgbstep + ")"
context.fillText("Drip, drip, drop, little April shower...", 500, canvas.height);
context.font= "40px Arial";
if (rgbstep > 30)
var t = setTimeout('Textfadedown()', 10);
if (rgbstep == 30) {
Textfadeup();
}
}
/* function drawDrop(drop){
context.beginPath();
context.moveTo(drop.x,drop.y);
context.lineTo(drop.x+10,drop.y+25);
context.lineTo(drop.x+13,drop.y+32);
context.lineTo(drop.x+46,drop.y+50);
context.lineTo(drop.x+72,drop.y+51);
context.lineTo(drop.x+81,drop.y+43);
context.lineTo(drop.x+104,drop.y+52);
context.lineTo(drop.x+111,drop.y+46);
context.lineTo(drop.x+83,drop.y+40);
context.lineTo(drop.x+75,drop.y+20);
context.lineTo(drop.x+57,drop.y+8);
context.closePath();
context.fillStyle = 'orange';
context.fill();
if (drop.y + drop.dy > canvas.height || drop.y + drop.dy < 0)
drop.dy != -drop.dy;
drop.y += drop.dy;
};
function drawDrop(drop){
context.beginPath();
context.moveTo(drop.x,drop.y);
context.beginPath();
context.moveTo(drop.x,drop.y);
context.lineTo(drop.x+24,drop.y);
context.lineTo(drop.x-2,drop.y+25);
context.lineTo(drop.x+17,drop.y+25);
context.lineTo(drop.x-18,drop.y+53);
context.lineTo(drop.x-3,drop.y+54);
context.lineTo(drop.x-47,drop.y+77);
context.lineTo(drop.x-31,drop.y+59);
context.lineTo(drop.x-40,drop.y+59);
context.moveTo(drop.x-40,drop.y+59);
context.moveTo(drop.x-14,drop.y+33);
context.lineTo(drop.x-30,drop.y+32);
context.closePath();
context.fillStyle = 'yellow';
context.fill();
if (drop.y + drop.dy > canvas.height || drop.y + drop.dy < 0)
drop.dy != -drop.dy;
drop.y += drop.dy;
};*/
function drawDrop(drop){
context.beginPath();
context.arc(drop.x, drop.y, 5, 0, Math.PI);
context.fillStyle = drop.color;
context.moveTo(drop.x - 5, drop.y);
context.lineTo(drop.x, drop.y - 7);
context.lineTo(drop.x + 5, drop.y);
context.closePath();
context.fill();
if (drop.y + drop.dy > canvas.height || drop.y + drop.dy < 0)
drop.dy != -drop.dy;
drop.y += drop.dy;
};
function drawSquare(square){
var sw = Math.floor(4);
var sx = Math.floor(Math.random() * canvas.width);
var sy = Math.floor(Math.random() * canvas.height);
context.beginPath();
context.rect(sx, sy, sw, sw);
context.fillStyle = '#add8e6';
context.fill();
};
function drawCloud(ox,oy) {
context.beginPath();
context.moveTo(ox,oy);
context.bezierCurveTo(ox-40, oy+20, ox-40, oy+70, ox+60, oy+70);
context.bezierCurveTo(ox+80, oy+100, ox+150, oy+100, ox+170, oy+70);
context.bezierCurveTo(ox+250, oy+70, ox+250, oy+50, ox+220, oy+20);
context.bezierCurveTo(ox+260, oy-40, ox+200, oy-50, ox+170, oy-30);
context.bezierCurveTo(ox+150, oy-75, ox+80, oy-10, ox+170, oy+5);
context.bezierCurveTo(ox+30, oy-75, ox-20, oy-60, ox, oy);
context.closePath();
context.fillStyle = 'white';
context.fill();
};
function fillBackgroundColor(){
context.fillStyle = 'gray';
context.fillRect(0,0,canvas.width,canvas.height);
}
function resizeCanvas(){
canvas.width = window.innerWidth - 20;
canvas.height = window.innerHeight - 20;
for(var i = 0; i<drops.length; i++){
drawDrop(drops[i]);
}
for(var i = 0; i<squares.length; i++){
drawSquare(squares[i]);
}
}
function draw() {
drawCloud(ox, oy, 500);
if (ox + ux > canvas.width || ox + ux < 0)
ux = -ux;
if (oy + uy > canvas.height || oy + uy < 0)
uy = -uy;
ox += ux;
}
function degreesToRadians(degrees) {
return (degrees * Math.PI)/180;
}
window.onload = init;
</script>
<body>
<canvas id='canvas' width=500 height=500></canvas>
</body>
You should not use setInterval to render to the canvas. You have set the time to 10 which is quicker than the screen refresh rate. There is no easy fix to your code as it's a little convoluted.
What you need to do is set up a main loop. From that function you do everything you need to do per animation frame. At the end of that function you use window.requestAnimationFrame(mainLoop) to request the next frame. It syncs the animation with the display refresh rate and stops the flicker.
Example
function mainLoop(){
drawCloud(); // draw your cloud
// other stuff did not get a chance to see what else you did.
// request the next animation frame that should occur in 1/60th of a second.
requestAnimationFrame(mainLoop);
}
To start it all call mainLoop from the init function
mainLoop(); // starts it all happening
You should NEVER use setInterval for anything but very short simple functions or long time periods. It caused your jsFiddle to crash the tab each time I looked.
I'm trying to animate a sine wave in JS but it's not acting as expected. I'm using a <canvas> element along with window.requestAnimationFrame() method but it's a CPU hog and as i change frequency with the slider it just break and show random waveforms. I also don't know if drawing adjacent lines is the best way to represent a sine wave. Please note that i'll use vanilla JS and that the sine's frequency and amplitude are variables set by sliders. Thanks in advance.
This is what i got so far: http://cssdeck.com/labs/8cq5vclp
UPDATE: i worked on it and this is the new version: http://cssdeck.com/labs/sbfynjkr
var canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d"),
cHeight = canvas.height,
cWidth = canvas.width,
frequency = document.querySelector("#f").value,
amplitude = 80,
x = 0,
y = cHeight / 2,
point_y = 0;
window.onload = init;
function init() {
document.querySelector("#f").addEventListener("input", function() {
frequency = this.value;
document.querySelector("#output_f").value = frequency;
}, false);
drawSine();
}
function drawSine() {
ctx.clearRect(0, 0, cWidth, cHeight);
ctx.beginPath();
ctx.moveTo(0, y);
ctx.strokeStyle = "red";
ctx.lineTo(cWidth, y);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.strokeStyle = "black";
for (x = 0; x < 600; x++) {
point_y = amplitude * -Math.sin((frequency / 95.33) * x) + y;
ctx.lineTo(x, point_y);
}
ctx.stroke();
ctx.closePath();
requestAnimationFrame(drawSine);
}
canvas {
border: 1px solid red;
margin: 10px;
}
<input id="f" type="range" min="0" max="20000" value="20" step="1">
<output for="f" id="output_f">20</output>
<canvas width="600px" height="200px"></canvas>
I've messed around with sine waves quite a bit, because I'm working on a little project that involves animated sine waves. I've got some code you might be interested in taking a look at. Like mentioned earlier, you need to make sure you are using the right increment in your loop so the lines do not look jagged.
https://jsfiddle.net/uawLvymc/
window.requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(f) {
return setTimeout(f, 1000 / 60)
};
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var startTime = new Date().getTime();
function getPath(height) {
var width = canvas.width;
var spacing = 0.08;
var loopNum = 0;
var pointList = [];
var i = 0;
for (i = 0; i < width / 2; i++) {
pointList[loopNum] = [loopNum, Math.sin(loopNum * spacing) * (i * height) + 100];
loopNum++;
}
for (i = width / 2; i > 0; i--) {
pointList[loopNum] = [loopNum, Math.sin(loopNum * spacing) * (i * height) + 100];
loopNum++;
}
return pointList;
}
function draw() {
var currentTime = new Date().getTime();
var runTime = currentTime - startTime;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = "rgb(80, 100, 230)";
var height = Math.sin(runTime * 0.008) * 0.2;
var pointList = getPath(height);
for (var i = 0; i < 500; i++) {
if (i === 0) {
ctx.moveTo(pointList[0][0], pointList[0][1]);
} else {
ctx.lineTo(pointList[i][0], pointList[i][1]);
}
}
ctx.stroke();
window.requestAnimationFrame(draw);
}
window.requestAnimationFrame(draw);
Sorry I didn't really edit down the code, it's just a direct copy from what I was working on. Hope it helps though.
See if this example could help you a little
Sine Wave Example canvas
function init()
{
setInterval(OnDraw, 200);
}
var time = 0;
var color = "#ff0000";
function OnDraw()
{
time = time + 0.2;
var canvas = document.getElementById("mycanvas");
var dataLine = canvas.getContext("2d");
var value = document.getElementById("lineWidth");
dataLine.clearRect(0, 0, canvas.width, canvas.height);
dataLine.beginPath();
for(cnt = -1; cnt <= canvas.width; cnt++)
{
dataLine.lineTo(cnt, canvas.height * 0.5 - (Math.random() * 2 + Math.cos(time + cnt * 0.05) * 20 ));
}
dataLine.lineWidth = value.value * 0.1;
dataLine.strokeStyle = color;
dataLine.stroke();
}
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
I have a piece of code. But my problem is.. I have no idea where i can change the animation speed. I've tried to edit last line into animate('fast'); but without success..how can i solve it?
I know it is mainy javascript but so far I didnt find such code which will be better in jquery
$('#kim-jestesmy').waypoint(function(direction) {
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 = '#E60086';
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
function doText(context,x,y,text) {
context.lineWidth = 1;
context.fillStyle = "#919191";
context.lineStyle = "#919191";
context.font = "60px NillandBold";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText(text, x, y);
}
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();
}
});
Since you're not throttling the fps of your animation, each frame is being rendered as fast as possible with this code. If you want it to be faster, the simplest answer is to drop frames by incrementing the curPerc variable by more than one:
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 += 2;
...
The above code will complete twice as quickly. If curPerc does not divide 100 evenly (100%curPerc != 0), then change the variable endPercent accordingly.