自制圆角矩形Mask 遮罩

可用于制作圆角/圆形头像,圆角裁剪等场景.
原理是改写了Mask 组件的绘制过程,绘制成圆角矩形.
可基于此写法,扩展自己的任意形状遮罩.
源码下载:
RoundRectMask.zip (1.1 KB)

使用方法:
直接类似于Mask组件, 将被遮罩节点挂载在此节点之下即可.

源码:

import property = cc._decorator.property;
import ccclass = cc._decorator.ccclass;
import executeInEditMode = cc._decorator.executeInEditMode;
import disallowMultiple = cc._decorator.disallowMultiple;
import requireComponent = cc._decorator.requireComponent;
import menu = cc._decorator.menu;

cc.macro.ENABLE_WEBGL_ANTIALIAS = true;

@ccclass()
//@ts-ignore
@executeInEditMode(true)
//@ts-ignore
@disallowMultiple(true)
@requireComponent(cc.Mask)
@menu("渲染组件/圆角遮罩")
export class RoundRectMask extends cc.Component {

    @property()
    private _radius: number = 50;

    @property({tooltip: "圆角半径:\n0-1之间为最小边长比例值, \n>1为具体像素值"})

    public get radius(): number {
        return this._radius;
    }

//    public radius: number = 50;
    public set radius(r: number) {
        this._radius = r;
        this.updateMask(r);
    }

    // @property(cc.Mask)
    protected mask: cc.Mask = null;

    protected onEnable(): void {
        this.mask = this.getComponent(cc.Mask);
        this.updateMask(this.radius);
    }

    private updateMask(r: number) {
        let _radius = r >= 0 ? r : 0;
        if (_radius < 1) {
            _radius = Math.min(this.node.width, this.node.height) * _radius;
        }
        this.mask["radius"] = _radius;
        this.mask["onDraw"] = this.onDraw.bind(this.mask);
        this.mask["_updateGraphics"] = this._updateGraphics.bind(this.mask);
        this.mask.type = cc.Mask.Type.RECT;
    }

    private _updateGraphics() {

        // @ts-ignore.
        let graphics = this._graphics;
        if (!graphics) {
            return;
        }
        this.onDraw(graphics);
    }

    /**
     * mask 用于绘制罩子的函数.
     * this 指向mask 对象,需要特别注意.
     * @param graphics
     */
    protected onDraw(graphics: cc.Graphics) {
        // Share render data with graphics content
        graphics.clear(false);
        let node = this.node;
        let width = node.width;
        let height = node.height;
        let x = -width * node.anchorX;
        let y = -height * node.anchorY;
        graphics.roundRect(x, y, width, height, this.radius || 0);
        if (cc.game.renderType === cc.game.RENDER_TYPE_CANVAS) {
            graphics.stroke();
        } else {
            graphics.fill();
        }
    }
}

效果:

可以直接在编辑器中实时看效果,
可以通过添加组件菜单/ 渲染组件/圆角矩形. 类似系统组件的添加方式.

21赞

谢谢分享

谢谢,挺好用的。

厉害,很实用

谢谢分享

mask

mark

mark

mark mark

谢谢分享!

感谢分享,大神大神!!!!!

大佬,我在节点上绑定了你的遮罩脚本,然后我动态批量生成,结果只有第一个生效,其他的遮罩全部没有效果阿
image
image
image

已解决:
将遮罩组件放圆角矩形遮罩下面

:smile: :grin: :grin: :grin:

  1. 这是个什么原理,批量情况下还有这种问题。。。

感谢分享!

mark mark 好用

mask的image_stencil模式不就能实现吗