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日

悬赏问题

  • ¥15 微信小程序 用oss下载 aliyun-oss-sdk-6.18.0.min client报错
  • ¥15 ArcGIS批量裁剪
  • ¥15 labview程序设计
  • ¥15 为什么在配置Linux系统的时候执行脚本总是出现E: Failed to fetch http:L/cn.archive.ubuntu.com
  • ¥15 Cloudreve保存用户组存储空间大小时报错
  • ¥15 伪标签为什么不能作为弱监督语义分割的结果?
  • ¥15 编一个判断一个区间范围内的数字的个位数的立方和是否等于其本身的程序在输入第1组数据后卡住了(语言-c语言)
  • ¥15 游戏盾如何溯源服务器真实ip?
  • ¥15 Mac版Fiddler Everywhere4.0.1提示强制更新
  • ¥15 android 集成sentry上报时报错。