Web开发我爱编程

双指缩放的实现方式对比

2018-04-15  本文已影响131人  nimw

一、双指缩放的实现方式

方式一: 根据手势计算scale重新render生成视图

实现逻辑

(1) 通过Web端手势库 AlloyFinger 获取元素onPinch事件的双指缩放比例scale。
(2) 修改DOM元素的宽高和字体大小,重新render视图

优点

(1) 清晰度
通过js修改元素样式,缩放过程中一直很清晰。
(2) 兼容性
通过js修改修改元素样式并重新render,不存在兼容性问题。
(3) 报表冻结
可以实现冻结报表在缩小的过程中展示更多内容。
(4) 局部缩放
可以实现整个页面不缩放,只缩放页面局部元素的效果。

缺点

(1) 性能
在双指缩放的过程中频繁执行js代码,持续render,性能很差。

方式二: 根据手势计算scale修改元素scale()样式

实现逻辑

(1) 通过Web端手势库 AlloyFinger 获取元素onPinch事件的双指缩放比例scale。
(2) 通过Web端CSS3动画库transformjs修改DOM元素的transform:scale缩放比例。

优点

(1) 性能
双指缩放的过程中不需要重新render,只修改DOM元素的scale,性能很好。
(2) 局部缩放
可以实现整个页面不缩放,只缩放页面局部元素的效果。

缺点

(1) 清晰度
放大过程中,在iOS设备浏览器中,清晰度降低。
(2) 报表冻结
难以实现冻结报表在缩小的过程中展示更多内容。
(3) 兼容性
不同系统、不同浏览器对transform:scale的CSS样式解析不同,兼容性不好。
(4) 父容器
在iOS设备浏览器中,被修改transform:scale元素(A)父元素(B)的滚动条以A元素的初始尺寸大小为准进行滚动条分配。如果元素A的scale增加了,则A在B中会滚不到头。除非同比例修改A的width和height,但这样在ios设备浏览器中又可能导致页面空白的bug。此问题未找到较好的解决办法,在android中没有此问题。

方式三: 浏览器默认实现

实现逻辑

通过动态修改"type=viewport"的meta标签的content属性值控制单页应用不同页面是否禁止双指缩放。

优点

(1) 性能
浏览器实现,性能最好
(2) 清晰度
浏览器实现,清晰度很好
(3) 兼容性
浏览器实现,兼容性一般

缺点

(1) 局部缩放
难以实现整个页面不缩放,只缩放页面局部元素的效果。
(2) 报表冻结
难以实现冻结报表在缩小的过程中展示更多内容。

方案对比

方案对比 根据手势计算scale重新render生成视图 根据手势计算scale修改元素scale()样式 浏览器默认实现
清晰度 iOS差
性能
兼容
冻结展示 可变 不可变 不可变
局部缩放 可以 可以 不可以
父容器 可变 iOS不可变 可变

方案选择

最终方案

(1) iOS设备性能较好,使用“方式一”解决方案。
(2) Android非冻结报表使用“方式二”解决方案。
(3) Android冻结报表使用双指缩放过程“方式二”,双指松开使用“方式一”解决方案。

代码实现

   /**
     * 双指缩放
     * @param evt
     */
    onPinch(evt){
        evt.stopPropagation();
        if(Device.ios()) {
            //重新render
            const lastScale = this.scale;
            const scale = lastScale * evt.scale;
            this.setTableZoomScale(scale);
        } else {
            if(this._isAnyFrozenTable()) {
                //缩放时修改CSS,松开时重新render
                let cssScale = this._getReportNodeCssScale();
                if(evt.scale / cssScale > 0.66 && evt.scale / cssScale < 1.5) {
                    this._setReportNodeCssScale(evt.scale);
                }
            } else {
                //只修改CSS
                const scale = this.cssScale * evt.scale;
                this._setBodyTableCssScale(scale);
            }

        }
    }

    /**
     * 多手指触摸释放事件
     */
    onMultipointEnd(){
        if(Device.ios()) {
            this.scale = this.reportRef.tableManager.getScale();
        } else {
            if(this._isAnyFrozenTable()) {
                //重新render
                let cssScale = this._getReportNodeCssScale();
                this.scale = cssScale * this.scale;
                this.setTableZoomScale(this.scale, ()=> {
                    this._setReportNodeCssScale(1);
                });
            } else {
                this._saveBodyTableCssScale();
            }
        }
    }
上一篇下一篇

猜你喜欢

热点阅读