【问题标题】:Drawing multiple offscreen canvases into onscreen canvas将多个屏幕外画布绘制到屏幕画布中
【发布时间】:2017-06-18 13:05:50
【问题描述】:

我在尝试将多个屏幕外画布渲染到屏幕画布时遇到问题。我确实得到了一个渲染的屏幕外画布,但问题是之前应该有另外两个渲染。换句话说,只渲染最后一个画布。预期的结果将是三个重叠的矩形(或正方形:),红色、绿色和蓝色。代码如下:

function rectangle(color) {
    var offScreenCanvas = document.createElement('canvas');
    var offScreenCtx = offScreenCanvas.getContext('2d');

    var width = offScreenCanvas.width = 150;
    var height = offScreenCanvas.height = 150;

    switch(color) {
        case 1: 
            offScreenCtx.fillStyle='rgb(255,0,0)';
            break;
        case 2:
            offScreenCtx.fillStyle='rgb(0,255,0)';
            break;
        case 3:
            offScreenCtx.fillStyle='rgb(0,0,255)';
            break;
    }

    offScreenCtx.fillRect(0,0,width,height);

return offScreenCanvas;
}

function draw(offScreenCanvas, x , y) {
    var canvas = document.getElementById('canvas')
    var ctx = canvas.getContext('2d');

    var width = canvas.width = window.innerWidth;
    var height = canvas.height = window.innerHeight;

    ctx.drawImage(offScreenCanvas, x, y);
}

var images = [];
var color = 1;

for (var i=0; i<3; i++) {
    var img = new rectangle(color);
    images.push(img);
    color++;
}

var x = 0;
var y = 0;

for (var i = 0; i < images.length; i++) {
    draw(images[i], x, y);
    x += 100;
    y += 100;
}

我进行了一些搜索,似乎我不是第一个遇到此问题的人,但我无法使其正常工作。

【问题讨论】:

    标签: javascript canvas


    【解决方案1】:

    设置画布height 或width 会清除画布。

    您的代码的问题是,当您在函数draw 中设置它的大小时,您会导致屏幕上的画布被清除

    设置画布大小,即使该大小相同,也会导致画布上下文重置并清除画布。所有其他画布都被渲染,但在您设置屏幕画布大小时被擦除。

    你的draw 函数

    function draw(offScreenCanvas, x , y) {
        var canvas = document.getElementById('canvas')
        var ctx = canvas.getContext('2d');
    
        // The cause of the problem ===================================
        // Either one of the following lines will clear the canvas
        var width = canvas.width = window.innerWidth;
        var height = canvas.height = window.innerHeight;
        //=============================================================
    
        ctx.drawImage(offScreenCanvas, x, y);
    }
    

    为避免这种情况,只需设置一次画布大小。如果您需要调整画布大小并保留其内容,您首先需要创建画布的副本,然后调整其大小,然后将副本渲染回原件。

    演示显示 5 个屏幕外画布被渲染到一个屏幕画布上。

    const colours = ['#f00', '#ff0', '#0f0', '#0ff', '#00f'];
    const ctx = can.getContext('2d');
    can.width = innerWidth - 4;  // sub 4 px for border
    can.height = innerHeight - 4;
    
    function createCanvas(color, i) {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      canvas.width = 150;
      canvas.height = 150;
      ctx.font = "24px arial";
      ctx.fillStyle = color;
      ctx.fillRect(0, i * 30, canvas.width, 30);
      ctx.fillStyle = "black";
      ctx.fillText("Canvas "+i,10,(i + 0.75) * 30);
      return canvas;
    }
    colours.forEach((c, i) => {
      ctx.drawImage(createCanvas(c, i), 0, 0);
    })
    canvas {
      border: 2px solid black;
      position : absolute;
      top : 0px;
      left : 0px;
    }
    &lt;canvas id="can"&gt;&lt;/canvas&gt;

    【讨论】:

    • ctx.clearRect(canvas.width,canvas.height) 也应该清除画布。
    • @RiazLaskar 打错了,你忘了坐标,你也可以通过上下文获取画布ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    猜你喜欢
    • 1970-01-01
    • 2013-07-15
    • 2018-04-26
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    相关资源
    最近更新 更多