vevet
Version:
Vevet is a JavaScript library for creative development that simplifies crafting rich interactions like split text animations, carousels, marquees, preloading, and more.
164 lines • 5.07 kB
JavaScript
import { Swipe } from '../../../components/Swipe';
export class SnapSwipe {
constructor(snap) {
this.snap = snap;
snap.on('destroy', () => this._destroy(), { protected: true });
this._startIndex = snap.activeIndex;
this._startTime = 0;
this._swipe = new Swipe({
container: snap.container,
enabled: snap.props.swipe,
grabCursor: snap.props.grabCursor,
minTime: snap.props.swipeMinTime,
threshold: snap.props.swipeThreshold,
axis: this.axis,
inertia: snap.props.freemode,
});
this._swipe.on('start', (data) => this._handleSwipeStart(data));
this._swipe.on('move', (data) => this._handleSwipeMove(data));
this._swipe.on('end', (data) => this._handleSwipeEnd(data));
// on props change
snap.on('props', () => {
this._swipe.updateProps({
enabled: snap.props.swipe,
grabCursor: snap.props.grabCursor,
minTime: snap.props.swipeMinTime,
threshold: snap.props.swipeThreshold,
axis: this.axis,
inertia: snap.props.freemode,
});
}, { protected: true });
}
/** Axis name depending on swipe direction */
get axis() {
const { snap } = this;
return snap.props.swipeAxis === 'auto' ? snap.axis : snap.props.swipeAxis;
}
/** Check if swiping in action */
get isSwiping() {
return this._swipe.isSwiping;
}
/** Detect if swipe is short */
get isShort() {
const { props } = this.snap;
if (!props.shortSwipes) {
return false;
}
const diff = +new Date() - this._startTime;
return diff <= props.shortSwipesDuration;
}
/** Checks if resistance is allowed */
get allowFriction() {
return !this.isShort && this.snap.props.swipeFriction;
}
/** Swipe difference between start and current coordinates */
get diff() {
return this.axis === 'x' ? this._swipe.diff.x : this._swipe.diff.y;
}
/**
* Handles swipe `start` event.
*/
_handleSwipeStart(coords) {
const { snap } = this;
this._startIndex = snap.activeIndex;
this._startTime = +new Date();
// disable pointer events
snap.container.style.pointerEvents = 'none';
// cancel sticky behavior
if (snap.props.followSwipe) {
snap.cancelTransition();
}
// Emit callbacks
snap.callbacks.emit('swipeStart', coords);
}
/**
* Handles swipe `move` event.
*/
_handleSwipeMove(coords) {
const { snap } = this;
const { swipeSpeed, followSwipe: shouldFollow } = snap.props;
if (!shouldFollow) {
return;
}
// Normalize wheel data
const swipeDelta = this.axis === 'x' ? coords.step.x : coords.step.y;
const delta = swipeDelta * -swipeSpeed;
// Update track target
snap.track.iterateTarget(delta);
// Clamp target if inertia active
if (this._swipe.hasInertia) {
snap.track.clampTarget();
}
// Emit move callbacks
snap.callbacks.emit('swipe', coords);
}
/** Handles swipe `end` event */
_handleSwipeEnd(coords) {
this._end();
// Enable pointer events
this.snap.container.style.pointerEvents = '';
// Emit end callbacks
this.snap.callbacks.emit('swipeEnd', coords);
}
/** End swipe action */
_end() {
const { snap, _swipe: swipe } = this;
const { props, track } = snap;
if (!props.followSwipe) {
this._endNoFollow();
return;
}
if (props.freemode) {
if (!track.canLoop &&
(track.target < track.min || track.target > track.max)) {
swipe.cancelInertia();
snap.stick();
}
return;
}
if (snap.track.isSlideScrolling) {
return;
}
if (this.isShort) {
this._endShort();
}
else {
snap.stick();
}
}
/** End short swipe */
_endShort() {
const { diff, snap } = this;
const { props } = snap;
if (Math.abs(diff) < props.shortSwipesThreshold ||
this._startIndex !== snap.activeIndex) {
snap.stick();
return;
}
if (Math.sign(diff) < 0) {
snap.next();
}
else {
snap.prev();
}
}
/** End action when `followSwipe` is disabled */
_endNoFollow() {
const { diff, snap } = this;
if (Math.abs(diff) < 20) {
snap.stick();
return;
}
if (diff < 0) {
snap.next();
}
else {
snap.prev();
}
}
/** Destroy swipe */
_destroy() {
this._swipe.destroy();
}
}
//# sourceMappingURL=index.js.map