【问题标题】:HTML5 Canvas - fillRect() vs rect()HTML5 画布 - fillRect() 与 rect()
【发布时间】:2020-10-27 18:49:55
【问题描述】:

在下面的代码中,如果我在两个地方都使用rect()fill()(即两个矩形都是绿色),则第二个fillStyle 会覆盖第一个指定的颜色(即,两个矩形都是绿色)但按预期工作(即如果我将第一个 rect() 更改为 fillRect(),则第一个矩形为蓝色,第二个为绿色。为什么会这样?我以为fillRect() 只是rect() 然后是fill(),对吧?

ctx.translate(canvas.width/2, canvas.height/2);

ctx.fillStyle = "#5A9BDC";
ctx.fillRect(0, 0, rectWidth, rectHeight);
// ctx.rect(0, 0, rectWidth, rectHeight);
// ctx.fill();    

ctx.translate(-canvas.width/2, -canvas.height/2);

ctx.fillStyle = "#31B131";
ctx.rect(0, 0, rectWidth, rectHeight);
ctx.fill();

在 Chrome 中测试 | Fiddle

【问题讨论】:

    标签: javascript html5-canvas


    【解决方案1】:

    fillRect

    .fillRect 是一个“独立”命令,用于绘制和填充矩形。

    因此,如果您使用多个 .fillStyle 命令发出多个 .fillRect 命令,则每个新矩形都将被前面的填充样式填充。

    ctx.fillStyle="red";
    ctx.fillRect(10,10,10,10);  // filled with red
    
    ctx.fillStyle="green";
    ctx.fillRect(20,20,10,10);  // filled with green
    
    ctx.fillStyle="blue";
    ctx.fillRect(30,30,10,10);  // filled with blue
    

    矩形

    .rect 是画布路径命令的一部分。

    路径命令是绘图组,从 beginPath() 开始,一直持续到另一个 beginPath() 发出。

    在每个组中,只有最后一个样式命令获胜。

    因此,如果您在一个路径中发出多个 .rect 命令和多个 .fillStyle 命令,则只有最后一个 .fillStyle 将用于所有 .rect。

    ctx.beginPath();  // path commands must begin with beginPath
    
    ctx.fillStyle="red";
    ctx.rect(10,10,10,10);  // blue
    
    ctx.fillStyle="green";
    ctx.rect(20,20,10,10);  // blue
    
    ctx.fillStyle="blue";  // this is the last fillStyle, so it "wins"
    ctx.rect(30,30,10,10);  // blue
    
    // only 1 fillStyle is allowed per beginPath, so the last blue style fills all
    
    ctx.fill()
    

    【讨论】:

    • ctx.rect 绘制大量像素是否更快?
    • 如果要画一个大矩形,那么两种方法都差不多。如果你想画很多分散的矩形,那么你应该使用:.beginPath + many .rect + .fill
    • 与@markE 形成对比:this benchmark 表明直接fillRect 每秒的操作数明显多于直接绘制甚至直接使用beginPath
    • 刚刚试了一下,我得到了:jsperf.com/canvas-fillrect-vs-rect/1 显然,fillRect 单次使用的速度是前者的两倍,而对于数千人来说,速度是后者的两倍
    • @waterplea - 链接断开?
    【解决方案2】:

    据我所知,画布有 3 个“矩形”函数:fillRectstrokeRectrect

    ctx.rect(0,0,rectWidth,rectHeight); // create some shape, there is nothing on the canvas yet
    ctx.stroke(); // draw stroke of the shape
    ctx.fill();   // fill the shape
    

    有两个快捷键:

    ctx.strokeRect(0,0,rectWidth,rectHeight); // shortcut to stroke rectangle
    ctx.fillRect(0, 0, rectWidth, rectHeight); // shortcut to fill rectangle
    

    因此,您的fill 调用只能填充您使用rect 创建的形状。

    【讨论】:

    • 我知道所有这些方法以及fillRect 应该做什么,但它的工作方式与rectfill 有点不同(至少对我而言)。 PS:fill 可以填充任何形状,即使是通过画线创建的形状
    • 注释 ctx.fillRect(0, 0, rectWidth, rectHeight); 行并取消注释它下面的 2 行,看看会发生什么。我的问题是为什么会发生这种情况
    【解决方案3】:

    如果您想为不同的路径命令使用不同的颜色,请在每个命令起作用之前调用beginPath()

    ctx.beginPath();  
    ctx.fillStyle="red";
    ctx.rect(10,10,10,10);
    ctx.fill()
    
    ctx.beginPath()
    ctx.fillStyle="green";
    ctx.rect(20,20,10,10);  
    ctx.fill()
    
    ctx.beginPath()
    ctx.fillStyle="blue";  
    ctx.rect(30,30,10,10);  
    ctx.fill()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 2013-08-12
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      相关资源
      最近更新 更多