Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
319 views
in Technique[技术] by (71.8m points)

javascript - Dynamically resize canvas on window resize

I am attempting to resize a canvas chart when a user resizes their browser window. The problem with changing it directly, or so I've found...is that the image disappears during the resizing. Here are some screenshots to help you understand my problem.

This is the chart before resizing. enter image description here

This is the chart during the resizing. (without targeting the DOM element)

  • I've identified the chart overflowing on the right hand side.

enter image description here

Chart being resized and targeting the canvas width.

  • As you can see, the chart disappears.
    let canvas = document.getElementById('canvas');
    this.canvas.width = ${
      event.target.innerWidth - (window.innerWidth / 100) * 2
    };

enter image description here

Please let me know what options I have for dynamically resizing canvas charts. Thanks!

P.S. I'm using AngularJs for this particular project.

Update 12/30/2020

Discovered that the obvious reason for the chart disappearing is that the canvas is based on coordinates which originate from a set height/width. So the solution was re-mapping the strokes/fills as the canvas is resizing.

New challenge:

  • Using clearRect (0, 0, width, height) doesn't clear the canvas. Re-mapping results in an inifite mapping of charts on top of one another. As shown in the photo below.

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Is this the solution I get paid a million dollars for? No. But...

After hours of spinning around thoughts as to why the creators never made an easy solution for resizing a canvas, I've finally found an option that works for resizing the charts. Note that if you're scaling up that it can become pixelated. But this option will work.

Instead of defining the height and width with the inline properties:

<canvas id="canvas" height="200" width="600" (window:resize)="onResize($event)"> </canvas>

You should use css to make the height and width 100%. This turns the canvas into an image essentially. Which is why it pixelates when you scale up. The next step is to setup functionality or styling for the element that the canvas is embedded within. This is where the solution arises. Because you can't adjust the canvas without losing the graphic. You have to adjust the element that encapsulates it!

Ex:

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

You would dynamically adjust the height and width of the #area-chart. I personally suggest using viewport width to define the height as it is the most flexible in terms of scaling and the graphic pixelates far less than using other measurements (%, px, pt, etc.). Of course your needs may be different than mine, but here's some sample styling.

Sample scss:

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

Chart on load:

enter image description here

Chart scaled down:

enter image description here

Chart scaled up:

enter image description here

** note that the pixel dimensions in the screenshots are the full window size and not the size of the element


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...