javascript 相对大小的 HTML Canvas

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7169879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 23:11:05  来源:igfitidea点击:

Relatively sizing HTML Canvas

javascripthtmlcanvas

提问by Portman

The HTML5 <canvas>element does not accept relative sizes (percent) for its widthand heightproperties.

HTML5<canvas>元素不接受其widthheight属性的相对大小(百分比)。

What I'm trying to accomplish is to have my canvas sized relative to the window. This is what I've come up with so far, but I'm wondering if there is a better way that is:

我想要完成的是让我的画布相对于窗口大小。到目前为止,这是我想出的,但我想知道是否有更好的方法:

  1. Simpler
  2. Does not require wrapping the <canvas>in a <div>.
  3. Not dependent on jQuery (I use it to get the width/height of the parent div)
  4. Ideally, doesn't redraw on browser resize (but I think that might be a requirement)
  1. 更简单
  2. 不需要将 包裹<canvas><div>.
  3. 不依赖于 jQuery(我用它来获取父 div 的宽度/高度)
  4. 理想情况下,不会在浏览器调整大小时重绘(但我认为这可能是一个要求)

See below for the code, which draws a circle in the middle of the screen, 40% wide up to a maximum of 400px.

请参阅下面的代码,它在屏幕中间绘制一个圆圈,宽度为 40%,最大为 400px。

Live demo: http://jsbin.com/elosil/2

现场演示:http: //jsbin.com/elosil/2

Code:

代码:

<!DOCTYPE html>
<html>
<head>
    <title>Canvas of relative width</title>
    <style>
        body { margin: 0; padding: 0; background-color: #ccc; }
        #relative { width: 40%; margin: 100px auto; height: 400px; border: solid 4px #999; background-color: White; }
    </style>
    <script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
    <script>
        function draw() {
            // draw a circle in the center of the canvas
            var canvas = document.getElementById('canvas');
            var relative = document.getElementById('relative');
            canvas.width = $(relative).width();
            canvas.height = $(relative).height();
            var w = canvas.width;
            var h = canvas.height;
            var size = (w > h) ? h : w; // set the radius of the circle to be the lesser of the width or height;
            var ctx = canvas.getContext('2d');
            ctx.beginPath();
            ctx.arc(w / 2, h / 2, size/2, 0, Math.PI * 2, false);
            ctx.closePath();
            ctx.fill();
        }

        $(function () {
            $(window).resize(draw);
        });
    </script>
</head>
<body onload="draw()">
    <div id="relative">
        <canvas id="canvas"></canvas>
    </div>
</body>
</html>

回答by sethobrien

The canvas widthand heightattributes are separate from the same canvas's widthand heightstyles. The widthand heightattributes are the size of the canvas's rendering surface, in pixels, whereas its styles choose a location in the document where the browser should draw the content from the rendering surface. It just so happens that the default value for the widthand heightstyles, if they're not specified, is the rendering surface's width and height. So you're right about #1: there's no reason to wrap it in a div. You can set percentage values for all of the styles on your canvas element, just like any other element.

画布widthheight属性与相同的画布widthheight样式是分开的。在widthheight属性是帆布的呈现表面的大小,以像素为单位,而它的样式中选择文档中的位置,其中,浏览器应该借鉴的呈现表面的内容。恰巧widthheight样式的默认值(如果未指定)是渲染表面的宽度和高度。所以你对 #1 是对的:没有理由将它包装在一个 div 中。您可以为画布元素上的所有样式设置百分比值,就像任何其他元素一样。

For #3, it's pretty easy (and cross-browser) to get the size of things with clientWidth and clientHeight, as long as you're not using padding on your canvas element.

对于 #3,使用 clientWidth 和 clientHeight 获取事物的大小非常容易(和跨浏览器),只要您不在画布元素上使用填充。

I coded up the slightly simplified version here.

在这里编写了稍微简化的版本。

For #4, you're right about being out of luck. It's possible to check before setting width and height and leave the canvas alone if it doesn't need resizing, which would eliminate some of the redraws, but you can't get rid of all of them.

对于#4,你运气不好是对的。可以在设置宽度和高度之前进行检查,如果不需要调整大小,可以单独保留画布,这将消除一些重绘,但您无法摆脱所有重绘。

EDIT: Portman pointed out I messed up the centering style. Updated version here.

编辑:波特曼指出我搞砸了居中风格。更新版本在这里

回答by 6502

Like said by sethobrien a canvaselement has TWOpairs width/height of attributes.

就像 sethobrien 所说的,一个canvas元素有对宽度/高度的属性。

  1. canvas.width/ canvas.heightare about the size in pixel of the buffer that will contains the result of drawing commands.

  2. canvas.style.width/ canvas.style.heightare about the size used to show the canvas object in the browser window and they can be in any of the units supported by css.

  1. canvas.width/canvas.height大约是包含绘图命令结果的缓冲区的像素大小。

  2. canvas.style.width/canvas.style.height是用于在浏览器窗口中显示画布对象的大小,它们可以是 css 支持的任何单位。

You can indeed set canvas.widthand canvas.heightjust once, do the drawing in the canvas, setting the style size parameters in percentage and then forget about redrawing the canvas content. Of course this means that the browser will just do the scaling itself like for a regular image loaded from the network so the visible result will show pixel scaling artifacts.

事实上,你可以设置canvas.widthcanvas.height只有一次,做绘图画布,设置百分比的风格尺寸参数,然后忘掉重绘帆布内容。当然,这意味着浏览器将像对从网络加载的常规图像一样自行进行缩放,因此可见结果将显示像素缩放伪影。

You only need to redrawing the canvas content after the resize of the canvas element only if you want pixel-perfect results.

仅当您想要像素完美的结果时,才需要在调整画布元素大小后重新绘制画布内容。

回答by Sri

Alright. Here is the technique that i ve used to implement the same.

好吧。这是我用来实现相同的技术。

Suppose you have the canvas height=400, for the window's height=480, and you want to change the height of it relatively if the window's height changes to 640.

假设你的画布高度=400,窗口高度=480,如果窗口高度变为640,你想相对改变它的高度。

canvas = document.getElementById("canvas"); 
canvas.height=window.innerHeight*400/480;

p.s: do not initialize the height of the canvas inside the html tag.

ps:不要在html标签内初始化canvas的高度。

Make use of 'window.innerHeight' (which returns the height of the browser's window.. similarly 'window.innerWidth') any where you want to calculate the relative positions on the window.

在您想要计算窗口上的相对位置的任何地方使用“window.innerHeight”(它返回浏览器窗口的高度。类似于“window.innerWidth”)。

Hope you got what you needed.

希望你得到了你需要的东西。