DIY - 使用Javascript轻松缩放移动设备

时间:2018-06-18 01:27:00

标签: javascript mobile pinchzoom

在我的项目中,我遇到了需要缩放缩放支持,但不是基本支持。

并且有两个主要的"必须有"这样做。

1)只有DIV容器会缩放,而不是页面的其余部分(例如:顶栏) 2)我需要保持窗口基本滚动

我添加了一个简单的代码,说明我是如何做到的,这给我留下了2个问题

I)当我捏缩放时页面很跳跃。 II)我有正确的计算吗?或者我应该采取另一种方式?

*您可以在下面的链接中找到一个有效的示例

https://www.klika.co.il/canvas/pinch.html



        // ----------- TOUCH -------------- 

        //handles on move events for tracking touches
       

        var touches = {
            points: null,

            start: function (e) {
                if (gesture.is.on) {
                    e = e || window.event;
                    if (e.preventDefault)
                        e.preventDefault();
                    e.returnValue = false;
                }
                //reset touches
                touches.points = null;
                msg('touch start');
            },

            move: function (e) {
               // msg('touch move');

                if (e.touches.length > 1) {
                   // msg('touch move ' + e.touches.length + ' fingers');

                    //set touches only if two fingers are on
                    touches.points = { x: {}, y: {} }
                    for (var i = 0; i < e.touches.length; i++) {
                        touches.points.x[i] = e.touches[i].clientX;
                        touches.points.y[i] = e.touches[i].clientY;
                    }
                }
            },

            end: function (e) {
                msg('touch end');
            }
        };


        // ----------- GESTURE -------------- 


        var gesture = {
            is: {
                on: false,
                init: false
            },

            data: {
                content: null,
                elem: null,
                width: 0,
                state: {},
            },

            start: function (e) {
                gesture.is.on = true;
                msg('gesture start');

                gesture.data.content = $('.containter')[0];
                gesture.data.elem = $('.containter .wrap')[0];

                gesture.data.width = toFloat(gesture.data.elem.style.width, 100);

                gesture.is.init = true;
            },

            move: function (e) {
                if (!touches.points) { return; }

                //set the body element for Y axis
                const el = document.scrollingElement || document.documentElement;

                //set mid points
                var X1 = touches.points.x[0];
                var Y1 = touches.points.y[0];

                var X2 = touches.points.x[1];
                var Y2 = touches.points.y[1];

                var mid = getMidPoint(X1, Y1, X2, Y2);

                //set start position on init
                if (gesture.is.init) {

                    gesture.data.state = {
                        w: gesture.data.width / 100,
                        sl: ((gesture.data.content.scrollLeft + mid.x) / gesture.data.content.scrollWidth) * 100,
                        st: ((el.scrollTop + mid.y) / el.scrollHeight) * 100,
                        mid: mid
                    }

                    gesture.is.init = false;
                }


                //calc/set width of the wrapping DIV
                var inc = e.scale * gesture.data.state.w;

                var WPX = gesture.data.content.scrollWidth * inc;
                var HPX = document.body.scrollHeight * inc;

                var w = (WPX / gesture.data.content.scrollWidth) * 100;

                gesture.data.elem.style.width = w + '%';


                //calc/set scrollLeft of the wrapping DIV (X axis)
                var sln = Math.round(((gesture.data.state.sl / 100) * gesture.data.content.scrollWidth) - (getWindowXY().w / 2));
                if (sln < 0) { sln = 0; }
                sln += gesture.data.state.mid.x - mid.x;

                gesture.data.content.scrollLeft = sln;


                //calc/set scrollLeft of the body element (Y axis)
                var slt = Math.round(((gesture.data.state.st / 100) * el.scrollHeight) - (getWindowXY().h / 2));
                if (slt < 0) { slt = 0; }
                slt += gesture.data.state.mid.y - mid.y;

                el.scrollTop = slt;
            },

            end: function (e) {

                var w = toFloat(gesture.data.elem.style.width);

                if (isNaN(w) || w < 100) {
                    gesture.data.elem.style.width = '100%';
                }

                gesture.is.on = false;
            }
        }


        // -------- BIND ------

        window.addEventListener('touchstart', touches.start, false);
        window.addEventListener('touchmove', touches.move, true);
        window.addEventListener('touchend', touches.end, true);

        window.addEventListener('gesturestart', gesture.start, false);
        window.addEventListener('gesturechange', gesture.move, false);
        window.addEventListener('gestureend', gesture.end, false);


        //------ GENERAL --------

        String.prototype.format = function () {
            var s = this,
                i = arguments.length;

            if (!s) {
                return "";
            }

            while (i--) {
                s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
            }
            return s;
        }

        var toFloat = function (val) {
            return parseFloat(val.replace("%", ""));
        }

        var getWindowXY = function () {
            var myWidth = 0, myHeight = 0;
            if (typeof (window.innerWidth) == 'number') {
                //Non-IE
                myWidth = window.innerWidth;
                myHeight = window.innerHeight;
            } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
                //IE 6+ in 'standards compliant mode'
                myWidth = document.documentElement.clientWidth;
                myHeight = document.documentElement.clientHeight;
            } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
                //IE 4 compatible
                myWidth = document.body.clientWidth;
                myHeight = document.body.clientHeight;
            }
            return {
                h: myHeight,
                w: myWidth
            }
        }

        var msg = function (text) {
            $('.info').html(text);
        }

        var getMidPoint = function (x1, y1, x2, y2) {
            return { x: ((x1 + x2) / 2), y: ((y1 + y2) / 2) }
        }

        window.oncontextmenu = function (event) {
            event.preventDefault();
            event.stopPropagation();
            return false;
        };

        window.addEventListener('error', function (e) {
            if (e.message == "Script error.") { return; }
            if (e.message.indexOf('facebook') != -1) { return; }

            msg(e.message);
        }, false);

    
&#13;
   body {
            margin: 0;
            padding: 0;
            width:100vw;
        }

        .top{
            position: fixed;
            width: 100%;
            background-color: #333;
            line-height: 40pt;
            text-align: center;
            color: #f1f1f1;
            font-size: 20pt;
            left: 0;
            top: 0;
        }

        .top .info{

        }

        .containter {
            width: 100%;
            overflow-x: auto;
        }

        .containter .wrap {
            display: flex;
            flex-direction: column;
            width: 100%;
        }

        .containter .wrap img {
            width: 100%;
            margin-top: 30pt;
        }
&#13;
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta name="viewport" content="width=device-width, height=device-height, user-scalable=no" />

    <title>Pinch to zoom</title>

    <script src="https://www.klika.co.il/plugins/jqTools/js/jquery-1.7.1.min.js" type="text/javascript"></script>


</head>
<body>
    <div class="top">
        <div class="info">Pinch to zoom</div>
    </div>

    <div class="containter">
        <div class="wrap">
            <img src="https://thumb7.shutterstock.com/display_pic_with_logo/91858/594887747/stock-photo-dreams-of-travel-child-flying-on-a-suitcase-against-the-backdrop-of-sunset-594887747.jpg" />
            <img src="https://thumb9.shutterstock.com/display_pic_with_logo/1020994/556702975/stock-photo-portrait-of-a-happy-and-proud-pregnant-woman-looking-at-her-belly-in-a-park-at-sunrise-with-a-warm-556702975.jpg" />
            <img src="https://thumb7.shutterstock.com/display_pic_with_logo/234100/599187701/stock-photo-funny-little-girl-plays-super-hero-over-blue-sky-background-superhero-concept-599187701.jpg" />
            <img src="https://thumb1.shutterstock.com/display_pic_with_logo/1316512/661476343/stock-photo-funny-pineapple-in-sunglasses-near-swimming-pool-661476343.jpg" />
            <img src="https://thumb1.shutterstock.com/display_pic_with_logo/2114402/689953639/stock-photo-adult-son-hugging-his-old-father-against-cloudy-sky-with-sunshine-689953639.jpg" />
            <img src="https://thumb7.shutterstock.com/display_pic_with_logo/172762/705978841/stock-photo-businessman-looking-to-the-future-for-new-business-opportunity-705978841.jpg" />
        </div>
    </div>


    
</body>
</html>
&#13;
&#13;
&#13;

0 个答案:

没有答案