168 lines
5.3 KiB
TypeScript
168 lines
5.3 KiB
TypeScript
import { Camera, Color, Component, Director, Material, RenderTexture, Sprite, SpriteFrame, UIOpacity, UITransform, _decorator, director } from 'cc';
|
|
import Core from '../../../Core';
|
|
const { ccclass, property, requireComponent } = _decorator;
|
|
|
|
@ccclass('UIMgrShade')
|
|
@requireComponent(Sprite)
|
|
@requireComponent(UIOpacity)
|
|
export default class UIMgrShade extends Component {
|
|
@property(Material)
|
|
private blurMaterial: Material = null;
|
|
|
|
@property(SpriteFrame)
|
|
private shadeFrame: SpriteFrame = null;
|
|
|
|
@property
|
|
private _delay = 0;
|
|
@property
|
|
get delay() { return this._delay; }
|
|
set delay(v) { this._delay = Math.max(v, 0); }
|
|
|
|
@property
|
|
private _begin = 0;
|
|
@property
|
|
get begin() { return this._begin; }
|
|
set begin(v) { if (v >= 0 && v <= 255) this._begin = v; }
|
|
|
|
@property
|
|
private _end = 255;
|
|
@property
|
|
get end() { return this._end; }
|
|
set end(v) { if (v >= 0 && v <= 255) this._end = v; }
|
|
|
|
@property
|
|
private _speed = 10;
|
|
@property
|
|
get speed() {
|
|
if (this.begin == this.end) {
|
|
return 0;
|
|
} else if (this.begin > this.end) {
|
|
return this._speed > 0 ? -this._speed : this._speed;
|
|
} else {
|
|
return this._speed >= 0 ? this._speed : -this._speed;
|
|
}
|
|
}
|
|
set speed(v) { this._speed = v; }
|
|
|
|
private get sprite() {
|
|
return this.node.getComponent(Sprite);
|
|
}
|
|
private get opacity() {
|
|
return this.node.getComponent(UIOpacity);
|
|
}
|
|
|
|
private inited = false;
|
|
private drawing = false;
|
|
private timedown = 0;
|
|
|
|
private blurFrame: SpriteFrame = null;
|
|
|
|
init(delay: number, begin: number, end: number, speed: number, blur: boolean) {
|
|
if (blur) {
|
|
director.targetOff(this);
|
|
this.inited = false;
|
|
this.drawing = false;
|
|
|
|
this.sprite.color = Color.WHITE;
|
|
this.sprite.customMaterial = null;
|
|
this.sprite.spriteFrame = this.blurFrame;
|
|
if (this.blurFrame) this.blurFrame.flipUVY = false;
|
|
|
|
let count = 0;
|
|
const cameras = director.getScene().getComponentsInChildren(Camera);
|
|
director.on(Director.EVENT_BEFORE_RENDER, () => {
|
|
count++;
|
|
|
|
const renderTexture = new RenderTexture();
|
|
const size = this.node.getComponent(UITransform);
|
|
renderTexture.reset({ width: size.width / 2, height: size.height / 2 });
|
|
renderTexture.addRef();
|
|
|
|
Core.inst.manager.ui.screenshot(renderTexture, {
|
|
cameraList: cameras
|
|
});
|
|
|
|
if (count === 1) {
|
|
this.blurFrame = new SpriteFrame();
|
|
this.blurFrame?.texture?.decRef();
|
|
this.blurFrame.texture = renderTexture;
|
|
this.blurFrame.flipUVY = true;
|
|
this.sprite.spriteFrame = this.blurFrame;
|
|
this.sprite.customMaterial = this.blurMaterial;
|
|
this.blurMaterial.setProperty('blurLevel', 2);
|
|
return;
|
|
}
|
|
|
|
if (count === 5) {
|
|
director.targetOff(this);
|
|
this.sprite.spriteFrame.flipUVY = false;
|
|
this.sprite.customMaterial = null;
|
|
return;
|
|
}
|
|
|
|
this.blurFrame?.texture?.decRef();
|
|
this.blurFrame.texture = renderTexture;
|
|
this.blurFrame.flipUVY = true;
|
|
this.sprite.spriteFrame = this.blurFrame;
|
|
this.sprite.customMaterial = this.blurMaterial;
|
|
this.blurMaterial.setProperty('blurLevel', count === 2 ? 3 : 1);
|
|
}, this);
|
|
} else {
|
|
director.targetOff(this);
|
|
this.sprite.spriteFrame = this.shadeFrame;
|
|
this.sprite.color = Color.BLACK;
|
|
this.sprite.customMaterial = null;
|
|
}
|
|
|
|
this.delay = delay;
|
|
this.begin = begin;
|
|
this.end = end;
|
|
this.speed = speed;
|
|
this.drawing = true;
|
|
|
|
if (this.inited) return;
|
|
this.inited = true;
|
|
this.timedown = this.delay;
|
|
// 初始透明度
|
|
this.opacity.opacity = this.timedown > 0 ? 0 : this.begin;
|
|
}
|
|
|
|
clear() {
|
|
this.inited = false;
|
|
this.drawing = false;
|
|
director.targetOff(this);
|
|
this.blurFrame?.texture?.decRef();
|
|
this.blurFrame?.destroy();
|
|
this.blurFrame = null;
|
|
this.sprite.spriteFrame = null;
|
|
}
|
|
|
|
protected update(dt: number) {
|
|
if (!this.inited) return;
|
|
if (!this.drawing) return;
|
|
|
|
if (this.timedown > 0) {
|
|
this.timedown -= dt;
|
|
if (this.timedown > 0) return;
|
|
// 初始透明度
|
|
this.opacity.opacity = this.begin;
|
|
}
|
|
|
|
const uiOpacity = this.opacity;
|
|
if (this.speed > 0) {
|
|
uiOpacity.opacity += this.speed * dt;
|
|
if (uiOpacity.opacity > this.end) {
|
|
uiOpacity.opacity = this.end;
|
|
}
|
|
} else if (this.speed < 0) {
|
|
uiOpacity.opacity += this.speed * dt;
|
|
if (uiOpacity.opacity < this.end) {
|
|
uiOpacity.opacity = this.end;
|
|
}
|
|
}
|
|
if (uiOpacity.opacity == this.end) {
|
|
this.drawing = false;
|
|
}
|
|
}
|
|
}
|