const { ccclass, property, executeInEditMode, playOnFocus } = cc._decorator; /** 效果类型 */ enum EffectType { none = 0, //无 scale = 1, //缩放 scaleToPoint = 2, //缩放到某点 centerUnfolding = 3, //从中部展开 } /** * 界面打开 和 关闭效果 * 组件请挂载到对应ui界面上 * @author 薛鸿潇 */ @ccclass @executeInEditMode() @playOnFocus() export default class UIOpenAndClose 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({ type: cc.Enum(EffectType), displayName: '关闭动画节点效果', visible() { return this.effect_par } }) private close_effect: EffectType = EffectType.scale; @property({ displayName: '关闭节点缩小到此节点坐标', visible() { return this.close_effect == EffectType.scaleToPoint } }) private close_toPoint: string = ""; 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; this.showEffect(); } /** * 界面打开效果 */ private showEffect() { if (this.effect_par) { switch (this.open_effect) { case EffectType.none: break; case EffectType.scale: this.effect_par.scale = 0; cc.tween(this.effect_par) .to(0.15, { scale: 1 }) .start() break; case EffectType.centerUnfolding: this.effect_par.scaleX = 0; cc.tween(this.effect_par) .to(0.15, { scaleX: 1 }) .start() break; } } } /** * 关闭打开效果 * @param cb 结束回调 */ public hideEffect(cb: Function = null) { if (this.effect_par) { switch (this.close_effect) { case EffectType.none: cb && cb(); break; case EffectType.scale: cc.tween(this.effect_par) .to(0.15, { scale: 0 }) .call(() => { cb && cb(); }) .start() 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); 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; } } else { cb && cb(); } } }