zoukankan      html  css  js  c++  java
  • 简单的移动端图片预览 包含放大缩小以及对各种手势的判定

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
        <title>title</title>
        <link rel="stylesheet" type="text/css" href="../css/api.css"/>   //这个css的作用是去边距的,就是清除默认样式,设置自己的默认样式的
        <style>
            body, html {
                width: 100%;
                height: 100%;
            }
            header {
                width: 100%;
                height: 50px;
                background-color: #23C6C8;
                margin-bottom: 40px;
                color: #fff;
                font-size: 18px;
                line-height: 50px;
                vertical-align: middle;
                text-indent: 2em;
            }
            .main {
                width: 98%;
                margin-left: 2%;
            }
            .each-div {
                width: 60px;
                height: 60px;
                text-align: center;
                line-height: 90px;
                vertical-align: middle;
                float: left;
            }
            .main img {
                height: 40px;
            }
            .preview {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
                background-color: rgba(0,0,0,0.8);
            }
            .preview-content {
                position: relative;
                top: 50px;
                left: 0;
                overflow: auto;
            }
            .preview img {
                position: absolute;
            }
        </style>
    </head>
    <body>
        <header>图片预览测试</header>
        <div class="main">
            <div class="each-div"><img src="images/icon_00.png"/></div>
            <div class="each-div"><img src="images/icon_01.png"/></div>
            <div class="each-div"><img src="images/icon_02.png"/></div>
            <div class="each-div"><img src="images/icon_03.png"/></div>
            <div class="each-div"><img src="images/icon_04.png"/></div>
            <div class="each-div"><img src="images/icon_05.png"/></div>
            <div class="each-div"><img src="images/icon_06.png"/></div>
            <div class="each-div"><img src="images/icon_07.png"/></div>
            <div class="each-div"><img src="images/icon_08.png"/></div>
            <div class="each-div"><img src="images/icon_09.png"/></div>
            <div class="each-div"><img src="images/icon_10.png"/></div>
            <div class="each-div"><img src="images/icon_11.png"/></div>
            <div class="each-div"><img src="images/icon_12.png"/></div>
            <div class="each-div"><img src="images/icon_13.png"/></div>
            <div class="each-div"><img src="images/icon_14.png"/></div>
            <div class="each-div"><img src="images/icon_15.png"/></div>
            <div class="each-div"><img src="images/icon_16.png"/></div>
            <div class="each-div"><img src="images/icon_17.png"/></div>
            <div class="each-div"><img src="images/icon_18.png"/></div>
            <div class="each-div"><img src="images/icon_19.png"/></div>
            <div class="each-div"><img src="images/icon_20.png"/></div>
            <div class="each-div"><img src="images/icon_21.png"/></div>
        </div>
    </body>
    <script type="text/javascript" src="jquery-2.1.1.js"></script>
    <script type="text/javascript">
        var isPress = 0;                   // 是否已经点击过,用来判断是单击还是双击,使用setTimeout来判断,如果在第一次点击完0.5秒内点击第二次,即判断为双击
        var isBiger = false;               // 是否放大,在双击和双指放大缩小中均有使用。一旦缩放就自动判断为已经放大
        var thisPicWidth, thisPicHeight;   // 图片在加载完成后的当前大小
        var theSpaceSite;                  // 上一个点的各种数据
    
        /*
         * 点击触发图片预览效果,后面如果改点击事件改这里,同时清空thisPicHeight、thisPicWidth
         */
        $('.main').on('click', '.each-div', function() {
            thisPicHeight = 0;
            thisPicWidth = 0;
            var mySrc = $(this).find('img').attr('src');
            addPreview( $(this).find('img').attr('src') );
        });
    
        /*
         * 添加预览图片的界面,传入参数为图片地址
         */
        function addPreview(src) {
            var node = $('<div class="preview" id="preview"><div class="preview-content"><img src="' + src + '"/></div></div>');
            $('body').append( node );
            changeSize();
            setClick();
        };
        
        /*
         * 改变当前图片的大小,以及总的div的大小
         */
        function changeSize() {
            // 总的手机的高宽
            var bodyHeight = $(document).height();
            var bodyWidth = $(document).width();
            // 原本图片的高宽
            var imgHeightBefore = $('.preview').find('img').height();
            var imgWidthBefore = $('.preview').find('img').width();
            // 当前div的高需要减去头部的100像素,和宽
            var contentHeight = bodyHeight - 100;
            var contentWidth = bodyWidth;
            $('.preview-content').width( contentWidth );
            $('.preview-content').height( contentHeight );
            // 判断横竖比例,以及该如何显示图片
            var contentRatio = contentHeight / contentWidth;
            var imageRatio = imgHeightBefore / imgWidthBefore;
            if( contentRatio >= imageRatio ) {
                thisPicWidth = contentWidth;
                thisPicHeight =  Math.round( contentWidth * imageRatio );
                $('.preview').find('img').width( thisPicWidth );
                $('.preview').find('img').height( thisPicHeight );
            } else {
                thisPicHeight = contentHeight;
                thisPicWidth =  Math.round( contentHeight / imageRatio );
                $('.preview').find('img').width( thisPicWidth );
                $('.preview').find('img').height( thisPicHeight );
            };
            // 给图片进行定位移位
            $('.preview').find('img').css( 'top', ( contentHeight - thisPicHeight ) / 2 );
            $('.preview').find('img').css( 'left', ( contentWidth - thisPicWidth ) / 2 );
        };
        
        /*
         * 点击事件,触摸屏幕事件
         */
        function setClick() {
            /*
             * 点击触发图片外面就关闭图片预览
             */
            $('body').on('click', '.preview', function() {
                isBiger = false;
                $('.preview').remove();
            });
        
            /*
             * 点击禁止关闭图片预览,与上一个配合
             */
            $('body').on('click', '.preview img', function(e) {
                e.stopPropagation();
            });
            
            
            var preview = document.getElementById('preview');
            /*
             * 触碰开始事件记录 1个 或 2个 的当前点的坐标等
             */
            preview.ontouchstart = function(event) {
                event.preventDefault();
                var e = window.event || event;
                if( isPress == 0 ) {
                    //singleFinger
                    isPress = 1;
                } else {
                    if (e.touches[1]) {
                        // doubleFinger
                        // 第一个点的坐标,用于和下一个点进行比较,判断该如何缩放
                        var x1 = e.touches[1].clientX - this.offsetLeft,
                            x2 = e.touches[0].clientX - this.offsetLeft,
                            y1 = e.touches[1].clientY - this.offsetTop,
                            y2 = e.touches[0].clientY - this.offsetTop;
                        theSpaceSite = [{ 'x': x2 , 'y': y2 } , { 'x': x1 , 'y': y1 }];
                    } else {
                        //doubleClick
                        var x = e.touches[0].clientX - this.offsetLeft;
                        var y = e.touches[0].clientY - this.offsetTop;
                        doubleClick(x, y);
                    };
                };
                setTimeout( yanChi , 500 );
            };
            
            /*
             * 移动事件,只处理双指放大缩小。其他的单指事件直接交给网页处理,即滑动事件。
             */
            preview.ontouchmove = function(event) {
                var e = window.event || event;
                if (e.touches[1]) {
                    event.preventDefault();
                    // 将isBiger设为true,触发双击事件时必定为缩小至原样
                    isBiger = true;
                    var thisImageSite = { 'width': $('.preview img').width() , 'height': $('.preview img').height() };
                    var thisImageScroll = { 'left': $('.preview-content').scrollLeft() , 'top': $('.preview-content').scrollTop() };
                    var x0 = e.touches[0].clientX - this.offsetLeft,
                        x1 = e.touches[1].clientX - this.offsetLeft,
                        y0 = e.touches[0].clientY - this.offsetTop,
                        y1 = e.touches[1].clientY - this.offsetTop;
                    var thisDoubleMove = [{ 'left': x0 - theSpaceSite[0].x , 'top': y0 - theSpaceSite[0].y }, { 'left': x1 - theSpaceSite[1].x , 'top': y1 - theSpaceSite[1].y }];
                    if( x0 >= x1 ) {
                        var bigerNumber = 0;
                    } else {
                        var bigerNumber = 1;
                    }
                    var midSitePlace = { 'x': Math.abs(( x0 + x1 ) * 0.5) , 'y': Math.abs(( y0 + y1 ) * 0.5) };
                    changeImageSize( thisImageSite, thisImageScroll, thisDoubleMove, bigerNumber, midSitePlace );
                    theSpaceSite = [{ 'x': x0 , 'y': y0 } , { 'x': x1 , 'y': y1 }];
                };
            };
        };
        
        /*
         * 延迟判断是双击或者是单击
         */
        function yanChi() {
            isPress = 0;
        };
        
        /*
         * 双击触发这个事件,传入当前点击的地址,将图片方法两倍或者缩小至原样
         */
        function doubleClick(x, y) {
            if( isBiger == false ) {
                //将图像放大到两倍大小
                isBiger = true;
                $('.preview').find('img').height( thisPicHeight * 2 );
                $('.preview').find('img').width( thisPicWidth *2 );
                
                //将图像放大后放到自己想要的位置上
                var contentHeight = $('.preview-content').height();
                var contentWidth = $('.preview-content').width();
                if( contentHeight == thisPicHeight ) {
                    $('.preview-content').scrollTop( y );
                    if( contentWidth < 2 * thisPicWidth ) {
                        var scrollX = x - ( contentWidth - thisPicWidth ) / 2;
                        $('.preview-content').scrollLeft( scrollX );
                    };
                } else if( contentWidth == thisPicWidth ) {
                    $('.preview-content').scrollLeft( x );
                    if( contentHeight < 2 * thisPicHeight ) {
                        var scrollY = y - ( contentHeight - thisPicHeight ) / 2;
                        $('.preview-content').scrollTop( scrollY );
                    };
                } else {
                    alert('出了一个问题');
                };
            } else {
                isBiger = false;
                $('.preview').find('img').height( thisPicHeight );
                $('.preview').find('img').width( thisPicWidth );
            };
        };
        
        /*
         * 双指缩放事件   这个逻辑可能不太好捋,有问题可以问我
         * param thisImageSite   当前图片的大小
         * param thisImageScroll 当前图片的scroll的位置
         * param thisDoubleMove  两只手指分别移动了多少位置,带 + — 号的
         * param bigerNumber     哪个手指在右边
         * param midSitePlace    两个手指的中间点的坐标
         */
        function changeImageSize( thisImageSite, thisImageScroll, thisDoubleMove, bigerNumber, midSitePlace ) {
            // 下面是计算总共两只手指挪动了多少,是绝对值的相加。
            // 不能分开算,不然图片会变形,所以取其中偏移量比较大的那个作为最后的偏移量。
            var finalMove;
            var leftTotalMove = Math.abs(thisDoubleMove[0].left) + Math.abs(thisDoubleMove[1].left),
                topTotalMove = Math.abs(thisDoubleMove[0].top) + Math.abs(thisDoubleMove[1].top);
            if( leftTotalMove >= topTotalMove ) {
                finalMove = leftTotalMove;
            } else {
                finalMove = topTotalMove;
            };
            
            // 计算乘积,我只取了一种情况,就是两只手指分别向反方向移动才能缩放。 所以下面的第一个if判断就是是否是反方向的
            var leftMultiple = thisDoubleMove[0].left * thisDoubleMove[1].left,
                topMultiple = thisDoubleMove[0].top * thisDoubleMove[1].top;
            if( leftMultiple <= 0 && topMultiple <= 0 ){
                // 下面这两个判断是判断分别是放大还是缩小。 其实可以不用管,直接在里面写就可以了。
                if( ( thisDoubleMove[0].left >= 0 && bigerNumber == 0 ) || ( thisDoubleMove[0].left < 0 && bigerNumber == 1 ) ){
                    $('.preview img').width( thisImageSite.width + finalMove );
                    $('.preview img').height( thisImageSite.height + ( finalMove * thisImageSite.width / thisImageSite.height ) );
                    $('.preview-content').scrollLeft( thisImageScroll.left + finalMove / 2 );
                    $('.preview-content').scrollTop( thisImageScroll.top + ( finalMove * thisImageSite.width / thisImageSite.height ) / 2 );
                } else if( ( thisDoubleMove[0].left >= 0 && bigerNumber == 1 ) || ( thisDoubleMove[0].left < 0 && bigerNumber == 0 ) ) {
                    if( thisImageSite.width > thisPicWidth && thisImageSite.height > thisPicHeight ) {
                        $('.preview img').width( thisImageSite.width - finalMove );
                        $('.preview img').height( thisImageSite.height - ( finalMove * thisImageSite.width / thisImageSite.height ) );
                        $('.preview-content').scrollLeft( thisImageScroll.left - finalMove / 2 );
                        $('.preview-content').scrollTop( thisImageScroll.top - ( finalMove * thisImageSite.width / thisImageSite.height ) / 2 );
                    };
                };
            };
        };
    </script>
    </html>
  • 相关阅读:
    实验二
    个人简介及对未来的想法
    读《构建之法》心得体会
    作业2
    个人简介
    第六次作业
    第二次作业
    个人简历
    购物系统测试缺陷报告
    读《构建之法》心得体会
  • 原文地址:https://www.cnblogs.com/neuscx/p/5069387.html
Copyright © 2011-2022 走看看