I've been working on a chunk of code for a would-be Sierpinski fractal animation, but for some reason, the animation part just doesn't seem to work. I also tried using setInterval(), with the same results, namely a blank canvas. The idea is to draw an equilateral triangle with vertex coordinates as parameters step by step, as though somebody was drawing it on a piece of paper. Could you have a look to see what's wrong with it?
On a side note, I've copied a few examples of canvas animation off a few web tutorials, and none of them appear to be working in my files either. I use Firefox and Chrome, both up to date, so I guess it's not a technical issue.
<!DOCTYPE html>
<style>
canvas {
width: 600px;
height: 600px;
text-align: center;
background-color: white;
background-position: center;
position: relative;
top: 0px;
left: 0px;
border:1px solid #d3d3d3;
}
<body>
<canvas id="sCanvas"></canvas>
<script>
This is where the animation is supposed to take place; draws a line from (Ax,Ay) to (Bx,By).
function lineAnimation(x1,y1,x2,y2,ctx) {
var deltaX = (x2 - x1) / 100;
var deltaY = (y2 - y1) / 100;
var x = x1;
var y = y1;
var timer = setInterval(function () {
ctx.moveTo(x,y);
ctx.lineTo(x+deltaX,y+deltaY);
ctx.stroke();
x += deltaX;
y += deltaY;
}, 100);
if ((x===x2) && (y===y2)) clearTimeout(timer);
}
function drawTriangle(Ax,Ay,Bx,By,Cx,Cy,ctx) {
lineAnimation(Ax,Ay,Bx,By,ctx);
lineAnimation(Bx,By,Cx,Cy,ctx);
lineAnimation(Cx,Cy,Ax,Ay,ctx);
}
function init() {
var canvas=document.getElementById("sCanvas");
var ctx = canvas.getContext("2d");
ctx.save();
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
drawTriangle(10,10,30,50,50,10);
}
init();
</script>
Your functions are requiring the parameter ctx which you didn't include, as such they don't know what ctx is. All you need to do is include it in drawTriangle():
drawTriangle(10,10,30,50,50,10,ctx);
And then everything works.
Try This
function lineAnimation(x1,y1,x2,y2,ctx) {
var deltaX = (x2 - x1) / 100;
var deltaY = (y2 - y1) / 100;
var x = x1;
var y = y1;
var timer = setInterval(function () {
var canvas=document.getElementById("sCanvas"); //Added Change
var ctx = canvas.getContext("2d"); //Added Change
ctx.moveTo(x,y);
ctx.lineTo(x+deltaX,y+deltaY);
ctx.stroke();
x += deltaX;
y += deltaY;
}, 100);
if ((x===x2) && (y===y2)) clearTimeout(timer);
}
function drawTriangle(Ax,Ay,Bx,By,Cx,Cy,ctx) {
lineAnimation(Ax,Ay,Bx,By,ctx);
lineAnimation(Bx,By,Cx,Cy,ctx);
lineAnimation(Cx,Cy,Ax,Ay,ctx);
}
function init() {
var canvas=document.getElementById("sCanvas");
var ctx = canvas.getContext("2d");
ctx.save();
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
drawTriangle(10,10,30,50,50,10);
}
init();
It is giving you an error over ctx.moveTo(x,y); and ctx.lineTo(x+deltaX,y+deltaY); because thet are not able to use you ctx which is basically an object of your canvas. so just try to add them in code and things will work fine
DEMO
Related
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>
I don't know what I did wrong about this code.
I've tried redoing the entire script many times, and even renamed it to see if it would change anything but it didn't.
<!DOCTYPE html>
<html>
<head>
<title>Purely's Tower Defense</title>
<style>
* { padding: 0; margin: 0; }
canvas {background: #eee; display: block; margin: 0 auto}
</style>
</head>
<body>
<canvas id="myCanvas" width='800' height='500'></canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas');
var ctx = myCanvas.getContext('2d');
var playerX = (canvas.width - playerWidth)/2;
var playerY = canvas.height - playerHeight;
var playerWidth = 30;
var playerHeight = 30;
function drawPlayer()
{
ctx.beginPath();
ctx.fillStyle = "#000000";
ctx.fillRect(playerX, playerY, playerWidth, paddleHeight);
ctx.closePath()
}
function draw()
{
ctx.clearRect(0,0,canvas.width,canvas.height);
drawPlayer();
}
draw();
</script>
</body>
</html>
I expected to just have the crystal & the player to spawn.
You have two separate issues in your code:
You are defining playerX and playerY based on the playerWidth and playerHeight before they are defined
You are using paddleHeight instead of playerHeight in your drawPlayer function.
To fix this, you need to change your variable declaration order to have playerWidth and playerHeight before X and Y:
var canvas = document.getElementById('myCanvas');
var ctx = myCanvas.getContext('2d');
var playerWidth = 30;
var playerHeight = 30;
var playerX = (canvas.width - playerWidth)/2;
var playerY = canvas.height - playerHeight;
And change your drawPlayer function to use playerHeight
function drawPlayer()
{
ctx.beginPath();
ctx.fillStyle = "#000000";
ctx.fillRect(playerX, playerY, playerWidth, playerHeight);
ctx.closePath();
}
The Js Fiddle attached draw a box where ever the mouse is clicked. It works as expected for the most part. Except every time a new box is drawn on the canvas it speeds up more and more every time to the point where it's way too fast.
I've console.loged the dx/dy values and they are not increasing in value so it's not that, I don't think.
The dx value is what the position of the box is moving by.
Can any one shed some light?
var canvas = document.getElementById('myCanvas');
var logger = document.getElementById('logger');
var ctx = canvas.getContext('2d');
var x = 0;
var y = 0;
var dx = -2;
var dy = -2;
var boxColour = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
var boxSize = 20;
var mousex,
mousey;
canvas.addEventListener('click',function(e){
mousex = e.clientX;
mousey = e.clientY;
x = mousex - canvas.offsetLeft-(boxSize/2);
y = mousey - canvas.offsetTop-(boxSize/2);
draw();
});
function draw(){
logger.innerHTML = "x: " + x + "y: " + y;
ctx.clearRect(0,0,canvas.width,canvas.height);
collistionDetection();
ctx.beginPath();
ctx.rect(x,y,boxSize,boxSize);
ctx.fillStyle=boxColour;
ctx.fill();
ctx.closePath();
x+=dx;
y+=dy;
requestAnimationFrame(draw);
};
function collistionDetection(){
if(x<0 || x>canvas.width-boxSize){
dx = -dx;
boxColour = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
};
if(y<canvas.offsetTop-(boxSize/2) || y>canvas.height-boxSize){
boxColour = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
dy = -dy;
};
};
* { padding: 0; margin: 0; }
canvas { background: #eee; display: block;
margin: 0 auto; margin-top:10px;
}
<canvas id="myCanvas" width='480' height='320'></canvas>
<div id="logger"></div>
Your help is always much appreciated.
Thanks
moe
I think your requestAnimationFrames are not being cleared so your animation function is just being called more and more frequently every time you click. I made a small change to your code below which seems to help.
var canvas = document.getElementById('myCanvas');
var logger = document.getElementById('logger');
var ctx = canvas.getContext('2d');
var x = 0;
var y = 0;
var dx = -2;
var dy = -2;
var boxColour = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
var boxSize = 20;
var mousex,
mousey;
var lastAnimationFrame;
canvas.addEventListener('click',function(e){
mousex = e.clientX;
mousey = e.clientY;
x = mousex - canvas.offsetLeft-(boxSize/2);
y = mousey - canvas.offsetTop-(boxSize/2);
cancelAnimationFrame(lastAnimationFrame)
draw();
});
function draw(){
logger.innerHTML = "x: " + x + "y: " + y;
ctx.clearRect(0,0,canvas.width,canvas.height);
collistionDetection();
ctx.beginPath();
ctx.rect(x,y,boxSize,boxSize);
ctx.fillStyle=boxColour;
ctx.fill();
ctx.closePath();
x+=dx;
y+=dy;
lastAnimationFrame = requestAnimationFrame(draw);
};
function collistionDetection(){
if(x<0 || x>canvas.width-boxSize){
dx = -dx;
boxColour = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
};
if(y<canvas.offsetTop-(boxSize/2) || y>canvas.height-boxSize){
boxColour = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
dy = -dy;
};
};
* { padding: 0; margin: 0; }
canvas { background: #eee; display: block;
margin: 0 auto; margin-top:10px;
<canvas id="myCanvas" width='480' height='320'></canvas>
<div id="logger"></div>
Because by each mouse click, you are calling draw once again, and this call, as apparent in your code, is recursive and keeps calling itself. So, by each click, you have a chain of calls to draw.
You can add a boolean to check whether draw has initially been called, and if so, prevent subsequent calls inside your draw function:
if(!initialized)
{
requestAnimationFrame(draw);
initialized = true;
}
I'm trying to resize a rotated shape on canvas. My problem is that when I call the rendering function, the shape starts "drifting" depending on the shape angle. How can I prevent this?
I've made a simplified fiddle demonstrating the problem, when the canvas is clicked, the shape is grown and for some reason it drifts upwards.
Here's the fiddle: https://jsfiddle.net/x5gxo1p7/
<style>
canvas {
position: absolute;
box-sizing: border-box;
border: 1px solid red;
}
</style>
<body>
<div>
<canvas id="canvas"></canvas>
</div>
</body>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
canvas.width = 300;
canvas.height= 150;
var ctx = canvas.getContext('2d');
var counter = 0;
var shape = {
top: 120,
left: 120,
width: 120,
height: 60,
rotation: Math.PI / 180 * 15
};
function draw() {
var h2 = shape.height / 2;
var w2 = shape.width / 2;
var x = w2;
var y = h2;
ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.translate(75,37.5)
ctx.translate(x, y);
ctx.rotate(Math.PI / 180 * 15);
ctx.translate(-x, -y);
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, shape.width, shape.height);
ctx.restore();
}
canvas.addEventListener('click', function() {
shape.width = shape.width + 15;
window.requestAnimationFrame(draw.bind(this));
});
window.requestAnimationFrame(draw.bind(this));
</script>
In the "real" code the shape is resized when the resize-handle is clicked and moved but I think this example demonstrates the problem sufficiently.
EDIT: updated fiddle to clarify the issue:
https://jsfiddle.net/x5gxo1p7/9/
Always use local coordinates to define shapes.
When rendering content that is intended to be transformed the content should be in its own (local) coordinate system. Think of a image. the top left pixel is always at 0,0 on the image no matter where you render it. The pixels are at their local coordinates, when rendered they are moved to the (world) canvas coordinates via the current transformation.
So if you make your shape with coordinates set to its local, making the rotation point at its local origin (0,0) the display coordinates are stored separately as world coordinates
var shape = {
top: -30, // local coordinates with rotation origin
left: -60, // at 0,0
width: 120,
height: 60,
world : {
x : canvas.width / 2,
y : canvas.height / 2,
rot : Math.PI / 12, // 15deg clockwise
}
};
Now you don't have to mess about with translating forward and back... blah blah total pain.
Just
ctx.save();
ctx.translate(shape.world.x,shape.world.y);
ctx.rotate(shape.world.rot);
ctx.fillRect(shape.left, shape.top, shape.width, shape.height)
ctx.restore();
or event quicker and eliminating the need to use save and restore
ctx.setTransform(1,0,0,1,shape.world.x,shape.world.y);
ctx.rotate(shape.world.rot);
ctx.fillRect(shape.left, shape.top, shape.width, shape.height);
The local shape origin (0,0) is where the transformation places the translation.
This greatly simplifies a lot of the work that has to be done
var canvas = document.getElementById('canvas');
canvas.width = 300;
canvas.height= 150;
var ctx = canvas.getContext('2d');
ctx.fillStyle = "black";
ctx.strokeStyle = "red";
ctx.lineWidth = 2;
var shape = {
top: -30, // local coordinates with rotation origin
left: -60, // at 0,0
width: 120,
height: 60,
world : {
x : canvas.width / 2,
y : canvas.height / 2,
rot : Math.PI / 12, // 15deg clockwise
}
};
function draw() {
ctx.setTransform(1,0,0,1,0,0); // to clear use default transform
ctx.clearRect(0, 0, canvas.width, canvas.height);
// you were scaling the shape, that can be done via a transform
// once you have moved the shape to the world coordinates.
ctx.setTransform(1,0,0,1,shape.world.x,shape.world.y);
ctx.rotate(shape.world.rot);
// after the transformations have moved the local to the world
// you can ignore the canvas coordinates and work within the objects
// local. In this case showing the unscaled box
ctx.strokeRect(shape.left, shape.top, shape.width, shape.height);
// and a line above the box
ctx.strokeRect(shape.left, shape.top - 5, shape.width, 1);
ctx.scale(0.5,0.5); // the scaling you were doing
ctx.fillRect(shape.left, shape.top, shape.width, shape.height);
}
canvas.addEventListener('click', function() {
shape.width += 15;
shape.left -= 15 / 2;
shape.world.rot += Math.PI / 45; // rotate to illustrate location
// of local origin
var distToMove = 15/2;
shape.world.x += Math.cos(shape.world.rot) * distToMove;
shape.world.y += Math.sin(shape.world.rot) * distToMove;
draw();
});
// no need to use requestAnimationFrame (RAF) if you are not animation
// but its not wrong. Nor do you need to bind this (in this case
// this = window) to the callback RAF does not bind a context
// to the callback
/*window.requestAnimationFrame(draw.bind(this));*/
requestAnimationFrame(draw); // functionaly identical
// or just
/*draw()*/ //will work
body { font-family : Arial,"Helvetica Neue",Helvetica,sans-serif; font-size : 12px; color : #242729;} /* SO font currently being used */
canvas { border: 1px solid red; }
<canvas id="canvas"></canvas>
<p>Click to grow "and rotate" (I add that to illustrate the local origin)</p>
<p>I have added a red box and a line above the box, showing how using the local coordinates to define a shape makes it a lot easier to then manipulate that shape when rendering "see code comments".</p>
Try this. You had ctx.translate() used where it was not entirely necessary. That caused the problems.
<script type="text/javascript">
var canvas = document.getElementById('canvas');
canvas.width = 300;
canvas.height= 150;
var ctx = canvas.getContext('2d');
var counter = 0;
var shape = {
top: 120,
left: 120,
width: 120,
height: 60,
rotation: Math.PI / 180 * 15
};
function draw() {
ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.translate(75,37.5)
ctx.rotate(Math.PI / 180 * 15);
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, shape.width, shape.height);
ctx.restore();
}
canvas.addEventListener('click', function() {
shape.width = shape.width + 15;
window.requestAnimationFrame(draw.bind(this));
});
window.requestAnimationFrame(draw.bind(this));
</script>
This is happening because the x and y are set as the half value of the shape size, which completely changes its position.
You should set a point for the center of the shape, anyway. I set this point as ctx.canvas.[width or height] / 2, the half of the canvas.
var h2 = shape.height / 2;
var w2 = shape.width / 2;
var x = (ctx.canvas.width / 2) - w2;
var y = (ctx.canvas.height / 2) - h2;
ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.translate(x + (shape.width / 2), y + (shape.height / 2));
ctx.rotate(((shape.rotation * Math.PI) / 180) * 15);
ctx.fillStyle = '#000';
ctx.fillRect(-shape.width / 2, -shape.height / 2, shape.width, shape.height);
ctx.restore();
Fiddle.
Found a solution, problem was that I wasn't calculating the new center point coordinates.
The new fiddle with solution: https://jsfiddle.net/HTxGb/151/
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width =500;
canvas.height = 500;
var x = canvas.width/2;
var y = canvas.height/2;
var rectw = 20;
var recth = 20;
var rectx = -rectw/2;
var recty = -recth/2;
var rotation = 0;
var addedRotation = Math.PI/12;
var addedWidth = 20;
var addedHeight = 10;
var draw = function() {
ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.translate(x, y);
ctx.rotate(rotation);
ctx.fillRect(rectx, recty, rectw, recth);
ctx.restore();
}
document.getElementById('growXRight').addEventListener('click', function() {
rectx -= addedWidth/2;
x += addedWidth/2 * Math.cos(rotation);
y -= addedWidth/2 * Math.sin(-rotation);
rectw += addedWidth;
draw();
})
document.getElementById('growXLeft').addEventListener('click', function() {
rectx -= addedWidth/2;
x -= addedWidth/2 * Math.cos(rotation);
y += addedWidth/2 * Math.sin(-rotation);
rectw += addedWidth;
draw();
})
document.getElementById('growYTop').addEventListener('click', function() {
recty -= addedHeight/2;
x += addedHeight/2 * Math.sin(rotation);
y -= addedHeight/2 * Math.cos(-rotation);
recth += addedHeight;
draw();
})
document.getElementById('growYBottom').addEventListener('click', function() {
recty -= addedHeight/2;
x -= addedHeight/2 * Math.sin(rotation);
y += addedHeight/2 * Math.cos(-rotation);
recth += addedHeight;
draw();
})
document.getElementById('rotatePlus').addEventListener('click', function() {
rotation += addedRotation;
rotation = rotation % (Math.PI*2);
if(rotation % Math.PI*2 < 0) {
rotation += Math.PI*2;
}
draw();
})
document.getElementById('rotateMinus').addEventListener('click', function() {
rotation -= addedRotation;
rotation = rotation % (Math.PI*2);
if(rotation % Math.PI*2 < 0) {
rotation += Math.PI*2;
}
draw();
})
draw();
Have what I think seems like a kind of strange problem.
I have a function that is made to draw an element in HTML5.
If i write it multiple times it is drawn those times, but if i place it in a loop it only draws the first time. Iv tried to monitor this by console.log for example but as soon as i try to draw this the loop is interrupted. It like there is some type of "break" function in it.
Anyone who has an idea about this?
<body>
<section id="wrapper">
<h1></h1>
<canvas id="canvas" width="800" height="600" style=" border-color: #000; border-style: solid; border-width: 1px;">
<p>Your browser doesn't support canvas.</p>
</canvas>
<script>
var context;
var canvas;
var WIDTH;
var HEIGHT;
$(document).ready(function() {
main_init();
});
function main_init() {
console.log("init");
WIDTH = $("#canvas").width();
HEIGHT = $("#canvas").height();
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
var width = 10;
var height = 10;
var posX = 30;
var posY = 60;
//NOT WORKING
for(y = 1; y < height; y+=1)
{
for(x = 1; x < width; x+=1)
{
console.log("y:"+ y + " x:" + x);
//console.log(isEven(x));
if(isEven(x))
{
HexagonObj(posX * x, posY * y, 0.95);
}
else
{
HexagonObj(posX * x, (posY + 20) * y, 0.95);
}
}
}
//WORKING
HexagonObj(-30, 60, 0.95);
HexagonObj(10, 80, 0.95);
HexagonObj(50, 60, 0.95);
HexagonObj(-30, 100, 0.95);
}
HexagonObj = function(xCorrd, yCorrd, size){
//console.log("hexagon");
var x0=xCorrd; var y0=yCorrd; //cordinates
var xx=20 * size; var yy=20 * size; //size of the legs of the shape
x=x0; y=y0; context.moveTo(x,y);
x+=xx; y+=0; context.moveTo(x,y);
x+=xx; y+=0; context.lineTo(x,y);
x+=xx; y+=yy; context.lineTo(x,y);
x+=(xx*-1); y+=yy; context.lineTo(x,y);
x+=(xx*-1); y+=0; context.lineTo(x,y);
x+=(xx*-1); y+=(yy*-1); context.lineTo(x,y);
x+=xx; y+=(yy*-1); context.lineTo(x,y);
context.fillStyle = "#FFFF99";
context.fill();
context.strokeStyle = "rgba(0,0,0,1)";
context.stroke();
}
function isEven(n)
{
return parseFloat(n) && (n % 2 == 0);
}
</script>
</section>
</body>
I have marked the HexagonObj creation that works and that dose not work.
You need to declare x and y as variables in each function where they are used. Because you are missing the var declaration, the functions are all accessing global x and y variables. As a consequence, the first call to HexagonObj clobbers the loop variables in main_init().
(Technically, you only need to declare var x, y in one of the functions to solve the immediate problem. However, it's bad form to be using global variables like that.)
for loop executing only once in function main_init since x and y which are global are modified inside HexagonObj function to y:81 and x:50