sencha touch的pinch zoom控件

pinch zoom是移动应用中非常实用的手势,尤其用于图片浏览。

遗憾的是sencha touch2仍然没有提供现成的官方控件。

人肉了下,找到以下资源:

1.https://market.sencha.com/extensions/pinch-zoom-image

 测试了下这个plug-in,存在明显的性能问题,缩放和平移均存在响应迟滞。

 

2.https://github.com/SunboX/ST2_ImageViewer

 有关此控件的讨论,参见这篇帖子:

 http://www.sencha.com/forum/showthread.php?197903-Pinch-Image-with-carousel-and-working-fine/page6

 此控件响应流畅,但存在一个明显的不足,就是当pinchEnd时,总是会出现画面闪烁。

认真读了相关代码,line254

 

    onImagePinchEnd : function(ev) {
        var me = this;

        // set new translation
        if (me.scale == me.baseScale) {
            // move to center
            me.setTranslation(me.translateBaseX, me.translateBaseY);
        } else {
            //Resize to init size like ios
            if (me.scale < me.baseScale && me.getResizeOnLoad()) {
                me.resetZoom();
                return;
            }
            // calculate rescaled origin
            me.originReScaledImgX = me.originScaledImgX * (me.scale / me.startScale);
            me.originReScaledImgY = me.originScaledImgY * (me.scale / me.startScale);

            // maintain zoom position
            me.setTranslation(me.originViewportX - me.originReScaledImgX, me.originViewportY - me.originReScaledImgY);
        }
        // reset origin and update transform with new translation
        me.setOrigin(0, 0);
        me.applyTransform();

        // adjust scroll container
        me.adjustScroller();
    },

 

 

分析结论如下:

  pinch end结束时出现闪烁,是由于直接将transform缩放之后的图片,由改变宽高、然后scrollto局部。

 

这中间改变宽高,再scrollto,始终对一个图片操作,而这个过程,图片经历了位置、尺寸的变化。

 

改进的思路如下:

要避免闪烁,必须做到,在图片的整个改变中,显示在屏幕前的始终是同样的画面,那么改变只能在后面发生,可以利用background-image作为切换的遮羞布。

具体步骤是:

  • 通过设置底图,先将底图变化为与当前局部一致;
  • 隐藏图片,显示底图,由于两者一致,不会出现闪烁;
  • 变化图片坐标,scrollto局部;
  • 显示图片;
  • 隐藏底图;
  • 整个过程最前面的局部图始终保持不变,因此去掉闪烁。

改进后的代码:

    onImagePinchEnd : function(ev) {
        var me = this;

        // set new translation
        if (me.scale == me.baseScale) {
            // move to center
            me.setTranslation(me.translateBaseX, me.translateBaseY);
        } else {
            //Resize to init size like ios
            if (me.scale < me.baseScale && me.getResizeOnLoad()) {
                me.resetZoom();
                return;
            }
            // calculate rescaled origin
            me.originReScaledImgX = me.originScaledImgX * (me.scale / me.startScale);
            me.originReScaledImgY = me.originScaledImgY * (me.scale / me.startScale);

            // maintain zoom position
            me.setTranslation(me.originViewportX - me.originReScaledImgX, me.originViewportY - me.originReScaledImgY);
        }
        
        //c4w       
        var scale=me.scale;
        var bw = me.imgWidth * scale;
        var bh = me.imgHeight * scale;
		var bs=bw+'px '+bh+'px';
        var x = 0;
        if (me.scrollX!=0) {
            x = me.scrollX;
        }else{
        	x = me.translateX;
        }
        
        var y = 0;
        if (me.scrollY!=0) {
            y = me.scrollY;
        }else{
        	 y = me.translateY;
        }
        var px=x+'px '+y+'px';
		
        me.element.setStyle({
            backgroundImage : 'url(' + me.getImageSrc() + ')',
            backgroundAttachment: 'fixed',
            backgroundPosition : px,
            backgroundSize: bs,
            backgroundRepeat : 'no-repeat'
        });

        me.imgEl.dom.style.visibility ='hidden';
        //c4w
        //me.ds=px+"\n"+bs;
       setTimeout(function() {
	        me.setOrigin(0, 0);
	        me.applyTransform();
	        // adjust scroll container
	        me.adjustScroller();

       		me.imgEl.dom.style.visibility ='visible';
			me.element.setStyle({
	           backgroundImage : 'none'
	        });
        }, 50);
		//c4wend
    },

 

在iphone4上做了测试,效果令人满意。

 

 

 

 

 

 

你可能感兴趣的:(Sencha Touch)