最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Resize div containing a canvas - Stack Overflow

programmeradmin7浏览0评论

I have a div containing a canvas:

<div class="canvas-wrapper">
    <canvas height="30px"></canvas>
</div>

The CSS for the "canvas-wrapper" class:

.canvas-wrapper{
    width: 100%;
    overflow: hidden;
}

Whenever the width of the div changes, the canvas width is updated (Angular directive):

link: function(scope, element, attr){
    var canvas = element.find('canvas')[0];
    var div = element.find('div')[0];

    scope.$watch(function(){
        return div.offsetWidth;
    }, function(newVal, oldVal){
        canvas.width = newVal;
    });
}

I've tested this by resizing the browser width. It works fine when I increase the window, but when I decrease the window the div will not resize.

I guess that's because it contains the canvas, but how can I get around this? The canvas is supposed to follow the div width, not block resizing.

Any ideas?

I have a div containing a canvas:

<div class="canvas-wrapper">
    <canvas height="30px"></canvas>
</div>

The CSS for the "canvas-wrapper" class:

.canvas-wrapper{
    width: 100%;
    overflow: hidden;
}

Whenever the width of the div changes, the canvas width is updated (Angular directive):

link: function(scope, element, attr){
    var canvas = element.find('canvas')[0];
    var div = element.find('div')[0];

    scope.$watch(function(){
        return div.offsetWidth;
    }, function(newVal, oldVal){
        canvas.width = newVal;
    });
}

I've tested this by resizing the browser width. It works fine when I increase the window, but when I decrease the window the div will not resize.

I guess that's because it contains the canvas, but how can I get around this? The canvas is supposed to follow the div width, not block resizing.

Any ideas?

Share Improve this question asked Aug 26, 2015 at 15:26 KMKKMK 1,5195 gold badges23 silver badges41 bronze badges 2
  • How about setting the canvas width in percentage? – Dave Commented Aug 26, 2015 at 15:33
  • Setting the width in HTML like width="100%" did not work, but adding CSS full width as Amit suggested did the trick. – KMK Commented Aug 27, 2015 at 6:28
Add a ment  | 

3 Answers 3

Reset to default 5

You could add a CSS width of 100% to the canvas element.

While resizing a canvas via CSS is usually not a good practice as it stretches / shrinks the "image inside the canvas", if it's in sync with the canvas width & height properties there's nothing wrong with it.

You can solve that inline:

<div class="canvas-wrapper">
    <canvas height="30px" style="width: 100%;"></canvas>
</div>

Or use whatever CSS selection method you prefer instead.

You're correct when you said: "[the div doesn't decrease] I guess that's because it contains the canvas"

The accepted answer suggests using the css width property with a caveat that the canvas will stretch. This is also pletely correct; the canvas will stretch.

You might want the canvas to stretch, but this is usually not desirable. For pleteness, here is an answer to actually resize the canvas.

For best results, you need to use the following logic:

Steps

  1. Capture the resize event, which you've done, and then...
  2. Hide the canvas
  3. Measure the parent div size
  4. Re-size the canvas's width and height properties to match the measured parent div size
  5. Re-show your canvas
  6. Redraw your canvas graphics. This is an important extra step. Anytime you manually re-size the canvas the existing graphics are cleared.

The last step, redrawing graphics, is really important. A detailed explanation on how to redraw graphics with the correct scaling can be found here: html5 canvas redraw on resize

Demo

A demo of this logic working can be found here: http://spencer-evans./share/github/canvas-resizer/

JavaScript Solution

In JavaScript, a solution is:

// Call this every time the canvas resizes
function resizeCanvas()
{
    // Grab the canvas and it's parent div
    var canvas = document.getElementById("myCanvasId");
    var parent = canvas.parentNode;

    // Hide the canvas so we can get the parent's responsive bounds
    var displayBackup = canvas.style.display;
    canvas.style.display = "none";

    // Measure parent without the canvas
    var w = parent.clientWidth;
    var h = parent.clientHeight;

    // Set the new canvas dimensions
    canvas.width = w;
    canvas.height = h;

    // Restore the canvas display property
    canvas.style.display = displayBackup;

    // IMPORTANT: Call code here to redraw canvas graphics!
}

Library Solution

This can be cumbersome and I've ran into it time and time again. I've written a small JS / typescript library to handle this. You can find the library here: https://github./swevans/canvas-resizer

The library also has the benefit of re-sizing the canvas to match high resolution displays where devicePixelRatio is not equal to 1 (ie Retina displays).

Thanks to the answer from Spencer Evans.

I was able to add (in the resize event) the 1x1 px and it works.

$(self.canvas).attr('width', 1)
$(self.canvas).attr('height', 1);
self.dimension = (self.el.width() >= self.el.height() ? self.el.height() : self.el.width());
发布评论

评论列表(0)

  1. 暂无评论