UNPKG

@visactor/vrender-animate

Version:

This module provides a graph-based animation system for VRender.

109 lines (104 loc) 8.21 kB
import { clamp, isValidNumber, Point } from "@visactor/vutils"; import { pointInterpolation } from "@visactor/vrender-core/interpolate"; import { ACustomAnimate } from "./custom-animate"; import { applyAnimationFrameAttributes, applyAnimationTransientAttributes } from "./transient"; import { commitAnimationStaticAttrs } from "./static-truth"; export class TagPointsUpdate extends ACustomAnimate { constructor(from, to, duration, easing, params) { var _a, _b; super(from, to, duration, easing, params), this.newPointAnimateType = null !== (_a = null == params ? void 0 : params.newPointAnimateType) && void 0 !== _a ? _a : "grow", this.clipRangeByDimension = null !== (_b = null == params ? void 0 : params.clipRangeByDimension) && void 0 !== _b ? _b : "x"; } getPoints(attribute, cache = !1) { if (attribute.points) return attribute.points; if (attribute.segments) { const points = []; return this.segmentsCache || (this.segmentsCache = []), attribute.segments.map((segment => { var _a, _b; segment.points && points.push(...segment.points), cache && this.segmentsCache.push(null !== (_b = null === (_a = segment.points) || void 0 === _a ? void 0 : _a.length) && void 0 !== _b ? _b : 0); })), points; } return []; } onBind() { var _a, _b, _c, _d, _e; super.onBind(); const currentAttribute = this.target.attribute, explicitFrom = null !== (_a = this.from) && void 0 !== _a ? _a : {}, explicitTo = null !== (_b = this.to) && void 0 !== _b ? _b : {}, context = null !== (_c = this.target.context) && void 0 !== _c ? _c : {}, contextFinalAttrs = null !== (_d = context.finalAttrs) && void 0 !== _d ? _d : {}, contextDiffAttrs = null !== (_e = context.diffAttrs) && void 0 !== _e ? _e : {}, finalAttribute = this.target.getFinalAttribute(); this.from = {}, this.to = {}, Object.prototype.hasOwnProperty.call(explicitFrom, "points") ? this.from.points = explicitFrom.points : Object.prototype.hasOwnProperty.call(currentAttribute, "points") && (this.from.points = currentAttribute.points), Object.prototype.hasOwnProperty.call(explicitFrom, "segments") ? this.from.segments = explicitFrom.segments : Object.prototype.hasOwnProperty.call(currentAttribute, "segments") && (this.from.segments = currentAttribute.segments), Object.prototype.hasOwnProperty.call(explicitTo, "points") ? this.to.points = explicitTo.points : Object.prototype.hasOwnProperty.call(contextFinalAttrs, "points") ? this.to.points = contextFinalAttrs.points : Object.prototype.hasOwnProperty.call(contextDiffAttrs, "points") ? this.to.points = contextDiffAttrs.points : finalAttribute && Object.prototype.hasOwnProperty.call(finalAttribute, "points") && (this.to.points = finalAttribute.points), Object.prototype.hasOwnProperty.call(explicitTo, "segments") ? this.to.segments = explicitTo.segments : Object.prototype.hasOwnProperty.call(contextFinalAttrs, "segments") ? this.to.segments = contextFinalAttrs.segments : Object.prototype.hasOwnProperty.call(contextDiffAttrs, "segments") ? this.to.segments = contextDiffAttrs.segments : finalAttribute && Object.prototype.hasOwnProperty.call(finalAttribute, "segments") && (this.to.segments = finalAttribute.segments), this.props = this.to; const originFromPoints = this.getPoints(this.from), originToPoints = this.getPoints(this.to, !0); this.fromPoints = originFromPoints ? Array.isArray(originFromPoints) ? originFromPoints : [ originFromPoints ] : [], this.toPoints = originToPoints ? Array.isArray(originToPoints) ? originToPoints : [ originToPoints ] : []; const tagMap = new Map; this.fromPoints.forEach((point => { point.context && tagMap.set(point.context, point); })); let firstMatchedPoint, lastMatchedPoint, firstMatchedIndex = 1 / 0, lastMatchedIndex = -1 / 0; for (let i = 0; i < this.toPoints.length; i += 1) if (tagMap.has(this.toPoints[i].context)) { firstMatchedIndex = i, firstMatchedPoint = tagMap.get(this.toPoints[i].context); break; } for (let i = this.toPoints.length - 1; i >= 0; i -= 1) if (tagMap.has(this.toPoints[i].context)) { lastMatchedIndex = i, lastMatchedPoint = tagMap.get(this.toPoints[i].context); break; } "clip" === this.newPointAnimateType && 0 !== this.toPoints.length && (Number.isFinite(lastMatchedIndex) ? (this.clipRange = this.toPoints[lastMatchedIndex][this.clipRangeByDimension] / this.toPoints[this.toPoints.length - 1][this.clipRangeByDimension], 1 === this.clipRange && (this.shrinkClipRange = this.toPoints[lastMatchedIndex][this.clipRangeByDimension] / this.fromPoints[this.fromPoints.length - 1][this.clipRangeByDimension]), isValidNumber(this.clipRange) ? this.clipRange = clamp(this.clipRange, 0, 1) : this.clipRange = 0) : this.clipRange = 0); let prevMatchedPoint = this.toPoints[0]; this.interpolatePoints = this.toPoints.map(((point, index) => { const matchedPoint = tagMap.get(point.context); return matchedPoint ? (prevMatchedPoint = matchedPoint, [ matchedPoint, point ]) : "appear" === this.newPointAnimateType || "clip" === this.newPointAnimateType ? [ point, point ] : index < firstMatchedIndex && firstMatchedPoint ? [ firstMatchedPoint, point ] : index > lastMatchedIndex && lastMatchedPoint ? [ lastMatchedPoint, point ] : [ prevMatchedPoint, point ]; })), this.points = this.interpolatePoints.map((interpolate => { const fromPoint = interpolate[0], toPoint = interpolate[1], newPoint = new Point(fromPoint.x, fromPoint.y, fromPoint.x1, fromPoint.y1); return newPoint.defined = toPoint.defined, newPoint.context = toPoint.context, newPoint; })); } onFirstRun() { const lastClipRange = this.target.attribute.clipRange; isValidNumber(lastClipRange * this.clipRange) && (this.clipRange *= lastClipRange); } onEnd(cb) { cb ? super.onEnd(cb) : (this.to && commitAnimationStaticAttrs(this.target, Object.keys(this.to), this.animate, this.to), super.onEnd()); } applyPointTransientAttributes(attributes) { const validAttrs = {}; Object.keys(attributes).forEach((key => { this.animate.validAttr(key) && (validAttrs[key] = attributes[key]); })), Object.keys(validAttrs).length && (applyAnimationFrameAttributes(this.target, validAttrs), this.target.addUpdatePositionTag(), this.target.addUpdateShapeAndBoundsTag()); } onUpdate(end, ratio, out) { if (end) this.applyPointTransientAttributes(this.to); else { if (this.points = this.points.map(((point, index) => { const newPoint = pointInterpolation(this.interpolatePoints[index][0], this.interpolatePoints[index][1], ratio); return newPoint.context = point.context, newPoint; })), this.clipRange) { if (this.shrinkClipRange) return void (end ? (out.points = this.toPoints, out.clipRange = 1) : (out.points = this.fromPoints, out.clipRange = this.clipRange - (this.clipRange - this.shrinkClipRange) * ratio)); applyAnimationTransientAttributes(this.target, { clipRange: this.clipRange + (1 - this.clipRange) * ratio }); } if (this.segmentsCache && this.to.segments) { let start = 0; const segments = this.to.segments.map(((segment, index) => { const end = start + this.segmentsCache[index], points = this.points.slice(start, end); return start = end, Object.assign(Object.assign({}, segment), { points: points }); })); this.applyPointTransientAttributes({ segments: segments }); } else this.applyPointTransientAttributes({ points: this.points }); } } } //# sourceMappingURL=tag-points.js.map