Files
mp-xieyingeng/assets/scripts/utils/RoundedRectMask.ts
2026-03-14 11:02:49 +08:00

112 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { _decorator, Component, UITransform, Graphics, Color, Mask } from 'cc';
const { ccclass, property } = _decorator;
/**
* 圆角矩形遮罩组件
* 使用 Graphics + Mask 绘制圆角矩形作为遮罩
*
* 使用方法:
* 1. 将此组件添加到需要圆角的节点上
* 2. 设置圆角半径
* 3. 该节点及其子节点会被裁剪为圆角矩形
*/
@ccclass('RoundedRectMask')
export class RoundedRectMask extends Component {
@property({
tooltip: '圆角半径(像素)'
})
radius: number = 20;
private _graphics: Graphics | null = null;
private _mask: Mask | null = null;
private _uiTransform: UITransform | null = null;
onLoad() {
this._uiTransform = this.getComponent(UITransform);
this.setupComponents();
}
/**
* 设置组件
*/
private setupComponents() {
// 获取或添加 Graphics 组件
this._graphics = this.getComponent(Graphics);
if (!this._graphics) {
this._graphics = this.addComponent(Graphics);
}
// 获取或添加 Mask 组件
this._mask = this.getComponent(Mask);
if (!this._mask) {
this._mask = this.addComponent(Mask);
}
// 设置 Mask 使用 Graphics 类型
this._mask.type = Mask.Type.GRAPHICS_STENCIL;
this.drawRoundedRect();
}
/**
* 绘制圆角矩形
*/
private drawRoundedRect() {
if (!this._graphics || !this._uiTransform) return;
const width = this._uiTransform.width;
const height = this._uiTransform.height;
const r = Math.min(this.radius, Math.min(width, height) / 2);
// 清除之前的绘制
this._graphics.clear();
// 设置填充颜色
this._graphics.fillColor = new Color(255, 255, 255, 255);
// 绘制圆角矩形路径
const halfW = width / 2;
const halfH = height / 2;
// 使用 lineTo 和 arc 绘制圆角矩形
// 从左下角开始,逆时针绘制
this._graphics.moveTo(-halfW + r, -halfH);
// 下边
this._graphics.lineTo(halfW - r, -halfH);
// 右下角圆角 (90度弧从 -90度 到 0度)
this._graphics.arc(halfW - r, -halfH + r, r, -Math.PI / 2, 0, false);
// 右边
this._graphics.lineTo(halfW, halfH - r);
// 右上角圆角 (90度弧从 0度 到 90度)
this._graphics.arc(halfW - r, halfH - r, r, 0, Math.PI / 2, false);
// 上边
this._graphics.lineTo(-halfW + r, halfH);
// 左上角圆角 (90度弧从 90度 到 180度)
this._graphics.arc(-halfW + r, halfH - r, r, Math.PI / 2, Math.PI, false);
// 左边
this._graphics.lineTo(-halfW, -halfH + r);
// 左下角圆角 (90度弧从 180度 到 270度)
this._graphics.arc(-halfW + r, -halfH + r, r, Math.PI, Math.PI * 1.5, false);
// 填充
this._graphics.fill();
}
/**
* 设置圆角半径
*/
setRadius(radius: number) {
this.radius = radius;
this.drawRoundedRect();
}
}