zzzl124 2023-04-01 17:01 采纳率: 0%
浏览 8

关于#双指缩放,图片偏移#的问题,如何解决?

原生js操作图片缩放,但是transformorigin变化时图片会发生位移,所有代码如下,麻烦指点

<!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>

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-04-02 03:21
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 4月1日

悬赏问题

  • ¥20 有偿:在ubuntu上安装arduino以及其常用库文件。
  • ¥15 请问用arcgis处理一些数据和图形,通常里面有一个根据点划泰森多边形的命令,直接划的弊端是只能执行一个完整的边界,但是我们有时候会用到需要在有很多边界内利用点来执行划泰森多边形的命令
  • ¥30 在wave2foam中执行setWaveField时遇到了如下的浮点异常问题,请问该如何解决呢?
  • ¥20 看图片)删除这个自动化录屏脚本就一直报错找不到脚本文件,如何解决?(相关搜索:bat文件)
  • ¥750 关于一道数论方面的问题,求解答!(关键词-数学方法)
  • ¥200 csgo2的viewmatrix值是否还有别的获取方式
  • ¥15 Stable Diffusion,用Ebsynth utility在视频选帧图重绘,第一步报错,蒙版和帧图没法生成,怎么处理啊
  • ¥15 请把下列每一行代码完整地读懂并注释出来
  • ¥15 pycharm运行main文件,显示没有conda环境
  • ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件