vevet
Version:
Vevet is a JavaScript library for creative development that simplifies crafting rich interactions like split text animations, carousels, marquees, preloading, and more.
98 lines • 3.04 kB
JavaScript
import { addEventListener, normalizeWheel } from '../../../utils';
export class SnapWheel {
constructor(_snap) {
this._snap = _snap;
/** Detects if wheel event is started */
this._hasStarted = false;
/** Accummulated wheel value for `followWheel=false` */
this._accum = 0;
_snap.on('destroy', () => this._destroy(), { protected: true });
this._destructor = addEventListener(_snap.container, 'wheel', (event) => this._handleWheel(event));
}
/** Snap component */
get snap() {
return this._snap;
}
/**
* Handles wheel events
*/
_handleWheel(event) {
const { snap } = this;
if (!snap.props.wheel) {
return;
}
event.preventDefault();
const { wheelAxis } = snap.props;
// Start callback
if (!this._hasStarted) {
this._hasStarted = true;
snap.callbacks.emit('wheelStart', undefined);
}
// Move callback
snap.callbacks.emit('wheel', event);
// Normalize wheel data
const axis = wheelAxis === 'auto' ? snap.axis : wheelAxis;
const wheelData = normalizeWheel(event);
const wheelDelta = axis === 'x' ? wheelData.pixelX : wheelData.pixelY;
const delta = wheelDelta * snap.props.wheelSpeed;
// Update wheel target
if (snap.props.followWheel) {
this._handleFollow(delta);
}
else {
this._handleNotFollow(delta);
}
// Debounce End
if (this._debounceEnd) {
clearTimeout(this._debounceEnd);
}
// End callback
this._debounceEnd = setTimeout(() => this._handleEnd(), 100);
}
/** Handle `followWheel=true` */
_handleFollow(delta) {
const { snap } = this;
// Cancel snap transition
snap.cancelTransition();
// Update track target
snap.track.iterateTarget(delta);
snap.track.clampTarget();
}
/** Handle `followWheel=false` */
_handleNotFollow(delta) {
if (this.snap.isTransitioning || Math.abs(delta) < 10) {
return;
}
this._accum += Math.abs(delta) / 2;
const direction = Math.sign(delta);
if (Math.abs(this._accum) < 100) {
return;
}
if (direction === 1) {
this.snap.next();
}
else {
this.snap.prev();
}
this._accum = 0;
}
/** Handle wheel end */
_handleEnd() {
const { snap } = this;
const { freemode: isFreemode, followWheel: isFollow } = snap.props;
this._hasStarted = false;
this._accum = 0;
if (!isFreemode && isFollow) {
snap.stick();
}
snap.callbacks.emit('wheelEnd', undefined);
}
/** Destroy wheel listeners */
_destroy() {
this._destructor();
if (this._debounceEnd) {
clearTimeout(this._debounceEnd);
}
}
}
//# sourceMappingURL=index.js.map