Canvas circle progress bar with bounce effect - javascript

I have this code.
How I can make bounce effect as here? http://themeforest.net/item/cloud-admin-bootstrap-3-responsive-dashboard/full_screen_preview/6069264

Bounce example with a div
Change div.style.width with your canvas data..
max with the max value and the duration ..
requestAnimationframe is 60fps so 3000ms/60 gives you the number of frames.
function bounceOut(k){
return k<1/2.75?
7.5625*k*k:k<2/2.75?
7.5625*(k-=1.5/2.75)*k+.75:k<2.5/2.75?
7.5625*(k-=2.25/2.75)*k+.9375:
7.5625*(k-=2.625/2.75)*k+.984375
}
function animate(){
div.style.width=(bounceOut(current/duration)*max|0)+'px';
++current>duration||(a=webkitRequestAnimationFrame(animate));
}
var div=document.getElementsByTagName('div')[0],
duration=3000/60|0,
current=0,
max=500;
var a=webkitRequestAnimationFrame(animate);
Demo
http://jsfiddle.net/vL7Mp/1/
FULL CANVAS version
http://jsfiddle.net/vL7Mp/2/
jsut add a canvas and set the width & height
<canvas width="128" height="128"></canvas>
js
function animateC(p,C,K){
var c=C.getContext("2d"),
x=C.width/2,
r=x-(x/4),
s=(-90/180)*Math.PI,
p=p||0,
e=(((p*360|0)-90)/180)*Math.PI;
c.clearRect(0,0,C.width,C.height);
c.fillStyle=K;
c.textAlign='center';
c.font='bold '+(x/2)+'px Arial';
c.fillText(p*100|0,x,x+(x/5));
c.beginPath();
c.arc(x,x,r,s,e);
c.lineWidth=x/2;
c.strokeStyle=K;
c.stroke();
}
function bounceOut(k){
return k<1/2.75?
7.5625*k*k:k<2/2.75?
7.5625*(k-=1.5/2.75)*k+.75:k<2.5/2.75?
7.5625*(k-=2.25/2.75)*k+.9375:
7.5625*(k-=2.625/2.75)*k+.984375
}
function animate(){
animateC(bounceOut(current/duration),canvas,'rgba(127,227,127,0.3)');
++current>duration||(a=webkitRequestAnimationFrame(animate));
}
var canvas=document.getElementsByTagName('canvas')[0],
duration=6000/60|0,
current=0,
max=500,
a=webkitRequestAnimationFrame(animate);
if you have any questions just ask.

You can achieve a bounce effect by animating the draw using tweening with an easing equation.
Tween.js is a simple lib for handling this: https://github.com/sole/tween.js/
You would use it something like this:
var duration = 1000,
startValue = 0,
endValue = 100;
var tween = new TWEEN.Tween({x: startValue})
.to({ x: endValue }, duration)
.onUpdate(function() {
animate(this.x);
})
.easing(TWEEN.Easing.Bounce.Out)
.start();

Use this gist to get an easing function https://gist.github.com/dezinezync/5487119 also check out http://gizma.com/easing/

<html>
<head>
<title> two ball game</title>
</head>
<script type="text/javascript" src="jquery-1.11.3.min.js"></script>
<body>
<canvas id="canvas" width="852" height= "521" style= "border:5px solid grey ;" margin = right >
</canvas>
<script>
var x = 1;
var y = 1;
var dx = 2;
var dy = 1;
var ctx;
var WIDTH;
var HEIGHT;
init();
function circle(x,y,r) {
ctx.beginPath();
ctx.fillStyle="blue";
ctx.arc(x, y, 8, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
}
function rect(x,y,w,h) {
ctx.beginPath();
ctx.rect(x,y,w,h);
ctx.closePath();
ctx.fill();
}
function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
function init() {
ctx = $('#canvas')[0].getContext("2d");
WIDTH = $("#canvas").width()
HEIGHT = $("#canvas").height()
return setInterval(draw, 10);
}
function draw() {
clear();
circle(x, y, 10);
if (x + dx > WIDTH || x + dx < 0)
dx = -dx;
if (y + dy > HEIGHT || y + dy < 0)
dy = -dy;
x += dx;
y += dy;
}
</script>
</body>
</html>
/****************************************************************\
write this code in your html

Related

Sine Wave Animation

This is the effect that I am trying to achieve: link
I have gotten the four waves and they are indeed animated, but I have gotten stuck on giving each of them a slightly different animation. At the current point, all curves move at the same speed, in the same direction and switch at the same place too. they should vary slightly in all these aspects. The end result I am looking for is very much like the link i posted, with difference that each wave can only have a maximum of one cycle, that is going up once and coming down once. Thank you for your input.
Below is my code:
function start() {
var canvas = $("canvas");
console.log(canvas);
canvas.each(function(index, canvas) {
var context = canvas.getContext("2d");
canvas.width = $(".box").eq(index).width();
canvas.height = $(".box").eq(index).height();
context.clearRect(0, 0, canvas.width, canvas.height);
drawCurves(context, step);
step += 1;
});
requestAnimationFrame(start);
}
var step = -1;
function drawCurves(ctx, step) {
var width = ctx.canvas.width;
var height = ctx.canvas.height;
ctx.lineWidth = 2;
for (i = 0; i < 4 ; i++) {
var x = 0;
var y = 0;
ctx.beginPath();
if (i === 0 ) {
ctx.strokeStyle = "red";
var amplitude = 20;
var frequency = height / (2 * Math.PI) ;
console.log(i, frequency);
} if ( i === 1) {
ctx.strokeStyle = "blue";
var amplitude = 30;
var frequency = (height / (2 * Math.PI));
console.log(i, frequency);
} if ( i === 2) {
ctx.strokeStyle = "green";
var amplitude = 40;
var frequency = height / (2 * Math.PI) ;
console.log(i, frequency);
} if (i === 3) {
ctx.strokeStyle = "yellow";
var amplitude = 50;
var frequency = height / (2 * Math.PI) ;
console.log(i, frequency);
}
ctx.save();
ctx.translate(-amplitude * Math.sin(step / frequency), 0);
while (y < height) {
x = (width / 2) + (amplitude * Math.sin((y + step) / frequency)) ;
ctx.lineTo(x, y);
y++;
}
ctx.closePath();
ctx.stroke();
ctx.restore();
}
}
$(document).ready(function() {
start();
})
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="box">
<canvas id="canvas"></canvas>
</div>
<div class="box">
<canvas id="canvas"></canvas>
</div>
</body>
</html>
And here a Code Pen
Your code draw only one sinus wave.
I'll advice you those points:
_If you want different(simultaneaous) wave you've to use differents x/y values at the draw point.
_You use $(document).ready(function() as animation loop, that's not the better way do do it. For animation you should set a setInterval or way better use the requestAnimationFrame who is meant to create animation. In each animation loop draw the 4 sinus lines, i'll forget about step for using objects instead that i think is better but that's not important point. I've no time to try your code but what is it doing when using requestAnimationFrame(start()) instead of the $document.ready ?
Obviously in each animatve to clear the drawing place using clearRect(width,height); for example.
_The 4 steps add +1 to +4 to y in the same cartesian equation. In a sinus curve that will not really be seeing by human eyes because it's a really slight variation. You can use differents equations using differents sinusoïd equations for each step/object, i.e. Math.sin(y)+10 or Math.sin(y)*10 etc...or even different incremantation value for each differents objects.
_i'll avoid translate and use a for loop to increment the x value and get the y value using sin(x) and whatever equation you need , that's personal choice but will avoid to write the .translate() line and will use normal coordinates instead of moved coordinates so you'll easily see in console.log real coordinates in canvas area.
_As for previous you can throw away the checking IFs at beginning of program if you use objets in a array (and loop it) and set a styleColor and weight of each of 4 objets.
Hope it's help, no time to write a clean code.
#enxaneta thank you for your input! Got it the way I wanted to, below is my solution:
var step = 0;
function start(timestamp) {
var canvas = $("canvas");
canvas.each(function(index, canvas) {
var context = canvas.getContext("2d");
canvas.width = $(".box").eq(index).width();
canvas.height = $(".box").eq(index).height();
context.clearRect(0, 0, canvas.width, canvas.height);
if (canvas.height > 1000 ) {
drawWave(context, 20,"sin");
drawWave(context, 60,"cos");
drawWave(context, 40,"sin");
drawWave(context, 80,"cos");
}
if (canvas.height < 1000 ) {
drawWave(context, 10,"sin");
drawWave(context, 30,"cos");
drawWave(context, 20,"sin");
drawWave(context, 40,"cos");
}
step = timestamp / 7;
});
window.requestAnimationFrame(start);
}
function drawWave(ctx,amplitude,trig){
var width = ctx.canvas.width;
var height = ctx.canvas.height;
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = "blue";
var x = 0;
var y = 0;
var frequency = height / (2 * Math.PI);
ctx.save();
ctx.translate(-amplitude * Math[trig](step / frequency), 0);
while (y < height) {
x = width / 2 + amplitude * Math[trig]((y + step) / frequency);
ctx.lineTo(x, y);
y++;
}
// ctx.closePath();
ctx.stroke();
ctx.restore();
}
$(document).ready(function() {
start();
});
canvas {
background-color: wheat;
position: absolute;
}
.box {
width: 500px;
height: 2000px;
border: solid;
}
.box.t {
width: 500px;
height: 200px;
border: solid;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="box t">
<canvas id="canvas"></canvas>
</div>
<div class="box">
<canvas id="canvas"></canvas>
</div>
</body>
</html>

Circle Following Mouse HTML5 Canvas jQuery

I am trying to make a circle follow the mouse in HTML Canvas which I am using in a game. I am trying to make the circle move 5px per iteration, but it goes slower when traveling horizontal and faster when it goes vertical. Here's the math that I used:
x=distance between mouse and circle on the x-axis
y=distance between mouse and circle on the y-axis
z=shortest distance between mouse and circle
a=number of units circle should move along the x-axis
b=number of units circle should move along the y axis
x^2 + y^2=z^2
Want the total distance traveled every iteration to be five pixels
a^2 + b^2 = 25
b/a=y/x
b=ay/x
a=sqrt(25-ay/x^2)
a^2+ay/x-25=0
Use Quadratic formula to find both answers
a=(-y/x+-sqrt(y/x)^2+100)/2
I replicated the problem in the code below
$(function(){
let canvas = $("canvas")[0];
let ctx = canvas.getContext("2d");
//Gets position of mouse and stores the value in variables mouseX and mouseY
let mouseX = mouseY = 0;
$("canvas").mousemove(function(e){
mouseX = e.pageX;
mouseY = e.pageY;
}).trigger("mousemove");
let circleX = 0;
let circleY = 0;
function loop(t){
//Background
ctx.fillStyle="blue";
ctx.fillRect(0, 0, canvas.width, canvas.height);
let xFromMouse = mouseX-circleX;
let yFromMouse = mouseY-circleY;
let yxRatio = yFromMouse/xFromMouse;
let xyRatio = xFromMouse/yFromMouse;
let speed = 25;
let possibleXValues = [(-yxRatio+Math.sqrt(Math.pow(yxRatio,2)+(4*speed)))/2,(-yxRatio-Math.sqrt(Math.pow(yxRatio,2)+(4*speed)))/2];
//I use this code as a temporary fix to stop the circle from completely disappearing
if(xFromMouse === 0 || isNaN(yxRatio) || isNaN(possibleXValues[0]) || isNaN(possibleXValues[1])){
possibleXValues = [0,0];
yxRatio = 0;
}
//Uses b=ay/x to calculate for y values
let possibleYValues = [possibleXValues[0]*yxRatio,possibleXValues[1]*yxRatio];
if(xFromMouse >= 0){
circleX += possibleXValues[0];
circleY += possibleYValues[0];
} else {
circleX += possibleXValues[1];
circleY += possibleYValues[1];
}
ctx.beginPath();
ctx.arc(circleX, circleY, 25, 0, 2 * Math.PI,false);
ctx.fillStyle = "red";
ctx.lineWidth = 0;
ctx.fill();
window.requestAnimationFrame(loop);
}
window.requestAnimationFrame(loop);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas width="450" height="250"></canvas>
I think you may be better using a cartesian to polar conversion. Here's an example from something I made previously. This will allow you to have a consistent step per iteration "speed".
//Canvas, context, mouse.
let c, a, m = { x:0, y:0};
//onload.
window.onload = function(){
let circle = {},
w, h,
speed = 5; //step speed = 5 "pixels" (this will be fractional in any one direction depending on direction of travel).
//setup
c = document.getElementById('canvas');
a = c.getContext('2d');
w = c.width = window.innerWidth;
h = c.height = window.innerHeight;
function move(){
//get distance and angle from mouse to circle.
let v1m = circle.x - m.x,
v2m = circle.y - m.y,
vDm = Math.sqrt(v1m*v1m + v2m*v2m),
vAm = Math.atan2(v2m, v1m);
//if distance is above some threshold, to stop jittering, move the circle by 'speed' towards mouse.
if(vDm > speed) {
circle.x -= Math.cos(vAm) * speed;
circle.y -= Math.sin(vAm) * speed;
}
}
function draw(){
//draw it all.
a.fillStyle = "blue";
a.fillRect(0,0,w,h);
a.fillStyle = "red";
a.beginPath();
a.arc(circle.x, circle.y, circle.r, Math.PI * 2, false);
a.closePath();
a.fill();
}
circle = {x:w/2, y:h/2, r:25};
function animate(){
requestAnimationFrame(animate);
move();
draw();
}
c.onmousemove = function(e){
m.x = e.pageX;
m.y = e.pageY;
};
animate();
}
<canvas id="canvas" width="450" height="250"></canvas>

Cannot clear HTML canvas after translating, leaving object moving and leaving trail

How do I clear the HTML canvas, Object is leaving a trail in the second canvas where it is grey?
var Xposition = 50;
var Yposition = 50;
var dx = 0.4;
var dy = 5;
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#D3D3D3";
//Draw Square
function draw() {
ctx.fillStyle = "#D3D3D3";
ctx.fillRect(0, 0, 300, 300);
ctx.save();
ctx.translate(-0.2, 0);
ctx.fillStyle = "red";
ctx.fillRect(Xposition, Yposition, 20, 20);
ctx.fillStyle = "green";
ctx.fillRect(100, 0, 2, 50);
ctx.fillStyle = "green";
ctx.fillRect(200, 30, 2, 100);
Xposition += dx;
}
setInterval(draw, 10);
//Move Square
document.addEventListener('keydown', function(event) {
Xposition += 1;
if (event.keyCode == 40 && Yposition < canvas.height - 20) {
Yposition += 10;
}
//top
else if (event.keyCode == 38 && Yposition > 0) {
Yposition -= 10;
}
});
<div id="centre">
<canvas id="myCanvas" height="200px" width="300px"></canvas>
</div>
var clearAdj = 0;
//Draw Square
function draw() {
clearAdj += 0.2;
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, 300 + clearAdj, 300);
ctx.save();
ctx.translate(-0.2, 0);
Here's a quick solution that just adds an adjustment value as you translate the canvas
The canvas is not clearing completely because the entire 300x300 entity of moving over to the left. Your call to clear a 300x300 space starts at the origin of THAT CANVAS and will translate along with it.
A more elegant fix would be to make object for each of your green bar things and just subtract the x value from them, effectively moving them to the left. This would be more efficient as you could just delete the object as they leave. Your approach requires a large canvas

Separating JavaScript from HTML doesn't work

I am trying to separate my JavaScript from my HTML, but it doesn't seem to want to work. Here is the combined code:
<script type="text/javascript">
var width = 100;
var height = 200;
function Ball(){
// random radius
this.radius = Math.floor(Math.random()*(10-5+1))+5;
// random x and y
this.x = Math.floor(Math.random()*(width-this.radius+1))+this.radius;
this.y = Math.floor(Math.random()*(width-this.radius+1))+this.radius;
// random direction, +1 or -1
this.dx = Math.floor(Math.random()*2) * 2 - 1;
this.dy = Math.floor(Math.random()*2) * 2 - 1;
//random colour, r, g or b
var rcol = Math.floor(Math.random()*3);
this.col = rcol==0 ? "red" :
rcol==1 ? "blue" : "green";
}
// create an array of balls
numBalls = 10;
var balls = new Array(numBalls);
for(i= 0 ; i < numBalls ; i++){
balls[i] = new Ball();
}
// draw the balls on the canvas
function draw(){
var canvas = document.getElementById("myCanvas");
// check if supported
if(canvas.getContext){
var ctx=canvas.getContext("2d");
//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 0.5;
ctx.strokeStyle="black";
// draw each ball
for(i = 0; i < numBalls ; i++){
var ball = balls[i];
ctx.fillStyle=ball.col;
ctx.beginPath();
// check bounds
// change direction if hitting border
if(ball.x<=ball.radius ||
ball.x >= (width-ball.radius)){
ball.dx *= -1;
}
if(ball.y<=ball.radius ||
ball.y >= (height-ball.radius)){
ball.dy *= -1;
}
// move ball
ball.x += ball.dx;
ball.y += ball.dy;
// draw it
ctx.arc(ball.x, ball.y, ball.radius, 0, 2*Math.PI, false);
ctx.stroke();
ctx.fill();
}
}
else{
//canvas not supported
}
}
// calls draw every 10 millis
function bounce(){
setInterval(draw, 10);
}
</script>
<canvas id="myCanvas" width="100" height="200" style="border-style:solid;border-width:1px" onclick="bounce()">
Canvas not supported.</canvas>
But when I separate it into separate html and javascript files like so:
<!DOCTYPE html>
<html>
<head>
<title>NodeJS, Socket.IO</title>
<!-- reference to the JQuery library -->
<script type="text/javascript" src="./js/jquery-2.1.4.min.js"></script>
<!-- our javascript file -->
<script type="text/javascript" src="./js/script.js"></script>
<!-- our css file -->
</head>
<body>
<canvas id="myCanvas" width="100" height="200" style="border-style:solid;border-width:1px">
Canvas not supported.</canvas>
</html>
And:
$(document).ready(function() {
var width = 100;
var height = 200;
function Ball(){
// random radius
this.radius = Math.floor(Math.random()*(10-5+1))+5;
// random x and y
this.x = Math.floor(Math.random()*(width-this.radius+1))+this.radius;
this.y = Math.floor(Math.random()*(width-this.radius+1))+this.radius;
// random direction, +1 or -1
this.dx = Math.floor(Math.random()*2) * 2 - 1;
this.dy = Math.floor(Math.random()*2) * 2 - 1;
//random colour, r, g or b
var rcol = Math.floor(Math.random()*3);
this.col = rcol==0 ? "red" :
rcol==1 ? "blue" : "green";
}
// create an array of balls
numBalls = 10;
var balls = new Array(numBalls);
for(i= 0 ; i < numBalls ; i++){
balls[i] = new Ball();
}
// draw the balls on the canvas
function draw(){
var canvas = document.getElementById("myCanvas");
// check if supported
if(canvas.getContext){
var ctx=canvas.getContext("2d");
//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 0.5;
ctx.strokeStyle="black";
// draw each ball
for(i = 0; i < numBalls ; i++){
var ball = balls[i];
ctx.fillStyle=ball.col;
ctx.beginPath();
// check bounds
// change direction if hitting border
if(ball.x<=ball.radius ||
ball.x >= (width-ball.radius)){
ball.dx *= -1;
}
if(ball.y<=ball.radius ||
ball.y >= (height-ball.radius)){
ball.dy *= -1;
}
// move ball
ball.x += ball.dx;
ball.y += ball.dy;
// draw it
ctx.arc(ball.x, ball.y, ball.radius, 0, 2*Math.PI, false);
ctx.stroke();
ctx.fill();
}
}
else{
//canvas not supported
}
}
// calls draw every 10 millis
function bounce(){
setInterval(draw, 10);
}
});
It doesn't work. Any help would be greatly appreciated!
The trouble is that you used to have the canvas defined like this:
<canvas id="myCanvas" width="100" height="200" style="border-style:solid;border-width:1px"
onclick="bounce()">
Canvas not supported.</canvas>
And now it's defined like this:
<canvas id="myCanvas" width="100" height="200" style="border-style:solid;border-width:1px">
Canvas not supported.</canvas>
Notice that onclick="bounce()" is missing from your new HTML file. That's not a problem! It's actually better not to attach event handlers inline. To make your script.js file work with the new HTML, change it so that the first few lines look like this:
$(document).ready(function() {
$('#myCanvas').click(bounce);
var width = 100;
var height = 200;
Actually, it would be even better to define the functions Ball(), draw() and bounce() outside the $(document).ready() function. Then you would write this:
var width = 100,
height = 200,
numBalls = 10,
balls;
$(document).ready(function() {
$('#myCanvas').click(bounce);
// create an array of balls
balls = new Array(numBalls);
for(i = 0 ; i < numBalls ; i++){
balls[i] = new Ball();
}
});
Here is a snippet containing the whole JavaScript file revised as I suggest:
var width = 100,
height = 200,
numBalls = 10,
balls;
$(document).ready(function() {
$('#myCanvas').click(bounce);
// create an array of balls
balls = new Array(numBalls);
for(i = 0 ; i < numBalls ; i++){
balls[i] = new Ball();
}
});
function Ball(){
// random radius
this.radius = Math.floor(Math.random()*(10-5+1))+5;
// random x and y
this.x = Math.floor(Math.random()*(width-this.radius+1))+this.radius;
this.y = Math.floor(Math.random()*(width-this.radius+1))+this.radius;
// random direction, +1 or -1
this.dx = Math.floor(Math.random()*2) * 2 - 1;
this.dy = Math.floor(Math.random()*2) * 2 - 1;
//random colour, r, g or b
var rcol = Math.floor(Math.random()*3);
this.col = rcol==0 ? "red" :
rcol==1 ? "blue" : "green";
}
// draw the balls on the canvas
function draw(){
var canvas = document.getElementById("myCanvas");
// check if supported
if(canvas.getContext){
var ctx=canvas.getContext("2d");
//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 0.5;
ctx.strokeStyle="black";
// draw each ball
for(i = 0; i < numBalls ; i++){
var ball = balls[i];
ctx.fillStyle=ball.col;
ctx.beginPath();
// check bounds
// change direction if hitting border
if(ball.x<=ball.radius ||
ball.x >= (width-ball.radius)){
ball.dx *= -1;
}
if(ball.y<=ball.radius ||
ball.y >= (height-ball.radius)){
ball.dy *= -1;
}
// move ball
ball.x += ball.dx;
ball.y += ball.dy;
// draw it
ctx.arc(ball.x, ball.y, ball.radius, 0, 2*Math.PI, false);
ctx.stroke();
ctx.fill();
}
}
else{
//canvas not supported
}
}
// calls draw every 10 millis
function bounce(){
setInterval(draw, 10);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<canvas id="myCanvas" width="100" height="200" style="border-style:solid;border-width:1px"> Canvas not supported.</canvas>
Add this to your js file : document.getElementById ("myCanvas").addEventListener ("click", bounce, false);
and remove onclick="bounce()" in your canevas tag if you left it in.
Also, you forgot the </body> before </html>.
I think that the problem is that you wrapped all your code in $(document).ready. If you didn't need it with the inline script, you should be good without it also when using the external script.

Optimizing canvas animation (sine curve)

how can I optimize this code to render sine wave without little blurring that happens when canvas is re-drawen
var canvas = document.getElementById("sinewave");
var points = {};
var counter = 0;
var intensity = 0;
function f(x, intensity) {
return intensity * Math.sin(0.25 * x) + 100;
}
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
var x = 0,
y = f(0,0);
var timeout = setInterval(function() {
if(counter < 400) {
ctx.beginPath();
ctx.moveTo(x, y);
x += 1;
y = f(x, intensity);
points[x] = y;
ctx.lineTo(x, y);
ctx.stroke();
if (x > 1000) {
clearInterval(timeout);
}
} else {
ctx.clearRect(0, 0, 400, 200);
ctx.beginPath();
points[x] = y;
x += 1;
y = f(x, intensity);
for(var i = 0; i < 400; i++) {
ctx.lineTo(i, points[i + counter - 400]);
}
ctx.stroke();
}
counter++;
}, 5);
}
Some thoughts:
Since x==0 & intensity==0 the first 400 plots form a straight line(?).
Your setInterval time is too short (5ms). The screen refreshes only about every 17ms so you are accumulating interval calls that the browser will futilely try to fill. (You're getting clogged up!).
Use the new(ish) requestAnimationFrame instead of setInterval because requestAnimationFrame is better integrated with the display hardware.
Here's example refactored code and Demo: http://jsfiddle.net/m1erickson/MZ7Ap/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: black; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
var points = {};
var counter = 0;
var intensity = 2;
var x = 0;
var y = fz(0,0);
animate();
function fz(x, intensity) {
return intensity * Math.sin(0.25 * x) + 100;
}
function animate(time){
requestAnimationFrame(animate);
draw(counter);
counter++;
}
function draw(counter){
if(counter < 400) {
ctx.beginPath();
ctx.moveTo(x, y);
x += 1;
y = fz(x, intensity);
points[x] = y;
ctx.lineTo(x, y);
ctx.stroke();
if (x > 1000) {
clearInterval(timeout);
}
} else {
ctx.clearRect(0, 0, 400, 200);
ctx.beginPath();
points[x] = y;
x += 1;
y = fz(x, intensity);
for(var i = 0; i < 400; i++) {
ctx.lineTo(i, points[i + counter - 400]);
}
ctx.stroke();
}
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=900 height=300></canvas>
</body>
</html>

Categories