使用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';

第二步:

确定换位逻辑

移动的图片跟每张图片的中心点比较,超过即表示用户有换位意图,如下判断语句:

if (other.index != imgIndex && other.center.x >= newLeft && other.center.x <= (newLeft + imgW) && other.center.y >= newTop && other.center.y <= (newTop + imgW))

判断好后,空出碰到的图片的那个位置,以及把空出位置那的图片往前或者往后一起移到手指带着的图片的位置,然后把移动的图片放在空出的位置上,这便完成了换位。

如下右移代码:

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;
		}
	}
}

第三步:

来写手指与屏幕的交互

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("拖拽");
		if (!timer) {
			timer = true;
            //防止一直执行
			setTimeout(() => {
			    timer = false;
			    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';
				tem.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)) {
						scope.changeIndex(item, other);//换位
						break;
					}
				}
			}, 100);
		}
	}

};

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();
})

 

p.s.实现上有些繁琐,现阶段想不到更好的写法,欢迎大家指点~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值