调整画布大小时,Canvas绘图会变形。

3
我正在使用HTML5和JavaScript在画布上实现绘图。
如果我不手动设置画布的宽度和高度(保留默认值),我的绘图效果良好。
然而,当我从CSS或JavaScript设置画布大小时,我的绘图看起来很扭曲。线条离线条稍微有点距离,并且看起来扭曲。
以下是mousedown事件的代码。 Distorted image
if (mouseDown)
    {
        previousX = currentX;
        previousY = currentY;
        currentX = e.clientX - canvas.offsetLeft;
        currentY = e.clientY - canvas.offsetTop;
        ctx.beginPath();
        ctx.moveTo(previousX, previousY);
        ctx.lineTo(currentX, currentY);
        ctx.strokeStyle = color;
        ctx.lineWidth = y;
        ctx.stroke();
        ctx.closePath();
    }
2个回答

7

您必须使用正确的属性/特性设置画布的尺寸。

画布是具有位图的元素。如果您使用CSS或样式,那么只会缩放该元素,而不是位图。结果就是图像模糊。

通过执行以下操作设置正确的尺寸(通常不需要使用CSS):

<canvas width=800 height=800></canvas>

或者在JavaScript中:
canvas.width = 800;    // example size
canvas.height = 800;

如果您使用CSS来缩放画布,无论是使用规则还是在元素中使用style属性,都只会将一个300x150像素的位图缩放到其他尺寸,这样会导致质量很差。请始终先缩放位图,然后重新绘制(因为画布将被清除)。


这个可以用,谢谢!但是,如果我在画布上向下滚动(当画布不适合屏幕时),鼠标在绘制线条时会离开。 - n32303
1
为什么不开一个新问题? - shmuli

3
Canvas API 仅用于栅格图像绘制,因此当其调整大小时会失去清晰度,这是可以预料的。如果您想要生成矢量图像,则必须使用 SVG(可缩放矢量图形)。但 SVG 不支持绘制。生成 SVG 基本上是通过 XML 实现的,因此与 Canvas API 的灵活性不同。以下是一款库,可帮助您在矢量画布上进行绘制:http://paperjs.org/。"Paper.js 是一个在 HTML5 Canvas 之上运行的开源矢量图形脚本框架。" 这里还有另一个线程,列举了更多选项:HTML5 Canvas Vector Graphics?

@NejcLovrencic 我不确定你的意思。您可以将画布大小设置为任何您想要的大小。 - shmuli
如果您使用百分比设置大小,则会出现扭曲,如果您使用像素设置大小,则不会出现扭曲。 - dwana
我建议你看一下我在答案中提到的paperjs库,那应该会解决这个问题。 - shmuli
1
@shmuli 这只有在你需要使用相同的位图进行缩放时才是正确的。如果你可以像使用画布一样重新绘制,那么就没有区别了。SVG也需要被光栅化才能在屏幕上显示。画布也像SVG一样使用路径,除了绘制图像或视频(嵌入式位图/图像也适用于SVG)。除此之外,这是开发者如何处理的问题,而不是画布本身的问题。我的意见。 - user1693593
2
@shmuli,当画布大小改变时,您必须重新绘制它,因为它将被清除。但是OP没有在这里展示他的设置代码,但他可能正在使用CSS将默认的300x150缩放到某个尺寸,这意味着画布的位图被缩放了。他需要使用width/height属性,然后重新绘制(点可以存储在数组中等)。 - user1693593
显示剩余6条评论

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