resig.js
Version:
Universal reactive signal library with complete platform features: signals, animations, CRDTs, scheduling, DOM integration. Works identically across React, SolidJS, Svelte, Vue, and Qwik.
360 lines • 32 kB
JavaScript
;
/**
* Advanced Animation Features
* Keyframes, spring physics, and timeline coordination systems
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.timelineBuilder = exports.presets = exports.gestureRecognizer = exports.physicsSpring = exports.pathAnimation = exports.keyframeAnimation = void 0;
const signal_1 = require("../core/signal");
const core_1 = require("./core");
const composer_1 = require("./composer");
const signals_1 = require("./signals");
// Keyframe animation implementation
const keyframeAnimation = (keyframes, duration, interpolator) => {
// Sort keyframes by time
const sortedKeyframes = [...keyframes].sort((a, b) => a.time - b.time);
// Ensure we have keyframes at 0 and 1
if (sortedKeyframes.length === 0 || sortedKeyframes[0].time > 0) {
throw new Error('Keyframe animation must have a keyframe at time 0');
}
if (sortedKeyframes[sortedKeyframes.length - 1].time < 1) {
throw new Error('Keyframe animation must have a keyframe at time 1');
}
const keyframeInterpolator = (_from, _to, t) => {
// Find the two keyframes to interpolate between
let startFrame = sortedKeyframes[0];
let endFrame = sortedKeyframes[sortedKeyframes.length - 1];
for (let i = 0; i < sortedKeyframes.length - 1; i++) {
if (t >= sortedKeyframes[i].time && t <= sortedKeyframes[i + 1].time) {
startFrame = sortedKeyframes[i];
endFrame = sortedKeyframes[i + 1];
break;
}
}
// Calculate local progress between the two keyframes
const localT = (t - startFrame.time) / (endFrame.time - startFrame.time);
// Apply easing if specified
const easing = endFrame.easing || core_1.easings.linear;
const easedT = easing(localT);
// Interpolate between the keyframe values
return interpolator(startFrame.value, endFrame.value, easedT);
};
const baseAnimation = (0, core_1.animation)(sortedKeyframes[0].value, sortedKeyframes[sortedKeyframes.length - 1].value, duration, keyframeInterpolator);
const instance = {
...baseAnimation,
keyframes: sortedKeyframes,
addKeyframe: (keyframe) => {
return (0, exports.keyframeAnimation)([...sortedKeyframes, keyframe], duration, interpolator);
},
removeKeyframe: (time) => {
const filtered = sortedKeyframes.filter((kf) => kf.time !== time);
return (0, exports.keyframeAnimation)(filtered, duration, interpolator);
},
};
return instance;
};
exports.keyframeAnimation = keyframeAnimation;
// Path animation implementation
const pathAnimation = (path, duration) => {
if (path.length < 2) {
throw new Error('Path animation requires at least 2 points');
}
// Calculate cumulative distances for natural timing
const distances = [0];
let totalDistance = 0;
for (let i = 1; i < path.length; i++) {
const prev = path[i - 1];
const curr = path[i];
const distance = Math.sqrt(Math.pow(curr.x - prev.x, 2) + Math.pow(curr.y - prev.y, 2));
totalDistance += distance;
distances.push(totalDistance);
}
const getPointAt = (t) => {
const clampedT = Math.max(0, Math.min(1, t));
const targetDistance = clampedT * totalDistance;
// Find the segment
let segmentIndex = 0;
for (let i = 0; i < distances.length - 1; i++) {
if (targetDistance >= distances[i] &&
targetDistance <= distances[i + 1]) {
segmentIndex = i;
break;
}
}
if (segmentIndex >= path.length - 1) {
return path[path.length - 1];
}
// Interpolate within the segment
const segmentStart = distances[segmentIndex];
const segmentEnd = distances[segmentIndex + 1];
const segmentT = (targetDistance - segmentStart) / (segmentEnd - segmentStart);
const startPoint = path[segmentIndex];
const endPoint = path[segmentIndex + 1];
return {
x: startPoint.x + (endPoint.x - startPoint.x) * segmentT,
y: startPoint.y + (endPoint.y - startPoint.y) * segmentT,
};
};
const pathInterpolator = (_from, _to, t) => getPointAt(t);
const baseAnimation = (0, core_1.animation)(path[0], path[path.length - 1], duration, pathInterpolator);
const instance = {
...baseAnimation,
path,
length: totalDistance,
getPointAt,
};
return instance;
};
exports.pathAnimation = pathAnimation;
// Advanced spring physics
const physicsSpring = (initial, interpolator, config = {
tension: 170,
friction: 26,
mass: 1,
precision: 0.01,
}) => {
const baseSpring = (0, signals_1.springSignal)(initial, interpolator, config);
let externalForce = 0;
const instance = {
...baseSpring,
addForce: (force) => {
externalForce += force;
// Force will be applied in the next physics step
},
setTarget: (newTarget) => {
baseSpring.animateTo(newTarget);
},
reset: () => {
externalForce = 0;
baseSpring.setImmediate(initial);
},
};
return instance;
};
exports.physicsSpring = physicsSpring;
// Gesture recognizer implementation
const gestureRecognizer = (element) => {
const onSwipe = (0, signal_1.signal)({ direction: 'left', velocity: 0 });
const onPinch = (0, signal_1.signal)({
scale: 1,
velocity: 0,
});
const onRotate = (0, signal_1.signal)({
angle: 0,
velocity: 0,
});
const onPan = (0, signal_1.signal)({
deltaX: 0,
deltaY: 0,
velocity: 0,
});
let isTracking = false;
let startX = 0;
let startY = 0;
let lastX = 0;
let lastY = 0;
let startTime = 0;
let lastTime = 0;
// Touch/mouse event handlers
const handleStart = (e) => {
isTracking = true;
startTime = lastTime = performance.now();
if (e instanceof TouchEvent && e.touches.length > 0) {
startX = lastX = e.touches[0].clientX;
startY = lastY = e.touches[0].clientY;
}
else if (e instanceof MouseEvent) {
startX = lastX = e.clientX;
startY = lastY = e.clientY;
}
};
const handleMove = (e) => {
if (!isTracking)
return;
const currentTime = performance.now();
let currentX = 0;
let currentY = 0;
if (e instanceof TouchEvent && e.touches.length > 0) {
currentX = e.touches[0].clientX;
currentY = e.touches[0].clientY;
}
else if (e instanceof MouseEvent) {
currentX = e.clientX;
currentY = e.clientY;
}
const deltaX = currentX - startX;
const deltaY = currentY - startY;
const deltaTime = currentTime - lastTime;
const velocity = Math.sqrt(Math.pow(currentX - lastX, 2) + Math.pow(currentY - lastY, 2)) /
deltaTime;
// Update pan signal
onPan._set({ deltaX, deltaY, velocity });
lastX = currentX;
lastY = currentY;
lastTime = currentTime;
};
const handleEnd = (_e) => {
if (!isTracking)
return;
isTracking = false;
const totalTime = performance.now() - startTime;
const totalDeltaX = lastX - startX;
const totalDeltaY = lastY - startY;
const totalDistance = Math.sqrt(totalDeltaX * totalDeltaX + totalDeltaY * totalDeltaY);
const velocity = totalDistance / totalTime;
// Detect swipe
if (totalDistance > 50 && velocity > 0.5) {
const angle = Math.atan2(totalDeltaY, totalDeltaX);
const degrees = (angle * 180) / Math.PI;
let direction;
if (degrees >= -45 && degrees <= 45) {
direction = 'right';
}
else if (degrees >= 45 && degrees <= 135) {
direction = 'down';
}
else if (degrees >= -135 && degrees <= -45) {
direction = 'up';
}
else {
direction = 'left';
}
onSwipe._set({ direction, velocity });
}
};
// Add event listeners
element.addEventListener('touchstart', handleStart, { passive: true });
element.addEventListener('touchmove', handleMove, { passive: true });
element.addEventListener('touchend', handleEnd, { passive: true });
element.addEventListener('mousedown', handleStart);
element.addEventListener('mousemove', handleMove);
element.addEventListener('mouseup', handleEnd);
const instance = {
element,
onSwipe,
onPinch,
onRotate,
onPan,
destroy: () => {
element.removeEventListener('touchstart', handleStart);
element.removeEventListener('touchmove', handleMove);
element.removeEventListener('touchend', handleEnd);
element.removeEventListener('mousedown', handleStart);
element.removeEventListener('mousemove', handleMove);
element.removeEventListener('mouseup', handleEnd);
},
};
return instance;
};
exports.gestureRecognizer = gestureRecognizer;
// Helper function to create object interpolator with default property interpolators
const createObjectInterpolator = () => {
return (from, to, t) => {
const result = {};
const keys = Array.from(new Set([...Object.keys(from), ...Object.keys(to)]));
for (const key of keys) {
// Use appropriate interpolator based on property type
const fromVal = from[key];
const toVal = to[key];
if (typeof fromVal === 'number' && typeof toVal === 'number') {
result[key] = core_1.interpolators.number(fromVal, toVal, t);
}
else {
result[key] = core_1.interpolators.string(fromVal, toVal, t);
}
}
return result;
};
};
// Animation presets
exports.presets = {
// Entrance animations
fadeInUp: (_element, duration = 600) => {
return (0, exports.keyframeAnimation)([
{ time: 0, value: { opacity: 0, translateY: 30 } },
{
time: 1,
value: { opacity: 1, translateY: 0 },
easing: core_1.easings.easeOut,
},
], duration, createObjectInterpolator());
},
fadeInDown: (_element, duration = 600) => {
return (0, exports.keyframeAnimation)([
{ time: 0, value: { opacity: 0, translateY: -30 } },
{
time: 1,
value: { opacity: 1, translateY: 0 },
easing: core_1.easings.easeOut,
},
], duration, createObjectInterpolator());
},
slideInLeft: (_element, duration = 600) => {
return (0, exports.keyframeAnimation)([
{ time: 0, value: { translateX: -100, opacity: 0 } },
{
time: 1,
value: { translateX: 0, opacity: 1 },
easing: core_1.easings.easeOut,
},
], duration, createObjectInterpolator());
},
// Attention seekers
pulse: (_element, duration = 1000) => {
return (0, exports.keyframeAnimation)([
{ time: 0, value: { scaleX: 1, scaleY: 1 } },
{
time: 0.5,
value: { scaleX: 1.05, scaleY: 1.05 },
easing: core_1.easings.easeInOut,
},
{ time: 1, value: { scaleX: 1, scaleY: 1 }, easing: core_1.easings.easeInOut },
], duration, createObjectInterpolator());
},
wobble: (_element, duration = 1000) => {
return (0, exports.keyframeAnimation)([
{ time: 0, value: { rotateZ: 0 } },
{ time: 0.15, value: { rotateZ: -5 }, easing: core_1.easings.easeInOut },
{ time: 0.3, value: { rotateZ: 4 }, easing: core_1.easings.easeInOut },
{ time: 0.45, value: { rotateZ: -3 }, easing: core_1.easings.easeInOut },
{ time: 0.6, value: { rotateZ: 2 }, easing: core_1.easings.easeInOut },
{ time: 0.75, value: { rotateZ: -1 }, easing: core_1.easings.easeInOut },
{ time: 1, value: { rotateZ: 0 }, easing: core_1.easings.easeInOut },
], duration, createObjectInterpolator());
},
// Exit animations
fadeOutUp: (_element, duration = 600) => {
return (0, exports.keyframeAnimation)([
{ time: 0, value: { opacity: 1, translateY: 0 } },
{
time: 1,
value: { opacity: 0, translateY: -30 },
easing: core_1.easings.easeIn,
},
], duration, createObjectInterpolator());
},
};
// Timeline builder with fluent API
const timelineBuilder = () => {
const tl = (0, composer_1.timeline)();
return {
to: (_target, _duration, _interpolator, _offset = 0) => {
// This would need the current value context
return (0, exports.timelineBuilder)();
},
from: (from, to, duration, interpolator, offset = 0) => {
const anim = (0, core_1.animation)(from, to, duration, interpolator);
tl.add(anim, offset);
return (0, exports.timelineBuilder)();
},
stagger: (animations, delay) => {
animations.forEach((anim, index) => {
tl.add(anim, index * delay);
});
return (0, exports.timelineBuilder)();
},
build: () => tl,
};
};
exports.timelineBuilder = timelineBuilder;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2YW5jZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYW5pbWF0aW9uL2FkdmFuY2VkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7OztBQUVILDJDQUFnRDtBQUNoRCxpQ0FPZ0I7QUFDaEIseUNBQXNDO0FBQ3RDLHVDQUF1RDtBQWlEdkQsb0NBQW9DO0FBQzdCLE1BQU0saUJBQWlCLEdBQUcsQ0FDL0IsU0FBd0IsRUFDeEIsUUFBZ0IsRUFDaEIsWUFBNkIsRUFDUCxFQUFFO0lBQ3hCLHlCQUF5QjtJQUN6QixNQUFNLGVBQWUsR0FBRyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFdkUsc0NBQXNDO0lBQ3RDLElBQUksZUFBZSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNoRSxNQUFNLElBQUksS0FBSyxDQUFDLG1EQUFtRCxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUNELElBQUksZUFBZSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3pELE1BQU0sSUFBSSxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQsTUFBTSxvQkFBb0IsR0FBb0IsQ0FDNUMsS0FBUSxFQUNSLEdBQU0sRUFDTixDQUFTLEVBQ04sRUFBRTtRQUNMLGdEQUFnRDtRQUNoRCxJQUFJLFVBQVUsR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEMsSUFBSSxRQUFRLEdBQUcsZUFBZSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7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