【问题标题】:why is center of the circles still transparent in Canvas element?为什么画布元素中的圆心仍然透明?
【发布时间】:2021-06-05 13:46:21
【问题描述】:

我正在阅读来自 MDN 的 Canvas 元素,并遇到了一个通过 globalAlpha 属性设置透明度的示例。

<!DOCTYPE html>
<html>
    <style type="text/css">
    
    canvas{
        border: 1px solid black;
    }
    </style>
    <head>
        <title>Canvas Example</title>
    </head>
    <body>
        <canvas id='tutorial' width="150" height="150"></canvas>
    </body>
    <script>
        let canvas=document.getElementById("tutorial");
        let ctx=canvas.getContext('2d');
        ctx.fillStyle="#F00";
        ctx.fillRect(0,0,75,75);
        ctx.fillStyle="#0F0"
        ctx.fillRect(75,0,75,75)
        ctx.fillStyle="#00F";
        ctx.fillRect(0,75,75,75);
        ctx.fillStyle="#0FF"
        ctx.fillRect(75,75,75,75)
        ctx.fillStyle='#FFF';
        ctx.globalAlpha=0.2;
        ctx.beginPath();
        for(let i=1;i<8;i++){
            ctx.arc(75, 75, 10*i, 0, 2 * Math.PI, true)
            ctx.fill();
        }
        ctx.fill();
    </script>
</html>

在上面的示例中,我创建了 8 个同心圆,每个同心圆的透明度为 0.2 。但我仍然可以看到画布元素的中心。

画布中心不应该被 5 个圆圈隐藏/不透明吗?

如果我将 globalAlpha 值更改为 0.4 或 0.5,我将无法再看到 Canvas 元素的中心

示例如下:

<!DOCTYPE html>
<html>
    <style type="text/css">
    
    canvas{
        border: 1px solid black;
    }
    </style>
    <head>
        <title>Canvas Example</title>
    </head>
    <body>
        <canvas id='tutorial' width="150" height="150"></canvas>
    </body>
    <script>
        let canvas=document.getElementById("tutorial");
        let ctx=canvas.getContext('2d');
        ctx.fillStyle="#F00";
        ctx.fillRect(0,0,75,75);
        ctx.fillStyle="#0F0"
        ctx.fillRect(75,0,75,75)
        ctx.fillStyle="#00F";
        ctx.fillRect(0,75,75,75);
        ctx.fillStyle="#0FF"
        ctx.fillRect(75,75,75,75)
        ctx.fillStyle='#FFF';
        ctx.globalAlpha=0.5;
        ctx.beginPath();
        for(let i=1;i<8;i++){
            ctx.arc(75, 75, 10*i, 0, 2 * Math.PI, true)
            ctx.fill();
        }
      
    </script>
</html>

谁能解释一下,

  1. 为什么当 globalAlpha 值为 0.2 而不是 0.5 时我仍然可以看到中心?

  2. 为什么堆叠 2 个不透明度为 0.5 的圆圈或 5 个不透明度为 0.2 的圆圈不会使其完全不透明?

【问题讨论】:

  • 我不知道该告诉你什么。如果你把一块玻璃板放在一个表面上,你可以透过它看到表面。
  • @Hiro 是的,我明白这一点,但是如果我们堆叠一定数量的板,每个都具有一定的不透明度,我们不应该看不到表面吗?
  • 我不明白为什么堆叠 2 个不透明度为 0.5 的圆圈或 5 个不透明度为 0.2 的圆圈使其完全不透明?
  • 不相关,但您应该真正将 beginPath() 放入循环中。

标签: javascript html canvas html5-canvas


【解决方案1】:

您对不透明度/透明度的直觉是错误的。通俗地说:当你画一个不透明度为 50% 的圆时,这意味着像素值由圆的 50% 和之前的 50% 组成。当您绘制第二个 50% 不透明的圆圈时,像素值由第二个圆圈的 50% 和之前的 50% 组成,即第一个圆圈的 50% 和圆圈之前的 50%。因此,在两个圆圈之后,像素值是第二个圆圈的 50%,第一个圆圈的 25%,以及之前的 25%。

换句话说,它实际上是乘法,而不是加法。将两个 50% 透明的东西放在一起使整个 (0.5 * 0.5 = 0.25) 透明,即 75% 不透明。

【讨论】:

    【解决方案2】:

    我正在创建 8 个同心圆,每个圆的透明度为 0.2

    其实 0.2 不是透明度,而是不透明度(反之)。所以 0.2 意味着 80% 的透明度。 其次,您正在绘制 7 个圆圈,而不是 8 个。检查您的循环条件:

    for(let i=1;i<8;i++){
    

    画布中心不应该被5个圆圈隐藏/不透明吗?

    不一定。 0.8透明度(0.2不透明度)还是很多的。与前一个相比,每个圆圈留下 80% 的透明度。第二个留下第一个 0.8 的 0.8 透明度,即 0.8 * 0.8 = 0.64,依此类推:

    circle combined transparency result
    1 0.8 0.8
    2 0.82 0.64
    3 0.83 0.512
    4 0.84 0.4096
    5 0.85 0.32768
    6 0.86 0.262144
    7 0.87 0.2097152

    所以您看到,在绘制了第 7th 个圆之后,仍有大约 21% 的透明度。

    如果您以 0.5 的透明度重复此练习,则第 7th 个圆圈将仅留下 0.57 = 0.0078125 的总透明度。这实际上意味着不透明度为 0.992。到时候看不到背景是正常的。

    【讨论】:

      猜你喜欢
      • 2015-06-26
      • 2022-01-26
      • 2011-01-22
      • 2018-12-15
      • 2018-01-28
      • 2018-09-13
      • 1970-01-01
      • 2014-03-25
      • 2013-04-14
      相关资源
      最近更新 更多