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.

363 lines 14.1 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); 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 utils_1 = require("../../../../utils"); var math_1 = require("../../../../utils/math"); var props_1 = require("../../props"); var SnapLogic_1 = require("../SnapLogic"); var SnapTrack = /** @class */ (function (_super) { __extends(SnapTrack, _super); function SnapTrack(snap) { var _this = _super.call(this, snap) || this; /** Interpolation influence */ _this._influence = { current: 0, target: 0, }; /** The current track value */ _this._current = 0; /** The target track value */ _this._target = 0; // Create the animation frame _this._raf = new Raf_1.Raf(); _this._raf.on('frame', function () { return _this._handleRaf(); }); _this._raf.on('play', function () { return snap.callbacks.emit('rafPlay', undefined); }); _this._raf.on('pause', function () { return snap.callbacks.emit('rafPause', undefined); }); // Destroy raf _this.addDestructor(function () { return _this._raf.destroy(); }); // Destroy timeline _this.addDestructor(function () { return _this.cancelTransition(); }); return _this; } Object.defineProperty(SnapTrack.prototype, "isInterpolated", { /** Whether the track is interpolated */ get: function () { return this.current === this.target && this._influence.current === 0; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "influence", { /** Gets the interpolation influence */ get: function () { return this._influence.current; }, /** Sets the interpolation influence */ set: function (value) { this._influence.current = value; this._influence.target = value; }, 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.snap.containerSize; var diff = value - this._target; this._target = value; this._influence.target += containerSize ? diff / containerSize : 0; this._influence.target = (0, math_1.clamp)(this._influence.target, -1, 1); }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "canLoop", { /** Detect if can loop */ get: function () { var snap = this.snap; return snap.props.loop && snap.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 snap = this.snap; return snap.props.centered ? snap.containerSize / 2 - snap.firstSlideSize / 2 : 0; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "loopCount", { /** Get loop count */ get: function () { return Math.floor(this.current / this.max); }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "isTransitioning", { /** If transition in progress */ get: function () { return !!this._timeline; }, enumerable: false, configurable: true }); /** Set a value to current & target value instantly */ SnapTrack.prototype.set = function (value) { this.current = value; this.target = value; this._influence.current = 0; this._influence.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; }; Object.defineProperty(SnapTrack.prototype, "min", { /** Get minimum track value */ get: function () { var snap = this.snap; if (this.canLoop || snap.isEmpty) { return 0; } if (snap.props.centered) { var firstSlide = snap.slides[0]; if (firstSlide.size > snap.containerSize) { return snap.containerSize / 2 - firstSlide.size / 2; } } return 0; }, enumerable: false, configurable: true }); Object.defineProperty(SnapTrack.prototype, "max", { /** Get maximum track value */ get: function () { var _a = this.snap, containerSize = _a.containerSize, slides = _a.slides, isEmpty = _a.isEmpty, props = _a.props; var canLoop = this.canLoop; if (isEmpty) { return 0; } 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 (props.centered) { max += containerSize / 2 - firstSlide.size / 2; if (lastSlide.size < containerSize) { max += containerSize / 2 - lastSlide.size / 2; } } if (!props.centered) { 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 this.current / this.max; }, enumerable: false, configurable: true }); /** Awake requestAnimationFrame */ SnapTrack.prototype.awake = function () { this._raf.play(); }; /** Iterate track target value */ SnapTrack.prototype.iterateTarget = function (delta) { this.target += delta; this.awake(); }; /** Set track target value */ SnapTrack.prototype.setTarget = 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(); }; Object.defineProperty(SnapTrack.prototype, "isStart", { /** If the start has been reached */ get: function () { if (this.snap.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.snap.props.loop) { return false; } return Math.floor(this.target) >= Math.floor(this.max); }, enumerable: false, configurable: true }); /** Handle RAF update, interpolate track values */ SnapTrack.prototype._handleRaf = function () { var snap = this.snap; if (snap.isTransitioning) { return; } // Interpolate track value var ease = this._raf.lerpFactor(snap.props.lerp); this.lerp(ease); // Stop raf if target reached if (this.isInterpolated) { this._raf.pause(); } // Render the scene snap.render(this._raf.duration); }; /** Interpolate the current track value */ SnapTrack.prototype.lerp = function (initialFactor) { var _a = this, snap = _a.snap, min = _a.min, max = _a.max; var target = this.target; var lerpFactor = initialFactor; var influence = this._influence; // Edge space & resistance if (!snap.props.loop) { var containerSize = snap.containerSize; var edgeSpace = (1 - snap.props.edgeFriction) * containerSize; if (target < min) { var edgeProgress = 1 - (0, math_1.scoped)(target, -containerSize, min); target = min - edgeProgress * edgeSpace; } else if (target > max) { var edgeProgress = (0, math_1.scoped)(target, max, max + containerSize); target = max + edgeProgress * edgeSpace; } target = (0, math_1.clamp)(target, min - edgeSpace, max + edgeSpace); } // 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 influence influence.target = (0, math_1.lerp)(influence.target, 0, lerpFactor, props_1.LERP_APPROXIMATION); influence.current = (0, math_1.lerp)(influence.current, influence.target, lerpFactor, props_1.LERP_APPROXIMATION); }; /** Cancel sticky behavior */ SnapTrack.prototype.cancelTransition = function () { var _a; (_a = this._timeline) === null || _a === void 0 ? void 0 : _a.destroy(); this._timeline = undefined; }; /** Go to a definite coordinate */ SnapTrack.prototype.toCoord = function (coordinate, options) { var _this = this; var _a, _b; var snap = this.snap; var props = snap.props, callbacks = snap.callbacks; if (snap.isEmpty || snap.isDestroyed) { return false; } 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 : snap.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._timeline = tm; tm.on('start', function () { var _a; callbacks.emit('timelineStart', undefined); (_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.influence *= 1 - data.progress; if (data.progress === 1) { snap.$_targetIndex = undefined; _this._timeline = undefined; } snap.render(); callbacks.emit('timelineUpdate', data); (_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(); callbacks.emit('timelineEnd', undefined); (_a = options === null || options === void 0 ? void 0 : options.onEnd) === null || _a === void 0 ? void 0 : _a.call(options); }); tm.on('destroy', function () { snap.$_targetIndex = undefined; }); tm.play(); return true; }; return SnapTrack; }(SnapLogic_1.SnapLogic)); exports.SnapTrack = SnapTrack; //# sourceMappingURL=index.js.map