kinetic-slider
Version:
A WebGL-powered kinetic slider component using PIXI.js
272 lines (267 loc) • 8.42 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var gsap = require('gsap');
var RenderScheduler = require('./RenderScheduler.cjs');
var UpdateTypes = require('./UpdateTypes.cjs');
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
const isDevelopment = false;
var AnimationGroupType = /* @__PURE__ */ ((AnimationGroupType2) => {
AnimationGroupType2["SLIDE_TRANSITION"] = "slide_transition";
AnimationGroupType2["MOUSE_MOVEMENT"] = "mouse_movement";
AnimationGroupType2["IDLE_EFFECT"] = "idle_effect";
AnimationGroupType2["FILTER_EFFECT"] = "filter_effect";
AnimationGroupType2["TEXT_ANIMATION"] = "text_animation";
AnimationGroupType2["DISPLACEMENT"] = "displacement";
AnimationGroupType2["INTERACTION"] = "interaction";
return AnimationGroupType2;
})(AnimationGroupType || {});
const GROUP_PRIORITY_MAP = {
["slide_transition" /* SLIDE_TRANSITION */]: "critical" /* CRITICAL */,
["mouse_movement" /* MOUSE_MOVEMENT */]: "high" /* HIGH */,
["interaction" /* INTERACTION */]: "high" /* HIGH */,
["displacement" /* DISPLACEMENT */]: "normal" /* NORMAL */,
["filter_effect" /* FILTER_EFFECT */]: "normal" /* NORMAL */,
["text_animation" /* TEXT_ANIMATION */]: "normal" /* NORMAL */,
["idle_effect" /* IDLE_EFFECT */]: "low" /* LOW */
};
const PRIORITY_UPDATE_TYPE_MAP = {
["critical" /* CRITICAL */]: UpdateTypes.UpdateType.SLIDE_TRANSITION,
["high" /* HIGH */]: UpdateTypes.UpdateType.INTERACTION_FEEDBACK,
["normal" /* NORMAL */]: UpdateTypes.UpdateType.FILTER_UPDATE,
["low" /* LOW */]: UpdateTypes.UpdateType.IDLE_EFFECT
};
const _AnimationCoordinator = class _AnimationCoordinator {
/**
* Private constructor for singleton pattern
*/
constructor() {
/** Active animation groups */
__publicField(this, "activeGroups", /* @__PURE__ */ new Map());
/** Resource manager for tracking animations */
__publicField(this, "resourceManager", null);
/** Render scheduler for coordinating updates */
__publicField(this, "scheduler");
/** Pending animation groups to be processed */
__publicField(this, "pendingGroups", []);
/** Processing state */
__publicField(this, "isProcessing", false);
/** Processing timeout ID */
__publicField(this, "processingTimeoutId", null);
this.scheduler = RenderScheduler.RenderScheduler.getInstance();
}
/**
* Get the singleton instance
*/
static getInstance() {
if (!_AnimationCoordinator.instance) {
_AnimationCoordinator.instance = new _AnimationCoordinator();
}
return _AnimationCoordinator.instance;
}
/**
* Set the resource manager
*/
setResourceManager(resourceManager) {
this.resourceManager = resourceManager;
}
/**
* Create and register an animation group
*/
createAnimationGroup(config) {
try {
const priority = config.priority || GROUP_PRIORITY_MAP[config.type];
const timeline = gsap.gsap.timeline({
onComplete: () => {
this.completeGroup(config.id);
if (config.onComplete) config.onComplete();
},
onStart: () => {
if (config.onStart) config.onStart();
}
});
config.animations.forEach((animation) => {
timeline.add(animation, 0);
});
const group = {
id: config.id,
type: config.type,
priority,
timeline,
animations: config.animations,
isActive: true,
startTime: Date.now()
};
this.activeGroups.set(config.id, group);
if (this.resourceManager) {
this.resourceManager.trackAnimation(timeline);
}
if (isDevelopment) ;
return timeline;
} catch (error) {
return gsap.gsap.timeline();
}
}
/**
* Queue an animation group for processing
*/
queueAnimationGroup(config) {
this.pendingGroups.push(config);
this.schedulePendingGroupsProcessing();
}
/**
* Schedule processing of pending animation groups
*/
schedulePendingGroupsProcessing() {
if (this.isProcessing || this.processingTimeoutId !== null) {
return;
}
this.processingTimeoutId = window.setTimeout(() => {
this.processingTimeoutId = null;
this.processPendingGroups();
}, 16);
}
/**
* Process pending animation groups
*/
processPendingGroups() {
if (this.pendingGroups.length === 0) {
return;
}
this.isProcessing = true;
try {
const groupedByType = /* @__PURE__ */ new Map();
this.pendingGroups.forEach((group) => {
if (!groupedByType.has(group.type)) {
groupedByType.set(group.type, []);
}
groupedByType.get(group.type).push(group);
});
groupedByType.forEach((groups, type) => {
if (groups.length > 1) {
this.combineAndCreateGroup(groups, type);
} else if (groups.length === 1) {
this.createAnimationGroup(groups[0]);
}
});
this.pendingGroups = [];
} catch (error) {
} finally {
this.isProcessing = false;
}
}
/**
* Combine multiple animation groups of the same type into a single group
*/
combineAndCreateGroup(groups, type) {
try {
const allAnimations = [];
const onCompleteCallbacks = [];
const onStartCallbacks = [];
groups.forEach((group) => {
allAnimations.push(...group.animations);
if (group.onComplete) onCompleteCallbacks.push(group.onComplete);
if (group.onStart) onStartCallbacks.push(group.onStart);
});
const combinedGroup = {
id: `combined_${type}_${Date.now()}`,
type,
animations: allAnimations,
onComplete: () => {
onCompleteCallbacks.forEach((callback) => callback());
},
onStart: () => {
onStartCallbacks.forEach((callback) => callback());
}
};
this.createAnimationGroup(combinedGroup);
if (isDevelopment) ;
} catch (error) {
}
}
/**
* Mark an animation group as complete
*/
completeGroup(groupId) {
try {
const group = this.activeGroups.get(groupId);
if (!group) return;
group.isActive = false;
this.activeGroups.delete(groupId);
if (isDevelopment) ;
} catch (error) {
}
}
/**
* Cancel all animations of a specific type
*/
cancelAnimationsByType(type) {
try {
const groupsToCancel = [];
this.activeGroups.forEach((group, id) => {
if (group.type === type) {
groupsToCancel.push(id);
}
});
groupsToCancel.forEach((id) => {
this.cancelAnimationGroup(id);
});
if (isDevelopment && groupsToCancel.length > 0) ;
} catch (error) {
}
}
/**
* Cancel a specific animation group
*/
cancelAnimationGroup(groupId) {
try {
const group = this.activeGroups.get(groupId);
if (!group) return;
group.timeline.kill();
this.activeGroups.delete(groupId);
if (isDevelopment) ;
} catch (error) {
}
}
/**
* Schedule an animation update with the render scheduler
*/
scheduleAnimationUpdate(groupType, callback, identifier = "animation") {
try {
const priority = GROUP_PRIORITY_MAP[groupType];
const updateType = PRIORITY_UPDATE_TYPE_MAP[priority];
this.scheduler.scheduleTypedUpdate(
identifier,
updateType,
callback
);
if (isDevelopment) ;
} catch (error) {
}
}
/**
* Get all active animation groups
*/
getActiveGroups() {
return new Map(this.activeGroups);
}
/**
* Check if there are any active animations of a specific type
*/
hasActiveAnimationsOfType(type) {
for (const group of this.activeGroups.values()) {
if (group.type === type && group.isActive) {
return true;
}
}
return false;
}
};
/** Singleton instance */
__publicField(_AnimationCoordinator, "instance");
let AnimationCoordinator = _AnimationCoordinator;
exports.AnimationCoordinator = AnimationCoordinator;
exports.AnimationGroupType = AnimationGroupType;
exports.default = AnimationCoordinator;
//# sourceMappingURL=AnimationCoordinator.cjs.map