我正在尝试通过图像上方的光泽效果,而我只希望该效果应显示在图像的内容中,而不是在所有容器中。我已经尝试了很多,但无法使alphaMaskChannel工作。如果有人可以帮助我并向我解释我在做什么错,我将不胜感激。

这是我的示例:

var stage = new createjs.Stage("canvas");
createjs.Ticker.addEventListener("tick", tick);

var imgSheen = new createjs.Shape();
var bmp = new createjs.Bitmap("http://upload.wikimedia.org/wikipedia/pt/0/02/Homer_Simpson_2006.png");


imgSheen.graphics.beginLinearGradientFill(['rgba(255,255,255,0)', '#000', 'rgba(255,255,255,0)'], [0, 0.5, 1], 0, 0, 50, 0).drawRect(0, 0, 100, 600);
imgSheen.rotation = 18;

imgSheen.filters = [
          new createjs.AlphaMapFilter(bmp)
        ];
stage.addChild(bmp, imgSheen);

function tick(event) {
    createjs.Tween.get(imgSheen).to({x:300}, 4000);
    stage.update();
}


链接:https://jsfiddle.net/Dbardaji/ndmzLt1z/

最佳答案

我想我知道您要做什么,并且有一些步骤可以达到目标。在画布中,Alpha蒙版比诸如Animate / Flash之类的更为复杂,因此设置起来更加困难。动画效果也很困难。

正确使用过滤器


您要查找的过滤器是AlphaMaskFilter,而不是AlphaMapFilter。后者使用颜色通道来应用滤镜,而不使用alpha通道。此外,滤镜将拍摄图像,而不是位图。
您应该等到图像加载后再应用图像,以免出现错误或什么都没有出现。
DisplayObject必须缓存才能应用过滤器。这会“冻结”对象,因此,无论何时更改,都必须将其重新缓存。
在您的情况下,您要将过滤器应用于“ imgSheen”,但应将imgSheen用作源。为此,您必须缓存imgSheen,将其cacheCanvas传递给AlphaMaskFilter,将其应用于bmp,然后缓存bmp以应用过滤器。
不要在舞台上添加imgSheen。它是应用于位图的过滤器的一部分,不应显示。


以下是上述步骤的示例:
https://jsfiddle.net/lannymcnie/ndmzLt1z/3/

关键位:

imgSheen.cache(0,0,100,400); // Cache the sheen so it can be used in the filter
bmp.filters = [
    new createjs.AlphaMaskFilter(imgSheen.cacheCanvas) // Use the right filter
];
bmp.cache(0,0,bmp.image.width,bmp.image.height); // Apply the filter
stage.addChild(bmp); // Don't add imgSheen to the stage


动画效果

为了添加动画,必须更改滤镜的位置。之所以很难,是因为:


每当过滤器更改时,您都必须重新缓存位图
线性位图填充的工作方式不能只是更改x位置(必须更新渐变位置,drawRect位置和缓存位置。为简化起见,我添加了一个Container,将渐变放进去,已缓存容器,这意味着imgSheen可以自由移动,我们可以随时更新容器缓存。
容器的高速缓存和过滤器的高速缓存必须随时更改。


我将Tween移出了tick方法(我们只希望它发生一次-不会在每个tick上创建),并添加了一个“ change”侦听器来更新缓存。这是更新的演示:https://jsfiddle.net/lannymcnie/ndmzLt1z/4/

关键位:

c = new createjs.Container();
c.addChild(imgSheen);

createjs.Tween.get(imgSheen, {loop:true}).to({x:200}, 2000, createjs.Ease.quadInOut)
    .on("change", function() {
        c.cache(0,0,250,400);
        bmp.cache(0,0,bmp.image.width,bmp.image.height);
    });


请注意,每帧更新缓存并不理想。最好制作一个覆盖图像的反向渐变,而不是对其进行遮罩(并融合到背景中)。您可以遮盖渐变和图像,以将其限制为图像大小。

希望有帮助!

10-07 17:43