首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Hammer JS作为转盘

使用Hammer JS作为转盘
EN

Stack Overflow用户
提问于 2017-11-14 19:38:16
回答 1查看 370关注 0票数 0

在使用Hammer JS 2.0.8构建自定义旋转木马时,我遇到了一些让它流畅工作的问题。经过多次尝试,我发现了一个真正有用的代码片段,当我最终完成这个模块时,我决定在这里同样分享

EN

回答 1

Stack Overflow用户

发布于 2017-11-14 19:38:16

理查德·刘的This was the snippet that really helped报道。

出于某些原因,切换回Hammer 2.0.4使得pancancel/panend回调更可靠。从那时起,我能够完成我的解决方案。JSFiddle上也有一个complete demo

代码语言:javascript
复制
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)`;
}
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47284857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档