- Creator 版本: 3.3.2
- 目标平台: Web: (Win10: Chrome, 手机: 小米浏览器)
需求:
在图片上涂鸦…可选彩色…不要越边…图片可更换…尺寸不固定…
(折腾了不少方案…暂时选择了最简单的Component组合…先实现再寻求更优方案…)
方案一:
让三个组件形成一个节点树: Sprite/Mask/Graphics
让触摸Sprite时计算坐标…在Graphics相同位置上绘制笔触…
Mask使用和Sprite相同的spf…过滤透明部分…
更换图片时…同时更换Sprite和Mask的spf…
结果:
估计Mask会在初始化时获取了宽高等信息…
更换spf后会有变形…修改UITsf的宽高也无法解决…
调用几个updateXXX之类的api也没效果…
查了官方手册也没什么资料…先放弃…
方案二:
场景只预备一个空白的Sprite…
Mask及Graphics均由代码创建…
其中Mask根据不同的spf各自创建一个节点…
Graphics再挂载到对应的Mask上…
结果:
首个创建的Mask有效…
其余时间创建的Mask会出现不正常的情况(呈现放大的状态…后面有图片)…
如果首个Mask延迟创建…亦会出现不正常的情况…
查了官方手册也没什么资料…
只能上论坛问了…

正常的情况(期望的效果)…

非首帧创建的Mask均被放大…
start() {
this._init();
// setTimeout(() => this._init(), 1000);
}
只要延迟就会放大…
Mask部分的代码:
public setSpf(spf: SpriteFrame) {
console.log('setSpf');
this._changeMask(spf);
}
private _mask: Mask;
private _masks: Map<SpriteFrame, Mask> = new Map();
private _changeMask(spf: SpriteFrame) {
console.log('changeMask');
let newMask = this._masks.get(spf);
if (!newMask) newMask = this._createMask(spf);
else newMask.node.active = true;
this.graphics.node.parent = newMask.node;
if (this._mask) this._mask.node.active = false;
this._mask = newMask;
this.status;
}
private _createMask(spf: SpriteFrame) {
console.log('createMask');
const node = this.node;
const nMask = new Node('Mask-' + spf.name);
nMask.parent = node;
nMask.layer = node.layer;
nMask.position = Vec3.ZERO;
const tsfMask = nMask.addComponent(UITransform);
tsfMask.width = spf.width;
tsfMask.height = spf.height;
const mask = nMask.addComponent(Mask);
mask.spriteFrame = spf;
mask.type = Mask.Type.IMAGE_STENCIL;
this._masks.set(spf, mask);
return mask;
}
Demo:
Test.rar (48.5 KB)








