import Coordinate from '../../utils/coordinate'; import { height, width } from '../../utils/css'; export default class Translate { constructor(transitioner, slider, options = {}) { this.transitioner = transitioner; this.slider = slider; this.options = { ...options }; this.onTransitionEnd = this.onTransitionEnd.bind(this); } init() { this._position = new Coordinate(this.slider.container.offsetLeft, this.slider.container.offsetTop); this._bindEvents(); return this; } destroy() { this._unbindEvents(); } _bindEvents() { this.slider.container.addEventListener('transitionend', this.onTransitionEnd); } _unbindEvents() { this.slider.container.removeEventListener('transitionend', this.onTransitionEnd); } enable() { this.slider.container.style.transition = `${this.options.duration}ms ${this.options.timing}`; } disable() { this.slider.container.style.transition = 'none'; } apply() { let maxOffset; if (this.options.effect === 'translate') { const slide = this.slider.slides.filter(slide => slide.dataset.sliderIndex == this.slider.state.next)[0]; const slideOffset = new Coordinate(slide.offsetLeft, slide.offsetTop); if (this.options.centerMode) { maxOffset = new Coordinate(Math.round(width(this.slider.container)), Math.round(height(this.slider.container))); } else { maxOffset = new Coordinate(Math.round(width(this.slider.container) - width(this.slider.wrapper)), Math.round(height(this.slider.container) - height(this.slider.wrapper))); } const nextOffset = new Coordinate(Math.min(Math.max(slideOffset.x * -1, maxOffset.x * -1), 0), Math.min(Math.max(slideOffset.y * -1, maxOffset.y * -1), 0)); if (this.options.loop) { if (!this.options.vertical && Math.abs(this._position.x) > maxOffset.x) { nextOffset.x = 0; this.slider.state.next = 0; } else if (this.options.vertical && Math.abs(this._position.y) > maxOffset.y) { nextOffset.y = 0; this.slider.state.next = 0; } } this._position.x = nextOffset.x; this._position.y = nextOffset.y; if (this.options.centerMode) { this._position.x = this._position.x + (this.slider.wrapperWidth / 2) - (width(slide) / 2); } if (this.slider.direction === 'rtl') { this._position.x = -this._position.x; this._position.y = -this._position.y; } this.slider.container.style.transform = `translate3d(${this._position.x}px, ${this._position.y}px, 0)`; /** * update the index with the nextIndex only if * the offset of the nextIndex is in the range of the maxOffset */ if (slideOffset.x > maxOffset.x) { this.slider.transitioner.end(); } } } onTransitionEnd(e) { if (this.options.effect === 'translate') { if (this.transitioner.isAnimating() && e.target == this.slider.container) { if (this.options.infinite) { this.slider._infinite.onTransitionEnd(e); } } this.transitioner.end(); } } }