基于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