使用ionic实现仿微信发朋友圈图片移动换位效果

使用ionic实现仿微信发朋友圈图片移动换位效果

<move-imgs con-wid=65 max-num=6 imgs-date="record.picture"></move-imgs>

restrict: 'E',
template: '<ul class="upload-imgs-con">' +
	'<li ng-style="upImg.showImg" ng-repeat="upImg in imgsDate" class="upload-imgs-base bgImg-center" ng-class="upImg.isAnimation?' + "''" + ':' + "'upload-imgs-animation'" + '" on-hold="onHold($event, upImg)" on-drag="onDrag($event, upImg)" on-release="onRelease($event, upImg)">' +
	'<i class="icon ion-ios-close-empty upload-imgs-delete" ng-click="deleteImg($event, $index, upImg)"></i></li>' +
	'<li class="upload-imgs-ico" style="left:{{uploadImgsIco.left}}px;top:{{uploadImgsIco.top}}px" ng-show="imgsDate.length<maxNum"><input class="hide-inputfile" type="file" imgs-date="imgsDate" file-model="post.myFile" accept="image/*" /></li>' +
	'</ul>',
replace: true,
scope: {
	conWid: '@',
	maxNum: '@',
	imgsDate: '='
},

第一步:

先把图片位置摆好

我是通过行列数来定位图片的具体位置

var imgW = 78,
	imgL = 9;
var imgRW = imgW + imgL;
scope.conWid = (document.body.offsetWidth) - Number(scope.conWid); //获得放图片的容器的宽度
var maxNum = Math.floor((scope.conWid + imgL) / imgRW); //一行最多能排的图片数量
for (var i = 0; i < scope.imgsDate.length; i++) {
	var item = scope.imgsDate[i];
	var h = Math.floor(i / maxNum); //行
	var l = i % maxNum; //列
	item.showImg = {
		'background-image': 'url(' + item.src + ')',
		'left': l * imgRW + 'px',
		'top': h * imgRW + 'px'
	};
	item.initPos = {
		left: l * imgRW,
		top: h * imgRW
	};
	item.center = {
		x: l * imgRW + imgW / 2,
		y: h * imgRW + imgW / 2
	};
	item.index = i;
}
//上传图片按钮的位置
scope.uploadImgsIco = {};
scope.uploadImgsIco.left = i % maxNum * imgRW;
scope.uploadImgsIco.top = Math.floor(i / maxNum) * imgRW;
element[0].style.height = Math.ceil(Number(scope.maxNum) / maxNum) * imgRW + 'px';

第二步:

确定换位逻辑

手指带着的图片碰到另外的图片时,空出碰到的图片的那个位置,以及把空出位置那的图片往前或者往后一起移到手指带着的图片的位置,这便完成了换位。

代码写在第三步的拖拽方法中

第三步:

来写手指与屏幕的交互

a.按压

按压的时候让图片放大,并锁住页面

scope.onHold = function ($event, item) {
	$event.preventDefault();
	if (scope.imgsDate.length === 1) {
		return;
	}
	$ionicScrollDelegate.freezeAllScrolls(true); //禁止页面滚动
	var moveX = $event.gesture.center.pageX;
	var moveY = $event.gesture.center.pageY;
	item.isAnimation = true;
	imgIndex = item.index;
	touchStartX = moveX;
	touchStartY = moveY;
	item.showImg.width = item.showImg.height = imgW + 4 + 'px';
	objStartX = item.initPos.left - 2;
	objStartY = item.initPos.top - 2;
	item.showImg.left = objStartX + 'px';
	item.showImg.top = objStartY + 'px';
	item.showImg["z-index"] = 9999;
	startDray = true;
};

b.拖拽

让图片跟着手指移动,并实现换位逻辑

scope.onDrag = function ($event, item) {
	if (startDray) {
		//console.log("拖拽");
		var moveX = $event.gesture.center.pageX;
		var moveY = $event.gesture.center.pageY;
		var newLeft = objStartX + (moveX - touchStartX);
		var newTop = objStartY + (moveY - touchStartY);
		item.showImg.left = newLeft + 'px';
		item.showImg.top = newTop + 'px';
		//console.log('onDrag:'+newLeft+','+newTop);
		//t = null;
		//判断是否移动到其他图片的上面
		for (var i = 0; i < scope.imgsDate.length; i++) {
			var other = scope.imgsDate[i];
			//找到移到到哪张图片上面
			if (other.index != imgIndex && other.center.x >= newLeft && other.center.x <= (newLeft + imgW) && other.center.y >= newTop && other.center.y <= (newTop + imgW)) {
                //小于右移,大于左移
				if (other.index < imgIndex) {
					for (var j = imgIndex - 1; j >= other.index; j--) {
						for (var k = 0; k < scope.imgsDate.length; k++) {
							if (scope.imgsDate[k].index === j) {
								var moveImg = scope.imgsDate[k];
								moveImg.showImg.left = item.initPos.left + 'px';
								moveImg.showImg.top = item.initPos.top + 'px';
								//交互位置代码
								var jx2 = moveImg.initPos;
								moveImg.initPos = item.initPos;
								item.initPos = jx2;

								jx2 = moveImg.center
								moveImg.center = item.center;
								item.center = jx2;

								moveImg.index = moveImg.index + item.index;
								item.index = moveImg.index - item.index;
								moveImg.index = moveImg.index - item.index;
								//console.log("从"+item.index+"移动到"+moveImg.index);
								break;
							}
						}
					}
				} else {
					for (var j = imgIndex + 1; j <= other.index; j++) {
						for (var k = 0; k < scope.imgsDate.length; k++) {
							if (scope.imgsDate[k].index === j) {
								var moveImg = scope.imgsDate[k];
								moveImg.showImg.left = item.initPos.left + 'px';
								moveImg.showImg.top = item.initPos.top + 'px';
								//交互位置代码
								var jx2 = moveImg.initPos;
								moveImg.initPos = item.initPos;
								item.initPos = jx2;

								jx2 = moveImg.center
								moveImg.center = item.center;
								item.center = jx2;

								moveImg.index = moveImg.index + item.index;
								item.index = moveImg.index - item.index;
								moveImg.index = moveImg.index - item.index;
								//console.log("从"+item.index+"移动到"+moveImg.index);
								break;
							}
						}

					}
				}
				imgIndex = item.index;
				break;

			}
		}
	}

};

c.释放

归位手指上的图片

scope.onRelease = function ($event, item) {
	if (startDray) {
		$ionicScrollDelegate.freezeAllScrolls(false);
		startDray = false;
		
		item.isAnimation = false;
		item.showImg = {
			'left': item.initPos.left + 'px',
			'top': item.initPos.top + 'px',
			'background-image': item.showImg["background-image"]
		};
	}

};

第四步:

删除图片,删除时也调用一次移位

 

注意点:

//移动图片时防止微信露底
document.body.ontouchmove = function (e) {
	if (startDray) {
		e.preventDefault();
	}
};
//阻止长按默认行为,比如微信长按图片弹出菜单
element.bind('contextmenu', function (e) {
	e.preventDefault();
})

欢迎大家一起探讨更优的写法~~