在窗口调整大小时动态调整画布大小

Posted

技术标签:

【中文标题】在窗口调整大小时动态调整画布大小【英文标题】:Dynamically resize canvas on window resize 【发布时间】:2021-04-06 17:57:45 【问题描述】:

当用户调整浏览器窗口的大小时,我正在尝试调整画布图表的大小。直接更改它的问题,或者我发现......是图像在调整大小时消失了。这里有一些截图可以帮助你理解我的问题。

这是调整大小之前的图表。

这是调整大小时的图表。 (不针对 DOM 元素)

我发现图表在右侧溢出。

图表正在调整大小并以画布宽度为目标。

如您所见,图表消失了。
    let canvas = document.getElementById('canvas');
    this.canvas.width = $
      event.target.innerWidth - (window.innerWidth / 100) * 2
    ;

请告诉我动态调整画布图表大小的选项。谢谢!

附:我正在为这个特定项目使用 AngularJs。

2020 年 12 月 30 日更新

发现图表消失的明显原因是画布基于源自设定高度/宽度的坐标。所以解决方案是在画布调整大小时重新映射笔触/填充。

新挑战:

使用 clearRect (0, 0, width, height) 不会清除画布。重新映射会导致图表在彼此之上的无限映射。如下图所示。

【问题讨论】:

如果不是this.canvas.width = `$event.target.innerWidth - (window.innerWidth / 100) * 2px`;请使用[<>] sn-p编辑器创建minimal reproducible example 宽度实际上默认为像素,所以除非我需要特定的测量单位,否则我通常会保留它。关于代码,我不能分享它背后的功能,因为它是公司所有的。图片是我能做的最好的。主要问题是动态调整图表大小时图表本身会消失。 【参考方案1】:

这是我获得一百万美元的解决方案吗?不,但是……

经过数小时的思考,为什么创作者从来没有为调整画布大小制定一个简单的解决方案,我终于找到了一个可以调整图表大小的选项。请注意,如果您要扩大规模,它可能会变得像素化。但是这个选项会起作用

而不是使用内联属性定义高度和宽度:

<canvas id="canvas"   (window:resize)="onResize($event)"> </canvas>

您应该使用 css 将高度和宽度设为 100%。这实际上将画布变成了图像。这就是为什么当你放大时它会像素化。下一步是为嵌入画布的元素设置功能或样式。这就是解决方案出现的地方。因为你不能在不丢失图形的情况下调整画布。你必须调整封装它的元素!

例如:

<div id="area-chart">
  <canvas id="canvas" (window:resize)="onResize($event)"> </canvas>
</div>

您可以动态调整 #area-chart 的高度和宽度。我个人建议使用视口宽度来定义高度,因为它在缩放方面是最灵活的,并且图形像素化远低于使用其他测量值(%、px、pt 等)。当然,您的需求可能与我的不同,但这里有一些示例样式。

示例 scss:

#area-chart 
  #canvas 
    width: 100%;
    height: 10vw;
  

加载图表:

按比例缩小的图表:

图表放大:

**请注意,屏幕截图中的像素尺寸是完整的窗口大小,而不是元素的大小

【讨论】:

以上是关于在窗口调整大小时动态调整画布大小的主要内容,如果未能解决你的问题,请参考以下文章

使用 javascript/jquery 动态调整画布窗口的大小?

Three.js 调整画布大小

在 NSView 和 HWND 中嵌入 skia 画布,当窗口调整大小时画布刷新为空白

将画布大小调整为窗口/用户控件大小

在 FabricJS 中调整窗口大小时如何始终将剪切区域居中?

HTML5 响应式画布:调整浏览器画布绘制的大小消失