HTML5 canvas正确绘制立方体

6

我正在尝试使用HTML5画布,并尝试正确地绘制等距立方体。

这是我目前用于绘制等距立方体的代码:

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();
}

我有两个问题:

第一个问题


当你缩放画布时,有一些像素问题/面部重叠问题:

错误立方体图像

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();
}

第二个问题


我该如何确定绘制整个立方体所需的画布宽度/高度,并将立方体设置为画布开头? (x&y = 0)



对于第一个问题我错在哪里了?第二个问题呢?可以给出一个修复这些问题的示例/片段吗?

1个回答

2

这与线连接处的斜接模式和斜接限制有关。

在调用fill()/stroke()之前,您可以通过以下两种方式解决此问题:

要么降低斜接限制(注意,斜接限制不能为0):

ctx.miterLimit = 1;

或者使用不同的线连接模式:

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();
}

对于第二个问题,您可以预先计算立方体的所有值并将它们存储在数组或对象中等。

然后在每个轴上运行最小-最大值。最大值(减去最小值)将是画布的宽度/高度。将画布放置在 -minX,-minY(或使用相同的平移)。


谢谢。你有什么想法可以让我的立方体“像素化”吗? - Johnny
还有第二个问题呢?我想在0, 0处绘制我的立方体。 - Johnny
@Johnny 对不起,没有看到第二个。针对这个问题添加了一种解决方法。 - user1693593
对于像素化,这可能会有所帮助:https://dev59.com/vWIk5IYBdhLWcg3wl_LE#19129822 - user1693593

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接