JavaScript Canvas globalAlpha属性如何工作?

时间:2016-03-01 16:20:05

标签: javascript html canvas

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

无效代码如下:

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/

工作代码如下:

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值?或者是代码中的问题?

1 个答案:

答案 0 :(得分:4)

  1. 在第二个示例中,每次在绘制白色矩形之前重置fillStyle 您在第一个示例中对globalAlpha执行的操作不同。
  2. globalAlpha属性不会接受所有值。引用MDN

      

    0.0(完全透明)和1.0之间的数字(完全不透明)。默认值为1.0范围之外的值(包括InfinityNaN)将不会设置,globalAlpha将保留其先前的值。

    由于浮动指针数学中的精度损失,当i变为负数时,globalAlpha会卡在0.009999999999999247上(可能因机器而异)。

  3. 要解决上述问题,请在绘制白色矩形之前重置globalAlpha

    ctx.globalAlpha = 1;
    

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

    i = i < 0 ? 0 : i;
    

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

    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);
    }
    

    [Updated fiddle]