Html5 canvas correctly draw cube
I am just testing HTML5 canvas and I am trying to draw an isometric cube correctly
Here's my current code for drawing an isometric cube:
function drawCube(x, y, wx, wy, h, color) {
// left face
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - wx, y - wx * 0.5);
ctx.lineTo(x - wx, y - h - wx * 0.5);
ctx.lineTo(x, y - h * 1);
ctx.closePath();
ctx.fillStyle = "#838357"
ctx.strokeStyle = "#7a7a51";
ctx.stroke();
ctx.fill();
// right face
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + wy, y - wy * 0.5);
ctx.lineTo(x + wy, y - h - wy * 0.5);
ctx.lineTo(x, y - h * 1);
ctx.closePath();
ctx.fillStyle = "#6f6f49";
ctx.strokeStyle = "#676744";
ctx.stroke();
ctx.fill();
// center face
ctx.beginPath();
ctx.moveTo(x, y - h);
ctx.lineTo(x - wx, y - h - wx * 0.5);
ctx.lineTo(x - wx + wy, y - h - (wx * 0.5 + wy * 0.5));
ctx.lineTo(x + wy, y - h - wy * 0.5);
ctx.closePath();
ctx.fillStyle = "#989865";
ctx.strokeStyle = "#8e8e5e";
ctx.stroke();
ctx.fill();
}
I have two problems:
First edition
There's some pixel issues / faces overlapping, which you can see when you scale the canvas:
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 800;
document.body.appendChild(canvas);
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
var sizeX = 32;
var sizeY = 32;
var sizeZ = 8;
ctx.scale(5, 5);
drawCube(50, 50, sizeX, sizeY, sizeZ);
}
requestAnimationFrame(draw);
function drawCube(x, y, wx, wy, h, color) {
// left face
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - wx, y - wx * 0.5);
ctx.lineTo(x - wx, y - h - wx * 0.5);
ctx.lineTo(x, y - h * 1);
ctx.closePath();
ctx.fillStyle = "#838357"
ctx.strokeStyle = "#7a7a51";
ctx.stroke();
ctx.fill();
// right face
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + wy, y - wy * 0.5);
ctx.lineTo(x + wy, y - h - wy * 0.5);
ctx.lineTo(x, y - h * 1);
ctx.closePath();
ctx.fillStyle = "#6f6f49";
ctx.strokeStyle = "#676744";
ctx.stroke();
ctx.fill();
// center face
ctx.beginPath();
ctx.moveTo(x, y - h);
ctx.lineTo(x - wx, y - h - wx * 0.5);
ctx.lineTo(x - wx + wy, y - h - (wx * 0.5 + wy * 0.5));
ctx.lineTo(x + wy, y - h - wy * 0.5);
ctx.closePath();
ctx.fillStyle = "#989865";
ctx.strokeStyle = "#8e8e5e";
ctx.stroke();
ctx.fill();
}
Second edition
How can I determine the required canvas width / height to draw the entire cube and then set the cube to the beginning of the canvas? (x and y = 0)
What am I doing wrong for the first problem? What about the second one? Can I get an example / snippet with the issues fixed?
source to share
It has to do with the miter mode for string concatenation and the miter limit.
You can solve these two ways, as before calling fill()
/ stroke()
:
Or lower the miter limit (note that the miter limit cannot be 0):
ctx.miterLimit = 1;
or use another line mode:
ctx.lineJoin = "round";
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 800;
document.body.appendChild(canvas);
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
var sizeX = 32;
var sizeY = 32;
var sizeZ = 8;
ctx.scale(5, 5);
drawCube(50, 50, sizeX, sizeY, sizeZ);
}
requestAnimationFrame(draw);
function drawCube(x, y, wx, wy, h, color) {
// LINE MODE
ctx.lineJoin = "round";
// left face
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - wx, y - wx * 0.5);
ctx.lineTo(x - wx, y - h - wx * 0.5);
ctx.lineTo(x, y - h * 1);
ctx.closePath();
ctx.fillStyle = "#838357"
ctx.strokeStyle = "#7a7a51";
ctx.stroke();
ctx.fill();
// right face
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + wy, y - wy * 0.5);
ctx.lineTo(x + wy, y - h - wy * 0.5);
ctx.lineTo(x, y - h * 1);
ctx.closePath();
ctx.fillStyle = "#6f6f49";
ctx.strokeStyle = "#676744";
ctx.stroke();
ctx.fill();
// center face
ctx.beginPath();
ctx.moveTo(x, y - h);
ctx.lineTo(x - wx, y - h - wx * 0.5);
ctx.lineTo(x - wx + wy, y - h - (wx * 0.5 + wy * 0.5));
ctx.lineTo(x + wy, y - h - wy * 0.5);
ctx.closePath();
ctx.fillStyle = "#989865";
ctx.strokeStyle = "#8e8e5e";
ctx.stroke();
ctx.fill();
}
In the second problem, you can pre-compute all the values ββfor the cube and store them in an array or object, etc.
Then run min-max on all values ββfor each axis. The maximum value (minus minus) will be the width / height of the canvas. Place the canvas on -minX, -minY (or translate using the same).
source to share