UNPKG

vevet

Version:

Vevet is a JavaScript library for creative development that simplifies crafting rich interactions like split text animations, carousels, marquees, preloading, and more.

362 lines 13.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SnapTrack = void 0; var Raf_1 = require("../../../components/Raf"); var Timeline_1 = require("../../../components/Timeline"); var isNumber_1 = require("../../../internal/isNumber"); var onlyFinite_1 = require("../../../internal/onlyFinite"); var utils_1 = require("../../../utils"); var math_1 = require("../../../utils/math"); var props_1 = require("../props"); var SnapTrack = /** @class */ (function () { function SnapTrack(props, _slides, ctx) { var _this = this; this.props = props; this._slides = _slides; this.ctx = ctx; /** Interpolation impulse */ this._impulse = { current: 0, target: 0 }; /** The current track value */ this._current = 0; /** The target track value */ this._target = 0; /** Whether the track is destroyed */ this._isDestroyed = false; // Create the animation frame this._raf = new Raf_1.Raf(); this._raf.on('frame', function () { return _this._handleRaf(); }); this._raf.on('play', function () { var _a; return (_a = ctx.onRafPlay) === null || _a === void 0 ? void 0 : _a.call(ctx); }); this._raf.on('pause', function () { var _a; return (_a = ctx.onRafPause) === null || _a === void 0 ? void 0 : _a.call(ctx); }); } Object.defineProperty(SnapTrack.prototype, "slides", { get: function () { return this._slides(); }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "targetIndex", { /** Gets the target slide index */ get: function () { return this._targetIndex; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "impulse", { /** Gets the interpolation impulse */ get: function () { return this._impulse.current; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "current", { /** Gets the current track value. */ get: function () { return this._current; }, /** Sets the current track value */ set: function (value) { this._current = value; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "target", { /** Gets the target track value. */ get: function () { return this._target; }, /** Sets the target track value */ set: function (value) { var containerSize = this.ctx.containerSize(); var diff = value - this._target; this._target = value; this._impulse.target += containerSize ? (0, onlyFinite_1.onlyFinite)(diff / containerSize) : 0; this._impulse.target = (0, math_1.clamp)(this._impulse.target, -1, 1); }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "canLoop", { /** Detect if can loop */ get: function () { var _a = this, props = _a.props, slides = _a.slides; return props.loop && slides.length > 1; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "loopedCurrent", { /** Get looped current value */ get: function () { return this.loopCoord(this.current); }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "offset", { /** Get track offset */ get: function () { var ctx = this.ctx; var origin = ctx.origin(); var containerSize = ctx.containerSize(); var firstSlideSize = ctx.firstSlideSize(); if (origin === 'center') { return containerSize / 2 - firstSlideSize / 2; } else if (origin === 'end') { return containerSize - firstSlideSize; } return 0; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "loopCount", { /** Get loop count */ get: function () { if (!this.canLoop) { return 0; } return Math.floor((0, onlyFinite_1.onlyFinite)(this.current / this.max)); }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "isTransitioning", { /** If transition in progress */ get: function () { return !!this._tm; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "min", { /** Get minimum track value */ get: function () { var containerSize = this.ctx.containerSize(); var origin = this.ctx.origin(); var firstSlide = this.slides[0]; if (this.canLoop) { return 0; } if (origin === 'center') { if (firstSlide.size > containerSize) { return containerSize / 2 - firstSlide.size / 2; } } if (origin === 'end') { if (firstSlide.size > containerSize) { return containerSize - firstSlide.size; } } return 0; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "max", { /** Get maximum track value */ get: function () { var containerSize = this.ctx.containerSize(); var origin = this.ctx.origin(); var _a = this, slides = _a.slides, canLoop = _a.canLoop, props = _a.props; var firstSlide = slides[0]; var lastSlide = slides[slides.length - 1]; var lastCoordWithSlide = lastSlide.staticCoord + lastSlide.size; var max = canLoop ? lastCoordWithSlide + (0, utils_1.toPixels)(props.gap) : lastCoordWithSlide - containerSize; if (canLoop) { return max; } if (origin === 'center') { max += containerSize / 2 - firstSlide.size / 2; if (lastSlide.size < containerSize) { max += containerSize / 2 - lastSlide.size / 2; } } if (origin === 'end') { max += containerSize - firstSlide.size; } if (origin === 'start') { max = Math.max(max, 0); } return max; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "progress", { /** Get track progress. From 0 to 1 if not loop. From -Infinity to Infinity if loop */ get: function () { return (0, onlyFinite_1.onlyFinite)(this.current / this.max); }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "isStart", { /** If the start has been reached */ get: function () { if (this.props.loop) { return false; } return Math.floor(this.target) <= Math.floor(this.min); }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "isEnd", { /** If the end has been reached */ get: function () { if (this.props.loop) { return false; } return Math.floor(this.target) >= Math.floor(this.max); }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "isInterpolated", { /** Whether the track is interpolated */ get: function () { return this.current === this.target && this._impulse.current === 0; }, enumerable: false, configurable: true }); /** Handle RAF update, interpolate track values */ SnapTrack.prototype._handleRaf = function () { var _a = this, isTransitioning = _a.isTransitioning, props = _a.props, raf = _a._raf; if (isTransitioning) { return; } // Interpolate track value var ease = raf.lerpFactor(props.lerp); this._lerp(ease); // Stop raf if target reached if (this.isInterpolated) { raf.pause(); } // Render the scene this.ctx.onRender(raf.duration); }; /** Awake requestAnimationFrame */ SnapTrack.prototype.awake = function () { this._raf.play(); }; /** Set track target value */ SnapTrack.prototype.updateTarget = function (value) { this.target = value; this.awake(); }; /** Clamp target value between min and max values */ SnapTrack.prototype.clampTarget = function () { if (!this.canLoop) { this.target = (0, math_1.clamp)(this.target, this.min, this.max); } this.awake(); }; /** Set a value to current & target value instantly */ SnapTrack.prototype.set = function (value) { this.current = value; this.target = value; this._impulse.current = 0; this._impulse.target = 0; }; /** Loop a coordinate if can loop */ SnapTrack.prototype.loopCoord = function (coord) { return this.canLoop ? (0, math_1.loop)(coord, this.min, this.max) : coord; }; /** Interpolate the current track value */ SnapTrack.prototype._lerp = function (initialFactor) { var _a = this, target = _a.target, impulse = _a._impulse; var lerpFactor = initialFactor; // Interpolate current value var rest = Math.abs(this.current - target); var fastThreshold = 3; if (rest < fastThreshold) { var fastProgress = 1 - rest / fastThreshold; var additionalFactor = (1 - lerpFactor) / 15; lerpFactor += additionalFactor * fastProgress; } this.current = (0, math_1.lerp)(this.current, target, lerpFactor, props_1.LERP_APPROXIMATION); // Interpolate impulse impulse.target = (0, math_1.lerp)(impulse.target, 0, lerpFactor, props_1.LERP_APPROXIMATION); impulse.current = (0, math_1.lerp)(impulse.current, impulse.target, lerpFactor, props_1.LERP_APPROXIMATION); }; /** Go to a definite coordinate */ SnapTrack.prototype.toCoord = function (coordinate, options) { var _this = this; var _a, _b; if (this._isDestroyed) { return false; } var _c = this, props = _c.props, ctx = _c.ctx; this.cancelTransition(); var start = this.current; var end = coordinate; var diff = Math.abs(end - start); var durationProp = (_a = options === null || options === void 0 ? void 0 : options.duration) !== null && _a !== void 0 ? _a : props.duration; var duration = (0, isNumber_1.isNumber)(durationProp) ? durationProp : durationProp(diff); if (diff === 0) { duration = 0; } var easing = (_b = options === null || options === void 0 ? void 0 : options.easing) !== null && _b !== void 0 ? _b : props.easing; var tm = new Timeline_1.Timeline({ duration: duration, easing: easing }); this._tm = tm; tm.on('start', function () { var _a; ctx.onTimelineStart(); (_a = options === null || options === void 0 ? void 0 : options.onStart) === null || _a === void 0 ? void 0 : _a.call(options); }); tm.on('update', function (data) { var _a; _this.current = (0, math_1.lerp)(start, end, data.eased); _this.target = _this.current; _this._impulse.current = _this._impulse.current * (1 - data.progress); _this._impulse.target = _this._impulse.current; if (data.progress === 1) { _this.setTargetIndex(undefined); _this._tm = undefined; } ctx.onTimelineUpdate(data); ctx.onRender(); (_a = options === null || options === void 0 ? void 0 : options.onUpdate) === null || _a === void 0 ? void 0 : _a.call(options, data); }); tm.on('end', function () { var _a; tm.destroy(); ctx.onTimelineEnd(); (_a = options === null || options === void 0 ? void 0 : options.onEnd) === null || _a === void 0 ? void 0 : _a.call(options); }); tm.on('destroy', function () { _this.setTargetIndex(undefined); }); tm.play(); return true; }; /** Set target index */ SnapTrack.prototype.setTargetIndex = function (value) { this._targetIndex = value; }; /** Cancel sticky behavior */ SnapTrack.prototype.cancelTransition = function () { var _a; (_a = this._tm) === null || _a === void 0 ? void 0 : _a.destroy(); this._tm = undefined; }; /** Destroy the instance */ SnapTrack.prototype.destroy = function () { this._isDestroyed = true; this._raf.destroy(); this.cancelTransition(); }; return SnapTrack; }()); exports.SnapTrack = SnapTrack; //# sourceMappingURL=index.js.map