Why isn't my program drawing anything? - javascript

I made this program that will hopefully draw a cool shape based on the sliders. The problem is, nothing is showing up other than the sliders! Why is this?
var aslider, lslider, sslider, newx, newy;
function setup() {
createCanvas(300,300);
aslider = createSlider(1,359,17);
lslider = createSlider(1,50,10);
sslider = createSlider(1,50,20);
}
function draw() {
var angle = aslider.value();
var length = lslider.value();
var size = sslider.value();
var startx = width / 2;
var starty = height / 2;
var radians = angle * (Math.PI/180);
for (var i = 0; i++; i < size) {
newx = startx * Math.sin(radians) + starty * Math.cos(radians);
newy = startx * Math.sin(radians) + starty * -Math.cos(radians);
line(startx, starty, newx, newy);
startx = newx;
starty = newy;
}
}

Your for loop is wrong. It should be
for (var i = 0; i < size; i++)
I tested it here: http://codepen.io/eerk/pen/wgOZVW?editors=1010

Related

rotation of a 3d cube relative to a specific point on the canvas

Using certain methods, I drew a 3D cube.
My task is to rotate it around the z axis. I also need to rotate the cube relative to the coordinates (0,0,0) (on my canvas, these will be the coordinates (150,150,0)). Now it rotates correctly, but only changes its angle relative to the 'top left corner of my canvas'.
I think the solution to my problem is as follows:
To rotate the cube relative to the given coordinates, the cube must first be translated to the negative coordinates of this point, and by changing the angle, it must be translated back, but only to the positive coordinates of this point.
In my case the pseudo code would be like this:
// if I want to flip the cube around the coordinates (150,150,0) (this is the center of my canvas), then I need to do the following
translate(-150,-150,0);
rotate();
translate(150,150,0);
In the commented parts of the code, I tried to do this, but when I translate the cube, it gets stuck somewhere in the corner and I don't know how to fix it.
function randInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) ) + min;
}
function randomColor() {
return "rgb(" + randInt(0,255) + "," + randInt(0,255) + "," + randInt(0,255) + ")";
}
function ctg(x) {
return 1 / Math.tan(x);
}
function draw() {
let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
let canvasWidth = 300;
canvas.width = canvas.height = canvasWidth;
function drawUW() {
context.lineWidth = 0.1;
context.beginPath();
context.moveTo(0,canvas.height/2);
context.lineTo(canvas.width,canvas.height/2);
context.moveTo(canvas.width/2,0);
context.lineTo(canvas.width/2,canvas.height);
context.stroke();
}
function updateCanvas() {
context.clearRect(0,0,canvas.width,canvas.height);
drawUW();
}
let x = 50, y = 50, z = 50;
let d = 100;
let x0 = canvas.width/2;
let y0 = canvas.height/2;
let x1 = x0+x;
let y1 = y0;
let x2 = x0;
let y2 = y0-y;
let x3 = x0+x;
let y3 = y0-y;
// x' = xd/(z+d)
// y' = yd/(z+d)
let x0p=x0*d/(z+d);
let y0p=y0*d/(z+d);
let x1p=x1*d/(z+d);
let y1p=y1*d/(z+d);
let x2p=x2*d/(z+d);
let y2p=y2*d/(z+d);
let x3p=x3*d/(z+d);
let y3p=y3*d/(z+d);
function getWalls() {
wall01 = [[x0,x2,x3,x1],[y0,y2,y3,y1]];
wall02 = [[x0p,x2p,x2,x0],[y0p,y2p,y2,y0]];
wall03 = [[x0p,x2p,x3p,x1p],[y0p,y2p,y3p,y1p]];
wall04 = [[x1p,x3p,x3,x1],[y1p,y3p,y3,y1]];
wall05 = [[x2,x2p,x3p,x3],[y2,y2p,y3p,y3]];
wall06 = [[x0,x0p,x1p,x1],[y0,y0p,y1p,y1]];
}
function drawWall(wall) {
context.fillStyle = randomColor();
context.strokeStyle = "black";
context.lineWidth = 0.5;
context.beginPath();
context.moveTo(wall[0][0],wall[1][0]);
context.lineTo(wall[0][1],wall[1][1]);
context.lineTo(wall[0][2],wall[1][2]);
context.lineTo(wall[0][3],wall[1][3]);
context.lineTo(wall[0][0],wall[1][0]);
context.fill();
context.stroke();
}
function rotatePoint(x,y,z,fi) {
fi*=Math.PI/180;
arr = [x,y,z,1];
newX = 0;
newY = 0;
newZ = 0;
tx = -150, ty = -150, tz = -150;
arrTranslate = [
[1,0,0,tx],
[0,1,0,ty],
[0,0,1,tz],
[0,0,0,1]
];
// z
arrRotate = [
[Math.cos(fi),-Math.sin(fi),0,0],
[Math.sin(fi),Math.cos(fi),0,0],
[0,0,1,0],
[0,0,0,1]
];
// translate
// for (let i = 0; i < arr.length; i++) {
// newX += arr[i] * arrTranslate[0][i];
// newY += arr[i] * arrTranslate[1][i];
// newZ += arr[i] * arrTranslate[2][i];
// }
//rotate
for (let i = 0; i < arr.length; i++) {
newX += arr[i] * arrRotate[0][i];
newY += arr[i] * arrRotate[1][i];
newZ += arr[i] * arrRotate[2][i];
}
tx = 150, ty = 150, tz = 150;
// translate
// for (let i = 0; i < arr.length; i++) {
// newX += arr[i] * arrTranslate[0][i];
// newY += arr[i] * arrTranslate[1][i];
// newZ += arr[i] * arrTranslate[2][i];
// }
x = newX;
y = newY;
z = newZ;
return [newX,newY,newZ];
}
function rotatePoints(fi) {
x0 = rotatePoint(x0,y0,z,fi)[0];
y0 = rotatePoint(x0,y0,z,fi)[1];
x1 = rotatePoint(x1,y1,z,fi)[0];
y1 = rotatePoint(x1,y1,z,fi)[1];
x2 = rotatePoint(x2,y2,z,fi)[0];
y2 = rotatePoint(x2,y2,z,fi)[1];
x3 = rotatePoint(x3,y3,z,fi)[0];
y3 = rotatePoint(x3,y3,z,fi)[1];
x0p = rotatePoint(x0p,y0p,z,fi)[0];
y0p = rotatePoint(x0p,y0p,z,fi)[1];
x1p = rotatePoint(x1p,y1p,z,fi)[0];
y1p = rotatePoint(x1p,y1p,z,fi)[1];
x2p = rotatePoint(x2p,y2p,z,fi)[0];
y2p = rotatePoint(x2p,y2p,z,fi)[1];
x3p = rotatePoint(x3p,y3p,z,fi)[0];
y3p = rotatePoint(x3p,y3p,z,fi)[1];
}
let inFi = document.getElementById("fi");
inFi.addEventListener("change", updateImage);
function updateImage() {
rotatePoints(inFi.value);
getWalls();
updateCanvas();
drawWall(wall06);
drawWall(wall04);
drawWall(wall03);
drawWall(wall02);
drawWall(wall05);
drawWall(wall01);
}
updateImage();
}
<body onload="draw();">
<canvas id="canvas"></canvas>
<div><input type="number" id="fi" value="0"></div>
</body>

How to find start and end points of filltext in canvas

Hey there how am i going to find the start and end point of a canvas
i have created a letter like this on a canvas
var centerx = (c.width - cx.measureText(letter).width) / 2;
var centery = c.height / 2;
console.log("Bilawal");
console.log(cx.measureText(letter));
var lines = letter.split('\n');
var lineheight = 20;
//for (var i = 0; i<lines.length; i++)
//cx.fillText(lines[i], centerx, centery + (i*lineheight) );
console.log("X "+centerx+" Y "+centery);
cx.fillText(letter, centerx, centery);
now i dont know how to find the start X,Y and end X,Y
You asked for a code sample. Below I have included the same math. Hope this helps.
var centerx = (c.width - cx.measureText(letter).width) / 2;
var centery = c.height / 2;
console.log("Bilawal");
console.log(cx.measureText(letter));
var lines = letter.split('\n');
var lineheight = 20;
//for (var i = 0; i<lines.length; i++)
//cx.fillText(lines[i], centerx, centery + (i*lineheight) );
console.log("X "+centerx+" Y "+centery);
cx.fillText(letter, centerx, centery);
startx = centerx;
starty = centery - 10;
endx = (c.width / 2) + (cx.measureText(letter).width / 2);
endy = centery + 10;
Start and end for each letter as you asked. Once it runs you can access the array of COORDS "startsEnds". If the space between the letters is to large drop the spacer value.
function COORD(sx,sy,ex,ey) {
this.startX = sx;
this.startY = sy;
this.endX = ex;
this.endY = ey;
}
var startsEnds = [];
var spacer = 1;
var centerx = (c.width - cx.measureText(letter).width) / 2;
var centery = c.height / 2;
console.log("Bilawal");
console.log(cx.measureText(letter));
console.log("X "+centerx+" Y "+centery);
var lines = letter.split('\n');
var lineheight = 20;
//for (var i = 0; i<lines.length; i++)
//cx.fillText(lines[i], centerx, centery + (i*lineheight) );
var lett = letter.split("");
var newCenterX = centerx;
var newCenterY = centery;
for (var i = 0; i < lett.length; i++){
console.log("X "+newCenterX+" Y "+newCenterY );
var startEnd = new COORD(newCenterX,newCenterY - 10,(c.width / 2) + (cx.measureText(lett[i]).width / 2), newCenterY + 10);
startsEnds.push(startEnd);
newCenterX = newCenterX + cx.measureText(lett[i]) + spacer;
}
cx.fillText(letter, centerx, centery);

How not to make the canvas flash when i call clearRect [duplicate]

I've a screen being redraw every 25ms, and images are flickering, here is my code
var FRAME_RATE = 40;
var intervalTime = 1000/FRAME_RATE;
gameLoop();
function gameLoop(){
context.clearRect(0, 0, 640, 640);
renderMap();
window.setTimeout(gameLoop, intervalTime);
}
and here is renderMap() function
function renderMap(){
var startX = playerX - (screenW / 2);
var startY = playerY - (screenH / 2);
maxX = playerX + (screenW / 2);
maxY = playerY + (screenH / 2);
$.getJSON('mapa3.json', function(json){
for (x = startX; x < maxX; x=x+32){
for (y = startY; y < maxY; y=y+32){
intTile = json.layers[0].data[((y/32)* 100) + (x/32)];
context.putImageData(getTile(intTile - 1), x - startX, y - startY);
}
}
});
var imgCharacter = new Image();
imgCharacter.src = 'char.png';
var posX = (screenW - imgCharacter.width) / 2;
var posY = (screenH - imgCharacter.height) / 2;
imgCharacter.onload = function(){context.drawImage(imgCharacter, posX, posY)}
}
What changes do I need to make to the code to stop flickering?
I believe it is because you are loading the image each iteration. Try putting the var imgCharacter..., the following line, and the image's onload function outside of renderMap so it is only ran once
var imgCharacter = new Image();
imgCharacter.onload = function () {
renderMap();
}
imgCharacter.src = 'char.png';
function renderMap() {
var startX = playerX - (screenW / 2);
var startY = playerY - (screenH / 2);
maxX = playerX + (screenW / 2);
maxY = playerY + (screenH / 2);
$.getJSON('mapa3.json', function (json) {
for (x = startX; x < maxX; x = x + 32) {
for (y = startY; y < maxY; y = y + 32) {
intTile = json.layers[0].data[((y / 32) * 100) + (x / 32)];
context.putImageData(getTile(intTile - 1), x - startX, y - startY);
}
}
});
var posX = (screenW - imgCharacter.width) / 2;
var posY = (screenH - imgCharacter.height) / 2;
context.drawImage(imgCharacter, posX, posY)
}
Thank you to markE for letting me know the onload function also needs to go outside renderMap, I overlooked it the first time
Load all images and other data before draw and storage them inside array.
Better use requestAnimationFrame.
Remember, getting JSON (or other data) can take some time.

How could a log X, Y mouse position on my grid?

I have this script to create grid of rectangles, how would I go about logging map co ordinates of the mouse position so if the mouse was on 1,1 it would log 1,1?:
+---+---+---+---+
|0,0|0,1|0,2|0,3|
+---+---+---+---+
|1,0|1,1|1,2|1,3|
+---+---+---+---+
|2,0|2,1|2,2|2,3|
+---+---+---+---+
|3,0|3,1|3,2|3,3|
+---+---+---+---+
here is the script I have to create the grid;
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = (32 * 12);
canvas.height = (32 * 12);
document.body.appendChild(canvas);
var posX = 0;
var posY = 0;
var tileSize = 32;
$(document).ready(function(){
drawGrid();
});
function drawGrid(){
for(var x = 0; x < 12; x++){
for(var y = 0; y < 12; y++){
ctx.rect(posX, posY, tileSize, tileSize);
ctx.stroke();
posX += tileSize;
}
posY += tileSize;
posX = 0;
}
}
Just quantize the mouse position based on the tile size, for example (assuming you have already obtained the mouse position):
var gridX = (mouseX / tileSize)|0;
var gridY = (mouseY / tileSize)|0;
Now you can log gridX and gridY as the original grid definition.
On mouse move get the x and y position of the mouse and divide them by the tileSize.
Demo on Fiddle
canvas.onmousemove = function(e) {
var mouseX = e.pageX;
var mouseY = e.pageY;
document.getElementsByTagName('div')[0].innerHTML = '(' + Math.floor(mouseX / tileSize) + ', ' + Math.floor(mouseY / tileSize) + ')';
}

redrawing canvas html5 without flickering

I've a screen being redraw every 25ms, and images are flickering, here is my code
var FRAME_RATE = 40;
var intervalTime = 1000/FRAME_RATE;
gameLoop();
function gameLoop(){
context.clearRect(0, 0, 640, 640);
renderMap();
window.setTimeout(gameLoop, intervalTime);
}
and here is renderMap() function
function renderMap(){
var startX = playerX - (screenW / 2);
var startY = playerY - (screenH / 2);
maxX = playerX + (screenW / 2);
maxY = playerY + (screenH / 2);
$.getJSON('mapa3.json', function(json){
for (x = startX; x < maxX; x=x+32){
for (y = startY; y < maxY; y=y+32){
intTile = json.layers[0].data[((y/32)* 100) + (x/32)];
context.putImageData(getTile(intTile - 1), x - startX, y - startY);
}
}
});
var imgCharacter = new Image();
imgCharacter.src = 'char.png';
var posX = (screenW - imgCharacter.width) / 2;
var posY = (screenH - imgCharacter.height) / 2;
imgCharacter.onload = function(){context.drawImage(imgCharacter, posX, posY)}
}
What changes do I need to make to the code to stop flickering?
I believe it is because you are loading the image each iteration. Try putting the var imgCharacter..., the following line, and the image's onload function outside of renderMap so it is only ran once
var imgCharacter = new Image();
imgCharacter.onload = function () {
renderMap();
}
imgCharacter.src = 'char.png';
function renderMap() {
var startX = playerX - (screenW / 2);
var startY = playerY - (screenH / 2);
maxX = playerX + (screenW / 2);
maxY = playerY + (screenH / 2);
$.getJSON('mapa3.json', function (json) {
for (x = startX; x < maxX; x = x + 32) {
for (y = startY; y < maxY; y = y + 32) {
intTile = json.layers[0].data[((y / 32) * 100) + (x / 32)];
context.putImageData(getTile(intTile - 1), x - startX, y - startY);
}
}
});
var posX = (screenW - imgCharacter.width) / 2;
var posY = (screenH - imgCharacter.height) / 2;
context.drawImage(imgCharacter, posX, posY)
}
Thank you to markE for letting me know the onload function also needs to go outside renderMap, I overlooked it the first time
Load all images and other data before draw and storage them inside array.
Better use requestAnimationFrame.
Remember, getting JSON (or other data) can take some time.

Categories