0
Hammer JS 2.0.8을 사용하여 사용자 정의 회전 목마를 만들 때 유동적으로 작동하는 데 약간의 문제가있었습니다. 여러 번 시도한 후 실제로 도움이되는 코드 조각을 발견했으며 결국 모듈을 완성 할 때 Richard Liu의Hammer JS를 회전 목마로 사용
Hammer JS 2.0.8을 사용하여 사용자 정의 회전 목마를 만들 때 유동적으로 작동하는 데 약간의 문제가있었습니다. 여러 번 시도한 후 실제로 도움이되는 코드 조각을 발견했으며 결국 모듈을 완성 할 때 Richard Liu의Hammer JS를 회전 목마로 사용
This was the snippet that really helped 등으로 똑같이 공유하기로 결정했습니다.
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)`;
}
}