基于Starling的mask实现

作为一个从c++转过来的程序员,flash原生的自定义mask实在是太好用,能方便实现各种效果,比如新手引导的高亮、viewport效果等。可惜starling的显示对象并不支持mask特性,查阅google,终于找到pixelmask这个开源代码,实现了想要的效果,感谢这位作者。(注:该mask只有渲染的裁剪功能,并没有原生mask的hitTest功能)

使用方法:

// myCustomDisplayObject and myCustomMaskDisplayObject can be any Starling display object:
var myCustomDisplayObject:Sprite = new Sprite();
var myCustomMaskDisplayObject:Sprite = new Sprite();
 
// for masks with animation: 较费,因为每次render都需要刷新RenderTexture,尽量避免同时出现大量这种带mask的动画。(宿主为动画或者mask本身也会动,都需要将animate设置成true)
var maskedDisplayObject:PixelMaskDisplayObject = new PixelMaskDisplayObject();
maskedDisplayObject.addChild(myCustomDisplayObject);
 
// for masks with no animation (note, MUCH better performance!) 静态
var maskedDisplayObject:PixelMaskDisplayObject = new PixelMaskDisplayObject(-1, false);
maskedDisplayObject.addChild(myCustomDisplayObject);
 
// Apply the masking as you would in classic flash.display style.
// Note: the mask display object should not be added to the display list.
 
maskedDisplayObject.mask = myCustomMaskDisplayObject; //mask基于像素,可以自定义形状,而不是传统的矩形viewport
addChild(maskedDisplayObject);

 

pixelMask通过两个renderTexture的Blend来实现,一个是要渲染的对象,另外一个是mask。

刷新RenderTexture        

        private function refreshRenderTextures(e:Event=null) : void {
            if (_mask) {

                clearRenderTextures();

                _maskRenderTexture = new RenderTexture(_mask.width, _mask.height, false, _scaleFactor);
                _renderTexture = new RenderTexture(_mask.width, _mask.height, false, _scaleFactor);

                // create image with the new render texture
                _image = new Image(_renderTexture);

                // create image to blit the mask onto
                _maskImage = new Image(_maskRenderTexture);

                // set the blending mode to MASK (ZERO, SRC_ALPHA)
         // BlendMode.register(MASK_MODE_NORMAL,Context3DBlendFactor.ZERO,Context3DBlendFactor.SOURCE_ALPHA);
         // BlendMode.register(MASK_MODE_INVERTED,Context3DBlendFactor.ZERO,Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA);
if (_inverted) { _maskImage.blendMode = MASK_MODE_INVERTED; } else { _maskImage.blendMode = MASK_MODE_NORMAL; } } _maskRendered = false; }

 

将mask叠加到目标texture

        private function drawRenderTextures() : void
        {
            // undo scaling and positioning temporarily because its already applied in this execution stack

            var matrix:Matrix = this.transformationMatrix.clone();

            this.transformationMatrix = new Matrix();
            _superRenderFlag = true;            
            _renderTexture.draw(this);
            _superRenderFlag = false;

            this.transformationMatrix = matrix;
            _renderTexture.draw(_maskImage);
        }

 

渲染

        public override function render(support:RenderSupport, parentAlpha:Number):void
        {
            if (_isAnimated || (!_isAnimated && !_maskRendered)) {
                if (_superRenderFlag || !_mask) {
                    super.render(support, parentAlpha);
                } else {            
                    if (_mask) {                   
                        _maskRenderTexture.draw(_mask);
                        _renderTexture.drawBundled(drawRenderTextures);                
                        _image.render(support, parentAlpha);
                        _maskRendered = true;
                    }
                }
            } else {
                _image.render(support, parentAlpha);
            }
        }

 

PixelMask: http://wiki.starling-framework.org/extensions/pixelmask

git: https://github.com/jonathanhart/pixelmask

posted on 2013-09-14 23:34  非合格程序员  阅读(982)  评论(0编辑  收藏  举报