【问题标题】:Coverflow plugin for JQuery-Mobile适用于 JQuery-Mobile 的 Coverflow 插件
【发布时间】:2012-02-24 02:20:30
【问题描述】:

我正在寻找类似 @​​987654321@ 的东西,以便在 JQuery Mobile/Phonegap 应用程序中使用它。图库中的图片应该可以通过向左/向右滑动来更改。 到目前为止,我发现的所有插件要么不是为移动设备设计的,要么没有像苹果这样的 Coverflow 风格。

【问题讨论】:

标签: javascript jquery-mobile


【解决方案1】:

不知道有什么开箱即用的插件,但实际上使用 CSS3 和 Javascript 从头开始​​构建非常简单 - 您甚至可以在 iOS 设备上获得硬件加速。

基本上,你想做三件事:

  1. 设置一个基本的触摸/滑动事件处理程序。这样的事情是一个很好的起点(可能需要调整 - “getMovement”函数绝对不是处理检测滑动事件的最佳方法。您还需要为您的参数设置一些默认值,以防它们为空......实际上,您最好将它们替换为“选项”对象,因此您不需要这样做)。
    它还实现了 webkitAnimationEnd 和 webkitTransitionEnd(注意:这些事件在 Fennec 中具有不同的名称,如果您打算支持该浏览器)侦听器来检测您的 css3 动画/过渡何时完成,以便您可以连接回调动画完成后要运行的事件:

    function TouchHandler(elem, tStart, tEnd, sLFunc, sRFunc, aFunc, trFunc) {
        //Members
        this.element = elem;
        this.animations = 0;
        this.transitions = 0;
    
        //Callbacks
        this.touchStart = tStart;
        this.touched = tFunc;
        this.swipeLeft = sLFunc;
        this.swipeRight = sRFunc;
        this.transitioned = trFunc;
        this.animated = aFunc;
    
        //Event Listners
        if (window.Touch) this.element.addEventListener('touchstart', this, false);
        this.element.addEventListener('webkitAnimationEnd', this, false);
        this.element.addEventListener('webkitTransitionEnd', this, false);
    }
    
    //Methods
    TouchHandler.prototype = {
        handleEvent: function (e) {
            switch (e.type) {
                case 'touchstart': this.onTouchStart(e); break;
                case 'touchmove': this.onTouchMove(e); break;
                case 'touchend': this.onTouchEnd(e); break;
                case 'webkitAnimationEnd': this.onAnimEnd(e); break;
                case 'webkitTransitionEnd': this.onTransEnd(e); break;
            }
        },
        onTouchStart: function (e) {
            e.preventDefault();
            this.touchStart();
            this.moved = false;
            this.startX = event.touches[0].pageX;
            this.startY = event.touches[0].pageY;
            this.element.className += ' touched';
            console.log('touched! ' + this.element.className);
            this.element.addEventListener('touchmove', this, false);
            this.element.addEventListener('touchend', this, false);
        },
        onTouchMove: function (e) {
            if (this.animations == 0) {
                this.moved = true;
                this.changeInX = event.touches[0].pageX;
                this.changeInY = event.touches[0].pageY;
            }
        },
        onTouchEnd: function (e) {
            this.element.removeEventListener('touchmove', this, false);
            this.element.removeEventListener('touchend', this, false);
            if (this.element.className.search('touched') >= 0) { this.element.className = this.element.className.replace(' touched', ''); }
            console.log('untouched! ' + this.element.className);
            if (this.animations == 0 && this.transitions == 0) {
                if (!this.moved) {
                    this.touched();
                } else {
                    if (this.getMovement() == 'imprecise') {
                        this.touched();
                    }
                    if (this.getMovement() == 'swipeLeft') {
                        this.swipeLeft();
                    }
                    if (this.getMovement() == 'swipeRight') {
                        this.swipeRight();
                    }
                }
            }
        },
        onAnimEnd: function (e) {
            if (this.animations > 0) {
                this.animations -= 1;
                if (this.animations == 0) {
                    this.animated();
                }
            }
        },
        onTransEnd: function (e) {
            if (this.transitions > 0) {
                this.transitions -= 1;
                if (this.transitions == 0) {
                    this.transitioned();
                }
            }
        },
        getMovement: function () {
            var diffY = this.startY - this.changeInY;
            var diffX = this.startX - this.changeInX;
            var impreciseTouch  = (diffX < 30 || diffX > -30) && (diffY > -30 || diffY < 30);
            var swipeLeft       = diffX > 60 && (diffY > -30 || diffY < 30);
            var swipeRight      = diffX < -60 && (diffY > -30 || diffY < 30);
    
            if (impreciseTouch) { return 'imprecise'; }
            else if (swipeLeft) { return 'swipeLeft'; }
            else if (swipeRight){ return 'swipeRight'; }
        }
    };
    
  2. 在您的 CSS 中,将您的图像元素设置为绝对位置,这样它们在操作它们时就不会影响其他页面元素(对性能很重要,因为我们将尽量避免触发页面重排)。还要确保将 -webkit-transform-style(和 -moz-transform-style,如果您想支持 Fennec)设置为 preserve-3d - 这将允许您的内层保留它们在 3space 中的位置,而不是被浏览器人为地压平。我们将使用 css3 translate3drotateY 在用户滑动时移动和旋转图像元素。通过使用 3dTransforms,我们还在 iOS 浏览器中激活硬件加速。现在,为照片可以位于的每个可见位置设置一个 css3 过渡。根据您的图像,您有 5 个位置。让我们称它们为 prev2、prev1、current、next1、next2。每张照片还应该有一个 .photo 类,我们将使用它来设置过渡属性 例如:

    .photo-container {-webkit-transform-style:preserve-3d;}
    .prev2   {-webkit-transform:  translate3d(0px,0,0)   rotateY(-45deg);}
    .prev1   {-webkit-transform:  translate3d(200px,0,0) rotateY(-30deg);}
    .current {-webkit-transform:  translate3d(400px,0,0) rotateY(-45deg);}
    .next1   {-webkit-transform:  translate3d(600px,0,0) rotateY(-30deg);}
    .next2   {-webkit-transform:  translate3d(800px,0,0) rotateY(-45deg);}
    
    .photo{ 
        -webkit-transition: -webkit-transform 500ms ease-in-out; 
    }
    
  3. 实例化一个 touchHandler 对象并将其绑定到您想要监听触摸事件的任何 DOM 元素。它必须是正在转换的元素的父级,以便动画事件冒泡。您还可以实例化每张照片,但根据您的设置,结果会有所不同。您可能想要测试这两种设置。基本上,当 swipeLeft 触发时,您想从当前照片中删除 .current 类并添加一个 .next 类(使用 javascript/jquery) - 将其写入函数并在实例化时将其传递给 touchHandler 的参数。这可能是无组织的,因此最好扩展类(或编写另一个继承自它的类)以编程方式处理您的照片转换。理想情况下,您可以将代表照片的 DOM 元素存储在一个数组中,并使用 this.array[i] 迭代地操作这些元素......

希望这一切对你有意义......

【讨论】:

  • P.S. -- 此解决方案适用于 iOS 和 Android,尽管硬件加速只会在 iOS 设备上触发 AFAIK。
  • 我还建议不要使用 jQueryMobile。它很臃肿,它的触摸事件不是很敏感,而且当你的应用达到最小尺寸时,它的性能会变得非常糟糕。
  • @mikeyUX:Android 3.0及以上,支持硬件加速,需要在Manifest文件中配置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多