325 lines
12 KiB
JavaScript
325 lines
12 KiB
JavaScript
|
import { __extends } from "tslib";
|
||
|
import Element from '../Element.js';
|
||
|
import BoundingRect from '../core/BoundingRect.js';
|
||
|
import { keys, extend, createObject } from '../core/util.js';
|
||
|
import { REDRAW_BIT, STYLE_CHANGED_BIT } from './constants.js';
|
||
|
var STYLE_MAGIC_KEY = '__zr_style_' + Math.round((Math.random() * 10));
|
||
|
export var DEFAULT_COMMON_STYLE = {
|
||
|
shadowBlur: 0,
|
||
|
shadowOffsetX: 0,
|
||
|
shadowOffsetY: 0,
|
||
|
shadowColor: '#000',
|
||
|
opacity: 1,
|
||
|
blend: 'source-over'
|
||
|
};
|
||
|
export var DEFAULT_COMMON_ANIMATION_PROPS = {
|
||
|
style: {
|
||
|
shadowBlur: true,
|
||
|
shadowOffsetX: true,
|
||
|
shadowOffsetY: true,
|
||
|
shadowColor: true,
|
||
|
opacity: true
|
||
|
}
|
||
|
};
|
||
|
DEFAULT_COMMON_STYLE[STYLE_MAGIC_KEY] = true;
|
||
|
var PRIMARY_STATES_KEYS = ['z', 'z2', 'invisible'];
|
||
|
var PRIMARY_STATES_KEYS_IN_HOVER_LAYER = ['invisible'];
|
||
|
var Displayable = (function (_super) {
|
||
|
__extends(Displayable, _super);
|
||
|
function Displayable(props) {
|
||
|
return _super.call(this, props) || this;
|
||
|
}
|
||
|
Displayable.prototype._init = function (props) {
|
||
|
var keysArr = keys(props);
|
||
|
for (var i = 0; i < keysArr.length; i++) {
|
||
|
var key = keysArr[i];
|
||
|
if (key === 'style') {
|
||
|
this.useStyle(props[key]);
|
||
|
}
|
||
|
else {
|
||
|
_super.prototype.attrKV.call(this, key, props[key]);
|
||
|
}
|
||
|
}
|
||
|
if (!this.style) {
|
||
|
this.useStyle({});
|
||
|
}
|
||
|
};
|
||
|
Displayable.prototype.beforeBrush = function () { };
|
||
|
Displayable.prototype.afterBrush = function () { };
|
||
|
Displayable.prototype.innerBeforeBrush = function () { };
|
||
|
Displayable.prototype.innerAfterBrush = function () { };
|
||
|
Displayable.prototype.shouldBePainted = function (viewWidth, viewHeight, considerClipPath, considerAncestors) {
|
||
|
var m = this.transform;
|
||
|
if (this.ignore
|
||
|
|| this.invisible
|
||
|
|| this.style.opacity === 0
|
||
|
|| (this.culling
|
||
|
&& isDisplayableCulled(this, viewWidth, viewHeight))
|
||
|
|| (m && !m[0] && !m[3])) {
|
||
|
return false;
|
||
|
}
|
||
|
if (considerClipPath && this.__clipPaths) {
|
||
|
for (var i = 0; i < this.__clipPaths.length; ++i) {
|
||
|
if (this.__clipPaths[i].isZeroArea()) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (considerAncestors && this.parent) {
|
||
|
var parent_1 = this.parent;
|
||
|
while (parent_1) {
|
||
|
if (parent_1.ignore) {
|
||
|
return false;
|
||
|
}
|
||
|
parent_1 = parent_1.parent;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
};
|
||
|
Displayable.prototype.contain = function (x, y) {
|
||
|
return this.rectContain(x, y);
|
||
|
};
|
||
|
Displayable.prototype.traverse = function (cb, context) {
|
||
|
cb.call(context, this);
|
||
|
};
|
||
|
Displayable.prototype.rectContain = function (x, y) {
|
||
|
var coord = this.transformCoordToLocal(x, y);
|
||
|
var rect = this.getBoundingRect();
|
||
|
return rect.contain(coord[0], coord[1]);
|
||
|
};
|
||
|
Displayable.prototype.getPaintRect = function () {
|
||
|
var rect = this._paintRect;
|
||
|
if (!this._paintRect || this.__dirty) {
|
||
|
var transform = this.transform;
|
||
|
var elRect = this.getBoundingRect();
|
||
|
var style = this.style;
|
||
|
var shadowSize = style.shadowBlur || 0;
|
||
|
var shadowOffsetX = style.shadowOffsetX || 0;
|
||
|
var shadowOffsetY = style.shadowOffsetY || 0;
|
||
|
rect = this._paintRect || (this._paintRect = new BoundingRect(0, 0, 0, 0));
|
||
|
if (transform) {
|
||
|
BoundingRect.applyTransform(rect, elRect, transform);
|
||
|
}
|
||
|
else {
|
||
|
rect.copy(elRect);
|
||
|
}
|
||
|
if (shadowSize || shadowOffsetX || shadowOffsetY) {
|
||
|
rect.width += shadowSize * 2 + Math.abs(shadowOffsetX);
|
||
|
rect.height += shadowSize * 2 + Math.abs(shadowOffsetY);
|
||
|
rect.x = Math.min(rect.x, rect.x + shadowOffsetX - shadowSize);
|
||
|
rect.y = Math.min(rect.y, rect.y + shadowOffsetY - shadowSize);
|
||
|
}
|
||
|
var tolerance = this.dirtyRectTolerance;
|
||
|
if (!rect.isZero()) {
|
||
|
rect.x = Math.floor(rect.x - tolerance);
|
||
|
rect.y = Math.floor(rect.y - tolerance);
|
||
|
rect.width = Math.ceil(rect.width + 1 + tolerance * 2);
|
||
|
rect.height = Math.ceil(rect.height + 1 + tolerance * 2);
|
||
|
}
|
||
|
}
|
||
|
return rect;
|
||
|
};
|
||
|
Displayable.prototype.setPrevPaintRect = function (paintRect) {
|
||
|
if (paintRect) {
|
||
|
this._prevPaintRect = this._prevPaintRect || new BoundingRect(0, 0, 0, 0);
|
||
|
this._prevPaintRect.copy(paintRect);
|
||
|
}
|
||
|
else {
|
||
|
this._prevPaintRect = null;
|
||
|
}
|
||
|
};
|
||
|
Displayable.prototype.getPrevPaintRect = function () {
|
||
|
return this._prevPaintRect;
|
||
|
};
|
||
|
Displayable.prototype.animateStyle = function (loop) {
|
||
|
return this.animate('style', loop);
|
||
|
};
|
||
|
Displayable.prototype.updateDuringAnimation = function (targetKey) {
|
||
|
if (targetKey === 'style') {
|
||
|
this.dirtyStyle();
|
||
|
}
|
||
|
else {
|
||
|
this.markRedraw();
|
||
|
}
|
||
|
};
|
||
|
Displayable.prototype.attrKV = function (key, value) {
|
||
|
if (key !== 'style') {
|
||
|
_super.prototype.attrKV.call(this, key, value);
|
||
|
}
|
||
|
else {
|
||
|
if (!this.style) {
|
||
|
this.useStyle(value);
|
||
|
}
|
||
|
else {
|
||
|
this.setStyle(value);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
Displayable.prototype.setStyle = function (keyOrObj, value) {
|
||
|
if (typeof keyOrObj === 'string') {
|
||
|
this.style[keyOrObj] = value;
|
||
|
}
|
||
|
else {
|
||
|
extend(this.style, keyOrObj);
|
||
|
}
|
||
|
this.dirtyStyle();
|
||
|
return this;
|
||
|
};
|
||
|
Displayable.prototype.dirtyStyle = function (notRedraw) {
|
||
|
if (!notRedraw) {
|
||
|
this.markRedraw();
|
||
|
}
|
||
|
this.__dirty |= STYLE_CHANGED_BIT;
|
||
|
if (this._rect) {
|
||
|
this._rect = null;
|
||
|
}
|
||
|
};
|
||
|
Displayable.prototype.dirty = function () {
|
||
|
this.dirtyStyle();
|
||
|
};
|
||
|
Displayable.prototype.styleChanged = function () {
|
||
|
return !!(this.__dirty & STYLE_CHANGED_BIT);
|
||
|
};
|
||
|
Displayable.prototype.styleUpdated = function () {
|
||
|
this.__dirty &= ~STYLE_CHANGED_BIT;
|
||
|
};
|
||
|
Displayable.prototype.createStyle = function (obj) {
|
||
|
return createObject(DEFAULT_COMMON_STYLE, obj);
|
||
|
};
|
||
|
Displayable.prototype.useStyle = function (obj) {
|
||
|
if (!obj[STYLE_MAGIC_KEY]) {
|
||
|
obj = this.createStyle(obj);
|
||
|
}
|
||
|
if (this.__inHover) {
|
||
|
this.__hoverStyle = obj;
|
||
|
}
|
||
|
else {
|
||
|
this.style = obj;
|
||
|
}
|
||
|
this.dirtyStyle();
|
||
|
};
|
||
|
Displayable.prototype.isStyleObject = function (obj) {
|
||
|
return obj[STYLE_MAGIC_KEY];
|
||
|
};
|
||
|
Displayable.prototype._innerSaveToNormal = function (toState) {
|
||
|
_super.prototype._innerSaveToNormal.call(this, toState);
|
||
|
var normalState = this._normalState;
|
||
|
if (toState.style && !normalState.style) {
|
||
|
normalState.style = this._mergeStyle(this.createStyle(), this.style);
|
||
|
}
|
||
|
this._savePrimaryToNormal(toState, normalState, PRIMARY_STATES_KEYS);
|
||
|
};
|
||
|
Displayable.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
|
||
|
_super.prototype._applyStateObj.call(this, stateName, state, normalState, keepCurrentStates, transition, animationCfg);
|
||
|
var needsRestoreToNormal = !(state && keepCurrentStates);
|
||
|
var targetStyle;
|
||
|
if (state && state.style) {
|
||
|
if (transition) {
|
||
|
if (keepCurrentStates) {
|
||
|
targetStyle = state.style;
|
||
|
}
|
||
|
else {
|
||
|
targetStyle = this._mergeStyle(this.createStyle(), normalState.style);
|
||
|
this._mergeStyle(targetStyle, state.style);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
targetStyle = this._mergeStyle(this.createStyle(), keepCurrentStates ? this.style : normalState.style);
|
||
|
this._mergeStyle(targetStyle, state.style);
|
||
|
}
|
||
|
}
|
||
|
else if (needsRestoreToNormal) {
|
||
|
targetStyle = normalState.style;
|
||
|
}
|
||
|
if (targetStyle) {
|
||
|
if (transition) {
|
||
|
var sourceStyle = this.style;
|
||
|
this.style = this.createStyle(needsRestoreToNormal ? {} : sourceStyle);
|
||
|
if (needsRestoreToNormal) {
|
||
|
var changedKeys = keys(sourceStyle);
|
||
|
for (var i = 0; i < changedKeys.length; i++) {
|
||
|
var key = changedKeys[i];
|
||
|
if (key in targetStyle) {
|
||
|
targetStyle[key] = targetStyle[key];
|
||
|
this.style[key] = sourceStyle[key];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
var targetKeys = keys(targetStyle);
|
||
|
for (var i = 0; i < targetKeys.length; i++) {
|
||
|
var key = targetKeys[i];
|
||
|
this.style[key] = this.style[key];
|
||
|
}
|
||
|
this._transitionState(stateName, {
|
||
|
style: targetStyle
|
||
|
}, animationCfg, this.getAnimationStyleProps());
|
||
|
}
|
||
|
else {
|
||
|
this.useStyle(targetStyle);
|
||
|
}
|
||
|
}
|
||
|
var statesKeys = this.__inHover ? PRIMARY_STATES_KEYS_IN_HOVER_LAYER : PRIMARY_STATES_KEYS;
|
||
|
for (var i = 0; i < statesKeys.length; i++) {
|
||
|
var key = statesKeys[i];
|
||
|
if (state && state[key] != null) {
|
||
|
this[key] = state[key];
|
||
|
}
|
||
|
else if (needsRestoreToNormal) {
|
||
|
if (normalState[key] != null) {
|
||
|
this[key] = normalState[key];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
Displayable.prototype._mergeStates = function (states) {
|
||
|
var mergedState = _super.prototype._mergeStates.call(this, states);
|
||
|
var mergedStyle;
|
||
|
for (var i = 0; i < states.length; i++) {
|
||
|
var state = states[i];
|
||
|
if (state.style) {
|
||
|
mergedStyle = mergedStyle || {};
|
||
|
this._mergeStyle(mergedStyle, state.style);
|
||
|
}
|
||
|
}
|
||
|
if (mergedStyle) {
|
||
|
mergedState.style = mergedStyle;
|
||
|
}
|
||
|
return mergedState;
|
||
|
};
|
||
|
Displayable.prototype._mergeStyle = function (targetStyle, sourceStyle) {
|
||
|
extend(targetStyle, sourceStyle);
|
||
|
return targetStyle;
|
||
|
};
|
||
|
Displayable.prototype.getAnimationStyleProps = function () {
|
||
|
return DEFAULT_COMMON_ANIMATION_PROPS;
|
||
|
};
|
||
|
Displayable.initDefaultProps = (function () {
|
||
|
var dispProto = Displayable.prototype;
|
||
|
dispProto.type = 'displayable';
|
||
|
dispProto.invisible = false;
|
||
|
dispProto.z = 0;
|
||
|
dispProto.z2 = 0;
|
||
|
dispProto.zlevel = 0;
|
||
|
dispProto.culling = false;
|
||
|
dispProto.cursor = 'pointer';
|
||
|
dispProto.rectHover = false;
|
||
|
dispProto.incremental = false;
|
||
|
dispProto._rect = null;
|
||
|
dispProto.dirtyRectTolerance = 0;
|
||
|
dispProto.__dirty = REDRAW_BIT | STYLE_CHANGED_BIT;
|
||
|
})();
|
||
|
return Displayable;
|
||
|
}(Element));
|
||
|
var tmpRect = new BoundingRect(0, 0, 0, 0);
|
||
|
var viewRect = new BoundingRect(0, 0, 0, 0);
|
||
|
function isDisplayableCulled(el, width, height) {
|
||
|
tmpRect.copy(el.getBoundingRect());
|
||
|
if (el.transform) {
|
||
|
tmpRect.applyTransform(el.transform);
|
||
|
}
|
||
|
viewRect.width = width;
|
||
|
viewRect.height = height;
|
||
|
return !tmpRect.intersect(viewRect);
|
||
|
}
|
||
|
export default Displayable;
|