BaseExp.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import { _decorator, Button, Component, easing, EventHandler, EventTouch, js, Node, Tween, tween, UITransform, Vec2, Vec3 } from 'cc';
  2. import { Utils } from '../../utils/Utils';
  3. import { Logger } from '../../extend/Logger';
  4. import { uiMgr } from '../manager/UIManager';
  5. import { eventEmitter } from '../event/EventEmitter';
  6. import { initAutoBindings } from '../../extend/AutoBind';
  7. const { ccclass, property } = _decorator;
  8. @ccclass('BaseExp')
  9. export class BaseExp extends Component {
  10. //事件数组
  11. private events:any[] = [];
  12. //是否允许点击空白关闭页面,默认true
  13. public closeOnBlank: boolean = true;
  14. //是否有出场放大的动画 默认true
  15. private _hasAnim: boolean = true;
  16. public set hasAnim(value: boolean) {
  17. if(value){
  18. this.showAnim();
  19. }
  20. this._hasAnim = value;
  21. }
  22. private oScale: Vec3 = Vec3.ZERO;
  23. private uiBG: Node = null;
  24. public onLoad() {
  25. this.events = [];
  26. //加入按钮点击
  27. this._addClickEvent(this.node);
  28. //自动绑定属性
  29. initAutoBindings(this);
  30. //监听节点点击事件
  31. this.node.on(Node.EventType.TOUCH_END, this.onNodeTouchEnd, this);
  32. //背景视图
  33. this.uiBG = this.node.getChildByName("UI");
  34. if(this.uiBG){
  35. this.oScale = this.uiBG.scale.clone();
  36. }
  37. }
  38. /**
  39. * 展示加载缓动动画
  40. */
  41. public showAnim(){
  42. if(this.uiBG && this._hasAnim){
  43. Tween.stopAllByTarget(this.uiBG);
  44. this.uiBG.scale = new Vec3(0.95,0.95,0.95);
  45. let scale: Vec3 = this.oScale;
  46. tween(this.uiBG)
  47. .to(0.1, {scale: new Vec3(0.02 + scale.x,0.02 + scale.y,0.02 + scale.z)},{easing: easing.backOut})
  48. .to(0.1, {scale: new Vec3(scale.x - 0.02,scale.y - 0.02,scale.z - 0.02)},{easing: easing.backOut})
  49. .call(() => {
  50. this.uiBG.scale = this.oScale;
  51. }).start();
  52. }
  53. }
  54. /**
  55. * 节点触摸结束事件处理
  56. * @param event 触摸事件
  57. */
  58. private onNodeTouchEnd(event: EventTouch) {
  59. const uiBG = this.node.getChildByName("UI");
  60. if (!uiBG || !this.closeOnBlank)return;
  61. let trans: UITransform = this.node.getComponent(UITransform);
  62. const location = event.getUILocation();
  63. let pos = trans.convertToNodeSpaceAR(new Vec3(location.x,location.y));
  64. if(!uiBG.getComponent(UITransform).getBoundingBox().contains(new Vec2(pos.x,pos.y))){
  65. this.close();
  66. }
  67. }
  68. /**
  69. * 关闭页面
  70. * @param cb 关闭页面的回调
  71. */
  72. private close(cb?: Function){
  73. let pagePath: string = this.node["_uiPath"];
  74. if(!Utils.isNull(pagePath)){
  75. uiMgr.hide(pagePath,cb);
  76. }else{
  77. Logger.log(`请检查该: ${this.node.name}页面路径信息,不存在`);
  78. }
  79. }
  80. /**
  81. * 点击事件
  82. * @param event 事件
  83. * @param customEventData 数据
  84. */
  85. public onBtnClicked(event:EventTouch, customEventData:any) {
  86. let btnName = event.target.name;
  87. if(btnName === 'close_btn'){
  88. this.close();
  89. }
  90. }
  91. /**
  92. * 是否允许添加
  93. * @param node 添加的节点
  94. */
  95. private _isSkipNode(node: Node): boolean {
  96. if(this.node == node) {
  97. return false;
  98. }
  99. let b = node.getComponent(BaseExp);
  100. if (b) //Logger.log("跳过", b.name)
  101. return b != null;
  102. }
  103. /**
  104. * 加入点击事件
  105. * @param node 加入点击的节点
  106. */
  107. private _addClickEvent(node: Node) {
  108. if (this._isSkipNode(node)) return;
  109. for (let i = 0; i < node.children.length; i++) {
  110. let n:Node = node.children[i];
  111. if(this._isSkipNode(n)) continue;
  112. if(n.getComponent(Button)) {
  113. this.addClickEvent(n, this.node, js.getClassName(this), "onBtnClicked", n);
  114. }
  115. this._addClickEvent(n);
  116. }
  117. }
  118. /**
  119. * 加入按钮点击事件
  120. * @param node 点击的节点
  121. * @param target 点击的对象
  122. * @param component 组建的类名
  123. * @param handler 处理的具柄
  124. * @param customEventData 传递的数据
  125. */
  126. private addClickEvent(node, target, component, handler, customEventData) {
  127. let eventHandler = new EventHandler()
  128. eventHandler.target = target;
  129. eventHandler.component = component;
  130. eventHandler.handler = handler;
  131. if(customEventData){
  132. eventHandler.customEventData = customEventData;
  133. }
  134. let clickEvents = node.getComponent(Button).clickEvents;
  135. if (clickEvents.length > 0) {
  136. Logger.log(`${node.name}按钮已经存在绑定,跳过自动绑定`);
  137. return;
  138. }
  139. clickEvents.push(eventHandler);
  140. }
  141. //销毁的时候注销所有的事件
  142. public onDestroy() {
  143. for(let i = 0; i < this.events.length; i++){
  144. eventEmitter.unregister(this, this.events[i]);
  145. }
  146. }
  147. //注册事件
  148. public register(type: any, cb: Function) {
  149. this.events.push(type);
  150. eventEmitter.register(this, type, cb);
  151. }
  152. //取消注册的时间
  153. public unregister(type: any) {
  154. eventEmitter.unregister(this, type);
  155. }
  156. //事件派发
  157. public dispatch(type: any, ...data: any[]) {
  158. eventEmitter.dispatch(type, ...data);
  159. }
  160. }