uni-image-menu.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. var nvMask, nvImageMenu;
  2. class NvImageMenu {
  3. constructor(arg) {
  4. this.isShow = false
  5. }
  6. show({
  7. list,
  8. cancelText
  9. }, callback) {
  10. if (!list) {
  11. list = [{
  12. "img": "/static/sharemenu/wechatfriend.png",
  13. "text": "图标文字"
  14. }]
  15. }
  16. //以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心
  17. var screenWidth = plus.screen.resolutionWidth
  18. //以360px宽度屏幕为例,上下左右边距及2排按钮边距留25像素,图标宽度55像素,同行图标间的间距在360宽的屏幕是30px,但需要动态计算,以此原则计算4列图标分别的left位置
  19. //图标下的按钮文字距离图标5像素,文字大小12像素
  20. //底部取消按钮高度固定为44px
  21. //TODO 未处理横屏和pad,这些情况6个图标应该一排即可
  22. var margin = 20,
  23. iconWidth = 60,
  24. icontextSpace = 5,
  25. textHeight = 12
  26. var left1 = margin / 360 * screenWidth
  27. var iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
  28. if (iconSpace <= 5) { //屏幕过窄时,缩小边距和图标大小,再算一次
  29. margin = 15
  30. iconWidth = 40
  31. left1 = margin / 360 * screenWidth
  32. iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
  33. }
  34. var left2 = left1 + iconWidth + iconSpace
  35. var left3 = left1 + (iconWidth + iconSpace) * 2
  36. var left4 = left1 + (iconWidth + iconSpace) * 3
  37. var top1 = left1
  38. var top2 = top1 + iconWidth + icontextSpace + textHeight + left1
  39. const TOP = {
  40. top1,
  41. top2
  42. },
  43. LEFT = {
  44. left1,
  45. left2,
  46. left3,
  47. left4
  48. };
  49. nvMask = new plus.nativeObj.View("nvMask", { //先创建遮罩层
  50. top: '0px',
  51. left: '0px',
  52. height: '100%',
  53. width: '100%',
  54. backgroundColor: 'rgba(0,0,0,0.2)'
  55. });
  56. nvImageMenu = new plus.nativeObj.View("nvImageMenu", { //创建底部图标菜单
  57. bottom: '0px',
  58. left: '0px',
  59. height: (iconWidth + textHeight + 2 * margin) * Math.ceil(list.length / 4) + 44 +
  60. 'px', //'264px',
  61. width: '100%',
  62. backgroundColor: 'rgb(255,255,255)'
  63. });
  64. nvMask.addEventListener("click", () => { //处理遮罩层点击
  65. // console.log('处理遮罩层点击');
  66. this.hide()
  67. callback({
  68. event: "clickMask"
  69. })
  70. })
  71. let myList = []
  72. list.forEach((item, i) => {
  73. myList.push({
  74. tag: 'img',
  75. src: item.img,
  76. position: {
  77. top: TOP['top' + (parseInt(i / 4) + 1)],
  78. left: LEFT['left' + (1 + i % 4)],
  79. width: iconWidth,
  80. height: iconWidth
  81. }
  82. })
  83. myList.push({
  84. tag: 'font',
  85. text: item.text,
  86. textStyles: {
  87. size: textHeight
  88. },
  89. position: {
  90. top: TOP['top' + (parseInt(i / 4) + 1)] + iconWidth + icontextSpace,
  91. left: LEFT['left' + (1 + i % 4)],
  92. width: iconWidth,
  93. height: textHeight
  94. }
  95. })
  96. })
  97. //绘制底部图标菜单的内容
  98. nvImageMenu.draw([{
  99. tag: 'rect', //菜单顶部的分割灰线
  100. color: '#e7e7e7',
  101. position: {
  102. top: '0px',
  103. height: '1px'
  104. }
  105. },
  106. {
  107. tag: 'font',
  108. text: cancelText, //底部取消按钮的文字
  109. textStyles: {
  110. size: '14px'
  111. },
  112. position: {
  113. bottom: '0px',
  114. height: '44px'
  115. }
  116. },
  117. {
  118. tag: 'rect', //底部取消按钮的顶部边线
  119. color: '#e7e7e7',
  120. position: {
  121. bottom: '45px',
  122. height: '1px'
  123. }
  124. },
  125. ...myList
  126. ])
  127. nvMask.show()
  128. nvImageMenu.show()
  129. // 开始动画
  130. /*
  131. plus.nativeObj.View.startAnimation({
  132. type: 'slide-in-bottom',
  133. duration: 300
  134. }, nvImageMenu, {}, function() {
  135. console.log('plus.nativeObj.View.startAnimation动画结束');
  136. // 关闭原生动画
  137. plus.nativeObj.View.clearAnimation();
  138. nvImageMenu.show()
  139. });
  140. */
  141. this.isShow = true
  142. nvImageMenu.addEventListener("click", e => { //处理底部图标菜单的点击事件,根据点击位置触发不同的逻辑
  143. // console.log("click menu"+JSON.stringify(e));
  144. if (e.screenY > plus.screen.resolutionHeight - 44) { //点击了底部取消按钮
  145. // callback({event:"clickCancelButton"})
  146. this.hide()
  147. } else if (e.clientX < 5 || e.clientX > screenWidth - 5 || e.clientY < 5) {
  148. //屏幕左右边缘5像素及菜单顶部5像素不处理点击
  149. } else { //点击了图标按钮
  150. var iClickIndex = -1 //点击的图标按钮序号,第一个图标按钮的index为0
  151. var iRow = e.clientY < (top2 - (left1 / 2)) ? 0 : 1
  152. var iCol = -1
  153. if (e.clientX < (left2 - (iconSpace / 2))) {
  154. iCol = 0
  155. } else if (e.clientX < (left3 - (iconSpace / 2))) {
  156. iCol = 1
  157. } else if (e.clientX < (left4 - (iconSpace / 2))) {
  158. iCol = 2
  159. } else {
  160. iCol = 3
  161. }
  162. if (iRow == 0) {
  163. iClickIndex = iCol
  164. } else {
  165. iClickIndex = iCol + 4
  166. }
  167. // console.log("点击按钮的序号: " + iClickIndex);
  168. // if (iClickIndex >= 0 && iClickIndex <= 5) { //处理具体的点击逻辑,此处也可以自行定义逻辑。如果增减了按钮,此处也需要跟着修改
  169. // }
  170. callback({
  171. event: "clickMenu",
  172. index: iClickIndex
  173. })
  174. }
  175. })
  176. /* nvImageMenu.addEventListener("touchstart", function(e) {
  177. if (e.screenY > (plus.screen.resolutionHeight - 44)) {
  178. //TODO 这里可以处理按下背景变灰的效果
  179. }
  180. })
  181. nvImageMenu.addEventListener("touchmove", function(e) {
  182. //TODO 这里可以处理按下背景变灰的效果
  183. if (e.screenY > plus.screen.resolutionHeight - 44) {}
  184. })
  185. nvImageMenu.addEventListener("touchend", function(e) {
  186. //TODO 这里可以处理释放背景恢复的效果
  187. })
  188. */
  189. }
  190. hide() {
  191. if (this.isShow) {
  192. nvMask.hide()
  193. nvImageMenu.hide()
  194. this.isShow = false
  195. }
  196. }
  197. }
  198. export default NvImageMenu