| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- var util_1 = require("@antv/util");
- var d3Timer = require("d3-timer");
- var d3_interpolate_1 = require("d3-interpolate"); // 目前整体动画只需要数值和数组的差值计算
- var register_1 = require("./register");
- var PathUtil = require("../util/path");
- var color_1 = require("../util/color");
- var IDENTITY_MATRIX = [1, 0, 0, 0, 1, 0, 0, 0, 1];
- /**
- * 使用 ratio 进行插值计算来更新属性
- * @param {IElement} shape 元素
- * @param {Animation} animation 动画
- * @param {number} ratio 比例
- * @return {boolean} 动画是否执行完成
- */
- function _update(shape, animation, ratio) {
- var cProps = {}; // 此刻属性
- var fromAttrs = animation.fromAttrs, toAttrs = animation.toAttrs;
- if (shape.destroyed) {
- return;
- }
- var interf; // 差值函数
- for (var k in toAttrs) {
- if (!util_1.isEqual(fromAttrs[k], toAttrs[k])) {
- if (k === 'path') {
- var toPath = toAttrs[k];
- var fromPath = fromAttrs[k];
- if (toPath.length > fromPath.length) {
- toPath = PathUtil.parsePathString(toAttrs[k]); // 终点状态
- fromPath = PathUtil.parsePathString(fromAttrs[k]); // 起始状态
- fromPath = PathUtil.fillPathByDiff(fromPath, toPath);
- fromPath = PathUtil.formatPath(fromPath, toPath);
- animation.fromAttrs.path = fromPath;
- animation.toAttrs.path = toPath;
- }
- else if (!animation.pathFormatted) {
- toPath = PathUtil.parsePathString(toAttrs[k]);
- fromPath = PathUtil.parsePathString(fromAttrs[k]);
- fromPath = PathUtil.formatPath(fromPath, toPath);
- animation.fromAttrs.path = fromPath;
- animation.toAttrs.path = toPath;
- animation.pathFormatted = true;
- }
- cProps[k] = [];
- for (var i = 0; i < toPath.length; i++) {
- var toPathPoint = toPath[i];
- var fromPathPoint = fromPath[i];
- var cPathPoint = [];
- for (var j = 0; j < toPathPoint.length; j++) {
- if (util_1.isNumber(toPathPoint[j]) && fromPathPoint && util_1.isNumber(fromPathPoint[j])) {
- interf = d3_interpolate_1.interpolate(fromPathPoint[j], toPathPoint[j]);
- cPathPoint.push(interf(ratio));
- }
- else {
- cPathPoint.push(toPathPoint[j]);
- }
- }
- cProps[k].push(cPathPoint);
- }
- }
- else if (k === 'matrix') {
- /*
- 对矩阵进行插值时,需要保证矩阵不为空,为空则使用单位矩阵
- TODO: 二维和三维场景下单位矩阵不同,之后 WebGL 版需要做进一步处理
- */
- var matrixFn = d3_interpolate_1.interpolateArray(fromAttrs[k] || IDENTITY_MATRIX, toAttrs[k] || IDENTITY_MATRIX);
- var currentMatrix = matrixFn(ratio);
- cProps[k] = currentMatrix;
- }
- else if (color_1.isColorProp(k) && color_1.isGradientColor(toAttrs[k])) {
- cProps[k] = toAttrs[k];
- }
- else if (!util_1.isFunction(toAttrs[k])) {
- // 非函数类型的值才能做插值
- interf = d3_interpolate_1.interpolate(fromAttrs[k], toAttrs[k]);
- cProps[k] = interf(ratio);
- }
- }
- }
- shape.attr(cProps);
- }
- /**
- * 根据自定义帧动画函数 onFrame 来更新属性
- * @param {IElement} shape 元素
- * @param {Animation} animation 动画
- * @param {number} elapsed 动画执行时间(毫秒)
- * @return {boolean} 动画是否执行完成
- */
- function update(shape, animation, elapsed) {
- var startTime = animation.startTime, delay = animation.delay;
- // 如果还没有开始执行或暂停,先不更新
- if (elapsed < startTime + delay || animation._paused) {
- return false;
- }
- var ratio;
- var duration = animation.duration;
- var easing = animation.easing;
- var easeFn = register_1.getEasing(easing);
- // 已执行时间
- elapsed = elapsed - startTime - animation.delay;
- if (animation.repeat) {
- // 如果动画重复执行,则 elapsed > duration,计算 ratio 时需取模
- ratio = (elapsed % duration) / duration;
- ratio = easeFn(ratio);
- }
- else {
- ratio = elapsed / duration;
- if (ratio < 1) {
- // 动画未执行完
- ratio = easeFn(ratio);
- }
- else {
- // 动画已执行完
- if (animation.onFrame) {
- shape.attr(animation.onFrame(1));
- }
- else {
- shape.attr(animation.toAttrs);
- }
- return true;
- }
- }
- if (animation.onFrame) {
- var attrs = animation.onFrame(ratio);
- shape.attr(attrs);
- }
- else {
- _update(shape, animation, ratio);
- }
- return false;
- }
- var Timeline = /** @class */ (function () {
- /**
- * 时间轴构造函数,依赖于画布
- * @param {}
- */
- function Timeline(canvas) {
- /**
- * 执行动画的元素列表
- * @type {IElement[]}
- */
- this.animators = [];
- /**
- * 当前时间
- * @type {number}
- */
- this.current = 0;
- /**
- * 定时器
- * @type {d3Timer.Timer}
- */
- this.timer = null;
- this.canvas = canvas;
- }
- /**
- * 初始化定时器
- */
- Timeline.prototype.initTimer = function () {
- var _this = this;
- var isFinished = false;
- var shape;
- var animations;
- var animation;
- this.timer = d3Timer.timer(function (elapsed) {
- _this.current = elapsed;
- if (_this.animators.length > 0) {
- for (var i = _this.animators.length - 1; i >= 0; i--) {
- shape = _this.animators[i];
- if (shape.destroyed) {
- // 如果已经被销毁,直接移出队列
- _this.removeAnimator(i);
- continue;
- }
- if (!shape.isAnimatePaused()) {
- animations = shape.get('animations');
- for (var j = animations.length - 1; j >= 0; j--) {
- animation = animations[j];
- isFinished = update(shape, animation, elapsed);
- if (isFinished) {
- animations.splice(j, 1);
- isFinished = false;
- if (animation.callback) {
- animation.callback();
- }
- }
- }
- }
- if (animations.length === 0) {
- _this.removeAnimator(i);
- }
- }
- var autoDraw = _this.canvas.get('autoDraw');
- // 非自动渲染模式下,手动调用 canvas.draw() 重新渲染
- if (!autoDraw) {
- _this.canvas.draw();
- }
- }
- });
- };
- /**
- * 增加动画元素
- */
- Timeline.prototype.addAnimator = function (shape) {
- this.animators.push(shape);
- };
- /**
- * 移除动画元素
- */
- Timeline.prototype.removeAnimator = function (index) {
- this.animators.splice(index, 1);
- };
- /**
- * 是否有动画在执行
- */
- Timeline.prototype.isAnimating = function () {
- return !!this.animators.length;
- };
- /**
- * 停止定时器
- */
- Timeline.prototype.stop = function () {
- if (this.timer) {
- this.timer.stop();
- }
- };
- /**
- * 停止时间轴上所有元素的动画,并置空动画元素列表
- * @param {boolean} toEnd 是否到动画的最终状态,用来透传给动画元素的 stopAnimate 方法
- */
- Timeline.prototype.stopAllAnimations = function (toEnd) {
- if (toEnd === void 0) { toEnd = true; }
- this.animators.forEach(function (animator) {
- animator.stopAnimate(toEnd);
- });
- this.animators = [];
- this.canvas.draw();
- };
- /**
- * 获取当前时间
- */
- Timeline.prototype.getTime = function () {
- return this.current;
- };
- return Timeline;
- }());
- exports.default = Timeline;
- //# sourceMappingURL=timeline.js.map
|