Draw HTML5 Canvas pulse line - javascript

Hey guys I've been trying to wrap my head around the HTML5 Canvas animation but failed miserably I wanted to achieve the below figure by animating this custom shape in an interval of 10 seconds.
I've pretty much screwed the math of it so I ended up just writing every lineTo statement manually, tried Paul Irish's requestAnimationFrame at the end to animate the line but no luck.
Any help would be highly appreciated, here is
thelive demo
Thanks guys

It's not moving cause you are basically not moving anything - the same shape is drawn to the same position each iteration.
Here is a modified version which animates the pulse to the left (adjust dlt to change speed):
Modified fiddle here
var segX = canvas.width / 6;
var segY = canvas.height / 2;
function draw() {
ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(0, segY);
for(var i = dlt, h = true; i < canvas.width + segX; i += segX) {
if (h) {
ctx.lineTo(i, segY);
ctx.lineTo(i, segY + segX);
} else {
ctx.lineTo(i, segY + segX);
ctx.lineTo(i, segY);
}
h = !h;
}
ctx.stroke();
dlt--;
if (dlt < -segX * 2) dlt = 0;
requestAnimFrame(draw);
}

You're basically needing a function that returns only 2 values--high and low.
Here's a function that returns only low/high values based on a period and oscillation values:
// squared wave
// p = period (how long it takes the wave to fully complete and begin a new cycle)
// o = oscillation (change in wave height)
function squareY(x) {
return( (x%p)<o?o:0 );
}
Demo: http://jsfiddle.net/m1erickson/A69ZV/
Example code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.lineWidth=3;
var p=30; // period
var o=15; // oscillation
var fps = 60;
var n=0;
animate();
function animate() {
setTimeout(function() {
requestAnimationFrame(animate);
// Drawing code goes here
n+=1.5;
if(n>300){
n=0;
}
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
for(var x=0;x<n;x++){
var y=squareY(x);
ctx.lineTo(x,y+50);
}
ctx.stroke();
}, 1000 / fps);
}
// squared sine
function squareY(x) {
return( (x%p)<o?o:0 );
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=350 height=350></canvas>
</body>
</html>

Related

How to shift an array of posenet points?

I'm a beginner at using p5.js but I'm currently currently attempting to create a brush sketch like this
ellipse brush
though using computer vision & posenet nose tracking (essentially a nose brush)
The problem is, while it doesn't state any errors, it doesn't work.
This is my code for the ellipse brush without posenet & camera vision
let mousePosition = [];
function setup() {
createCanvas(400, 400);
}
function draw() {
background(0);
//Every frame of animation
//storing the mouse position in an array
mousePosition.push({x: mouseX, y: mouseY});
//shift the array so that the older ones deletes itself
if(mousePosition.length > 100) mousePosition.shift();
//loop
for(let i = 0; i < mousePosition.length; i++) {
//if the variable is less than 50, loop function
let x = mousePosition[i].x;
let y = mousePosition[i].y;
ellipse(x, y, r,r);
var r = 20
}
}
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/addons/p5.dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
and this is the one with computer vision & nose tracking w/ posenet
let capture;
let poseNet;
let pose;
let text;
let pg;
let nosePosition = []
function setup() {
createCanvas(700, 700);
capture = createCapture(VIDEO);
capture.hide();
pg = createGraphics(width, height);
poseNet = ml5.poseNet(capture, modelLoaded);
poseNet.on('pose', gotPoses);
// background(255)
// color picker
}
function gotPoses(poses) {
//console.log(poses);
if (poses.length > 0) {
pose = poses[0].pose;
}
}
function modelLoaded() {
console.log('poseNet.ready');
}
function draw() {
translate(width, 0); // move to far corner
scale(-1.0, 1.0); // flip x-axis backwards
image(capture, 0, 0, width, width * capture.height /
capture.width);
image(pg, 0, 0, width, height);
if (pose) {
nosePosition.push({x:pose.nose.x ,y: pose.nose.y});
if(nosePosition.length > 100) nosePosition.shift(); {
}
for(let i = 0; i < nosePosition.length; i++) {
//if the variable is less than 50, loop function
let x = nosePosition[i].x;
let y = nosePosition[i].y;
pg.ellipse(x, y, i/5,i/5);
var r = 20 //how big the ellipse is
pg.fill(255)
pg.noStroke();
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js"></script>
<script src="https://unpkg.com/ml5#latest/dist/ml5.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
The second is essentially very similar to the first, as I've only changed the mouseX/Ys into the posenet Nose keypoint.
Any insight/solution would be highly appreciated!
Thank you :)
You're shifting properly, but you forgot to clear the pg graphic, which is kind of like forgetting to put background(0) in your original sketch. So instead of drawing all the ellipses on a blank background, you're drawing them on top of the previous frame.
Adding pg.clear() anywhere in draw() after you display pg on the canvas (image(pg, ...)) and before you draw the ellipses (for (...) {... ellipse(nosePosition[i].x...)}) should do the trick. Here's where I put it:
image(pg, 0, 0, width, height);
pg.clear();//HERE
if (pose) {//...

How can I make an animation effect on the canvas while moving?

Is it possible to make an animation effect on the canvas while moving?
I just need to make an animation movement between canvas' positions,
Like in css3: -webkit-transition-duration: 1s;
Any help is appreciated.
<html>
<head>
<style>
#myCanvas {
-webkit-transition-duration: 1s;
}
</style>
<title>JS Bin</title>
</head>
<body>
<canvas id="myCanvas" width="1280" height="600" style="border:1px solid #d3d3d3;color:red;"></canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var w = document.getElementById("myCanvas");
timer = setInterval(function() {
var f = Math.floor(1+Math.random()*680);
var f2 = Math.floor(1+Math.random()*400);
console.log (f, f2);
ctx.fillStyle="#FF0000";
ctx.clearRect(0, 0, c.width, c.height);
ctx.fillRect(f, f2, 100, 50);
w.onclick = function() {
clearInterval(timer);
falling();
}
}, 300 //the seconds of interval movement)
function falling(){
ctx.clearRect(0,0,c.width,c.height);
ctx.fillRect(500,500,100,50)
}
</script>
</body>
</html>
Sure. If you just want to calculate interim positions along a line from a starting point to an ending point then you can do it like this:
// percentComplete is a number between 0.00 and 1.00
// representing the current progress of the animation from start to end
var x = startingX+(endingX-startingX)*percentComplete;
var y = startingY+(endingY-startingY)*percentComplete;
If you want to animate with flair, then you can use Robert Penner's easing functions to animate in a non-linear way.
To include a fixed duration for your animation you can calculate percentComplete based as:
var percentComplete = elapsedTime / animationDuration;

console.log() keeps running infinitely even after the program finishes execution

I have an ECG program which plots ECG after taking values from arrays. Upon opening the console (By pressing the f12 button) in Firefox, it shows that the log keeps on writing infinitely even after all the 12 graphs are constructed. It is not supposed to happen! There are 12 arrays each with 1250 elements. I'm giving one array because of the word limit here. Clicking "Click Me" button plots the graph using canvas. Please take the values given at bottom of the question for reference. Please help me find why this overflow is happening. I'm a beginner.
Code:
<!doctype html>
<html>
<head>
<script>
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
window.addEventListener('load', onLoadd, false);
var YRatio=0.75;
var nPointsPerFrame = 10;//This value determines the speed. Higher value means more speed.
var Lead_1 = [];
function onLoadd(evt)
{
drawBkg(byId('canvas'), 3.78, "0.35", "black");
}
function onDocLoaded(evt)
{
//Markings();
drawcurFrame_Lead_1.apply(this, Lead_1);
}
function drawBkg(canvasElem, squareSize, minorLineWidthStr, lineColStr)
{
var nLinesDone = 0;
var i, curX, curY;
var ctx = canvasElem.getContext('2d');
ctx.clearRect(0,0,canvasElem.width,canvasElem.height);
// draw the vertical lines
curX=0;
ctx.strokeStyle = lineColStr;
while (curX < canvasElem.width)
{
ctx.lineWidth = minorLineWidthStr;
ctx.beginPath();
ctx.moveTo(curX, 0);
ctx.lineTo(curX, canvasElem.height);
ctx.stroke();
curX += squareSize;
nLinesDone++;
}
// draw the horizontal lines
curY=0;
nLinesDone = 0;
while (curY < canvasElem.height)
{
ctx.lineWidth = minorLineWidthStr;
ctx.beginPath();
ctx.moveTo(0, curY);
ctx.lineTo(canvasElem.width, curY);
ctx.stroke();
curY += squareSize;
nLinesDone++;
}
}
//FIRST GRAPH Lead_1
// position that will be treated as 0,0 when drawing our points.
var originX_Lead_1=46;
var originY_Lead_1=16;
function Draw_Lead_1(nSamplesToDraw, firstSample, lineWidthStr, lineColourStr)
{
var can = byId('canvas');
var ctx = can.getContext('2d');
ctx.strokeStyle = lineColourStr;
ctx.lineWidth = lineWidthStr;
console.log(firstSample);
ctx.beginPath();
ctx.moveTo( originX_Lead_1+(firstSample*0.377), originY_Lead_1+(Lead_1[firstSample-1]*YRatio) );
for (i=0; i<nSamplesToDraw; i++)
{
var curSample = Lead_1[i + firstSample];// calculate y coordinate
ctx.lineTo( originX_Lead_1+((firstSample+i)*0.377), originY_Lead_1+(curSample*YRatio) );
}
ctx.stroke();
}
var curFrame_Lead_1=0;//Starts with frame 0.
function drawcurFrame_Lead_1()
{
Draw_Lead_1(nPointsPerFrame, nPointsPerFrame*curFrame_Lead_1, "0.75", "blue");//Calling function to draw the graph
curFrame_Lead_1+=1;//Frame is incremented one by 1.
requestAnimationFrame( drawcurFrame_Lead_1 );
}
</script>
</head>
<body>
<div id='txt'></div>
<canvas id="canvas" width="1250" height="800"></canvas>
<button onclick="onDocLoaded()">Click Me</button>
</body>
</html>
Lead_1 = [69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,72,71,71,71,70,69,69,68,67,67,67,67,68,68,69,69,70,71,72,72,73,73,73,73,73,73,73,73,73,72,72,73,73,73,73,73,72,72,73,76,79,81,80,75,67,55,44,36,34,38,46,57,67,74,77,77,76,74,73,72,73,73,73,73,73,73,73,74,74,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,73,74,73,73,72,71,70,69,68,68,67,66,66,65,64,63,63,62,61,61,61,61,61,61,61,61,61,62,62,63,64,64,65,66,67,68,69,70,71,71,72,73,73,73,73,73,73,73,73,73,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,73,73,74,74,73,73,72,72,72,72,73,73,73,72,72,72,72,72,73,73,73,72,72,72,72,73,73,72,72,72,71,70,69,69,69,68,67,67,67,67,67,67,68,69,69,70,71,71,72,73,73,73,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,73,75,78,80,78,72,62,51,40,34,33,39,49,59,69,75,77,77,75,73,72,72,72,72,73,73,73,72,72,72,73,73,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,71,71,71,70,70,69,68,67,66,65,64,64,64,63,63,62,61,61,60,60,60,60,60,60,60,61,61,62,62,63,64,65,66,67,67,68,69,70,71,71,72,72,72,72,72,72,72,73,73,73,73,72,72,72,72,72,72,72,72,72,73,73,73,73,73,73,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,71,70,70,69,69,68,68,67,67,66,66,66,67,67,68,69,70,71,71,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,74,76,79,80,77,70,60,49,39,33,33,40,50,61,70,75,77,76,75,73,72,72,72,73,73,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,73,72,72,71,70,69,69,68,67,66,65,64,64,63,62,62,61,60,60,60,60,61,61,61,61,61,61,62,62,63,64,65,66,67,68,69,69,70,71,72,73,73,73,73,73,73,73,73,73,73,73,72,73,73,73,73,73,73,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,72,73,73,73,73,72,72,72,72,73,73,73,72,72,71,70,70,69,68,68,67,67,67,67,67,67,68,68,69,69,70,70,71,72,72,72,72,72,72,72,73,73,73,73,72,72,72,72,72,72,72,73,74,77,79,79,76,68,57,45,36,33,36,44,54,64,72,76,77,76,75,73,72,72,72,73,73,73,73,73,72,72,72,72,72,72,72,72,73,73,73,73,73,73,73,73,72,73,73,73,72,72,71,70,69,68,68,67,66,65,64,63,62,62,62,61,61,61,60,60,61,61,61,61,62,62,63,63,64,64,65,66,67,68,69,69,70,71,72,72,72,73,73,73,73,73,73,73,72,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,73,73,73,73,73,73,72,72,72,72,73,73,72,72,72,72,72,73,73,73,72,72,72,72,72,72,72,72,72,71,70,69,68,68,67,67,67,66,66,67,67,68,69,70,70,71,71,72,72,72,72,72,72,72,72,73,72,72,72,72,72,72,72,72,71,72,74,77,79,78,74,66,55,44,36,33,36,44,55,65,72,76,77,76,74,73,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,71,71,71,70,70,69,68,67,66,65,64,64,63,63,62,61,61,60,60,60,60,60,60,60,61,61,62,62,63,63,64,65,66,67,67,68,69,70,71,72,73,73,72,72,72,72,72,72,73,73,73,73,72,72,72,73,73,72,72,72,72,72,72,72,73,73,72,72,72,72,72,73,73,73,73,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,71,70,70,69,68,68,67,67,67,67,67,67,68,68,69,70,70,71,72,72,72,72,72,72,72,72,72,72,72,72,72,72,73,72,72,72,72,73,76,79,80,79,73,64,52,41,34,34,39,49,59,69,75,77,77,76,74,73,73,73,73,73,73,73,73,73,73,73,73,73,74,74,73,73,73,73,73,73,74,74,74,74,74,74,74,74,73,72,71,70,69,68,68,67,67,66,65,64,64,64,63,63,63,62,62,62,62,63,63,63,63,64,64,65,66,66,67,68,69,71,72,72,73,74,75,75,75,76,76,76,74,72,70,70,69,69];
It is because you are calling drawcurFrame_Lead_1 in requestAnimationFrame. You have to put condition to finish the execution of program in drawcurFrame_Lead_1
Update
var flag= 0;
function drawcurFrame_Lead_1()
{
if(flag ==0)
{
Draw_Lead_1(nPointsPerFrame, nPointsPerFrame*curFrame_Lead_1, "0.75", "blue");//Calling function to draw the graph
curFrame_Lead_1+=1;//Frame is incremented one by 1.
requestAnimationFrame( drawcurFrame_Lead_1 );
}
}
I have declared a variable flag = 0;
Now what you can do is set flag to 1 whenever your program is finished

HTML5 canvas continuously stroking lines

I want to draw some continuously growing lines in HTML5 and Javascript. Here is what I want to do:
A point located at the center of my screen will have 3 lines growing (120 degree to each other) to a certain length, say 50 pix, then each of this 3 vertex will become a new center and have another 3 lines.
(I couldnt post images due to low reputation I have, hopefully you know what I mean abt the image here...)
I already written the function to have a array of all the points I need as the centers, starting from the center of my screen. I am thinking to write a loop over this array to draw the lines. I DO NOT want to directly use the stroke so that the line just appears on the screen. I want to have something like the the lines are drawn bit by bit (bad english here, please excuse my english) until it reaches the pre-defined length. However my code dont work quite well here, it only displays all the center points and only the last center point has the movement to have the 3 lines to grow...
I need to know the correct way to do this... many thanks in advance!
(please ignore the variable time or startTime in my code... )
<script>
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var canvas = document.getElementById('myCanvas');
canvas.width= window.innerWidth;
canvas.height= window.innerHeight;
var context = canvas.getContext('2d');
var totalLength = 50;
var centreSet = new Array();
var counter = 0;
var centre = {
x: canvas.width / 2,
y: canvas.height / 2,
};
var myLine = {
length : 0,
color : 'grey',
lineWidth : 0.5,
};
function drawLine(centre, context, mylength) {
context.beginPath();
context.moveTo(centre.x, centre.y);
context.lineTo(centre.x, centre.y - mylength);
context.moveTo(centre.x, centre.y);
context.lineTo(centre.x - 0.866 * mylength, centre.y + mylength/2);
context.moveTo(centre.x, centre.y);
context.lineTo(centre.x + 0.866 * mylength, centre.y + mylength/2);
context.lineWidth = myLine.lineWidth;
context.strokeStyle = myLine.color;
context.closePath();
context.stroke();
}
function startAnimate(centre, canvas, context, startTime, mylength) {
// update
var time = (new Date()).getTime() - startTime;
var linearSpeed = 5;
// pixels / second
var newX = linearSpeed / 10;
if(mylength < totalLength) {
mylength = mylength + newX;
// clear
//context.clearRect(0, 0, canvas.width, canvas.height);
drawLine(centre, context, mylength);
// request new frame
requestAnimFrame(function() {
startAnimate(centre, canvas, context, startTime, mylength);
});
}
}
function animate(centre, canvas, context, startTime){
//create array to have all the center points
centreSet = getCentres();
for (var i = 0; i < centreSet.length; i++){
//pass the x and y values in a object for each center we have in the array
centre.x = str2x(centreSet[i]);
centre.y = str2y(centreSet[i]);
startAnimate(centre, canvas, context, startTime, 0);
}
}
setTimeout(function() {
var startTime = (new Date()).getTime();
animate(centre, canvas, context, startTime);
}, 1000);
I just edited your code, I added the following part:
var length = 0;
for(var i = 0; i < 380; i++){
window.setTimeout(function() {drawFrame(length);},16.67);
length = length + 0.25;
}
I expect the screen appears to draw the incremental lines bit by bit until it reaches the length I want. However, it seems like the whole incremental process is not shown and it only shows the finished drawing.
Can anyone tell me why?
Regarding your followup question about why your animation loop fails
By putting your setTimeout in a for-loop, each new setTimeout is cancelling the previous setTimeout.
So you’re just left with the very last setTimeout running to completion.
In an animation loop, you typically do 3 things during each "frame":
Change some data to reflect how the new frame is different from the previous frame.
Draw the frame.
Test if the animation is complete. If not, do another frame (go to #1).
The setTimeout function is used to do the last part of #3 (do another frame)
So setTimeout is really acting as your animation loop. --- Your for-loop is not needed.
This is how you would restructure your code to follow this pattern:
var length=0;
var maxLength=50;
function draw(){
// make the line .25 longer
length=length+.25;
// draw
drawFrame(length);
// test if the line is fully extended
// if not, call setTimeout again
// setTimeout(draw,100) will call this same draw() function in 100ms
if(length<maxLength){
setTimeout(draw,100);
}
}
[Edited: to include spawning of child objects after lines reach terminal distance]
In your code you were not spawning new center points when the lines reached their maximum extension.
I would suggest that each of your centre objects have at least this much information in order to spawn a new set of centre objects when their lines reach terminal length:
var newCentrePoint={
x:x,
y:y,
maxLength:newMaxLength,
growLength:growLength,
currentLength:0,
isActive:true
}
The x,y are the centerpoint’s coordinates.
maxLength is the maximum extension of the 3 lines before they are terminated.
growLength is the amount by which each line will grow in each new frame.
currentLength is the current length of the line.
isActive is a flag indicating if this point is growing lines (true) or if it’s terminated (false)
Then when each line reaches terminal length you can spawn a new set of lines like this:
// spawns 3 new centre points – default values are for testing
function spawn(point,newMaxLength,newColor,growLength,newLineWidth){
var max=newMaxLength||point.maxLength/2;
var color=newColor|| (colors[++colorIndex%(colors.length)]);
var grow=growLength||point.growLength/2;
var lw=newLineWidth||point.lineWidth-1;
// new center points are spawned at the termination points of the 3 current lines
newPoint((point.x),(point.y-point.maxLength),max,color,grow,lw);
newPoint((point.x-0.866*point.maxLength),(point.y+point.maxLength/2),max,color,grow,lw);
newPoint((point.x+0.866*point.maxLength),(point.y+point.maxLength/2),max,color,grow,lw);
}
// creates a new point object and puts in the centreSet array for processing
function newPoint(x,y,newMaxLength,newColor,growLength,newLineWidth){
var newPt={
x:x,
y:y,
maxLength:newMaxLength,
color:newColor,
lineWidth:newLineWidth,
growLength:growLength,
currentLength:0,
isActive:true
}
centreSet.push(newPt);
}
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/Vc8Gf/
<!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: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var context = canvas.getContext('2d');
// colors
var colors=["red","blue","gold","purple","green"];
var colorIndex=0;
//
var centreSet=[]
var generations=1;
// seed point
newPoint(canvas.width/2,canvas.height/2,100,"red",15);
// start
draw();
//
function draw(){
//
context.clearRect(0,0,canvas.width,canvas.height);
//
for(var i=0;i<centreSet.length;i++){
//
var centre=centreSet[i];
//
if(centre.isActive){
//
centre.currentLength+=centre.growLength;
//
if(centre.currentLength>=centre.maxLength){
centre.isActive=false;
centre.currentLength=centre.maxLength;
spawn(centre);
}
}
//
drawLines(centre);
}
//
if(generations<120){
setTimeout(draw,500);
}else{
context.font="18pt Verdana";
context.fillText("Finished 120 generations",40,350);
}
}
function spawn(point,newMaxLength,newColor,growLength,newLineWidth){
var max=newMaxLength||point.maxLength/2;
var color=newColor|| (colors[++colorIndex%(colors.length)]);
var grow=growLength||point.growLength/2;
var lw=newLineWidth||point.lineWidth-1;
newPoint((point.x),(point.y-point.maxLength),max,color,grow,lw);
newPoint((point.x-0.866*point.maxLength),(point.y+point.maxLength/2),max,color,grow,lw);
newPoint((point.x+0.866*point.maxLength),(point.y+point.maxLength/2),max,color,grow,lw);
generations++;
}
function newPoint(x,y,newMaxLength,newColor,growLength,newLineWidth){
var newPt={
x:x,
y:y,
maxLength:newMaxLength,
color:newColor,
lineWidth:newLineWidth,
growLength:growLength,
currentLength:0,
isActive:true
}
centreSet.push(newPt);
}
function drawLines(centre) {
var length=centre.currentLength;
//
context.beginPath();
context.moveTo(centre.x, centre.y);
context.lineTo(centre.x, centre.y - length);
//
context.moveTo(centre.x, centre.y);
context.lineTo(centre.x - 0.866 * length, centre.y + length/2);
//
context.moveTo(centre.x, centre.y);
context.lineTo(centre.x + 0.866 * length, centre.y + length/2);
//
context.strokeStyle=centre.color;
context.lineWidth = centre.lineWidth;
context.stroke();
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=400 height=400></canvas>
</body>
</html>

clearRect of canvas context does not clear the pixels

I want to make an animation with javascript and html canvas, just the make a rectangle move from the top of the window to the bottom, I use canvas.clearRect to clear all the pixel on the canvas, but, it seems this function does not work, the previously drawing was still there. here is all the code
<!DOCTYPE HTML>
<html>
<title>Jave script tetris by zdd</title>
<head>
<script>
function point(x, y)
{
this.x = x;
this.y = y;
}
function draw(timeDelta)
{
// Vertices to draw a square
var v1 = new point( 0, 0);
var v2 = new point(100, 0);
var v3 = new point(100, 100);
var v4 = new point( 0, 100);
this.vertices = [v1, v2, v3, v4];
// Get canvas context
var c = document.getElementById("canvas");
var cxt = c.getContext("2d");
// Clear the canvas, this does not work?
cxt.clearRect(0, 0, 800, 600);
// Move the piece based on time elapsed, just simply increase the y-coordinate here
for (var i = 0; i < this.vertices.length; ++i)
{
this.vertices[i].y += timeDelta;
}
cxt.moveTo(this.vertices[0].x, this.vertices[0].y);
for (var i = 1; i < this.vertices.length; ++i)
{
cxt.lineTo(this.vertices[i].x, this.vertices[i].y);
}
cxt.lineTo(this.vertices[0].x, this.vertices[0].y);
cxt.stroke();
}
var lastTime = Date.now();
function mainLoop()
{
window.requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
window.requestAnimationFrame(mainLoop);
var currentTime = Date.now();
var timeDelta = (currentTime - lastTime);
draw(timeDelta);
lastTime = currentTime;
}
</script>
</head>
<body>
<canvas id="canvas" width="800" height="600">
</canvas>
<script>
</script>
<button type="button" style="position:absolute; left:500px; top:600px; width:100px; height:50px;" class="start" onclick="mainLoop()">start</button>
</body>
</html>
and here is the result picture in Chrome, I want only one rectangle, but the clearRect function didn't clear the old rectangle, so..., how to fix this?
You are missing beginPath. Without it each box is actually part of the last box.
cxt.beginPath();
cxt.moveTo(this.vertices[0].x, this.vertices[0].y);
for (var i = 1; i < this.vertices.length; ++i) {
cxt.lineTo(this.vertices[i].x, this.vertices[i].y);
}
after adding that, the box seems to jiggle around, not sure if thats your intention.
Here's a fiddle: http://jsfiddle.net/6xbQN/
Good luck!

Categories