简单的移动端图片预览 包含放大缩小以及对各种手势的判定

复制代码
<!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>
复制代码

 

posted @   木头耕田  阅读(2058)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示