UNPKG

38.7 kBJavaScriptView Raw
1import Transformable, { TRANSFORMABLE_PROPS } from './core/Transformable.js';
2import Animator, { cloneValue } from './animation/Animator.js';
3import BoundingRect from './core/BoundingRect.js';
4import Eventful from './core/Eventful.js';
5import { calculateTextPosition, parsePercent } from './contain/text.js';
6import { guid, isObject, keys, extend, indexOf, logError, mixin, isArrayLike, isTypedArray, isGradientObject, filter, reduce } from './core/util.js';
7import { LIGHT_LABEL_COLOR, DARK_LABEL_COLOR } from './config.js';
8import { parse, stringify } from './tool/color.js';
9import { REDRAW_BIT } from './graphic/constants.js';
10export var PRESERVED_NORMAL_STATE = '__zr_normal__';
11var PRIMARY_STATES_KEYS = TRANSFORMABLE_PROPS.concat(['ignore']);
12var DEFAULT_ANIMATABLE_MAP = reduce(TRANSFORMABLE_PROPS, function (obj, key) {
13 obj[key] = true;
14 return obj;
15}, { ignore: false });
16var tmpTextPosCalcRes = {};
17var tmpBoundingRect = new BoundingRect(0, 0, 0, 0);
18var Element = (function () {
19 function Element(props) {
20 this.id = guid();
21 this.animators = [];
22 this.currentStates = [];
23 this.states = {};
24 this._init(props);
25 }
26 Element.prototype._init = function (props) {
27 this.attr(props);
28 };
29 Element.prototype.drift = function (dx, dy, e) {
30 switch (this.draggable) {
31 case 'horizontal':
32 dy = 0;
33 break;
34 case 'vertical':
35 dx = 0;
36 break;
37 }
38 var m = this.transform;
39 if (!m) {
40 m = this.transform = [1, 0, 0, 1, 0, 0];
41 }
42 m[4] += dx;
43 m[5] += dy;
44 this.decomposeTransform();
45 this.markRedraw();
46 };
47 Element.prototype.beforeUpdate = function () { };
48 Element.prototype.afterUpdate = function () { };
49 Element.prototype.update = function () {
50 this.updateTransform();
51 if (this.__dirty) {
52 this.updateInnerText();
53 }
54 };
55 Element.prototype.updateInnerText = function (forceUpdate) {
56 var textEl = this._textContent;
57 if (textEl && (!textEl.ignore || forceUpdate)) {
58 if (!this.textConfig) {
59 this.textConfig = {};
60 }
61 var textConfig = this.textConfig;
62 var isLocal = textConfig.local;
63 var innerTransformable = textEl.innerTransformable;
64 var textAlign = void 0;
65 var textVerticalAlign = void 0;
66 var textStyleChanged = false;
67 innerTransformable.parent = isLocal ? this : null;
68 var innerOrigin = false;
69 innerTransformable.copyTransform(textEl);
70 if (textConfig.position != null) {
71 var layoutRect = tmpBoundingRect;
72 if (textConfig.layoutRect) {
73 layoutRect.copy(textConfig.layoutRect);
74 }
75 else {
76 layoutRect.copy(this.getBoundingRect());
77 }
78 if (!isLocal) {
79 layoutRect.applyTransform(this.transform);
80 }
81 if (this.calculateTextPosition) {
82 this.calculateTextPosition(tmpTextPosCalcRes, textConfig, layoutRect);
83 }
84 else {
85 calculateTextPosition(tmpTextPosCalcRes, textConfig, layoutRect);
86 }
87 innerTransformable.x = tmpTextPosCalcRes.x;
88 innerTransformable.y = tmpTextPosCalcRes.y;
89 textAlign = tmpTextPosCalcRes.align;
90 textVerticalAlign = tmpTextPosCalcRes.verticalAlign;
91 var textOrigin = textConfig.origin;
92 if (textOrigin && textConfig.rotation != null) {
93 var relOriginX = void 0;
94 var relOriginY = void 0;
95 if (textOrigin === 'center') {
96 relOriginX = layoutRect.width * 0.5;
97 relOriginY = layoutRect.height * 0.5;
98 }
99 else {
100 relOriginX = parsePercent(textOrigin[0], layoutRect.width);
101 relOriginY = parsePercent(textOrigin[1], layoutRect.height);
102 }
103 innerOrigin = true;
104 innerTransformable.originX = -innerTransformable.x + relOriginX + (isLocal ? 0 : layoutRect.x);
105 innerTransformable.originY = -innerTransformable.y + relOriginY + (isLocal ? 0 : layoutRect.y);
106 }
107 }
108 if (textConfig.rotation != null) {
109 innerTransformable.rotation = textConfig.rotation;
110 }
111 var textOffset = textConfig.offset;
112 if (textOffset) {
113 innerTransformable.x += textOffset[0];
114 innerTransformable.y += textOffset[1];
115 if (!innerOrigin) {
116 innerTransformable.originX = -textOffset[0];
117 innerTransformable.originY = -textOffset[1];
118 }
119 }
120 var isInside = textConfig.inside == null
121 ? (typeof textConfig.position === 'string' && textConfig.position.indexOf('inside') >= 0)
122 : textConfig.inside;
123 var innerTextDefaultStyle = this._innerTextDefaultStyle || (this._innerTextDefaultStyle = {});
124 var textFill = void 0;
125 var textStroke = void 0;
126 var autoStroke = void 0;
127 if (isInside && this.canBeInsideText()) {
128 textFill = textConfig.insideFill;
129 textStroke = textConfig.insideStroke;
130 if (textFill == null || textFill === 'auto') {
131 textFill = this.getInsideTextFill();
132 }
133 if (textStroke == null || textStroke === 'auto') {
134 textStroke = this.getInsideTextStroke(textFill);
135 autoStroke = true;
136 }
137 }
138 else {
139 textFill = textConfig.outsideFill;
140 textStroke = textConfig.outsideStroke;
141 if (textFill == null || textFill === 'auto') {
142 textFill = this.getOutsideFill();
143 }
144 if (textStroke == null || textStroke === 'auto') {
145 textStroke = this.getOutsideStroke(textFill);
146 autoStroke = true;
147 }
148 }
149 textFill = textFill || '#000';
150 if (textFill !== innerTextDefaultStyle.fill
151 || textStroke !== innerTextDefaultStyle.stroke
152 || autoStroke !== innerTextDefaultStyle.autoStroke
153 || textAlign !== innerTextDefaultStyle.align
154 || textVerticalAlign !== innerTextDefaultStyle.verticalAlign) {
155 textStyleChanged = true;
156 innerTextDefaultStyle.fill = textFill;
157 innerTextDefaultStyle.stroke = textStroke;
158 innerTextDefaultStyle.autoStroke = autoStroke;
159 innerTextDefaultStyle.align = textAlign;
160 innerTextDefaultStyle.verticalAlign = textVerticalAlign;
161 textEl.setDefaultTextStyle(innerTextDefaultStyle);
162 }
163 textEl.__dirty |= REDRAW_BIT;
164 if (textStyleChanged) {
165 textEl.dirtyStyle(true);
166 }
167 }
168 };
169 Element.prototype.canBeInsideText = function () {
170 return true;
171 };
172 Element.prototype.getInsideTextFill = function () {
173 return '#fff';
174 };
175 Element.prototype.getInsideTextStroke = function (textFill) {
176 return '#000';
177 };
178 Element.prototype.getOutsideFill = function () {
179 return this.__zr && this.__zr.isDarkMode() ? LIGHT_LABEL_COLOR : DARK_LABEL_COLOR;
180 };
181 Element.prototype.getOutsideStroke = function (textFill) {
182 var backgroundColor = this.__zr && this.__zr.getBackgroundColor();
183 var colorArr = typeof backgroundColor === 'string' && parse(backgroundColor);
184 if (!colorArr) {
185 colorArr = [255, 255, 255, 1];
186 }
187 var alpha = colorArr[3];
188 var isDark = this.__zr.isDarkMode();
189 for (var i = 0; i < 3; i++) {
190 colorArr[i] = colorArr[i] * alpha + (isDark ? 0 : 255) * (1 - alpha);
191 }
192 colorArr[3] = 1;
193 return stringify(colorArr, 'rgba');
194 };
195 Element.prototype.traverse = function (cb, context) { };
196 Element.prototype.attrKV = function (key, value) {
197 if (key === 'textConfig') {
198 this.setTextConfig(value);
199 }
200 else if (key === 'textContent') {
201 this.setTextContent(value);
202 }
203 else if (key === 'clipPath') {
204 this.setClipPath(value);
205 }
206 else if (key === 'extra') {
207 this.extra = this.extra || {};
208 extend(this.extra, value);
209 }
210 else {
211 this[key] = value;
212 }
213 };
214 Element.prototype.hide = function () {
215 this.ignore = true;
216 this.markRedraw();
217 };
218 Element.prototype.show = function () {
219 this.ignore = false;
220 this.markRedraw();
221 };
222 Element.prototype.attr = function (keyOrObj, value) {
223 if (typeof keyOrObj === 'string') {
224 this.attrKV(keyOrObj, value);
225 }
226 else if (isObject(keyOrObj)) {
227 var obj = keyOrObj;
228 var keysArr = keys(obj);
229 for (var i = 0; i < keysArr.length; i++) {
230 var key = keysArr[i];
231 this.attrKV(key, keyOrObj[key]);
232 }
233 }
234 this.markRedraw();
235 return this;
236 };
237 Element.prototype.saveCurrentToNormalState = function (toState) {
238 this._innerSaveToNormal(toState);
239 var normalState = this._normalState;
240 for (var i = 0; i < this.animators.length; i++) {
241 var animator = this.animators[i];
242 var fromStateTransition = animator.__fromStateTransition;
243 if (animator.getLoop() || fromStateTransition && fromStateTransition !== PRESERVED_NORMAL_STATE) {
244 continue;
245 }
246 var targetName = animator.targetName;
247 var target = targetName
248 ? normalState[targetName] : normalState;
249 animator.saveTo(target);
250 }
251 };
252 Element.prototype._innerSaveToNormal = function (toState) {
253 var normalState = this._normalState;
254 if (!normalState) {
255 normalState = this._normalState = {};
256 }
257 if (toState.textConfig && !normalState.textConfig) {
258 normalState.textConfig = this.textConfig;
259 }
260 this._savePrimaryToNormal(toState, normalState, PRIMARY_STATES_KEYS);
261 };
262 Element.prototype._savePrimaryToNormal = function (toState, normalState, primaryKeys) {
263 for (var i = 0; i < primaryKeys.length; i++) {
264 var key = primaryKeys[i];
265 if (toState[key] != null && !(key in normalState)) {
266 normalState[key] = this[key];
267 }
268 }
269 };
270 Element.prototype.hasState = function () {
271 return this.currentStates.length > 0;
272 };
273 Element.prototype.getState = function (name) {
274 return this.states[name];
275 };
276 Element.prototype.ensureState = function (name) {
277 var states = this.states;
278 if (!states[name]) {
279 states[name] = {};
280 }
281 return states[name];
282 };
283 Element.prototype.clearStates = function (noAnimation) {
284 this.useState(PRESERVED_NORMAL_STATE, false, noAnimation);
285 };
286 Element.prototype.useState = function (stateName, keepCurrentStates, noAnimation, forceUseHoverLayer) {
287 var toNormalState = stateName === PRESERVED_NORMAL_STATE;
288 var hasStates = this.hasState();
289 if (!hasStates && toNormalState) {
290 return;
291 }
292 var currentStates = this.currentStates;
293 var animationCfg = this.stateTransition;
294 if (indexOf(currentStates, stateName) >= 0 && (keepCurrentStates || currentStates.length === 1)) {
295 return;
296 }
297 var state;
298 if (this.stateProxy && !toNormalState) {
299 state = this.stateProxy(stateName);
300 }
301 if (!state) {
302 state = (this.states && this.states[stateName]);
303 }
304 if (!state && !toNormalState) {
305 logError("State " + stateName + " not exists.");
306 return;
307 }
308 if (!toNormalState) {
309 this.saveCurrentToNormalState(state);
310 }
311 var useHoverLayer = !!((state && state.hoverLayer) || forceUseHoverLayer);
312 if (useHoverLayer) {
313 this._toggleHoverLayerFlag(true);
314 }
315 this._applyStateObj(stateName, state, this._normalState, keepCurrentStates, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg);
316 var textContent = this._textContent;
317 var textGuide = this._textGuide;
318 if (textContent) {
319 textContent.useState(stateName, keepCurrentStates, noAnimation, useHoverLayer);
320 }
321 if (textGuide) {
322 textGuide.useState(stateName, keepCurrentStates, noAnimation, useHoverLayer);
323 }
324 if (toNormalState) {
325 this.currentStates = [];
326 this._normalState = {};
327 }
328 else {
329 if (!keepCurrentStates) {
330 this.currentStates = [stateName];
331 }
332 else {
333 this.currentStates.push(stateName);
334 }
335 }
336 this._updateAnimationTargets();
337 this.markRedraw();
338 if (!useHoverLayer && this.__inHover) {
339 this._toggleHoverLayerFlag(false);
340 this.__dirty &= ~REDRAW_BIT;
341 }
342 return state;
343 };
344 Element.prototype.useStates = function (states, noAnimation, forceUseHoverLayer) {
345 if (!states.length) {
346 this.clearStates();
347 }
348 else {
349 var stateObjects = [];
350 var currentStates = this.currentStates;
351 var len = states.length;
352 var notChange = len === currentStates.length;
353 if (notChange) {
354 for (var i = 0; i < len; i++) {
355 if (states[i] !== currentStates[i]) {
356 notChange = false;
357 break;
358 }
359 }
360 }
361 if (notChange) {
362 return;
363 }
364 for (var i = 0; i < len; i++) {
365 var stateName = states[i];
366 var stateObj = void 0;
367 if (this.stateProxy) {
368 stateObj = this.stateProxy(stateName, states);
369 }
370 if (!stateObj) {
371 stateObj = this.states[stateName];
372 }
373 if (stateObj) {
374 stateObjects.push(stateObj);
375 }
376 }
377 var lastStateObj = stateObjects[len - 1];
378 var useHoverLayer = !!((lastStateObj && lastStateObj.hoverLayer) || forceUseHoverLayer);
379 if (useHoverLayer) {
380 this._toggleHoverLayerFlag(true);
381 }
382 var mergedState = this._mergeStates(stateObjects);
383 var animationCfg = this.stateTransition;
384 this.saveCurrentToNormalState(mergedState);
385 this._applyStateObj(states.join(','), mergedState, this._normalState, false, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg);
386 var textContent = this._textContent;
387 var textGuide = this._textGuide;
388 if (textContent) {
389 textContent.useStates(states, noAnimation, useHoverLayer);
390 }
391 if (textGuide) {
392 textGuide.useStates(states, noAnimation, useHoverLayer);
393 }
394 this._updateAnimationTargets();
395 this.currentStates = states.slice();
396 this.markRedraw();
397 if (!useHoverLayer && this.__inHover) {
398 this._toggleHoverLayerFlag(false);
399 this.__dirty &= ~REDRAW_BIT;
400 }
401 }
402 };
403 Element.prototype.isSilent = function () {
404 var isSilent = this.silent;
405 var ancestor = this.parent;
406 while (!isSilent && ancestor) {
407 if (ancestor.silent) {
408 isSilent = true;
409 break;
410 }
411 ancestor = ancestor.parent;
412 }
413 return isSilent;
414 };
415 Element.prototype._updateAnimationTargets = function () {
416 for (var i = 0; i < this.animators.length; i++) {
417 var animator = this.animators[i];
418 if (animator.targetName) {
419 animator.changeTarget(this[animator.targetName]);
420 }
421 }
422 };
423 Element.prototype.removeState = function (state) {
424 var idx = indexOf(this.currentStates, state);
425 if (idx >= 0) {
426 var currentStates = this.currentStates.slice();
427 currentStates.splice(idx, 1);
428 this.useStates(currentStates);
429 }
430 };
431 Element.prototype.replaceState = function (oldState, newState, forceAdd) {
432 var currentStates = this.currentStates.slice();
433 var idx = indexOf(currentStates, oldState);
434 var newStateExists = indexOf(currentStates, newState) >= 0;
435 if (idx >= 0) {
436 if (!newStateExists) {
437 currentStates[idx] = newState;
438 }
439 else {
440 currentStates.splice(idx, 1);
441 }
442 }
443 else if (forceAdd && !newStateExists) {
444 currentStates.push(newState);
445 }
446 this.useStates(currentStates);
447 };
448 Element.prototype.toggleState = function (state, enable) {
449 if (enable) {
450 this.useState(state, true);
451 }
452 else {
453 this.removeState(state);
454 }
455 };
456 Element.prototype._mergeStates = function (states) {
457 var mergedState = {};
458 var mergedTextConfig;
459 for (var i = 0; i < states.length; i++) {
460 var state = states[i];
461 extend(mergedState, state);
462 if (state.textConfig) {
463 mergedTextConfig = mergedTextConfig || {};
464 extend(mergedTextConfig, state.textConfig);
465 }
466 }
467 if (mergedTextConfig) {
468 mergedState.textConfig = mergedTextConfig;
469 }
470 return mergedState;
471 };
472 Element.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
473 var needsRestoreToNormal = !(state && keepCurrentStates);
474 if (state && state.textConfig) {
475 this.textConfig = extend({}, keepCurrentStates ? this.textConfig : normalState.textConfig);
476 extend(this.textConfig, state.textConfig);
477 }
478 else if (needsRestoreToNormal) {
479 if (normalState.textConfig) {
480 this.textConfig = normalState.textConfig;
481 }
482 }
483 var transitionTarget = {};
484 var hasTransition = false;
485 for (var i = 0; i < PRIMARY_STATES_KEYS.length; i++) {
486 var key = PRIMARY_STATES_KEYS[i];
487 var propNeedsTransition = transition && DEFAULT_ANIMATABLE_MAP[key];
488 if (state && state[key] != null) {
489 if (propNeedsTransition) {
490 hasTransition = true;
491 transitionTarget[key] = state[key];
492 }
493 else {
494 this[key] = state[key];
495 }
496 }
497 else if (needsRestoreToNormal) {
498 if (normalState[key] != null) {
499 if (propNeedsTransition) {
500 hasTransition = true;
501 transitionTarget[key] = normalState[key];
502 }
503 else {
504 this[key] = normalState[key];
505 }
506 }
507 }
508 }
509 if (!transition) {
510 for (var i = 0; i < this.animators.length; i++) {
511 var animator = this.animators[i];
512 var targetName = animator.targetName;
513 if (!animator.getLoop()) {
514 animator.__changeFinalValue(targetName
515 ? (state || normalState)[targetName]
516 : (state || normalState));
517 }
518 }
519 }
520 if (hasTransition) {
521 this._transitionState(stateName, transitionTarget, animationCfg);
522 }
523 };
524 Element.prototype._attachComponent = function (componentEl) {
525 if (componentEl.__zr && !componentEl.__hostTarget) {
526 if (process.env.NODE_ENV !== 'production') {
527 throw new Error('Text element has been added to zrender.');
528 }
529 return;
530 }
531 if (componentEl === this) {
532 if (process.env.NODE_ENV !== 'production') {
533 throw new Error('Recursive component attachment.');
534 }
535 return;
536 }
537 var zr = this.__zr;
538 if (zr) {
539 componentEl.addSelfToZr(zr);
540 }
541 componentEl.__zr = zr;
542 componentEl.__hostTarget = this;
543 };
544 Element.prototype._detachComponent = function (componentEl) {
545 if (componentEl.__zr) {
546 componentEl.removeSelfFromZr(componentEl.__zr);
547 }
548 componentEl.__zr = null;
549 componentEl.__hostTarget = null;
550 };
551 Element.prototype.getClipPath = function () {
552 return this._clipPath;
553 };
554 Element.prototype.setClipPath = function (clipPath) {
555 if (this._clipPath && this._clipPath !== clipPath) {
556 this.removeClipPath();
557 }
558 this._attachComponent(clipPath);
559 this._clipPath = clipPath;
560 this.markRedraw();
561 };
562 Element.prototype.removeClipPath = function () {
563 var clipPath = this._clipPath;
564 if (clipPath) {
565 this._detachComponent(clipPath);
566 this._clipPath = null;
567 this.markRedraw();
568 }
569 };
570 Element.prototype.getTextContent = function () {
571 return this._textContent;
572 };
573 Element.prototype.setTextContent = function (textEl) {
574 var previousTextContent = this._textContent;
575 if (previousTextContent === textEl) {
576 return;
577 }
578 if (previousTextContent && previousTextContent !== textEl) {
579 this.removeTextContent();
580 }
581 if (process.env.NODE_ENV !== 'production') {
582 if (textEl.__zr && !textEl.__hostTarget) {
583 throw new Error('Text element has been added to zrender.');
584 }
585 }
586 textEl.innerTransformable = new Transformable();
587 this._attachComponent(textEl);
588 this._textContent = textEl;
589 this.markRedraw();
590 };
591 Element.prototype.setTextConfig = function (cfg) {
592 if (!this.textConfig) {
593 this.textConfig = {};
594 }
595 extend(this.textConfig, cfg);
596 this.markRedraw();
597 };
598 Element.prototype.removeTextConfig = function () {
599 this.textConfig = null;
600 this.markRedraw();
601 };
602 Element.prototype.removeTextContent = function () {
603 var textEl = this._textContent;
604 if (textEl) {
605 textEl.innerTransformable = null;
606 this._detachComponent(textEl);
607 this._textContent = null;
608 this._innerTextDefaultStyle = null;
609 this.markRedraw();
610 }
611 };
612 Element.prototype.getTextGuideLine = function () {
613 return this._textGuide;
614 };
615 Element.prototype.setTextGuideLine = function (guideLine) {
616 if (this._textGuide && this._textGuide !== guideLine) {
617 this.removeTextGuideLine();
618 }
619 this._attachComponent(guideLine);
620 this._textGuide = guideLine;
621 this.markRedraw();
622 };
623 Element.prototype.removeTextGuideLine = function () {
624 var textGuide = this._textGuide;
625 if (textGuide) {
626 this._detachComponent(textGuide);
627 this._textGuide = null;
628 this.markRedraw();
629 }
630 };
631 Element.prototype.markRedraw = function () {
632 this.__dirty |= REDRAW_BIT;
633 var zr = this.__zr;
634 if (zr) {
635 if (this.__inHover) {
636 zr.refreshHover();
637 }
638 else {
639 zr.refresh();
640 }
641 }
642 if (this.__hostTarget) {
643 this.__hostTarget.markRedraw();
644 }
645 };
646 Element.prototype.dirty = function () {
647 this.markRedraw();
648 };
649 Element.prototype._toggleHoverLayerFlag = function (inHover) {
650 this.__inHover = inHover;
651 var textContent = this._textContent;
652 var textGuide = this._textGuide;
653 if (textContent) {
654 textContent.__inHover = inHover;
655 }
656 if (textGuide) {
657 textGuide.__inHover = inHover;
658 }
659 };
660 Element.prototype.addSelfToZr = function (zr) {
661 if (this.__zr === zr) {
662 return;
663 }
664 this.__zr = zr;
665 var animators = this.animators;
666 if (animators) {
667 for (var i = 0; i < animators.length; i++) {
668 zr.animation.addAnimator(animators[i]);
669 }
670 }
671 if (this._clipPath) {
672 this._clipPath.addSelfToZr(zr);
673 }
674 if (this._textContent) {
675 this._textContent.addSelfToZr(zr);
676 }
677 if (this._textGuide) {
678 this._textGuide.addSelfToZr(zr);
679 }
680 };
681 Element.prototype.removeSelfFromZr = function (zr) {
682 if (!this.__zr) {
683 return;
684 }
685 this.__zr = null;
686 var animators = this.animators;
687 if (animators) {
688 for (var i = 0; i < animators.length; i++) {
689 zr.animation.removeAnimator(animators[i]);
690 }
691 }
692 if (this._clipPath) {
693 this._clipPath.removeSelfFromZr(zr);
694 }
695 if (this._textContent) {
696 this._textContent.removeSelfFromZr(zr);
697 }
698 if (this._textGuide) {
699 this._textGuide.removeSelfFromZr(zr);
700 }
701 };
702 Element.prototype.animate = function (key, loop, allowDiscreteAnimation) {
703 var target = key ? this[key] : this;
704 if (process.env.NODE_ENV !== 'production') {
705 if (!target) {
706 logError('Property "'
707 + key
708 + '" is not existed in element '
709 + this.id);
710 return;
711 }
712 }
713 var animator = new Animator(target, loop, allowDiscreteAnimation);
714 key && (animator.targetName = key);
715 this.addAnimator(animator, key);
716 return animator;
717 };
718 Element.prototype.addAnimator = function (animator, key) {
719 var zr = this.__zr;
720 var el = this;
721 animator.during(function () {
722 el.updateDuringAnimation(key);
723 }).done(function () {
724 var animators = el.animators;
725 var idx = indexOf(animators, animator);
726 if (idx >= 0) {
727 animators.splice(idx, 1);
728 }
729 });
730 this.animators.push(animator);
731 if (zr) {
732 zr.animation.addAnimator(animator);
733 }
734 zr && zr.wakeUp();
735 };
736 Element.prototype.updateDuringAnimation = function (key) {
737 this.markRedraw();
738 };
739 Element.prototype.stopAnimation = function (scope, forwardToLast) {
740 var animators = this.animators;
741 var len = animators.length;
742 var leftAnimators = [];
743 for (var i = 0; i < len; i++) {
744 var animator = animators[i];
745 if (!scope || scope === animator.scope) {
746 animator.stop(forwardToLast);
747 }
748 else {
749 leftAnimators.push(animator);
750 }
751 }
752 this.animators = leftAnimators;
753 return this;
754 };
755 Element.prototype.animateTo = function (target, cfg, animationProps) {
756 animateTo(this, target, cfg, animationProps);
757 };
758 Element.prototype.animateFrom = function (target, cfg, animationProps) {
759 animateTo(this, target, cfg, animationProps, true);
760 };
761 Element.prototype._transitionState = function (stateName, target, cfg, animationProps) {
762 var animators = animateTo(this, target, cfg, animationProps);
763 for (var i = 0; i < animators.length; i++) {
764 animators[i].__fromStateTransition = stateName;
765 }
766 };
767 Element.prototype.getBoundingRect = function () {
768 return null;
769 };
770 Element.prototype.getPaintRect = function () {
771 return null;
772 };
773 Element.initDefaultProps = (function () {
774 var elProto = Element.prototype;
775 elProto.type = 'element';
776 elProto.name = '';
777 elProto.ignore =
778 elProto.silent =
779 elProto.isGroup =
780 elProto.draggable =
781 elProto.dragging =
782 elProto.ignoreClip =
783 elProto.__inHover = false;
784 elProto.__dirty = REDRAW_BIT;
785 var logs = {};
786 function logDeprecatedError(key, xKey, yKey) {
787 if (!logs[key + xKey + yKey]) {
788 console.warn("DEPRECATED: '" + key + "' has been deprecated. use '" + xKey + "', '" + yKey + "' instead");
789 logs[key + xKey + yKey] = true;
790 }
791 }
792 function createLegacyProperty(key, privateKey, xKey, yKey) {
793 Object.defineProperty(elProto, key, {
794 get: function () {
795 if (process.env.NODE_ENV !== 'production') {
796 logDeprecatedError(key, xKey, yKey);
797 }
798 if (!this[privateKey]) {
799 var pos = this[privateKey] = [];
800 enhanceArray(this, pos);
801 }
802 return this[privateKey];
803 },
804 set: function (pos) {
805 if (process.env.NODE_ENV !== 'production') {
806 logDeprecatedError(key, xKey, yKey);
807 }
808 this[xKey] = pos[0];
809 this[yKey] = pos[1];
810 this[privateKey] = pos;
811 enhanceArray(this, pos);
812 }
813 });
814 function enhanceArray(self, pos) {
815 Object.defineProperty(pos, 0, {
816 get: function () {
817 return self[xKey];
818 },
819 set: function (val) {
820 self[xKey] = val;
821 }
822 });
823 Object.defineProperty(pos, 1, {
824 get: function () {
825 return self[yKey];
826 },
827 set: function (val) {
828 self[yKey] = val;
829 }
830 });
831 }
832 }
833 if (Object.defineProperty) {
834 createLegacyProperty('position', '_legacyPos', 'x', 'y');
835 createLegacyProperty('scale', '_legacyScale', 'scaleX', 'scaleY');
836 createLegacyProperty('origin', '_legacyOrigin', 'originX', 'originY');
837 }
838 })();
839 return Element;
840}());
841mixin(Element, Eventful);
842mixin(Element, Transformable);
843function animateTo(animatable, target, cfg, animationProps, reverse) {
844 cfg = cfg || {};
845 var animators = [];
846 animateToShallow(animatable, '', animatable, target, cfg, animationProps, animators, reverse);
847 var finishCount = animators.length;
848 var doneHappened = false;
849 var cfgDone = cfg.done;
850 var cfgAborted = cfg.aborted;
851 var doneCb = function () {
852 doneHappened = true;
853 finishCount--;
854 if (finishCount <= 0) {
855 doneHappened
856 ? (cfgDone && cfgDone())
857 : (cfgAborted && cfgAborted());
858 }
859 };
860 var abortedCb = function () {
861 finishCount--;
862 if (finishCount <= 0) {
863 doneHappened
864 ? (cfgDone && cfgDone())
865 : (cfgAborted && cfgAborted());
866 }
867 };
868 if (!finishCount) {
869 cfgDone && cfgDone();
870 }
871 if (animators.length > 0 && cfg.during) {
872 animators[0].during(function (target, percent) {
873 cfg.during(percent);
874 });
875 }
876 for (var i = 0; i < animators.length; i++) {
877 var animator = animators[i];
878 if (doneCb) {
879 animator.done(doneCb);
880 }
881 if (abortedCb) {
882 animator.aborted(abortedCb);
883 }
884 if (cfg.force) {
885 animator.duration(cfg.duration);
886 }
887 animator.start(cfg.easing);
888 }
889 return animators;
890}
891function copyArrShallow(source, target, len) {
892 for (var i = 0; i < len; i++) {
893 source[i] = target[i];
894 }
895}
896function is2DArray(value) {
897 return isArrayLike(value[0]);
898}
899function copyValue(target, source, key) {
900 if (isArrayLike(source[key])) {
901 if (!isArrayLike(target[key])) {
902 target[key] = [];
903 }
904 if (isTypedArray(source[key])) {
905 var len = source[key].length;
906 if (target[key].length !== len) {
907 target[key] = new (source[key].constructor)(len);
908 copyArrShallow(target[key], source[key], len);
909 }
910 }
911 else {
912 var sourceArr = source[key];
913 var targetArr = target[key];
914 var len0 = sourceArr.length;
915 if (is2DArray(sourceArr)) {
916 var len1 = sourceArr[0].length;
917 for (var i = 0; i < len0; i++) {
918 if (!targetArr[i]) {
919 targetArr[i] = Array.prototype.slice.call(sourceArr[i]);
920 }
921 else {
922 copyArrShallow(targetArr[i], sourceArr[i], len1);
923 }
924 }
925 }
926 else {
927 copyArrShallow(targetArr, sourceArr, len0);
928 }
929 targetArr.length = sourceArr.length;
930 }
931 }
932 else {
933 target[key] = source[key];
934 }
935}
936function isValueSame(val1, val2) {
937 return val1 === val2
938 || isArrayLike(val1) && isArrayLike(val2) && is1DArraySame(val1, val2);
939}
940function is1DArraySame(arr0, arr1) {
941 var len = arr0.length;
942 if (len !== arr1.length) {
943 return false;
944 }
945 for (var i = 0; i < len; i++) {
946 if (arr0[i] !== arr1[i]) {
947 return false;
948 }
949 }
950 return true;
951}
952function animateToShallow(animatable, topKey, animateObj, target, cfg, animationProps, animators, reverse) {
953 var targetKeys = keys(target);
954 var duration = cfg.duration;
955 var delay = cfg.delay;
956 var additive = cfg.additive;
957 var setToFinal = cfg.setToFinal;
958 var animateAll = !isObject(animationProps);
959 var existsAnimators = animatable.animators;
960 var animationKeys = [];
961 for (var k = 0; k < targetKeys.length; k++) {
962 var innerKey = targetKeys[k];
963 var targetVal = target[innerKey];
964 if (targetVal != null && animateObj[innerKey] != null
965 && (animateAll || animationProps[innerKey])) {
966 if (isObject(targetVal)
967 && !isArrayLike(targetVal)
968 && !isGradientObject(targetVal)) {
969 if (topKey) {
970 if (!reverse) {
971 animateObj[innerKey] = targetVal;
972 animatable.updateDuringAnimation(topKey);
973 }
974 continue;
975 }
976 animateToShallow(animatable, innerKey, animateObj[innerKey], targetVal, cfg, animationProps && animationProps[innerKey], animators, reverse);
977 }
978 else {
979 animationKeys.push(innerKey);
980 }
981 }
982 else if (!reverse) {
983 animateObj[innerKey] = targetVal;
984 animatable.updateDuringAnimation(topKey);
985 animationKeys.push(innerKey);
986 }
987 }
988 var keyLen = animationKeys.length;
989 if (!additive && keyLen) {
990 for (var i = 0; i < existsAnimators.length; i++) {
991 var animator = existsAnimators[i];
992 if (animator.targetName === topKey) {
993 var allAborted = animator.stopTracks(animationKeys);
994 if (allAborted) {
995 var idx = indexOf(existsAnimators, animator);
996 existsAnimators.splice(idx, 1);
997 }
998 }
999 }
1000 }
1001 if (!cfg.force) {
1002 animationKeys = filter(animationKeys, function (key) { return !isValueSame(target[key], animateObj[key]); });
1003 keyLen = animationKeys.length;
1004 }
1005 if (keyLen > 0
1006 || (cfg.force && !animators.length)) {
1007 var revertedSource = void 0;
1008 var reversedTarget = void 0;
1009 var sourceClone = void 0;
1010 if (reverse) {
1011 reversedTarget = {};
1012 if (setToFinal) {
1013 revertedSource = {};
1014 }
1015 for (var i = 0; i < keyLen; i++) {
1016 var innerKey = animationKeys[i];
1017 reversedTarget[innerKey] = animateObj[innerKey];
1018 if (setToFinal) {
1019 revertedSource[innerKey] = target[innerKey];
1020 }
1021 else {
1022 animateObj[innerKey] = target[innerKey];
1023 }
1024 }
1025 }
1026 else if (setToFinal) {
1027 sourceClone = {};
1028 for (var i = 0; i < keyLen; i++) {
1029 var innerKey = animationKeys[i];
1030 sourceClone[innerKey] = cloneValue(animateObj[innerKey]);
1031 copyValue(animateObj, target, innerKey);
1032 }
1033 }
1034 var animator = new Animator(animateObj, false, false, additive ? filter(existsAnimators, function (animator) { return animator.targetName === topKey; }) : null);
1035 animator.targetName = topKey;
1036 if (cfg.scope) {
1037 animator.scope = cfg.scope;
1038 }
1039 if (setToFinal && revertedSource) {
1040 animator.whenWithKeys(0, revertedSource, animationKeys);
1041 }
1042 if (sourceClone) {
1043 animator.whenWithKeys(0, sourceClone, animationKeys);
1044 }
1045 animator.whenWithKeys(duration == null ? 500 : duration, reverse ? reversedTarget : target, animationKeys).delay(delay || 0);
1046 animatable.addAnimator(animator, topKey);
1047 animators.push(animator);
1048 }
1049}
1050export default Element;