@visactor/vrender-animate
Version:
This module provides a graph-based animation system for VRender.
161 lines (156 loc) • 7.3 kB
JavaScript
import { AnimationTransitionRegistry } from "./animation-states-registry";
import { AnimateExecutor } from "../executor/animate-executor";
import { isArray } from "@visactor/vutils";
export const AnimationStates = {
APPEAR: "appear",
DISAPPEAR: "disappear",
UPDATE: "update",
HIGHLIGHT: "highlight",
UNHIGHLIGHT: "unhighlight",
SELECT: "select",
UNSELECT: "unselect",
HOVER: "hover",
UNHOVER: "unhover",
ACTIVE: "active",
INACTIVE: "inactive"
};
export class AnimationStateStore {
constructor(graphic) {
this.graphic = graphic;
}
registerState(state) {
this.states || (this.states = new Map), this.states.set(state.name, state);
}
clearStates() {
var _a;
null === (_a = this.states) || void 0 === _a || _a.clear();
}
}
export class AnimationStateManager {
constructor(graphic) {
this.stateList = null, this.graphic = graphic, this.trackedAnimates = new Map, this.graphic.animates = this.trackedAnimates;
}
trackAnimate(animate) {
this.trackedAnimates.set(animate.id, animate);
}
untrackAnimate(animateId) {
this.trackedAnimates.delete(animateId);
}
forEachTrackedAnimate(cb) {
this.trackedAnimates.forEach(cb);
}
getTrackedAnimates() {
return this.trackedAnimates;
}
hasTrackedAnimate() {
return this.trackedAnimates.size > 0;
}
hasStateInfo(list, target) {
for (let i = 0; i < list.length; i++) if (list[i] === target) return !0;
return !1;
}
takeOverUpdateAttrs(nextState, currentStates, shouldStopState) {
if (nextState.state !== AnimationStates.UPDATE || !currentStates.length) return;
const nextKeys = nextState.executor.getActiveAttrKeys();
if (nextKeys.length) for (let i = 0; i < currentStates.length; i++) {
const currentState = currentStates[i];
currentState.state !== AnimationStates.UPDATE || currentState === nextState || this.hasStateInfo(shouldStopState, currentState) || (currentState.executor.preventAttrs(nextKeys) || (currentState.executor.stop(null, !1),
shouldStopState.push(currentState)));
}
}
applyState(nextState, animationConfig, callback) {
var _a;
const registry = AnimationTransitionRegistry.getInstance(), currentStateList = null !== (_a = this.stateList) && void 0 !== _a ? _a : [], shouldStopState = [], shouldApplyState = [];
if (this.stateList && this.stateList.length ? nextState.forEach(((state, index) => {
const result = {
allowTransition: !0,
stopOriginalTransition: !0
};
currentStateList.forEach((currState => {
const _result = registry.isTransitionAllowed(currState.state, state, this.graphic);
result.allowTransition = result.allowTransition && _result.allowTransition;
})), result.allowTransition && (shouldApplyState.push({
state: state,
animationConfig: isArray(animationConfig[index]) ? animationConfig[index].map((item => item.animation)) : animationConfig[index].animation,
executor: new AnimateExecutor(this.graphic)
}), currentStateList.forEach((currState => {
registry.isTransitionAllowed(currState.state, state, this.graphic).stopOriginalTransition && shouldStopState.push(currState);
})));
})) : nextState.forEach(((state, index) => {
shouldApplyState.push({
state: state,
animationConfig: isArray(animationConfig[index]) ? animationConfig[index].map((item => item.animation)) : animationConfig[index].animation,
executor: new AnimateExecutor(this.graphic)
});
})), shouldStopState.forEach((state => {
state.executor.stop(null, !1);
})), shouldApplyState.length) {
shouldApplyState[0].executor.execute(shouldApplyState[0].animationConfig), this.takeOverUpdateAttrs(shouldApplyState[0], currentStateList, shouldStopState);
for (let i = 0; i < shouldApplyState.length; i++) {
const nextState = shouldApplyState[i + 1], currentState = shouldApplyState[i];
currentState.executor.onEnd((() => {
var _a;
if (nextState) {
nextState.executor.execute(nextState.animationConfig);
const stoppedStates = [];
this.takeOverUpdateAttrs(nextState, null !== (_a = this.stateList) && void 0 !== _a ? _a : [], stoppedStates),
stoppedStates.length && this.stateList && (this.stateList = this.stateList.filter((state => !this.hasStateInfo(stoppedStates, state))));
}
this.stateList = this.stateList.filter((state => state !== currentState)), i === shouldApplyState.length - 1 && callback && callback(!1);
}));
}
} else callback && callback(!0);
this.stateList ? this.stateList = this.stateList.filter((state => !shouldStopState.includes(state))) : this.stateList = [],
this.stateList.push(...shouldApplyState);
}
applyAppearState(animationConfig, callback) {
this.applyState([ AnimationStates.APPEAR ], [ {
name: AnimationStates.APPEAR,
animation: animationConfig
} ], callback);
}
applyDisappearState(animationConfig, callback) {
this.applyState([ AnimationStates.DISAPPEAR ], [ {
name: AnimationStates.DISAPPEAR,
animation: animationConfig
} ], callback);
}
applyUpdateState(animationConfig, callback) {
this.applyState([ AnimationStates.UPDATE ], [ {
name: AnimationStates.UPDATE,
animation: animationConfig
} ], callback);
}
applyHighlightState(animationConfig, callback) {
this.applyState([ AnimationStates.HIGHLIGHT ], [ {
name: AnimationStates.HIGHLIGHT,
animation: animationConfig
} ], callback);
}
applyUnhighlightState(animationConfig, callback) {
this.applyState([ AnimationStates.UNHIGHLIGHT ], [ {
name: AnimationStates.UNHIGHLIGHT,
animation: animationConfig
} ], callback);
}
stopState(state, type) {
var _a;
const stateInfo = null === (_a = this.stateList) || void 0 === _a ? void 0 : _a.find((stateInfo => stateInfo.state === state));
stateInfo && stateInfo.executor.stop(type);
}
clearState() {
var _a;
null === (_a = this.stateList) || void 0 === _a || _a.forEach((state => {
state.executor.stop(null, !1);
})), this.stateList = null;
}
reApplyState(state) {
var _a;
const stateInfo = null === (_a = this.stateList) || void 0 === _a ? void 0 : _a.find((stateInfo => stateInfo.state === state));
if (stateInfo && stateInfo.executor.started) {
const stateList = this.stateList.slice();
stateInfo.executor.stop(), this.stateList = stateList, stateInfo.executor.execute(stateInfo.animationConfig);
}
}
}
//# sourceMappingURL=animation-state.js.map