动态展开画布,而不拉伸所绘制的内容

Dynamically expand canvas without stretching what is drawn

本文关键字:绘制 动态      更新时间:2023-09-26

我有一个画布,在画布上添加正方形。现在,正如您将在我所包含的示例中看到的那样,单击"展开画布"按钮确实会展开画布,但会拉伸已经在其中的内容,而不是适应新内容。我如何才能使新的盒子显示出来,而旧的盒子保持不变?

请参见以下内容:http://jsfiddle.net/3q8tj17c/1/

代码如下:

HTML

<canvas id="canvas" width=100 height=100></canvas>
<button>expand canvas</button>

CSS

#canvas{
    border:2px dashed #00242D;
    border-right:none; 
}

JS

var canvas;
var ctx;
createBox()
function createBox(){
    canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
}
var squareCount = 0;
function drawSquare(squareNumber){
    squareNumber = (squareNumber*100) + 35
    ctx.beginPath();
    ctx.lineWidth="6";
    ctx.setLineDash([0]);
    ctx.fillStyle="#006C85";
    ctx.strokeStyle="#008BAB";
    ctx.fillRect(squareNumber,35,30,30);
    ctx.rect(squareNumber,35,30,30); 
    ctx.stroke();
    squareCount++;
}
function drawborderRight(squareNumber){
    squareNumber = (squareNumber * 100) - 1
    ctx.beginPath();
    ctx.setLineDash([8]);
    ctx.lineWidth="1";
    ctx.strokeStyle="#00242D";
    ctx.moveTo(squareNumber,0);
    ctx.lineTo(squareNumber, 100);
    ctx.stroke();    
}
function addBoxText(text, squareNumber){
    squareNumber = (squareNumber*100) + 50;
    ctx.textAlign="center";
    ctx.font = "16px Segoe UI Light";
    ctx.fillStyle = "#333"
    ctx.fillText(text,squareNumber,90)   
}
$('button').on('click', function() {
    canvasSize = (squareCount*100) + 100
    addBoxText("hello",squareCount)
    drawSquare(squareCount)
    drawborderRight(squareCount)
    $('#canvas').width(canvasSize).height(100);
})
addBoxText("blah",squareCount)
drawSquare(squareCount)
drawborderRight(squareCount)

此行错误。

$("#canvas").width(canvasWidth)

这就是jQuery设置CSS宽度,您需要设置画布的宽度属性。请注意,这将擦除画布(但无论如何都要重新绘制,所以在这种情况下这不是什么大不了的事)。

所以你的点击功能应该看起来像这个

$('button').on('click', function() {
  squareCount++;
  canvasSize = (squareCount*100);
  $('#canvas')[0].width = canvasSize;
  for (var i=0; i<squareCount; i++){
    addBoxText("hello",i)
    drawSquare(i)
  }
  drawborderRight(squareCount);
})

编辑:围绕事物的顺序进行更改,以产生所需的行为。关键的变化是在调整画布大小后重新绘制所有的正方形,因为正如我前面提到的,更改画布尺寸会清除画布。

$('#canvas').width使用CSS更改画布的宽度。

这将"拉伸"现有内容以适应更大的宽度,因此这就是拉伸现有内容的原因。

如果你想使用CSS来增加画布大小,那么你应该将画布宽度和画布高度都调整相同的百分比,以避免失真:

var pct=((squareCount*100) + 100)/canvas.width;
$('#canvas').width(canvas.width*pct).height(canvas.height*pct);

使用CSS调整大小的一个副作用是,当内容被绘制得更大时,它将变得"像素化"。

为了避免这种像素化:

  • "记住"您已经绘制了哪些正方形(可能是在javascript对象中)。

    var box1={x:35,y:35,w:30,h:30};
    
  • 调整画布元素的大小,而不是使用CSS。调整画布元素的大小也会自动清除所有画布内容。

    canvas.width=(squareCount*100) + 100;
    
  • 使用保存在JS对象中的信息重新绘制之前的所有方块。

    // redraw box1
    ctx.fillRect(box1.x,box1.y,box1.w,box1.h);
    
  • 为了提高效率,您可能会将所有以前的var box对象放在一个数组中,并重新绘制该数组中的所有框。

    var boxes=[];
    boxes.push(box1);
    for(var i=0;i<boxes.length;i++){
        var box=boxes[i];
        ctx.fillRect(box.x,box.y,box.w,box.h);
    }