@visactor/vgrammar-core
Version:
VGrammar is a visual grammar library
136 lines (126 loc) • 6.52 kB
JavaScript
import { ACustomAnimate, AttributeUpdateType, NOWORK_ANIMATE_ATTR } from "@visactor/vrender-core";
import { isArray, isFunction, isNil, isObject, isValid } from "@visactor/vutils";
import { isValidPointsChannel } from "../attributes/helpers";
import { Factory } from "../../core/factory";
const transformAnimationAttributes = (attributes, element) => {
if (!attributes) return null;
if (attributes.from) {
const from = attributes.from, fromKeys = Object.keys(from);
fromKeys.forEach((channel => {
isNil(from[channel]) && delete from[channel];
}));
const computePoints = isValidPointsChannel(fromKeys, element.mark.markType) && !isValid(from.segments);
if (computePoints) {
const items = element.items.map((item => Object.assign({}, item, {
nextAttrs: Object.assign({}, from)
})));
attributes.from = element.transformElementItems(items, element.mark.markType, computePoints);
}
}
if (attributes.to) {
const to = attributes.to, toKeys = Object.keys(to);
toKeys.forEach((channel => {
isNil(to[channel]) && delete to[channel];
}));
const computePoints = isValidPointsChannel(toKeys, element.mark.markType) && !isValid(to.segments);
if (computePoints) {
const items = element.items.map((item => Object.assign({}, item, {
nextAttrs: Object.assign({}, to)
})));
attributes.to = element.transformElementItems(items, element.mark.markType, computePoints);
}
}
return attributes;
};
export function typeAnimationAttributes(element, effect, animationParameters, parameters) {
const options = isFunction(effect.options) ? effect.options.call(null, element.getDatum(), element, parameters) : effect.options;
if (!effect.type || !Factory.getAnimationType(effect.type)) return null;
const attributes = Factory.getAnimationType(effect.type)(element, options, animationParameters);
return transformAnimationAttributes(attributes, element);
}
const parseChannelValue = (element, channel, channelValue, animationParameters, parameters) => isFunction(channelValue) ? channelValue(element.getDatum(), element, parameters) : channelValue;
export function channelAnimationAttributes(element, effect, animationParameters, parameters) {
const channel = effect.channel;
let attributes = null;
return isArray(channel) ? attributes = channel.reduce(((res, key) => (res.from[key] = element.getGraphicAttribute(key, !0),
res.to[key] = element.getGraphicAttribute(key, !1), res)), {
from: {},
to: {}
}) : isObject(channel) && (attributes = Object.keys(channel).reduce(((res, key) => {
var _a, _b;
const hasFrom = !isNil(null === (_a = channel[key]) || void 0 === _a ? void 0 : _a.from), hasTo = !isNil(null === (_b = channel[key]) || void 0 === _b ? void 0 : _b.to);
return (hasFrom || hasTo) && (res.from[key] = hasFrom ? parseChannelValue(element, 0, channel[key].from, 0, parameters) : void 0,
res.to[key] = hasTo ? parseChannelValue(element, 0, channel[key].to, 0, parameters) : element.getGraphicAttribute(key, !1)),
res;
}), {
from: {},
to: {}
})), transformAnimationAttributes(attributes, element);
}
export class CustomInterpolator extends ACustomAnimate {
constructor(from, to, duration, easing, params) {
super(from, to, duration, easing, params), this._interpolator = null == params ? void 0 : params.interpolator,
this._element = null == params ? void 0 : params.element;
}
onBind() {
var _a, _b;
this.from = null !== (_a = this.from) && void 0 !== _a ? _a : {}, this.to = null !== (_b = this.to) && void 0 !== _b ? _b : {};
}
getEndProps() {
return this.to;
}
onUpdate(end, ratio, out) {
this._interpolator && this._element && this._interpolator.call(this, ratio, this.from, this.to, out, this._element.getDatum(), this._element, this.params.parameters);
}
}
export class AttributeAnimate extends ACustomAnimate {
getEndProps() {
return this.to;
}
onBind() {
var _a;
const excludedChannelMap = null !== (_a = this.target.constructor.NOWORK_ANIMATE_ATTR) && void 0 !== _a ? _a : NOWORK_ANIMATE_ATTR, excludedChannels = Object.keys(excludedChannelMap).filter((channel => 0 !== excludedChannelMap[channel]));
this.subAnimate.animate.preventAttrs(excludedChannels);
const from = Object.assign({}, this.from), to = Object.assign({}, this.to), animatedChannels = [];
Object.keys(to).forEach((k => {
excludedChannels.includes(k) ? (from[k] = to[k], this.from[k] = to[k]) : isNil(from[k]) ? from[k] = this.target.getComputedAttribute(k) : animatedChannels.push(k);
})), this.target.animates.forEach((a => {
a !== this.subAnimate.animate && a.preventAttrs(animatedChannels);
})), this._fromAttribute = from, this._toAttribute = to;
}
onStart() {
if (this._fromAttribute) {
const from = {};
Object.keys(this._fromAttribute).forEach((key => {
this.subAnimate.animate.validAttr(key) && (from[key] = this._fromAttribute[key]);
})), this.target.setAttributes(from, !1, {
type: AttributeUpdateType.ANIMATE_UPDATE,
animationState: {
ratio: 0,
end: !1
}
});
}
}
onEnd() {
if (this._toAttribute) {
const out = {};
Object.keys(this._toAttribute).forEach((key => {
this.subAnimate.animate.validAttr(key) && (out[key] = this._toAttribute[key]);
})), this.target.setAttributes(out, !1, {
type: AttributeUpdateType.ANIMATE_END
});
}
}
update(end, ratio, out) {
0 === this.updateCount && this.onFirstRun(), this.updateCount += 1;
const lastProps = this.step.getLastProps();
Object.keys(lastProps).forEach((key => {
this.subAnimate.animate.validAttr(key) && (out[key] = lastProps[key]);
})), this.onUpdate(end, ratio, out), end && this.onEnd();
}
onUpdate(end, ratio, out) {
this.target.stepInterpolate(this.subAnimate, this.subAnimate.animate, out, this.step, ratio, end, this._toAttribute, this._fromAttribute);
}
}
//# sourceMappingURL=attribute.js.map