import UIBG from "../UIBG"; const { ccclass, property, executeInEditMode, playOnFocus } = cc._decorator; /** 效果类型 */ enum EffectType { none = 0, //无 scale = 1, //缩放 scaleToPoint = 2, //缩放到某点 centerUnfolding = 3, //从中部展开 rightIn = 4, //从右侧进入 bottomIn = 5, //从底部进入 } /** * 界面打开 和 关闭效果 * 组件请挂载到对应ui界面上 * @author 薛鸿潇 */ @ccclass @executeInEditMode() @playOnFocus() export default class EffectOpenAndClose extends cc.Component { @property({ type: cc.Node, displayName: '动画节点' }) private effect_par: cc.Node = null @property({ type: cc.Enum(EffectType), displayName: '打开动画节点效果', visible() { return this.effect_par } }) private open_effect: EffectType = EffectType.scale; @property({ displayName: '是否打开关闭动画' }) public isOpenCloseEffect: boolean = true; @property({ type: cc.Enum(EffectType), displayName: '关闭动画节点效果', visible() { return this.effect_par && this.isOpenCloseEffect } }) private close_effect: EffectType = EffectType.scale; @property({ displayName: '关闭节点缩小到此节点坐标', visible() { return this.close_effect == EffectType.scaleToPoint } }) private close_toPoint: string = ""; @property({ displayName: '做关闭动画之前是否关闭黑背景' }) private close_uibg: boolean = false; @property({ displayName: '是否延迟一帧做动画' }) private isDelayOneFrame: boolean = false; private _play_open: boolean = false; @property({ displayName: "预览开" }) get play_open(): boolean { if (this._play_open) { this.showEffect(); this._play_open = false; } return this._play_open; } set play_open(v: boolean) { this._play_open = v; } private _play_close: boolean = false; @property({ displayName: "预览关" }) get play_close(): boolean { if (this._play_close) { this.effect_par.scale = 1; this.hideEffect(); this._play_close = false; } return this._play_close; } set play_close(v: boolean) { this._play_close = v; } onLoad() { // this.node.on('ui-close', this.hideEffect, this);// 界面关闭事件 } start() { if (CC_EDITOR) return; if (this.isDelayOneFrame) { if(EffectType.scale === this.open_effect) { this.effect_par.opacity = 0; } cc.tween(this.effect_par).delay(0.16).call(() => { this.showEffect(); }).start(); } else { this.showEffect(); } } /** * 界面打开效果 */ private showEffect() { if (this.effect_par) { switch (this.open_effect) { case EffectType.none: break; case EffectType.scale: let scale = this.effect_par.scale; this.effect_par.opacity = 255; mk.tween.scale(this.effect_par, 0.3, undefined, scale, undefined, 'backOut'); break; case EffectType.centerUnfolding: mk.tween.scaleX(this.effect_par, 0.3, undefined, undefined, undefined, 'backOut'); break; case EffectType.rightIn: this.effect_par.active = true; this.effect_par.x = 1000; cc.tween(this.effect_par) .to(0.3, { x: 0 }, cc.easeOut(3)) .start() break; case EffectType.bottomIn: this.effect_par.active = true; this.effect_par.x = 0; this.effect_par.y = this.effect_par.y - cc.winSize.height; //let toY = this.effect_par.y + this.effect_par.height; let toY = 0; cc.tween(this.effect_par) .by(0.15, { y: cc.winSize.height }, cc.easeOut(3)) .start() break; } } } /** * 关闭打开效果 * @param cb 结束回调 */ public hideEffect(cb?: Function) { if (!this.isOpenCloseEffect) return; if (this.effect_par) { if (this.close_uibg) { let graph = this.node.getComponentInChildren(cc.Graphics); if (graph) { graph.enabled = false; } } switch (this.close_effect) { case EffectType.none: cb && cb(); break; case EffectType.scale: mk.tween.scale(this.effect_par, 0.15, 1, 0, cb); break; case EffectType.scaleToPoint: if (this.close_toPoint == "") { console.error('需要配置缩小到终点节点路径') } else { let path = this.close_toPoint; let node = cc.find(path); if (node) { let world_pos = node.parent.convertToWorldSpaceAR(node.getPosition()); let node_pos = this.effect_par.parent.convertToNodeSpaceAR(world_pos); mk.tween.scaleParallelMove(this.effect_par, 0.3, 1, 0, node_pos, cb) // cc.tween(this.effect_par) // .to(0.3, { scale: 0, position: new cc.Vec3(node_pos.x, node_pos.y, 0) }) // .call(() => { // cb && cb(); // }) // .start() } else { cb && cb(); cc.error('关闭时动画节点未找到,请检查!!!!!') } } break; case EffectType.rightIn: mk.tween.move(this.effect_par, 0.3, this.effect_par.getPosition(), new cc.Vec2(1000, this.effect_par.y), () => { this.effect_par.active = false; cb && cb(); }, 'sineOut') // cc.tween(this.effect_par) // .to(0.3, { x: 1000 }, cc.easeOut(3)) // .call(() => { // this.effect_par.active = false; // cb && cb(); // }) // .start() break; case EffectType.bottomIn: let toY = -cc.winSize.height; cc.tween(this.effect_par) .to(0.4, { y: toY }, cc.easeSineOut()) .call(() => { // this.effect_par.active = false; cb && cb(); }) .start() break; } } else { cb && cb(); } } }