【问题标题】:Using Hammer JS as a carousel使用 Hammer JS 作为轮播
【发布时间】:2017-11-14 11:38:15
【问题描述】:

在使用 Hammer JS 2.0.8 构建自定义轮播时,我在使其流畅运行时遇到了一些麻烦。经过多次尝试,我找到了一个真正有帮助的sn-p,当我最终完成模块时,我决定在这里平等分享

【问题讨论】:

    标签: javascript hammer.js


    【解决方案1】:

    This was the snippet that really helped 来自 Richard Liu。

    由于某种原因,切换回 Hammer 2.0.4 使 pancancel/panend 回调更加可靠。从那里,我能够完成我的解决方案。 complete demo 也在 JSFiddle 上

    class Carousel {
    constructor(options) {
        this.transiting = false;
        this.activeCard = 1;
        this.offset = 0;
        this.delta = 0;
        this.element = options.carousel;
        this.slides = this.element.children.length;
        this.element.style.width = `${this.slides * 100}%`;
        this.width = options.carousel.clientWidth;
        this.boundaryLeft = 0;
        this.boundaryRight = ((this.count - 1) / this.count) * this.width;
        this.outOfBounds = false;
        this.panRequiredToMove = options.container.clientWidth * 0.25;
        this.hammer = new Hammer(options.container);
    
        this.init();
    }
    
    init() {
        var self = this;
    
        function handleHammer(e) {
            switch (e.type) {
                case 'swipeleft':
                case 'swiperight':
                    self.handleSwipe(e);
                    break;
                case 'panleft':
                case 'panright':
                case 'panend':
                case 'pancancel':
                    self.handlePan(e);
                    break;
            }
        }
    
        this.hammer.on('swipeleft swiperight panleft panright panend pancancel', handleHammer);
        this.element.addEventListener("transitionend", function (event) {
            this.classList.remove('carousel--in-motion');
        }, false);
    }
    
    handleSwipe(e) {
        switch (e.direction) {
            case Hammer.DIRECTION_LEFT:
                this.next();
                break;
            case Hammer.DIRECTION_RIGHT:
                this.previous();
                break;
        }
        this.hammer.stop(true);
    }
    
    checkBounds() {    
        var beforeFirstCard = this.activeCard === 1 && (this.offset + this.delta) >= this.boundaryLeft;
        var afterLastCard = this.activeCard === this.slides && Math.abs(this.offset + this.delta) >= this.boundaryRight;
    
        if (beforeFirstCard) {
            this.outOfBounds = { recoilPosition: this.boundaryLeft };
        } else if (afterLastCard) {
            this.outOfBounds = { recoilPosition: this.boundaryRight * -1 };
        } else {
            this.outOfBounds = false;
        }
    }
    
    handlePan(e) {
        switch (e.type) {
            case 'panleft':
            case 'panright':
                    this.checkBounds();
                if (this.outOfBounds) e.deltaX *= .2;
                this.transition(e.deltaX);
                break;
            case 'panend':
            case 'pancancel':
                if (this.outOfBounds) {
                    this.recoil(this.outOfBounds.recoilPosition);
                } else if (Math.abs(e.deltaX) > this.panRequiredToMove) {
                    e.deltaX > 0 ? this.previous() : this.next();
                } else {
                    this.recoil();
                }
                break;
        }
    }
    
    next() {
        if (this.activeCard < this.slides) {
            let newPosition = this.activeCard / this.slides * this.width * -1;
            this.goToSlide(newPosition, () => {
                this.activeCard++;
            });
        }
    }
    
    previous() {
        if (this.activeCard > 1) {
            let activeCard = this.activeCard - (this.slides - 1);
            let newPosition = activeCard / this.slides * this.width * -1;
            this.goToSlide(newPosition, () => {
                this.activeCard--;
            });
        }
    }
    
    goToSlide(position, callback) {
        let self = this;
        let currentPosition = this.offset + this.delta;
        this.transiting = true;
    
    // I used AnimatePlus for the other movement between slides
        animate({
            el: this.element,
            translateX: [`${currentPosition}px`, `${position}px`],
            duration: 300,
            easing: "easeInOutQuad",
            complete() {
                self.transiting = false;
                self.offset = position;
                self.delta = 0;
                if (callback) callback();
            }
        });
    }
    
    transition(deltaX) {
        this.delta = deltaX;
        let position = this.offset + this.delta;
        this.element.style.webkitTransform = `translateX(${position}px)`;
    }
    
    recoil(position) {      
        this.element.classList.add('carousel--in-motion');
        this.element.style.webkitTransform = `translateX(${position || this.offset}px)`;
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-25
      • 2013-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2017-05-02
      相关资源
      最近更新 更多