model.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. const { statusBarHeight } = uni.getSystemInfoSync();
  2. class NativeMsg {
  3. // 整个区域的宽高
  4. viewStyle = {
  5. backgroundColor: "rgba(255,255,255,0)",
  6. top: "0px",
  7. left: "0px",
  8. width: "100%",
  9. // 取图片的高度(带阴影的尺寸)
  10. height: `${uni.upx2px(239)}px`
  11. };
  12. constructor(item, cb) {
  13. // 记录内容信息,以供回调使用
  14. this.item = item;
  15. // 弹出、消失动画要用
  16. this.offsetTop = -statusBarHeight - uni.upx2px(159);
  17. // 上边界
  18. this.startTop = -statusBarHeight - uni.upx2px(159);
  19. // 下边界
  20. this.endTop = statusBarHeight;
  21. // 上滑关闭要用
  22. this.clientY = 0;
  23. // nativeObj.View 实例
  24. this.view = null;
  25. // 背景图片
  26. this.bgBitmap = null;
  27. // 回调函数
  28. this.cb = cb || null;
  29. // 隐藏过程flag,防止重复执行
  30. this.hiding = false;
  31. // 标记当前弹窗状态
  32. this.status = "active";
  33. this.create();
  34. }
  35. // 创建区域以及背景
  36. create() {
  37. this.loadBg().then(() => {
  38. let _view = null;
  39. // 创建 View区域
  40. _view = new plus.nativeObj.View(`alarmMsg-${this.item.alarmId || "ins"}`, this.viewStyle);
  41. // 画背景
  42. _view.drawBitmap(
  43. this.bitmap,
  44. {},
  45. { width: this.viewStyle.width, height: this.viewStyle.height, left: 0, top: 0 },
  46. "alarm-bg"
  47. );
  48. // 拦截触摸事件: 开启后 区域内的触摸事件不会透传到下面
  49. _view.interceptTouchEvent(true);
  50. // 增加点击事件监听
  51. _view.addEventListener("click", () => {
  52. if (this.hiding) return;
  53. this.hiding = true;
  54. this.cb && this.cb({ type: "click", result: this.item });
  55. this.animationHide();
  56. });
  57. // 触摸事件监听
  58. _view.addEventListener("touchstart", res => {
  59. this.clientY = res.clientY;
  60. });
  61. // 触摸事件监听
  62. _view.addEventListener("touchmove", res => {
  63. const { clientY } = res;
  64. let offsetY = this.clientY - clientY;
  65. if (offsetY > 25 && !this.hiding) {
  66. this.hiding = true;
  67. this.cb && this.cb({ type: "move", result: this.item });
  68. this.animationHide();
  69. }
  70. });
  71. // 保存
  72. this.view = _view;
  73. // 画内容
  74. this.drawInfo();
  75. // 显示
  76. this.animationShow();
  77. });
  78. }
  79. // 加载背景图片
  80. loadBg() {
  81. // 创建Bitmap图片
  82. this.bitmap = new plus.nativeObj.Bitmap("nativeMsg-bg");
  83. // 以Promise方式封装 图片加载过程
  84. return new Promise((resolve, reject) => {
  85. // 加载图片, 路径需要注意
  86. this.bitmap.load(
  87. "_www/static/tpt/alarm-bg.png",
  88. () => {
  89. resolve();
  90. },
  91. error => {
  92. console.log(" ====> error", error);
  93. reject();
  94. }
  95. );
  96. });
  97. }
  98. // 画内容
  99. drawInfo() {
  100. const { warningTypeStr, projectName, description } = this.item;
  101. this.view.draw([
  102. {
  103. tag: "font",
  104. id: "mainFont",
  105. text: warningTypeStr,
  106. textStyles: { size: `${uni.upx2px(36)}px`, color: "#262626", weight: "bold", align: "left" },
  107. position: { top: `${uni.upx2px(60)}px`, left: `${uni.upx2px(80)}px`, height: "wrap_content" }
  108. },
  109. {
  110. tag: "font",
  111. id: "projectFont",
  112. text: projectName,
  113. textStyles: { size: `${uni.upx2px(24)}px`, color: "#7B7B7B", align: "right", overflow: "ellipsis" },
  114. position: {
  115. top: `${uni.upx2px(60)}px`,
  116. left: `50%`,
  117. width: `${uni.upx2px(750 / 2 - 40 - 20)}px`,
  118. height: "wrap_content"
  119. }
  120. },
  121. {
  122. tag: "font",
  123. id: "infoFont",
  124. text: description,
  125. textStyles: { size: `${uni.upx2px(28)}px`, color: "#7B7B7B", align: "left", overflow: "ellipsis" },
  126. position: {
  127. top: `${uni.upx2px(117)}px`,
  128. left: `${uni.upx2px(80)}px`,
  129. width: `${uni.upx2px(670 - 40 - 10)}px`,
  130. height: "wrap_content"
  131. }
  132. }
  133. ]);
  134. }
  135. // 简易向下出现动画
  136. animationShow() {
  137. this.view.show();
  138. this.view.setStyle({
  139. ...this.viewStyle,
  140. top: `${this.offsetTop++}px`
  141. });
  142. if (this.offsetTop >= this.endTop) {
  143. this.status = "active";
  144. return;
  145. }
  146. setTimeout(() => {
  147. this.animationShow();
  148. }, 0);
  149. }
  150. // 简易向上消失动画
  151. animationHide() {
  152. this.view.setStyle({
  153. ...this.viewStyle,
  154. top: `${this.offsetTop--}px`
  155. });
  156. if (this.offsetTop <= this.startTop) {
  157. this.view.close();
  158. this.hiding = false;
  159. this.status = "close";
  160. return;
  161. }
  162. setTimeout(() => {
  163. this.animationHide();
  164. }, 0);
  165. }
  166. // 获取当前状态
  167. getStatus() {
  168. return this.status;
  169. }
  170. // 不用动画,直接消失
  171. hide() {
  172. this.view.hide();
  173. this.view.close();
  174. }
  175. }
  176. // 对外暴露一个创建实例的方法
  177. export function createAlarm(item, cb) {
  178. return new NativeMsg(item, cb);
  179. }