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.44 kB
JavaScript
import { isFiniteNumber } from '../../../internal/isFiniteNumber';
import { lerp } from '../../../utils';
import { LERP_APPROXIMATION } from '../constants';
import { svgQuadraticCurvePath } from './svgQuadraticCurvePath';
export class CursorPath {
/** Cursor SVG Path */
get path() {
return this._path;
}
constructor(_isEnabled) {
this._isEnabled = _isEnabled;
/** Cursor SVG Path Points */
this._points = [];
/** Cursor SVG Path Line */
this._line = { current: 0, target: 0 };
this._path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
const path = this._path;
path.setAttribute('stroke-linecap', 'round');
path.setAttribute('stroke-linejoin', 'round');
path.setAttribute('fill', 'transparent');
path.setAttribute('stroke', '#f00');
}
/** Update SVG Path */
addPoint(coords, isInstant = false) {
if (!this._isEnabled) {
return;
}
const points = this._points;
const path = this._path;
const line = this._line;
// Add point
const newPoint = { x: coords.x, y: coords.y, length: 0 };
points.push(newPoint);
// Update path
path.setAttribute('d', svgQuadraticCurvePath(points));
// Update total length
const totalLength = path.getTotalLength();
newPoint.length = totalLength;
line.target = totalLength;
// Instant update of line
if (isInstant) {
line.current = line.target;
}
}
/** Minimize SVG Path */
minimize() {
if (!this._isEnabled) {
return;
}
const points = this._points;
const line = this._line;
if (points.length < 3) {
return;
}
let accumulated = 0;
let removeCount = 0;
for (let i = 1; i < points.length; i += 1) {
const dx = points[i].x - points[i - 1].x;
const dy = points[i].y - points[i - 1].y;
const segLength = Math.hypot(dx, dy);
if (accumulated + segLength < line.current) {
accumulated += segLength;
removeCount += 1;
}
else {
break;
}
}
if (isFiniteNumber(removeCount) && removeCount > 0) {
let removedLength = 0;
for (let i = 1; i <= removeCount; i += 1) {
const dx = points[i].x - points[i - 1].x;
const dy = points[i].y - points[i - 1].y;
removedLength += Math.hypot(dx, dy);
}
points.splice(0, removeCount);
// Fix line after points removed
line.current = Math.max(0, line.current - removedLength);
line.target = Math.max(0, line.target - removedLength);
// Update path
this._path.setAttribute('d', svgQuadraticCurvePath(points));
}
}
/** Check if the path is interpolated */
get isInterpolated() {
return this._line.current === this._line.target;
}
/** Interpolate line */
lerp(factor) {
const line = this._line;
line.current = lerp(line.current, line.target, factor, LERP_APPROXIMATION);
}
/** Get current coordinate */
get coord() {
return this._path.getPointAtLength(this._line.current);
}
}
//# sourceMappingURL=index.js.map