uni-image-menu.js 5.7 KB
Newer Older
雪洛's avatar
雪洛 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
var nvMask, nvImageMenu;
class NvImageMenu {
	constructor(arg) {
		this.isShow = false
	}
	show({
		list,
		cancelText
	}, callback) {
		if (!list) {
			list = [{
				"img": "/static/sharemenu/wechatfriend.png",
				"text": "图标文字"
			}]
		}
		//以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心
		var screenWidth = plus.screen.resolutionWidth
		//以360px宽度屏幕为例,上下左右边距及2排按钮边距留25像素,图标宽度55像素,同行图标间的间距在360宽的屏幕是30px,但需要动态计算,以此原则计算4列图标分别的left位置
		//图标下的按钮文字距离图标5像素,文字大小12像素
		//底部取消按钮高度固定为44px
		//TODO 未处理横屏和pad,这些情况6个图标应该一排即可
		var margin = 20,
			iconWidth = 60,
			icontextSpace = 5,
			textHeight = 12
		var left1 = margin / 360 * screenWidth
		var iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
		if (iconSpace <= 5) { //屏幕过窄时,缩小边距和图标大小,再算一次
			margin = 15
			iconWidth = 40
			left1 = margin / 360 * screenWidth
			iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
		}
		var left2 = left1 + iconWidth + iconSpace
		var left3 = left1 + (iconWidth + iconSpace) * 2
		var left4 = left1 + (iconWidth + iconSpace) * 3
		var top1 = left1
		var top2 = top1 + iconWidth + icontextSpace + textHeight + left1

		const TOP = {
				top1,
				top2
			},
			LEFT = {
				left1,
				left2,
				left3,
				left4
			};

		nvMask = new plus.nativeObj.View("nvMask", { //先创建遮罩层
			top: '0px',
			left: '0px',
			height: '100%',
			width: '100%',
			backgroundColor: 'rgba(0,0,0,0.2)'
		});
		nvImageMenu = new plus.nativeObj.View("nvImageMenu", { //创建底部图标菜单
			bottom: '0px',
			left: '0px',
			height: (iconWidth + textHeight + 2 * margin) * Math.ceil(list.length / 4) + 44 +
			'px', //'264px',
			width: '100%',
			backgroundColor: 'rgb(255,255,255)'
		});
		nvMask.addEventListener("click", () => { //处理遮罩层点击
			// console.log('处理遮罩层点击');
			this.hide()
			callback({
				event: "clickMask"
			})
		})
		let myList = []
		list.forEach((item, i) => {
			myList.push({
				tag: 'img',
				src: item.img,
				position: {
					top: TOP['top' + (parseInt(i / 4) + 1)],
					left: LEFT['left' + (1 + i % 4)],
					width: iconWidth,
					height: iconWidth
				}
			})
			myList.push({
				tag: 'font',
				text: item.text,
				textStyles: {
					size: textHeight
				},
				position: {
					top: TOP['top' + (parseInt(i / 4) + 1)] + iconWidth + icontextSpace,
					left: LEFT['left' + (1 + i % 4)],
					width: iconWidth,
					height: textHeight
				}
			})
		})

		//绘制底部图标菜单的内容
		nvImageMenu.draw([{
				tag: 'rect', //菜单顶部的分割灰线
				color: '#e7e7e7',
				position: {
					top: '0px',
					height: '1px'
				}
			},
			{
				tag: 'font',
				text: cancelText, //底部取消按钮的文字
				textStyles: {
					size: '14px'
				},
				position: {
					bottom: '0px',
					height: '44px'
				}
			},
			{
				tag: 'rect', //底部取消按钮的顶部边线
				color: '#e7e7e7',
				position: {
					bottom: '45px',
					height: '1px'
				}
			},
			...myList
		])
		nvMask.show()
		nvImageMenu.show()
		// 开始动画
		/*
			plus.nativeObj.View.startAnimation({
				type: 'slide-in-bottom',
				duration: 300
			}, nvImageMenu, {}, function() {
				console.log('plus.nativeObj.View.startAnimation动画结束');
				// 关闭原生动画
				plus.nativeObj.View.clearAnimation();
				nvImageMenu.show()
			});
		*/


		this.isShow = true
		nvImageMenu.addEventListener("click", e => { //处理底部图标菜单的点击事件,根据点击位置触发不同的逻辑
			// console.log("click menu"+JSON.stringify(e));
			if (e.screenY > plus.screen.resolutionHeight - 44) { //点击了底部取消按钮
				// callback({event:"clickCancelButton"})
				this.hide()
			} else if (e.clientX < 5 || e.clientX > screenWidth - 5 || e.clientY < 5) {
				//屏幕左右边缘5像素及菜单顶部5像素不处理点击
			} else { //点击了图标按钮
				var iClickIndex = -1 //点击的图标按钮序号,第一个图标按钮的index为0
				var iRow = e.clientY < (top2 - (left1 / 2)) ? 0 : 1
				var iCol = -1
				if (e.clientX < (left2 - (iconSpace / 2))) {
					iCol = 0
				} else if (e.clientX < (left3 - (iconSpace / 2))) {
					iCol = 1
				} else if (e.clientX < (left4 - (iconSpace / 2))) {
					iCol = 2
				} else {
					iCol = 3
				}
				if (iRow == 0) {
					iClickIndex = iCol
				} else {
					iClickIndex = iCol + 4
				}
				// console.log("点击按钮的序号: " + iClickIndex);
				// if (iClickIndex >= 0 && iClickIndex <= 5) { //处理具体的点击逻辑,此处也可以自行定义逻辑。如果增减了按钮,此处也需要跟着修改
				// }
				callback({
					event: "clickMenu",
					index: iClickIndex
				})
			}
		})
		/* nvImageMenu.addEventListener("touchstart", function(e) {
			if (e.screenY > (plus.screen.resolutionHeight - 44)) {
				//TODO 这里可以处理按下背景变灰的效果
			}
		})
		nvImageMenu.addEventListener("touchmove", function(e) {
			//TODO 这里可以处理按下背景变灰的效果
			if (e.screenY > plus.screen.resolutionHeight - 44) {}
		})
		nvImageMenu.addEventListener("touchend", function(e) {
			//TODO 这里可以处理释放背景恢复的效果
		})
		*/
	}

	hide() {
		nvMask.hide()
		nvImageMenu.hide()
		this.isShow = false
	}
}

export default NvImageMenu