zoukankan      html  css  js  c++  java
  • 安卓设备上,前端页面,手势缩放页面功能实现

    1、单页面,head标签里增加属性:

    <meta name="viewport" 
    content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=3.5, user-scalable=yes">
    /*注释*/
    // width:控制 viewport 的大小,可以指定的一个值,如果 600,或者特殊的值,如 device-width 为设备的宽度(单位为缩放为 100% 时的 CSS 的像素)
    // height:和 width 相对应,指定高度。
    // initial-scale:初始缩放比例,也即是当页面第一次 load 的时候缩放比例。
    // maximum-scale:允许用户缩放到的最大比例。
    // minimum-scale:允许用户缩放到的最小比例。
    // user-scalable:用户是否可以手动缩放
    // 
    

      

    2、iframe引入的页面,想要缩放,这个标签就不生效了

     

    手势动作,iframe引入的页面并不能生效缩放动作。
    iframe页面支持手势缩放的基本思路:
    (1)监听手指缩放事件
    (2)根据手指动作,判断缩放,并体现在页面上
    (3)页面变化顺滑流畅的响应手指动作

    (1)js监听事件:

    //监听touchstart事件
        document.addEventListener('touchstart', function(e) {
            if (e.touches.length >= 2) { //判断是否有两个点在屏幕上
              
            } else {
             
            }
        }, false);
        //监听touchmove事件
        document.addEventListener('touchmove', function(e) {
           
            if (e.touches.length >= 2 && isDoubleTouch) { //手势事件
              
            } else if (isTouch) {
              
            }
        }, false);
        //监听touchend事件
        document.addEventListener('touchend', function(e) {
            if (isDoubleTouch) {
              
            };
        }, false);
    

    动作:放-缩-放,缩放比例数值(scale)会根据手势动作变化

    (2)根据手指动作,判断缩放,并体现在页面上:

    方式1:

    缩放事件响应时候,调节页面大小。初步实现方式是,缩放事件响应后,根据两指距离,调节scale属性,放大或缩小页面。

    代码(错误示范):

    //缩放比例
    var scalingRatio = 1;
    var DOM = $("#image");
    function touchChange(n,gesturechange) {
        if(gesturechange.scale>1){
            // 放大
            if(scalingRatio<5)scalingRatio += gesturechange.scale/10
        }else{
            // 缩小
            if(scalingRatio>0.5)scalingRatio -= gesturechange.scale
        }
        DOM.css({'transform':'scale('+scalingRatio+')'})
    
        n+= "<br>"+gesturechange.scale;
        document.querySelector("#logs").innerHTML = n;
    }
    

      

    存在明显的问题:
    [1] 两指放在屏幕上不动,两指间的距离有着细微的变化,也会修改scale的值,触发页面持续缩放,会在极短的时间内放的极大或缩的极小。
    [2] 页面渲染速率比屏幕刷新率快,页面必然会出现卡顿

    [3] 每次缩放操作,页面会定位回左上角。

    方式2:

    为解决以上问题:

    [1] 随手势变化,实时监听中心坐标、两指见的距离

    [2] 使用【scale3d】缩放,使用【translate3d、translate】移动页面

    [3] 延时执行

    该方案存在问题:

    在低配置安卓分机上,卡顿严重!

    具体实现方式:

    (1) 响应touchmove事件,获取两指间的距离:

    el.addEventListener('touchmove', function (event) {
        if(target.enabled) {
            if (firstMove) {
                updateInteraction(event);
                if (interaction) {
                    cancelEvent(event);
                }
                startTouches = targetTouches(event.touches);
            } else {
                console.log('记录起始---startTouches--',JSON.stringify(startTouches),'
    ','记录结束---endTouches--',JSON.stringify(targetTouches(event.touches)))
              
                switch (interaction) {
                    case 'zoom':
                        target.handleZoom(event, calculateScale(startTouches, targetTouches(event.touches)));
                        break;
                    case 'drag':
                        target.handleDrag(event);
                        break;
                }
                if (interaction) {
                    cancelEvent(event);
                    target.update();
                }
            }
    
            firstMove = false;
        }
    });
    

      

    // 记录手指坐标
    targetTouches = function (touches) {
        return Array.prototype.slice.call(touches).map(function (touch) {
            return {
                x: touch.pageX,
                y: touch.pageY
            };
        });
    },
    

      

    //根据起止坐标计算距离变化
    calculateScale = function (startTouches, endTouches) {
        var startDistance = getDistance(startTouches[0], startTouches[1]),
            endDistance = getDistance(endTouches[0], endTouches[1]);
        return endDistance / startDistance;
    },
    getDistance = function (a, b) {
        var x, y;
        x = a.x - b.x;
        y = a.y - b.y;
        return Math.sqrt(x * x + y * y);
    },
    

      (2) 根据当前缩放系数和偏移量更新css值

    update: function () {
    
        if (this.updatePlaned) {
            return;
        }
        this.updatePlaned = true;
    
        setTimeout((function () {
            this.updatePlaned = false;
            this.updateAspectRatio();
    
            var zoomFactor = this.getInitialZoomFactor() * this.zoomFactor,
                offsetX = -this.offset.x / zoomFactor,
                offsetY = -this.offset.y / zoomFactor,
                transform3d =   'scale3d('     + zoomFactor + ', '  + zoomFactor + ',1) ' +
                    'translate3d(' + offsetX    + 'px,' + offsetY    + 'px,0px)',
                transform2d =   'scale('       + zoomFactor + ', '  + zoomFactor + ') ' +
                    'translate('   + offsetX    + 'px,' + offsetY    + 'px)',
                removeClone = (function () {
                    if (this.clone) {
                        this.clone.remove();
                        delete this.clone;
                    }
                }).bind(this);
    
            // PinchZoom在交互过程中使用3d变换
            // 互动后,它会退回到2D转换
            if (!this.options.use2d || this.hasInteraction || this.inAnimation) {
                this.is3d = true;
                removeClone();
                this.el.css({
                    '-webkit-transform':  transform3d,
                    '-o-transform':       transform2d,
                    '-ms-transform':      transform2d,
                    '-moz-transform':     transform2d,
                    'transform':        transform3d
                });
            } else {
    
                // 从3d转换为2d转换时,Webkit会有一些故障。
                // 为避免这种情况,3D变换后的元素的副本会显示在
                // 元素从3d转换为2d转换时的前景
                if (this.is3d) {
                    this.clone = this.el.clone();
                    this.clone.css('pointer-events', 'none');
                    this.clone.appendTo(this.container);
                    setTimeout(removeClone, 200);
                }
                this.el.css({
                    '-webkit-transform':  transform2d,
                    '-o-transform':       transform2d,
                    '-ms-transform':      transform2d,
                    '-moz-transform':     transform2d,
                    'transform':        transform2d
                });
                this.is3d = false;
            }
        }).bind(this), 0);
    },
    

      

    (3) 单指拖动,实时更新中心坐标,并根据容器限制滑动区域

    /**
     * 计算当前偏移量和缩放系数的虚拟缩放中心
     * (used for reverse zoom)
     * @return {Object} the current zoom center
     */
    getCurrentZoomCenter: function () {
    
        // uses following formula to calculate the zoom center x value
        // offset_left / offset_right = zoomcenter_x / (container_x - zoomcenter_x)
        var length = this.container[0].offsetWidth * this.zoomFactor,
            offsetLeft  = this.offset.x,
            offsetRight = length - offsetLeft -this.container[0].offsetWidth,
            widthOffsetRatio = offsetLeft / offsetRight,
            centerX = widthOffsetRatio * this.container[0].offsetWidth / (widthOffsetRatio + 1),
    
        // the same for the zoomcenter y
            height = this.container[0].offsetHeight * this.zoomFactor,
            offsetTop  = this.offset.y,
            offsetBottom = height - offsetTop - this.container[0].offsetHeight,
            heightOffsetRatio = offsetTop / offsetBottom,
            centerY = heightOffsetRatio * this.container[0].offsetHeight / (heightOffsetRatio + 1);
    
        // prevents division by zero
        if (offsetRight === 0) { centerX = this.container[0].offsetWidth; }
        if (offsetBottom === 0) { centerY = this.container[0].offsetHeight; }
    
        return {
            x: centerX,
            y: centerY
        };
    },
    

      完整代码:

    html:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
            "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
        <title>Pinchzoom.js Demo</title>
    
        <style type="text/css">
            div.pinch-zoom,
            div.pinch-zoom img{
                 100%;
                -webkit-user-drag: none;
            }
    
        </style>
        <link rel="stylesheet" href="style.css" />
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        <meta name="apple-mobile-web-app-capable" content="yes" />
    
        <!-- pinchzoom requires: jquery -->
        <script type="text/javascript" src="../dependencies/jquery-1.7.2.min.js"></script>
        <script type="text/javascript" src="../src/pinchzoom.js"></script>
        <script type="text/javascript">
            $(function () {
                $('div.pinch-zoom').each(function () {
                    new RTP.PinchZoom($(this), {});
                });
            })
        </script>
    </head>
    <body>
    
        <div class="page">
            <div class="pinch-zoom">
                <div class="d11" id="logs" style="min-height: 160px;background: #bcffe1;position: fixed; 500px;color:red;font-size:2vw;height: auto;"></div>
                <div class="d11">1 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">2 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">3 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">4 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">5 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">6 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">7 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">8 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">9 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">10 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">11 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">12<img src="../../11371.jpg" alt=""></div>
                <div class="d11">13 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">14 <img src="../../11371.jpg" alt=""></div>
                <div class="d11"> 15<img src="../../11371.jpg" alt=""></div>
                <div class="d11"> 16<img src="../../11371.jpg" alt=""></div>
                <div class="d11"> 17<img src="../../11371.jpg" alt=""></div>
                <div class="d11">18 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">19 <img src="../../11371.jpg" alt=""></div>
                <div class="d11">20 <img src="../../11371.jpg" alt=""></div>
            </div>
        </div>
    
    </body>
    </html>
    

      JS:

      1 /*global jQuery, console, define, setTimeout, window*/
      2 (function () {
      3     'use strict';
      4     var definePinchZoom = function ($) {
      5 
      6         /**
      7          * Pinch zoom using jQuery
      8          * @version 0.0.2
      9          * @author Manuel Stofer <mst@rtp.ch>
     10          * @param el
     11          * @param options
     12          * @constructor
     13          */
     14         var PinchZoom = function (el, options) {
     15                 this.el = $(el);
     16                 this.zoomFactor = 1;
     17                 this.lastScale = 1;
     18                 this.offset = {
     19                     x: 0,
     20                     y: 0
     21                 };
     22                 this.options = $.extend({}, this.defaults, options);
     23                 this.setupMarkup();
     24                 this.bindEvents();
     25                 this.update();
     26                 // default enable.
     27                 this.enable();
     28 
     29             },
     30             sum = function (a, b) {
     31                 return a + b;
     32             },
     33             isCloseTo = function (value, expected) {
     34                 return value > expected - 0.01 && value < expected + 0.01;
     35             };
     36 
     37         PinchZoom.prototype = {
     38 
     39             defaults: {
     40                 tapZoomFactor: 2,
     41                 zoomOutFactor: 1.1,
     42                 animationDuration: 300,
     43                 maxZoom: 4,
     44                 minZoom: 0.5,
     45                 lockDragAxis: false,
     46                 use2d: true,
     47                 zoomStartEventName: 'pz_zoomstart',
     48                 zoomEndEventName: 'pz_zoomend',
     49                 dragStartEventName: 'pz_dragstart',
     50                 dragEndEventName: 'pz_dragend',
     51                 doubleTapEventName: 'pz_doubletap'
     52             },
     53 
     54             /**
     55              * Event handler for 'dragstart'
     56              * @param event
     57              */
     58             handleDragStart: function (event) {
     59                 this.el.trigger(this.options.dragStartEventName);
     60                 this.stopAnimation();
     61                 this.lastDragPosition = false;
     62                 this.hasInteraction = true;
     63                 this.handleDrag(event);
     64             },
     65 
     66             /**
     67              * Event handler for 'drag'
     68              * @param event
     69              */
     70             handleDrag: function (event) {
     71                 if (this.zoomFactor > 1.0) {
     72                     var touch = this.getTouches(event)[0];
     73                     this.drag(touch, this.lastDragPosition);
     74                     // this.offset = this.sanitizeOffset(this.offset);
     75                     this.lastDragPosition = touch;
     76                 }
     77             },
     78 
     79             handleDragEnd: function () {
     80                 this.el.trigger(this.options.dragEndEventName);
     81                 this.end();
     82             },
     83 
     84             /**
     85              * Event handler for 'zoomstart'
     86              * @param event
     87              */
     88             handleZoomStart: function (event) {
     89                 this.el.trigger(this.options.zoomStartEventName);
     90                 this.stopAnimation();
     91                 this.lastScale = 1;
     92                 this.nthZoom = 0;
     93                 this.lastZoomCenter = false;
     94                 this.hasInteraction = true;
     95             },
     96 
     97             /**
     98              * 缩放的事件处理程序
     99              * @param event
    100              */
    101             handleZoom: function (event, newScale) {
    102                 // a relative scale factor is used
    103                 var touchCenter = this.getTouchCenter(this.getTouches(event)),
    104                     scale = newScale / this.lastScale;
    105                 this.lastScale = newScale;
    106 
    107                 // 第一次触摸事件由于不精确而被丢弃
    108                 this.nthZoom += 1;
    109                 if (this.nthZoom > 3) {
    110                     this.scale(scale, touchCenter);
    111                     this.drag(touchCenter, this.lastZoomCenter);
    112                 }
    113                 this.lastZoomCenter = touchCenter;
    114             },
    115 
    116             handleZoomEnd: function () {
    117                 this.el.trigger(this.options.zoomEndEventName);
    118                 this.end();
    119             },
    120 
    121             /**
    122              * Event handler for 'doubletap'
    123              * @param event
    124              */
    125             handleDoubleTap: function (event) {
    126                 var center = this.getTouches(event)[0],
    127                     zoomFactor = this.zoomFactor > 1 ? 1 : this.options.tapZoomFactor,
    128                     startZoomFactor = this.zoomFactor,
    129                     updateProgress = (function (progress) {
    130                         this.scaleTo(startZoomFactor + progress * (zoomFactor - startZoomFactor), center);
    131                     }).bind(this);
    132 
    133                 if (this.hasInteraction) {
    134                     return;
    135                 }
    136                 if (startZoomFactor > zoomFactor) {
    137                     center = this.getCurrentZoomCenter();
    138                 }
    139 
    140                 this.animate(this.options.animationDuration, updateProgress, this.swing);
    141                 this.el.trigger(this.options.doubleTapEventName);
    142             },
    143 
    144             /**
    145              * 偏移的最大值/最小值
    146              * @param offset
    147              * @return {Object} the sanitized offset
    148              */
    149             sanitizeOffset: function (offset) {
    150                 var maxX = (this.zoomFactor - 1) * this.getContainerX(),
    151                     maxY = (this.zoomFactor - 1) * this.getContainerY(),
    152                     maxOffsetX = Math.max(maxX, 0),
    153                     maxOffsetY = Math.max(maxY, 0),
    154                     minOffsetX = Math.min(maxX, 0),
    155                     minOffsetY = Math.min(maxY, 0),
    156                     RY = offset.y
    157                 ;
    158 
    159                 if(offset.y < 0 ){
    160                     RY = Math.min(Math.max(offset.y, minOffsetY), maxOffsetY)
    161                 }
    162                 else if(offset.y > this.getContainerY()){
    163                     RY = this.getContainerY()
    164                 }
    165 
    166                 console.log(
    167                     'offset:',offset,'
    ',
    168                     'maxX:',maxX,'
    ',
    169                     'maxY:',maxY,'
    ',
    170                     '容器高度:',this.getContainerY(),'
    '
    171                 )
    172 
    173                 return {
    174                     x: Math.min(Math.max(offset.x, minOffsetX), maxOffsetX),
    175                     y: RY
    176                 };
    177             },
    178 
    179             /**
    180              * Scale to a specific zoom factor (not relative)
    181              * @param zoomFactor
    182              * @param center
    183              */
    184             scaleTo: function (zoomFactor, center) {
    185                 this.scale(zoomFactor / this.zoomFactor, center);
    186             },
    187 
    188             /**
    189              * 从指定的中心缩放元素
    190              * @param scale
    191              * @param center
    192              */
    193             scale: function (scale, center) {
    194                 scale = this.scaleZoomFactor(scale);
    195                 this.addOffset({
    196                     x: (scale - 1) * (center.x + this.offset.x),
    197                     y: (scale - 1) * (center.y + this.offset.y)
    198                 });
    199             },
    200 
    201             /**
    202              * 相对于当前状态缩放缩放系数
    203              * @param scale
    204              * @return the actual scale (can differ because of max min zoom factor)
    205              */
    206             scaleZoomFactor: function (scale) {
    207                 var originalZoomFactor = this.zoomFactor;
    208                 this.zoomFactor *= scale;
    209                 this.zoomFactor = Math.min(this.options.maxZoom, Math.max(this.zoomFactor, this.options.minZoom));
    210                 return this.zoomFactor / originalZoomFactor;
    211             },
    212 
    213             /**
    214              * 拖动元素
    215              * @param center
    216              * @param lastCenter
    217              */
    218             drag: function (center, lastCenter) {
    219                 // console.log('拖动事件参数:',center, lastCenter,'
    this.options',this.options)
    220                 if (lastCenter) {
    221                   if(this.options.lockDragAxis) {
    222                     // 将滚动条锁定到更改最多的位置
    223                     if(Math.abs(center.x - lastCenter.x) > Math.abs(center.y - lastCenter.y)) {
    224                       this.addOffset({
    225                         x: -(center.x - lastCenter.x),
    226                         y: 0
    227                       });
    228                     }
    229                     else {
    230                       this.addOffset({
    231                         y: -(center.y - lastCenter.y),
    232                         x: 0
    233                       });
    234                     }
    235                   }
    236                   else {
    237                     this.addOffset({
    238                       y: -(center.y - lastCenter.y),
    239                       x: -(center.x - lastCenter.x)
    240                     });
    241                   }
    242                 }
    243             },
    244 
    245             /**
    246              * Calculates the touch center of multiple touches
    247              * @param touches
    248              * @return {Object}
    249              */
    250             getTouchCenter: function (touches) {
    251                 return this.getVectorAvg(touches);
    252             },
    253 
    254             /**
    255              * Calculates the average of multiple vectors (x, y values)
    256              */
    257             getVectorAvg: function (vectors) {
    258                 return {
    259                     x: vectors.map(function (v) { return v.x; }).reduce(sum) / vectors.length,
    260                     y: vectors.map(function (v) { return v.y; }).reduce(sum) / vectors.length
    261                 };
    262             },
    263 
    264             /**
    265              * 添加偏移
    266              * @param offset the offset to add
    267              * @return return true when the offset change was accepted
    268              */
    269             addOffset: function (offset) {
    270                 this.offset = {
    271                     x: this.offset.x + offset.x,
    272                     y: this.offset.y + offset.y
    273                 };
    274             },
    275 
    276             sanitize: function () {
    277                 if (this.zoomFactor < this.options.zoomOutFactor) {
    278                     this.zoomOutAnimation();
    279                 } else if (this.isInsaneOffset(this.offset)) {
    280                     this.sanitizeOffsetAnimation();
    281                 }
    282             },
    283 
    284             /**
    285              * 检查当前缩放倍数的偏移量是否正确
    286              * @param offset
    287              * @return {Boolean}
    288              */
    289             isInsaneOffset: function (offset) {
    290                 var sanitizedOffset = this.sanitizeOffset(offset);
    291                 return sanitizedOffset.x !== offset.x ||
    292                     sanitizedOffset.y !== offset.y;
    293             },
    294 
    295             /**
    296              * 创建移动到合理偏移的动画
    297              */
    298             sanitizeOffsetAnimation: function () {
    299                 console.log('创建移动到合理偏移的动画')
    300                 var targetOffset = this.sanitizeOffset(this.offset),
    301                     startOffset = {
    302                         x: this.offset.x,
    303                         y: this.offset.y
    304                     },
    305                     updateProgress = (function (progress) {
    306                         this.offset.x = startOffset.x + progress * (targetOffset.x - startOffset.x);
    307                         this.offset.y = startOffset.y + progress * (targetOffset.y - startOffset.y);
    308                         this.update();
    309                     }).bind(this);
    310 
    311                 this.animate(
    312                     this.options.animationDuration,
    313                     updateProgress,
    314                     this.swing
    315                 );
    316             },
    317 
    318             /**
    319              * 缩放回原始位置,
    320              * (no offset and zoom factor 1)
    321              */
    322             zoomOutAnimation: function () {
    323                 var startZoomFactor = this.zoomFactor,
    324                     zoomFactor = 1,
    325                     center = this.getCurrentZoomCenter(),
    326                     updateProgress = (function (progress) {
    327                         this.scaleTo(startZoomFactor + progress * (zoomFactor - startZoomFactor), center);
    328                     }).bind(this);
    329 
    330                 this.animate(
    331                     this.options.animationDuration,
    332                     updateProgress,
    333                     this.swing
    334                 );
    335             },
    336 
    337             /**
    338              * 更新宽高比
    339              */
    340             updateAspectRatio: function () {
    341                 this.setContainerY(this.getContainerX() / this.getAspectRatio());
    342             },
    343 
    344             /**
    345              *计算初始缩放系数(以使元素适合容器)
    346              * @return the initial zoom factor
    347              */
    348             getInitialZoomFactor: function () {
    349                 // use .offsetWidth instead of width()
    350                 // because jQuery-width() return the original width but Zepto-width() will calculate width with transform.
    351                 // the same as .height()
    352                 return this.container[0].offsetWidth / this.el[0].offsetWidth;
    353             },
    354 
    355             /**
    356              * 计算元素的长宽比
    357              * @return the aspect ratio
    358              */
    359             getAspectRatio: function () {
    360                 return this.el[0].offsetWidth / this.el[0].offsetHeight;
    361             },
    362 
    363             /**
    364              * 计算当前偏移量和缩放系数的虚拟缩放中心
    365              * (used for reverse zoom)
    366              * @return {Object} the current zoom center
    367              */
    368             getCurrentZoomCenter: function () {
    369 
    370                 // uses following formula to calculate the zoom center x value
    371                 // offset_left / offset_right = zoomcenter_x / (container_x - zoomcenter_x)
    372                 var length = this.container[0].offsetWidth * this.zoomFactor,
    373                     offsetLeft  = this.offset.x,
    374                     offsetRight = length - offsetLeft -this.container[0].offsetWidth,
    375                     widthOffsetRatio = offsetLeft / offsetRight,
    376                     centerX = widthOffsetRatio * this.container[0].offsetWidth / (widthOffsetRatio + 1),
    377 
    378                 // the same for the zoomcenter y
    379                     height = this.container[0].offsetHeight * this.zoomFactor,
    380                     offsetTop  = this.offset.y,
    381                     offsetBottom = height - offsetTop - this.container[0].offsetHeight,
    382                     heightOffsetRatio = offsetTop / offsetBottom,
    383                     centerY = heightOffsetRatio * this.container[0].offsetHeight / (heightOffsetRatio + 1);
    384 
    385                 // prevents division by zero
    386                 if (offsetRight === 0) { centerX = this.container[0].offsetWidth; }
    387                 if (offsetBottom === 0) { centerY = this.container[0].offsetHeight; }
    388 
    389                 return {
    390                     x: centerX,
    391                     y: centerY
    392                 };
    393             },
    394 
    395             canDrag: function () {
    396                 return !isCloseTo(this.zoomFactor, 1);
    397             },
    398 
    399             /**
    400              * Returns the touches of an event relative to the container offset
    401              * @param event
    402              * @return array touches
    403              */
    404             getTouches: function (event) {
    405                 var position = this.container.offset();
    406                 return Array.prototype.slice.call(event.touches).map(function (touch) {
    407                     return {
    408                         x: touch.pageX - position.left,
    409                         y: touch.pageY - position.top
    410                     };
    411                 });
    412             },
    413 
    414             /**
    415              * Animation loop
    416              * does not support simultaneous animations
    417              * @param duration
    418              * @param framefn
    419              * @param timefn
    420              * @param callback
    421              */
    422             animate: function (duration, framefn, timefn, callback) {
    423                 var startTime = new Date().getTime(),
    424                     renderFrame = (function () {
    425                         if (!this.inAnimation) { return; }
    426                         var frameTime = new Date().getTime() - startTime,
    427                             progress = frameTime / duration;
    428                         if (frameTime >= duration) {
    429                             framefn(1);
    430                             if (callback) {
    431                                 callback();
    432                             }
    433                             this.update();
    434                             this.stopAnimation();
    435                             this.update();
    436                         } else {
    437                             if (timefn) {
    438                                 progress = timefn(progress);
    439                             }
    440                             framefn(progress);
    441                             this.update();
    442                             requestAnimationFrame(renderFrame);
    443                         }
    444                     }).bind(this);
    445                 this.inAnimation = true;
    446                 requestAnimationFrame(renderFrame);
    447             },
    448 
    449             /**
    450              * Stops the animation
    451              */
    452             stopAnimation: function () {
    453                 this.inAnimation = false;
    454             },
    455 
    456             /**
    457              * Swing timing function for animations
    458              * @param p
    459              * @return {Number}
    460              */
    461             swing: function (p) {
    462                 return -Math.cos(p * Math.PI) / 2  + 0.5;
    463             },
    464 
    465             getContainerX: function () {
    466                 return this.container[0].offsetWidth;
    467             },
    468 
    469             getContainerY: function () {
    470                 return this.container[0].offsetHeight;
    471             },
    472 
    473             setContainerY: function (y) {
    474                 return this.container.height(y);
    475             },
    476 
    477             /**
    478              * 创建预期的html结构
    479              */
    480             setupMarkup: function () {
    481                 this.container = $('<div class="pinch-zoom-container"></div>');
    482                 this.el.before(this.container);
    483                 this.container.append(this.el);
    484 
    485                 this.container.css({
    486                     'overflow': 'hidden',
    487                     'position': 'relative'
    488                 });
    489 
    490                 // Zepto无法识别“ webkitTransform ..”样式
    491                 this.el.css({
    492                     '-webkit-transform-origin': '0% 0%',
    493                     '-moz-transform-origin': '0% 0%',
    494                     '-ms-transform-origin': '0% 0%',
    495                     '-o-transform-origin': '0% 0%',
    496                     'transform-origin': '0% 0%',
    497                     'position': 'absolute'
    498                 });
    499             },
    500 
    501             end: function () {
    502                 this.hasInteraction = false;
    503                 this.sanitize();
    504                 this.update();
    505             },
    506 
    507             /**
    508              * 绑定所有必需的事件侦听器
    509              */
    510             bindEvents: function () {
    511                 detectGestures(this.container.get(0), this);
    512                 // Zepto and jQuery both know about `on`
    513                 $(window).on('resize', this.update.bind(this));
    514                 $(this.el).find('img').on('load', this.update.bind(this));
    515             },
    516 
    517             /**
    518              * 根据当前缩放系数和偏移量更新css值
    519              */
    520             update: function () {
    521 
    522                 if (this.updatePlaned) {
    523                     return;
    524                 }
    525                 this.updatePlaned = true;
    526 
    527                 setTimeout((function () {
    528                     this.updatePlaned = false;
    529                     this.updateAspectRatio();
    530 
    531                     var zoomFactor = this.getInitialZoomFactor() * this.zoomFactor,
    532                         offsetX = -this.offset.x / zoomFactor,
    533                         offsetY = -this.offset.y / zoomFactor,
    534                         transform3d =   'scale3d('     + zoomFactor + ', '  + zoomFactor + ',1) ' +
    535                             'translate3d(' + offsetX    + 'px,' + offsetY    + 'px,0px)',
    536                         transform2d =   'scale('       + zoomFactor + ', '  + zoomFactor + ') ' +
    537                             'translate('   + offsetX    + 'px,' + offsetY    + 'px)',
    538                         removeClone = (function () {
    539                             if (this.clone) {
    540                                 this.clone.remove();
    541                                 delete this.clone;
    542                             }
    543                         }).bind(this);
    544 
    545                     var n = "第一行 - this.zoomFactor:"+this.zoomFactor+"<br>"+
    546                         "|||zoomFactor:"+zoomFactor+"<br>"+
    547                         "|||transform2d:"+transform2d+"<br>"+
    548                         "|||transform3d:"+transform3d+"<br>"+
    549                         "|||this.lastScale:"+this.lastScale+"<br>"+
    550                         "|||this.lastZoomCenter:"+JSON.stringify(this.lastZoomCenter)+"<br>"+
    551                         "|||this.offset:"+JSON.stringify(this.offset)+"<br>"+
    552                         "|||this.nthZoom:"+this.nthZoom+"<br>"+
    553                         "|||this.zoomFactor:"+this.zoomFactor+"<br>"+
    554                         "|||this.updatePlaned:"+this.updatePlaned
    555                     ;
    556                     document.getElementById('logs').innerHTML = n
    557                     /*console.log(
    558                         'this.offset:',JSON.stringify(this.offset),
    559                         '
    ',
    560                         'offsetX:',offsetX,
    561                         '
    ',
    562                         'offsetY:',offsetY,
    563                         '
    ',
    564                         'transform2d:',transform2d,
    565                         '
    ',
    566                         'transform3d:',transform3d,
    567                         '
    ',
    568 
    569                         ''
    570                     )*/
    571 
    572                     // Scale 3d和translate3d更快(至少在iOS上)
    573                     // 但它们也会降低质量
    574                     // PinchZoom在交互过程中使用3d变换
    575                     // 互动后,它会退回到2D转换
    576                     if (!this.options.use2d || this.hasInteraction || this.inAnimation) {
    577                         this.is3d = true;
    578                         removeClone();
    579                         this.el.css({
    580                             '-webkit-transform':  transform3d,
    581                             '-o-transform':       transform2d,
    582                             '-ms-transform':      transform2d,
    583                             '-moz-transform':     transform2d,
    584                             'transform':        transform3d
    585                         });
    586                     } else {
    587 
    588                         // 从3d转换为2d转换时,Webkit会有一些故障。
    589                         // 为避免这种情况,3D变换后的元素的副本会显示在
    590                         // 元素从3d转换为2d转换时的前景
    591                         if (this.is3d) {
    592                             this.clone = this.el.clone();
    593                             this.clone.css('pointer-events', 'none');
    594                             this.clone.appendTo(this.container);
    595                             setTimeout(removeClone, 200);
    596                         }
    597                         this.el.css({
    598                             '-webkit-transform':  transform2d,
    599                             '-o-transform':       transform2d,
    600                             '-ms-transform':      transform2d,
    601                             '-moz-transform':     transform2d,
    602                             'transform':        transform2d
    603                         });
    604                         this.is3d = false;
    605                     }
    606                 }).bind(this), 0);
    607             },
    608 
    609             /**
    610              * Enables event handling for gestures
    611              */
    612             enable: function() {
    613               this.enabled = true;
    614             },
    615 
    616             /**
    617              * Disables event handling for gestures
    618              */
    619             disable: function() {
    620               this.enabled = false;
    621             }
    622         };
    623 
    624         var detectGestures = function (el, target) {
    625             var interaction = null,
    626                 fingers = 0,
    627                 lastTouchStart = null,
    628                 startTouches = null,
    629 
    630                 setInteraction = function (newInteraction, event) {
    631                     if (interaction !== newInteraction) {
    632                         // console.log('interaction && !newInteraction: ',interaction,newInteraction,interaction && !newInteraction)
    633                         if (interaction && !newInteraction) {
    634                             switch (interaction) {
    635                                 case "zoom":
    636                                     target.handleZoomEnd(event);
    637                                     break;
    638                                 case 'drag':
    639                                     target.handleDragEnd(event);
    640                                     break;
    641                             }
    642                         }
    643 
    644                         switch (newInteraction) {
    645                             case 'zoom':
    646                                 target.handleZoomStart(event);
    647                                 break;
    648                             case 'drag':
    649                                 target.handleDragStart(event);
    650                                 break;
    651                         }
    652                     }
    653                     interaction = newInteraction;
    654                 },
    655 
    656                 updateInteraction = function (event) {
    657                     if (fingers === 2) {
    658                         setInteraction('zoom');
    659                     } else if (fingers === 1 && target.canDrag()) {
    660                         setInteraction('drag', event);
    661                     } else {
    662                         setInteraction(null, event);
    663                     }
    664                 },
    665 
    666                 targetTouches = function (touches) {
    667                     return Array.prototype.slice.call(touches).map(function (touch) {
    668                         return {
    669                             x: touch.pageX,
    670                             y: touch.pageY
    671                         };
    672                     });
    673                 },
    674 
    675                 getDistance = function (a, b) {
    676                     var x, y;
    677                     x = a.x - b.x;
    678                     y = a.y - b.y;
    679                     return Math.sqrt(x * x + y * y);
    680                 },
    681 
    682                 calculateScale = function (startTouches, endTouches) {
    683                     var startDistance = getDistance(startTouches[0], startTouches[1]),
    684                         endDistance = getDistance(endTouches[0], endTouches[1]);
    685                     return endDistance / startDistance;
    686                 },
    687 
    688                 cancelEvent = function (event) {
    689                     event.stopPropagation();
    690                     event.preventDefault();
    691                 },
    692 
    693                 detectDoubleTap = function (event) {
    694                     var time = (new Date()).getTime();
    695 
    696                     if (fingers > 1) {
    697                         lastTouchStart = null;
    698                     }
    699 
    700                     if (time - lastTouchStart < 300) {
    701                         cancelEvent(event);
    702 
    703                         target.handleDoubleTap(event);
    704                         switch (interaction) {
    705                             case "zoom":
    706                                 target.handleZoomEnd(event);
    707                                 break;
    708                             case 'drag':
    709                                 target.handleDragEnd(event);
    710                                 break;
    711                         }
    712                     }
    713 
    714                     if (fingers === 1) {
    715                         lastTouchStart = time;
    716                     }
    717                 },
    718                 firstMove = true;
    719 
    720             el.addEventListener('touchstart', function (event) {
    721                 if(target.enabled) {
    722                     firstMove = true;
    723                     fingers = event.touches.length;
    724                     detectDoubleTap(event);
    725                 }
    726             });
    727 
    728             el.addEventListener('touchmove', function (event) {
    729                 // console.log('target.enabled: ',target.enabled,'
    firstMove:',firstMove,'
    interaction:',interaction)
    730                 if(target.enabled) {
    731                     if (firstMove) {
    732                         /*console.log('单指事件
    ',
    733                             '器使坐标startTouches:',
    734                             startTouches,
    735                             '
    ',
    736                             '终点坐标:',
    737                             targetTouches(event.touches)
    738                         )*/
    739 
    740                         updateInteraction(event);
    741                         if (interaction) {
    742                             cancelEvent(event);
    743                         }
    744                         startTouches = targetTouches(event.touches);
    745                     } else {
    746                         /*console.log('双指事件
    根据起止坐标计算距离变化--',
    747                             calculateScale(startTouches, targetTouches(event.touches)),
    748                             '
    ',
    749                             '器使坐标startTouches:',
    750                             startTouches,
    751                             '
    ',
    752                             '终点坐标:',
    753                             targetTouches(event.touches)
    754                         )*/
    755                         switch (interaction) {
    756                             case 'zoom':
    757                                 target.handleZoom(event, calculateScale(startTouches, targetTouches(event.touches)));
    758                                 break;
    759                             case 'drag':
    760                                 target.handleDrag(event);
    761                                 break;
    762                         }
    763                         if (interaction) {
    764                             cancelEvent(event);
    765                             target.update();
    766                         }
    767                     }
    768 
    769                     firstMove = false;
    770                 }
    771             });
    772 
    773             el.addEventListener('touchend', function (event) {
    774                 if(target.enabled) {
    775                     fingers = event.touches.length;
    776                     updateInteraction(event);
    777                 }
    778             });
    779         };
    780 
    781         return PinchZoom;
    782     };
    783 
    784     if (typeof define !== 'undefined' && define.amd) {
    785         define(['jquery'], function ($) {
    786             return definePinchZoom($);
    787         });
    788     } else {
    789         window.RTP = window.RTP || {};
    790         window.RTP.PinchZoom = definePinchZoom(window.$);
    791     }
    792 }).call(this);
    View Code

    页面效果:

    方式3:

    [1] 同样的随手势变化,实时监听中心坐标、两指见的距离,显示改变的百分比

    [2] 手指抬起后,获取最终变化的百分比,计算页面样式重绘

    该方案存在问题:

    安卓分机上,获取手指离开事件,有几率获取不到(加一个1s的延时,直接关闭提示,并计算样式)。

    重新计算样式,触发浏览器重绘动作,数据量较大的情况下,时间会比较慢。

    完整代码:

    HTML:

    <div id="showProportion" style="position: fixed;z-index: 99999; 16vw;height: 16vh;line-height: 16vh;left: 42vw;top:33vh;background: rgba(0,0,0,.5);text-align: center;color: #fff;font-size: 8vh;display: none;">100%</div>
    

      JS:

    (function(){
        var isTouch = false;
        var isDoubleTouch = false; //是否为多触点
        var start = []; //存放触点坐标
        var now, delta; //当前时间,两次触发事件时间差
        var timer = null; //计时器,触发单击事件
        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 oneTouch = new CustomEvent("oneTouch");
    
        //监听touchstart事件
        document.addEventListener('touchstart', function(e) {
            if (e.touches.length >= 2) { //判断是否有两个点在屏幕上
                isDoubleTouch = true;
                start = e.touches; //得到第一组两个点
                var screenMinPoint = getMidpoint(start[0], start[1]); //获取两个触点中心坐标
                gesturestart.midPoint = [screenMinPoint[0] - e.target.offsetLeft, screenMinPoint[1] - e.target.offsetTop]; //获取中心点坐标相对目标元素坐标
                e.target.dispatchEvent(gesturestart);
            } else {
                delta = Date.now() - now; //计算两次点击时间差
                now = Date.now();
                startPosition = [e.touches[0].pageX, e.touches[0].pageY];
                if (delta > 0 && delta <= 250) { //双击事件
                    clearTimeout(timer);
    
                    doubleTouch.position = [e.touches[0].pageX - e.target.offsetLeft, e.touches[0].pageY - e.target.offsetTop];
                    e.target.dispatchEvent(doubleTouch);
                } else { //滑动事件
                    timer = setTimeout(function(){
                        e.target.dispatchEvent(oneTouch);//单击事件
                    },450)
                }
                isTouch = true;
    
            }
        }, false);
        //监听touchmove事件
        document.addEventListener('touchmove', function(e) {
            clearTimeout(timer);
    
            if (e.touches.length >= 2 && isDoubleTouch) { //手势事件
                var now = e.touches; //得到第二组两个点
                // console.log('移动:',now);
                var scale = getDistance(now[0], now[1]) / getDistance(start[0], start[1]); //得到缩放比例
                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);
    
                if(Math.abs(now[1]['clientX'] - now[0]['clientX'])>50 && Math.abs(now[1]['clientY'] - now[0]['clientY'])<50){
                    TouchChange.move(gesturechange);
                }else{
                    isDoubleTouch = false
                }
    
            } 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);
        //监听touchend事件
        document.addEventListener('touchend', function(e) {
            if (isDoubleTouch) {
                var now = e.touches; //得到第二组两个点
                // console.log(now);
                isDoubleTouch = false;
                gestureend.position = endPosition;
                e.target.dispatchEvent(gestureend);
    
                TouchChange.end(gesturechange);
            };
        }, false);
        /*
         * 两点的距离
         */
        function getDistance(p1, p2) {
            var x = p2.pageX - p1.pageX,
                y = p2.pageY - p1.pageY;
            return Math.sqrt((x * x) + (y * y));
        };
        /*
         * 两点的夹角
         */
        function getAngle(p1, p2) {
            var x = p1.pageX - p2.pageX,
                y = p1.pageY - p2.pageY;
            return Math.atan2(y, x) * 180 / Math.PI;
        };
        /*
         * 获取中点
         */
        function getMidpoint(p1, p2) {
            var x = (p1.pageX + p2.pageX) / 2,
                y = (p1.pageY + p2.pageY) / 2;
            return [x, y];
        }
    
    })()
    
    targetTouches = function (touches) {
        return Array.prototype.slice.call(touches).map(function (touch) {
            return {
                x: touch.pageX,
                y: touch.pageY
            };
        });
    };
    
    
    var TouchChange = {
        scalingRatio: 1 , // 初始比例
        DOM : $(".container"),
        /**
         * 手指移动事件
         * @param gesturechange
         */
        move: function (gesturechange) {
            var _this = this;
            var scale = parseInt(gesturechange.scale * 100);
            _this.scalingRatio = gesturechange.scale;
            if(scale > 200){
                scale = 200;
            }else if (scale < 70){
                scale = 70;
            }
            scale += '%';
    
            setTimeout(function () {
                _this.closeProportion()
            },1000)
    
            $("#showProportion").show();
            $("#showProportion").html(scale);
        },
        /**
         * 如果比例提示框还在显示,
         * 关闭提示框,并计算样式
         */
        closeProportion:function(){
            var _this = this;
            if($('#showProportion').is(':hidden')){
    
                //如果隐藏时。。。
    
            }else{
                //如果显示时。。。
                _this.end({scale: _this.scalingRatio})
            }
        },
        /**
         * 手指抬起事件
         * 重新计算样式
         * @param gesturechange
         */
        end: function (gesturechange) {
            var _this = this;
            var scale = gesturechange.scale;
            if(scale > 2){
                scale = 2;
            }else if (scale < 0.7){
                scale = 0.7;
            }
    
            _this.scalingRatio = scale;
            $("#showProportion").hide();
            resize_resolution(scale);
        }
    }
      1 //分辨率
      2 function resize_resolution(proportion) {
      3     width = document.body.clientWidth || document.documentElement.clientWidth;
      4     height = document.body.clientHeight || document.documentElement.clientHeight;
      5     w = width / 1863;
      6     h = height / 855;
      7     console.log('2', width, w, height, h);
      8     w = parseFloat(w.toFixed(2));
      9     h = parseFloat(h.toFixed(2));
     10     if(proportion && proportion !== 1){
     11         w = w*proportion;
     12         h = h*proportion;
     13     }
     14 
     15 
     16     //if(w != 1){
     17     $('.card').css({
     18          305 * w + 'px',
     19         height: 160 * h + 'px',
     20     });
     21     $('.card .top').css({
     22         height: 80 * h + 'px',
     23     });
     24     $('.card .bed_no').css({
     25          76.7 * w + 'px',
     26         lineHeight: 68 * h + 'px',
     27         fontSize: 46.97 * w + 'px',
     28     });
     29     $('.card .top .name_sex_age').css({
     30         //  227.3 * w + 'px',
     31          220 * w + 'px',
     32         // height: 44 * h + 'px',
     33         height: 60 * h + 'px',
     34         // lineHeight: 44 * h + 'px',
     35         lineHeight: 60 * h + 'px',
     36         fontSize: 15.45 * w + 'px',
     37     });
     38     $('.card .top .name').css({
     39         //  140 * w + 'px',
     40          130 * w + 'px',
     41         paddingLeft: 15 * w + 'px',
     42         fontSize: 36.7 * w + 'px',
     43         height: 44 * h + 'px',
     44         lineHeight: 44 * h + 'px',
     45     });
     46     $('.card .top .name p').css({
     47         height: 44 * h + 'px',
     48          145 * w + 'px',
     49     });
     50     // $('.simple_card .card .top .name').css({
     51     //     height: 60 * h + 'px',
     52     //     lineHeight: 60 * h + 'px',
     53     // });
     54     $('.card .top .sex').css({
     55          20 * w + 'px',
     56         fontSize: 15.45 * w + 'px',
     57     });
     58     $('.card .top .age').css({
     59          50 * w + 'px',
     60         fontSize: 15.45 * w + 'px',
     61     });
     62     $('.card .top .id p:first-child').css({
     63         fontSize: 15.45 * w + 'px',
     64     });
     65     $('.card .top .id').css({
     66         height: 24 * h + 'px',
     67         paddingLeft: 15 * w + 'px',
     68          119 * w + 'px',
     69     });
     70     $('.card .top .ryrq').css({});
     71     $('.card .middle').css({
     72         height: 58 * h + 'px',
     73         // marginTop: 5 * h + 'px',
     74         // marginBottom: 5 * h + 'px',
     75         marginTop: 0 * h + 'px',
     76         marginBottom: 0 * h + 'px',
     77     });
     78     $('.card .bottom').css({
     79         height: 15 * h + 'px',
     80         paddingLeft: 22 * w + 'px',
     81         paddingRight: 22 * w + 'px',
     82         fontSize: 15.45 * w + 'px',
     83     });
     84     $('.card .middle .label4').css({
     85         paddingLeft: 22 * w + 'px',
     86         height: 44 * h + 'px',
     87         paddingRight: 22 * w + 'px',
     88     });
     89     $('.card .label4 li').css({
     90          44 * w + 'px',
     91         height: 44 * h + 'px',
     92         lineHeight: 44 * h + 'px',
     93         fontSize: 23.49 * w + 'px',
     94     });
     95     $('.card .middle .label5-8').css({
     96         marginTop: 15 * h + 'px',
     97         height: 36 * h + 'px',
     98         marginBottom: 15 * h + 'px',
     99     });
    100     $('.card .label5-8 li').css({
    101          36 * w + 'px',
    102         height: 36 * w + 'px',
    103         lineHeight: 36 * w + 'px',
    104         fontSize: 20 * w + 'px',
    105         marginLeft: 5 * w + 'px',
    106         marginRight: 5 * w + 'px',
    107     });
    108     $('.card .middle .label9-16').css({
    109         paddingTop: 2 * h + 'px',
    110         paddingLeft: 3 * w + 'px',
    111         paddingRight: 3 * w + 'px',
    112         paddingBottom: 2 * h + 'px',
    113         marginTop: 10 * h + 'px',
    114     });
    115     $('.card .label9-16 li').css({
    116          30 * w + 'px',
    117         height: 30 * w + 'px',
    118         lineHeight: 30 * w + 'px',
    119         fontSize: 17 * w + 'px',
    120         marginTop: 3 * h + 'px',
    121         marginLeft: 7.5 * w + 'px',
    122         marginRight: 7.5 * w + 'px',
    123         marginBottom: 10 * h + 'px',
    124     });
    125     // console.log(top.card_type);
    126     if (top.card_type) {
    127         $('.simple_card').css({
    128              305 * w + 'px',
    129             // height: 60 * h + 'px',
    130             height: 82 * h + 'px',
    131             // flexBasis: 300 * w + 'px',
    132             flexBasis: 305 * w + 'px',
    133             // marginBottom: 22 * h + 'px',
    134             marginBottom: 10.2 * h + 'px',
    135             marignLeft: 5.2 * w + 'px',
    136             marginRiht: 5.2 * w + 'px',
    137         });
    138         // }
    139         $('.simple_card .top').css({
    140             height: 82 * h + 'px',
    141         });
    142         $('.simple_card .top .bed_no').css({
    143             // minWidth: 60 * w + 'px',
    144             // height: 60 * h + 'px',
    145             // lineHeight: 60 * h + 'px',
    146             minWidth: 82 * w + 'px',
    147             height: 82 * h + 'px',
    148             lineHeight: 82 * h + 'px',
    149         });
    150         $('.simple_card .top .name_sex_age').css({
    151             height: 50 * h + 'px',
    152             lineHeight: 50 * h + 'px',
    153         });
    154         $('.simple_card .top .name').css({
    155              130 * w + 'px',
    156             fontSize: 36 * w + 'px',
    157             lineHeight: 60 * h + 'px',
    158             paddingLeft: 5 + 'px',
    159         });
    160         $('.simple_card .card .top .ryrq').css({
    161             height: 30 * h + 'px',
    162             lineHeight: 30 * h + 'px',
    163             paddingLeft: 10 * w + 'px',
    164              200 * w + 'px',
    165         });
    166         $('.card .top .name p').css({
    167             height: 44 * h + 'px',
    168              100 * w + 'px',
    169         });
    170         $('.simple_card .top .sex').css({
    171             lineHeight: 65 * h + 'px',
    172             fontSize: 18 + w + 'px',
    173         });
    174         $('.simple_card .top .payOff').css({
    175             fontSize: 20 * w + 'px',
    176             // right: 16 * w + 'px',
    177             right: 5 * w + 'px',
    178             height: 60 * w + 'px',
    179             lineHeight: 65 * h + 'px',
    180         });
    181     }
    182     //详情
    183     $('.detail_container .top').css({
    184         height: 168 * h + 'px',
    185         property2: 'value2'
    186     });
    187     $('.detail_container .top .nav').css({
    188         height: 86 * h + 'px',
    189         lineHeight: 86 * h + 'px',
    190         fontSize: 40 * w + 'px'
    191     });
    192     $('.detail_container .top .simple_info').css({
    193         height: 82 * h + 'px',
    194         fontSize: 32 * w + 'px'
    195     });
    196     $('.detail_container .simple_info .left').css({
    197          1000 * w + 'px'
    198     });
    199     $('.detail_container .simple_info .left ul').css({
    200         height: 82 * h + 'px',
    201         lineHeight: 82 * w + 'px'
    202     });
    203     $('.detail_container .simple_info .left li').css({
    204         marginLeft: 45 * w + 'px'
    205     });
    206     $('.detail_container .simple_info .right').css({
    207          800 * w + 'px'
    208     });
    209     $('.detail_container .simple_info .right ul').css({
    210         marginTop: 19 * h + 'px',
    211         marginLeft: 19 * w + 'px',
    212         marginRight: 19 * w + 'px',
    213         marginBottom: 19 * h + 'px'
    214     });
    215     $('.detail_container .middle').css({
    216         height: 640 * h + 'px',
    217         fontSize: 30 * w + 'px'
    218     });
    219     $('.detail_container .middle table').css({
    220          1730 * w + 'px',
    221         fontSize: 30 * w + 'px'
    222     });
    223     $('.detail_container .middle td.left').css({
    224          250 * w + 'px'
    225     });
    226     $('.detail_container .middle td.right').css({
    227          610 * w + 'px'
    228     });
    229     $('.detail_container .middle td').css({
    230         lineHeight: 81 * h + 'px'
    231     });
    232     $('.detail_container .bottom').css({
    233         height: 59 * h + 'px',
    234         lineHeight: 59 * h + 'px'
    235     });
    236     //}
    237 }
    View Code

    页面效果:

    方式4:

    将iframe中的页面单独拿出来,有安卓加一个新的webview,加载这个页面,手势动作由安卓端显示,手指拿开后,传一个缩放比例来,前端计算需要显示的页面样式。

  • 相关阅读:
    心情日记:疯人疯语
    疾病研究:转载口服药物恢复了杜氏进行性肌营养不良患者缺失的蛋白
    报告论文:游程(行程)长度编码matlab(或者C++)实现
    技巧心得:没有 显示隐藏的文件和文件夹 选项
    视频教程:YUV420和RGB相互转换C++实现(二)
    应聘经历:网易公司 笔试
    视频教程:YUV和RGB相互转换MATLAB实现(一)
    读书札记:7天搞定C语言(一)
    嵌入式系统Linux内核开发工程师必须掌握的三十道题
    交流:IT学习大本营:“2×10+10:积分+资源分”大派送
  • 原文地址:https://www.cnblogs.com/pangchunlei/p/14231013.html
Copyright © 2011-2022 走看看