Maximum size of a element

后端 未结 14 1779
粉色の甜心
粉色の甜心 2020-11-22 07:34

I\'m working with a canvas element with a height of 600 to 1000 pixels and a width of several tens or hundreds of thousands of pixels. However, aft

相关标签:
14条回答
  • 2020-11-22 08:09

    According to w3 specs, the width/height interface is an unsigned long - so 0 to 4,294,967,295 (if I remember that number right -- might be off a few).

    EDIT: Strangely, it says unsigned long, but it testing shows just a normal long value as the max: 2147483647. Jsfiddle - 47 works but up to 48 and it reverts back to default.

    0 讨论(0)
  • 2020-11-22 08:13

    Update for 2018:

    As time marches on, canvas limitations have changed. Sadly, what hasn't changed is the fact that browser's still do not provide information on canvas size limitations through the Canvas API.

    For those looking to programmatically determine the browser's max canvas size or test support for custom canvas dimensions, check out canvas-size.

    • GitHub: https://github.com/jhildenbiddle/canvas-size
    • NPM: https://www.npmjs.com/package/canvas-size

    From the docs:

    The HTML canvas element is widely supported by modern and legacy browsers, but each browser and platform combination imposes unique size limitations that will render a canvas unusable when exceeded. Unfortunately, browsers do not provide a way to determine what their limitations are, nor do they provide any kind of feedback after an unusable canvas has been created. This makes working with large canvas elements a challenge, especially for applications that support a variety of browsers and platforms.

    This micro-library provides the maximum area, height, and width of an HTML canvas element supported by the browser as well as the ability to test custom canvas dimensions. By collecting this information before a new canvas element is created, applications are able to reliably set canvas dimensions within the size limitations of each browser/platform.

    A demo link and test results are available in the README, as well as a known issues section which touches on performance and virtual machine considerations.

    Full disclosure, I am the author of the library. I created it back in 2014 and recently revisited the code for a new canvas-related project. I was surprised to find the same lack of available tools for detecting canvas size limitations in 2018 so I updated code, released it, and hope it helps others running into similar issues.

    0 讨论(0)
  • 2020-11-22 08:15

    When you are using WebGL canvases, the browsers (including the desktop ones) will impose extra limits on the size of the underlying buffer. Even if your canvas is big, e.g. 16,000x16,000, most browsers will render a smaller (let's say 4096x4096) picture, and scale it up. That might cause ugly pixelating, etc.

    I have written some code to determine that maximum size using exponential search, if anyone ever needs it. determineMaxCanvasSize() is the function you are interested in.

    function makeGLCanvas()
    {
        // Get A WebGL context
        var canvas = document.createElement('canvas');
        var contextNames = ["webgl", "experimental-webgl"];
        var gl = null;
        for (var i = 0; i < contextNames.length; ++i)
        {
            try
            {
                gl = canvas.getContext(contextNames[i], {
                    // Used so that the buffer contains valid information, and bytes can
                    // be retrieved from it. Otherwise, WebGL will switch to the back buffer
                    preserveDrawingBuffer: true
                });
            }
            catch(e) {}
            if (gl != null)
            {
                break;
            }
        }
        if (gl == null)
        {
            alert("WebGL not supported.\nGlobus won't work\nTry using browsers such as Mozilla " +
                "Firefox, Google Chrome or Opera");
            // TODO: Expecting that the canvas will be collected. If that is not the case, it will
            // need to be destroyed somehow.
            return;
        }
    
        return [canvas, gl];
    }
    
    // From Wikipedia
    function gcd(a,b) {
        a = Math.abs(a);
        b = Math.abs(b);
        if (b > a) {var temp = a; a = b; b = temp;}
        while (true) {
            if (b == 0) return a;
            a %= b;
            if (a == 0) return b;
            b %= a;
        }
    }
    
    function isGlContextFillingTheCanvas(gl) {
        return gl.canvas.width == gl.drawingBufferWidth && gl.canvas.height == gl.drawingBufferHeight;
    }
    
    // (See issue #2) All browsers reduce the size of the WebGL draw buffer for large canvases 
    // (usually over 4096px in width or height). This function uses a varian of binary search to
    // find the maximum size for a canvas given the provided x to y size ratio.
    //
    // To produce exact results, this function expects an integer ratio. The ratio will be equal to:
    // xRatio/yRatio.
    function determineMaxCanvasSize(xRatio, yRatio) {
        // This function works experimentally, by creating an actual canvas and finding the maximum
        // value, the browser allows.
        [canvas, gl] = makeGLCanvas();
    
        // Reduce the ratio to minimum
        gcdOfRatios = gcd(xRatio, yRatio);
        [xRatio, yRatio] = [xRatio/gcdOfRatios, yRatio/gcdOfRatios];
    
        // if the browser cannot handle the minimum ratio, there is not much we can do
        canvas.width = xRatio;
        canvas.height = yRatio;
    
        if (!isGlContextFillingTheCanvas(gl)) {
            throw "The browser is unable to use WebGL canvases with the specified ratio: " + 
                xRatio + ":" + yRatio;
        }
    
        // First find an upper bound
        var ratioMultiple = 1;  // to maintain the exact ratio, we will keep the multiplyer that
                                // resulted in the upper bound for the canvas size
        while (isGlContextFillingTheCanvas(gl)) {
            canvas.width *= 2;
            canvas.height *= 2;
            ratioMultiple *= 2;
        }
    
        // Search with minVal inclusive, maxVal exclusive
        function binarySearch(minVal, maxVal) {
            if (minVal == maxVal) {
                return minVal;
            }
    
            middle = Math.floor((maxVal - minVal)/2) + minVal;
    
            canvas.width = middle * xRatio;
            canvas.height = middle * yRatio;
    
            if (isGlContextFillingTheCanvas(gl)) {
                return binarySearch(middle + 1, maxVal);
            } else {
                return binarySearch(minVal, middle);
            }
        }
    
        ratioMultiple = binarySearch(1, ratioMultiple);
        return [xRatio * ratioMultiple, yRatio * ratioMultiple];
    }
    

    Also in a jsfiddle https://jsfiddle.net/1sh47wfk/1/

    0 讨论(0)
  • 2020-11-22 08:16

    I don't know how to detect the max possible size without itteration, but you can detect if a given canvas size works by filling a pixel and then reading the colour back out. If the canvas has not rendered then the color you get back will not match. W

    partial code:

    function rgbToHex(r, g, b) {
        if (r > 255 || g > 255 || b > 255)
            throw "Invalid color component";
        return ((r << 16) | (g << 8) | b).toString(16);
    }
    var test_colour = '8ed6ff';
    working_context.fillStyle = '#' + test_colour;
    working_context.fillRect(0,0,1,1);
    var colour_data = working_context.getImageData(0, 0, 1, 1).data;
    var colour_hex = ("000000" + rgbToHex(colour_data[0], colour_data[1], colour_data[2])).slice(-6);
    
    0 讨论(0)
  • 2020-11-22 08:19

    Updated 10/13/2014

    All tested browsers have limits to the height/width of canvas elements, but many browsers also limit the total area of the canvas element. The limits are as follows for the browsers I'm able to test:

    Chrome:

    Maximum height/width: 32,767 pixels
    Maximum area: 268,435,456 pixels (e.g., 16,384 x 16,384)

    Firefox:

    Maximum height/width: 32,767 pixels
    Maximum area: 472,907,776 pixels (e.g., 22,528 x 20,992)

    IE:

    Maximum height/width: 8,192 pixels
    Maximum area: N/A

    IE Mobile:

    Maximum height/width: 4,096 pixels
    Maximum area: N/A

    Other:

    I'm not able to test other browsers at this time. Refer to the other answers on this page for additional limits.


    Exceeding the maximum length/width/area on most browsers renders the canvas unusable. (It will ignore any draw commands, even in the usable area.) IE and IE Mobile will honor all draw commands within the usable space.

    0 讨论(0)
  • 2020-11-22 08:26

    I've ran into out of memory errors on Firefox with canvas heights greater than 8000, chrome seems to handle much higher, at least to 32000.

    EDIT: After running some more tests, I've found some very strange errors with Firefox 16.0.2.

    First, I seem to get different behavior from in memory (created in javascript) canvas as opposed to html declared canvas.

    Second, if you don't have the proper html tag and meta charset, the canvas might be restricted to 8196, otherwise you can go up to 32767.

    Third, if you get the 2d context of the canvas and then change the canvas size, you might be restricted to 8196 as well. Simply setting the canvas size before grabbing the 2d context allows you to have up to 32767 without getting memory errors.

    I haven't been able to consistently get the memory errors, sometimes it's only on the first page load, and then subsequent height changes work. This is the html file I was testing with http://pastebin.com/zK8nZxdE.

    0 讨论(0)
提交回复
热议问题