如何解决transformorigin变化导致图片位移的问题?

zzzl124 2023-04-01 17:10:44
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport"
			content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<title></title>
		<script src="js/mui.min.js"></script>
		<link href="css/mui.min.css" rel="stylesheet" />
		<script type="text/javascript" charset="utf-8">
			mui.init();
		</script>
		<style>
			#image{
				will-change: transform;

			}
		</style>
	</head>
	<body>
		<div style="height: 300px;">
		</div>
		<div id="container" style="align-items: center;">
			<img id="image" style="border: 1px solid red;width: 100%;" 
				src="https://www.akailibrary.com/wp-content/uploads/2020/05/1589443043-3784896.jpg" alt="">
		</div>
	</body>  
	<style>
		#image{
			translate: 0;
		}
	</style>
	<script>
		var isTouch = false; //点击
		var isDoubleTouch = false; //是否为多触点   
		var start = []; //存放触点坐标
		var timer = null;
		var now, delta; //当前时间,两次触发事件时间差
		var startPosition, movePosition, endPosition; //滑动起点,移动,结束点坐标
		//事件声明
		var gesturestart = new CustomEvent('gesturestart');
		var gesturechange = new CustomEvent('gesturechange');
		var gestureend = new CustomEvent('gestureend');
		var swipeMove = new CustomEvent('swipeMove');
		var doubleTouch = new CustomEvent("doubleTouch");
		var doubleTouchReduce = new CustomEvent("doubleTouchReduce");
		let dbcl = 1;//设置双击退出和进入的
		let slsc;//设置滑动放大时的位置
		let trso;//放大起源
		let sc;
		var store = {
			scale: 1
		}; 
		var image = document.getElementById('image');
		//监听touchstart事件
		image.addEventListener('touchstart', function(e) {
			if (e.touches.length >= 2) { //判断是否有两个点在屏幕上
				console.log('两个点在屏幕上');
				isDoubleTouch = true;
				start = e.touches; //得到第一组两个点  闹钟电脑 126... 83...
				console.log('tMatrix[0]',parseFloat(tMatrix[0]));
				
				//  if(tMatrix[0]>1){  
				// 		let rect = image.getBoundingClientRect();
				// 		let left = -rect.left;
				// 		let top = rect.top;
				// 		//第1个点x总长
				// 		let fzcx = e.touches[0].pageX + left;
				// 		//第1个点x相对缩小
				// 		let fxdsx = fzcx/tMatrix[0].toFixed(2)
				// 		console.log('一样的大小',fxdsx);
				// 		//第2个点x总长
				// 		let szcx = e.touches[1].pageX + left;
				// 		//第2个点x相对缩小
				// 		let sxdsx = szcx/tMatrix[0].toFixed(2)
				// 		console.log('一样的大小',sxdsx);
				// 		let top1;
				// 		let fzcy;
				// 		let fxdsy;
				// 		let szcy;
				// 		let sxdsy;
				// 		if(top<0){ 
				// 			 top1 = -top;
				// 			 fzcy = e.touches[0].pageY + top1;
				// 			 fxdsy = fzcy/tMatrix[3].toFixed(2)
				// 			 szcy = e.touches[1].pageY + top1;
				// 			 sxdsy = szcy/tMatrix[3].toFixed(2)
				// 		}else{
				// 			 fzcy = e.touches[0].pageY - top;
				// 			 fxdsy = fzcy/tMatrix[3].toFixed(2)
				// 			 szcy = e.touches[1].pageY - top;
				// 			 sxdsy = szcy/tMatrix[3].toFixed(2)
				// 		} 
				// 		var screenMinPoint1 = getMidpoint1(fxdsx,fxdsy,sxdsx,sxdsy); //获取两个触点中心坐标
				// 		console.log('放大一次后的放大中点',screenMinPoint1)
				// 		gesturestart.midPoint = screenMinPoint1;
				// 		e.target.dispatchEvent(gesturestart);  
				// }else{
					 
					var screenMinPoint = getMidpoint(start[0], start[1]); //获取两个触点中心坐标
					let dycfdzd = [screenMinPoint[0] - e.target.offsetLeft, screenMinPoint[1] - e.target.offsetTop]
					console.log('第一次放大的中点',dycfdzd);
					gesturestart.midPoint = [screenMinPoint[0] - e.target.offsetLeft, screenMinPoint[1] - e.target.offsetTop]; //获取中心点坐标相对目标元素坐标
					e.target.dispatchEvent(gesturestart);  
					
					
				// }
			} else {
				// console.log('一个点在屏幕上');
				delta = Date.now() - now; //计算两次点击时间差
				// console.log('时间差',delta);
				now = Date.now(); 
				startPosition = [e.touches[0].pageX, e.touches[0].pageY]; //点击位置距离屏幕左侧距离,点击位置距离屏幕顶部距离
				// console.log('当前点击的在页面中的位置:',startPosition); 
				// console.log('点击的位置',startPosition[0]);
				
				// let rect = image.getBoundingClientRect();
				// let left = -rect.left;
				// console.log('left',left);
				// if(tMatrix[0]>1){
				// 		let wd = (left + e.touches[0].pageX)/tMatrix[0]; 
				// 		console.log('wd',wd)
						
				// }
			
				
			
						
				
				if (dbcl == 1) {
					if (delta > 0 && delta <= 250) { //双击事件
						// console.log('双击事件放大'); 
						//           clearTimeout(timer);
						doubleTouch.position = [e.touches[0].pageX - e.target.offsetLeft, e.touches[0].pageY - e
							.target.offsetTop
						];
						// console.log('点击位置距离当前所在盒子的距离',doubleTouch.position);
						e.target.dispatchEvent(doubleTouch);
						dbcl = 2;
					} else {
						// console.log('单击退出事件'); 
						// alert('11')
						//                 timer = setTimeout(function(){ //单击事件
						//             e.target.dispatchEvent(oneTouch);
						//          })
					}

				} else {

					if (delta > 0 && delta <= 250) { //双击事件
						// console.log('双击事件缩小');
						clearTimeout(timer);
						doubleTouch.position = [e.touches[0].pageX - e.target.offsetLeft, e.touches[0].pageY - e.target.offsetTop];
						// console.log('点击位置距离当前所在盒子的距离',doubleTouch.position);
						e.target.dispatchEvent(doubleTouchReduce);
						dbcl = 1;
					} else { //滑动事件
						//                 timer = setTimeout(function(){ //单击事件
						//             e.target.dispatchEvent(oneTouch);
						//          })
					}
				}
				isTouch = true;
			}
		}, false);




		//监听touchmove事件
		image.addEventListener('touchmove', function(e) {
			console.log('进入缩放');
			clearTimeout(timer);
			if (e.touches.length >= 2 && isDoubleTouch) { //手势事件
				console.log('缩放');
				var now = e.touches; //得到第二组两个点
				// console.log('now',now); 
				var scale = getDistance(now[0], now[1]) / getDistance(start[0], start[1]); //得到缩放比例
				// console.log('scale缩放比例', scale);
				// var rotation = getAngle(now[0], now[1]) - getAngle(start[0], start[1]); //得到旋转角度差
				gesturechange.scale = scale.toFixed(2);
				// gesturechange.rotation = rotation.toFixed(2);
				
				e.target.dispatchEvent(gesturechange);
			} else if (isTouch) {
				// movePosition = [e.touches[0].pageX, e.touches[0].pageY];
				// endPosition = movePosition;
				// movePosition = [movePosition[0] - startPosition[0], movePosition[1] - startPosition[1]];
				// startPosition = [e.touches[0].pageX, e.touches[0].pageY];
				// swipeMove.distance =[movePosition[0].toFixed(2) , movePosition[1].toFixed(2)];
				// e.target.dispatchEvent(swipeMove);
			}
		}, false);



		/* 两点的距离 */
		function getDistance(p1, p2) {
			var x = p2.pageX - p1.pageX,
				y = p2.pageY - p1.pageY;
			return Math.sqrt((x * x) + (y * y));
		};
		/* 获取中点 */
		function getMidpoint(p1, p2) {
			var x = (p1.pageX + p2.pageX) / 2,
				y = (p1.pageY + p2.pageY) / 2;
			return [x, y];
		}
		/* 获取中点2 */
		function getMidpoint1(x1,y1,x2,y2) {
			var x = (x1 + x2) / 2,
				y = (y1 + y2) / 2;
			return [x, y];
		}










		image.addEventListener('doubleTouch', gesture, false);
		image.addEventListener('doubleTouchReduce', gesture, false);
		image.addEventListener('gesturestart', gesture, false);
		image.addEventListener('gesturechange', gesture, false);
		var tMatrix = [1, 0, 0, 1, 0, 0]; //x缩放,无,无,y缩放,x平移,y平移

		function gesture(event) {
			switch (event.type) {
				case "doubleTouch":
					originLast = event.position;
					// console.log('点击位置距离当前所在盒子的距离',originLast);
					//transformOrigin变形原点,该属性只有在设置了transform属性的时候起作用
					image.style.transformOrigin = event.position[0] + "px " + event.position[1] + "px";
					console.log('进入双击',image.style.transformOrigin)
					tMatrix[0] = 4;
					tMatrix[3] = 4;
					//把数组分隔成字符串
					var temp = tMatrix.join(",");
					// console.log('temp',temp);
					//设置缩放或者3旋转啥的
					image.style.transform = "matrix(" + temp + ")";
					// console.log('image.style.transform',image.style.transform);
					// maxMove(); 
					break;
				case "doubleTouchReduce":
					// console.log('进入缩小');
					tMatrix[0] = 1;
					tMatrix[3] = 1;
					var temp = tMatrix.join(",");
					image.style.transform = "matrix(" + temp + ")";
					break;
					//监听 gesturestart 设置 变换中心	
				case "gesturestart":
					originLast = event.midPoint; 
					// console.log('originLast',originLast);
					 
					image.style.transformOrigin  = event.midPoint[0] + "px " + event.midPoint[1] + "px";
					image.style.translate = event.midPoint[0] + "px " + event.midPoint[1] + "px";
					// image.style.translate =  event.midPoint[0].toFixed(2) + "px " + event.midPoint[1].toFixed(2) + "px";
					// image.style.transformOrigin = 222.182 + "px " + 131.818 + "px";
					console.log('进入双击2',image.style.transformOrigin,image.style.translate);
					
					break; 
				case "gesturechange":  
					sc = parseFloat(event.scale);
					// image.style.transformOrigin = trso;
					if ( sc > 0.6) {
						tMatrix[0] = tMatrix[0] + sc - 1 > 1 && tMatrix[0] + sc - 1 < 10 ? tMatrix[0] + sc - 1 : tMatrix[0];
						// console.log('tMatrix[0]', tMatrix[0])
						tMatrix[3] = tMatrix[3] + sc - 1 > 1 && tMatrix[3] + sc - 1 < 10 ? tMatrix[3] + sc - 1 : tMatrix[3];
						// console.log('tMatrix[3]', tMatrix[3])
						var temp = tMatrix.join(",");  
						// console.log('temp',temp);
						image.style.transform = "matrix(" + temp + ")";
						console.log('image.style.transform',image.style.transform) 
						console.log('情况',tMatrix[0].toFixed(2) )
						image.style.transition = "transform 0.1s linear";
						slsc = 1; 
						// console.log('image.style.transformOrigin',image.style.transformOrigin);
					} else {
						tMatrix[0] = 1;
						console.log('tMatrix[0]', tMatrix[0])
						tMatrix[3] = 1;
						console.log('tMatrix[3]', tMatrix[3])
						var temp = tMatrix.join(",");
						image.style.transform = "matrix(" + temp + ")";
						image.style.transition = "transform 0.1s linear";
						
						// console.log('image.style.transformOrigin',image.style.transformOrigin);
					}
					dbcl = 2;
					break;
				
			}
		}

	</script>


</html>

 

...全文
370 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

109

社区成员

发帖
与我相关
我的任务
社区描述
Crypto Startup School 创投研习社 by 校园VC
前端css 高校
社区管理员
  • jiansongy
  • land_world
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧