关于html:JavaScript Canvas globalAlpha属性如何工作?

How does the JavaScript Canvas globalAlpha Property work?

我正在尝试在Canvas元素上使用JavaScript淡出效果。我目前有两种解决方案。从理论上讲,两者都可以正常工作,但实际上只有一个可以,我想知道为什么。

无效的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var i = 1;
requestAnimationFrame(test);

function test(){
 i-=0.01;
 ctx.fillStyle ="white";
 ctx.fillRect(20, 20, 75, 50);
 ctx.globalAlpha = i;
 ctx.fillStyle ="red";
 ctx.fillRect(20, 20, 75, 50);
 requestAnimationFrame(test);
}

我想要实现的是逐渐更改当前上下文的alpha值,以使其褪色为白色。一段时间后,它应该具有完全的透明度,但是没有透明度。它会在到达该状态之前停止。它在JSFiddle中:https://jsfiddle.net/bq75v1mm/

工作代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var i = 1;
requestAnimationFrame(test);
function test(){
 i-=0.01;
 ctx.fillStyle ="white";
 ctx.fillRect(20, 20, 75, 50);
 ctx.fillStyle ="rgba("+255+","+0+","+0+","+i+")";
 ctx.fillRect(20, 20, 75, 50);
 requestAnimationFrame(test);
}

使用此代码,我只是为即将到来的矩形更改给定fillStyle的alpha值,它的工作原理就像一个魅力,使正方形消失了。它在JSFiddle中:https://jsfiddle.net/mxtynwwd/

我想了解为什么第一种解决方案不起作用?为什么在给定最小值后不能降低globalAlpha值?还是代码中的问题?


  • 在第二个示例中,每次绘制白色矩形之前都要重置fillStyle
    在第一个示例中,您没有对globalAlpha做相同的事情。
  • 并非所有值都被globalAlpha属性接受。 报价MDN:

    A number between 0.0 (fully transparent) and 1.0 (fully opaque). The default value is 1.0 Values outside the range, including Infinity and NaN will not be set and globalAlpha will retain its previous value.

    由于浮点数学运算的精度损失,当i变为负数时,globalAlpha会卡在0.009999999999999247上(可能因计算机而异)。

  • 要解决以上两个问题,请在绘制白色矩形之前重置globalAlpha

    1
    ctx.globalAlpha = 1;

    在绘制红色的红色之前,请确保i>= 0

    1
    i = i < 0 ? 0 : i;

    您的第一个示例可以相应地更新为与第二个示例完全相同:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    var i = 1;
    requestAnimationFrame(test);

    function test() {
        i -= 0.01;
        i = i < 0 ? 0 : i;
        ctx.globalAlpha = 1;
        ctx.fillStyle ="white";
        ctx.fillRect(20, 20, 75, 50);
        ctx.globalAlpha = i;
        ctx.fillStyle ="red";
        ctx.fillRect(20, 20, 75, 50);
        requestAnimationFrame(test);
    }

    [更新小提琴]