269 lines
5.3 KiB
JavaScript
269 lines
5.3 KiB
JavaScript
var guid = require("./core/guid");
|
||
|
||
var Eventful = require("./mixin/Eventful");
|
||
|
||
var Transformable = require("./mixin/Transformable");
|
||
|
||
var Animatable = require("./mixin/Animatable");
|
||
|
||
var zrUtil = require("./core/util");
|
||
|
||
/**
|
||
* @alias module:zrender/Element
|
||
* @constructor
|
||
* @extends {module:zrender/mixin/Animatable}
|
||
* @extends {module:zrender/mixin/Transformable}
|
||
* @extends {module:zrender/mixin/Eventful}
|
||
*/
|
||
var Element = function (opts) {
|
||
// jshint ignore:line
|
||
Transformable.call(this, opts);
|
||
Eventful.call(this, opts);
|
||
Animatable.call(this, opts);
|
||
/**
|
||
* 画布元素ID
|
||
* @type {string}
|
||
*/
|
||
|
||
this.id = opts.id || guid();
|
||
};
|
||
|
||
Element.prototype = {
|
||
/**
|
||
* 元素类型
|
||
* Element type
|
||
* @type {string}
|
||
*/
|
||
type: 'element',
|
||
|
||
/**
|
||
* 元素名字
|
||
* Element name
|
||
* @type {string}
|
||
*/
|
||
name: '',
|
||
|
||
/**
|
||
* ZRender 实例对象,会在 element 添加到 zrender 实例中后自动赋值
|
||
* ZRender instance will be assigned when element is associated with zrender
|
||
* @name module:/zrender/Element#__zr
|
||
* @type {module:zrender/ZRender}
|
||
*/
|
||
__zr: null,
|
||
|
||
/**
|
||
* 图形是否忽略,为true时忽略图形的绘制以及事件触发
|
||
* If ignore drawing and events of the element object
|
||
* @name module:/zrender/Element#ignore
|
||
* @type {boolean}
|
||
* @default false
|
||
*/
|
||
ignore: false,
|
||
|
||
/**
|
||
* 用于裁剪的路径(shape),所有 Group 内的路径在绘制时都会被这个路径裁剪
|
||
* 该路径会继承被裁减对象的变换
|
||
* @type {module:zrender/graphic/Path}
|
||
* @see http://www.w3.org/TR/2dcontext/#clipping-region
|
||
* @readOnly
|
||
*/
|
||
clipPath: null,
|
||
|
||
/**
|
||
* 是否是 Group
|
||
* @type {boolean}
|
||
*/
|
||
isGroup: false,
|
||
|
||
/**
|
||
* Drift element
|
||
* @param {number} dx dx on the global space
|
||
* @param {number} dy dy on the global space
|
||
*/
|
||
drift: function (dx, dy) {
|
||
switch (this.draggable) {
|
||
case 'horizontal':
|
||
dy = 0;
|
||
break;
|
||
|
||
case 'vertical':
|
||
dx = 0;
|
||
break;
|
||
}
|
||
|
||
var m = this.transform;
|
||
|
||
if (!m) {
|
||
m = this.transform = [1, 0, 0, 1, 0, 0];
|
||
}
|
||
|
||
m[4] += dx;
|
||
m[5] += dy;
|
||
this.decomposeTransform();
|
||
this.dirty(false);
|
||
},
|
||
|
||
/**
|
||
* Hook before update
|
||
*/
|
||
beforeUpdate: function () {},
|
||
|
||
/**
|
||
* Hook after update
|
||
*/
|
||
afterUpdate: function () {},
|
||
|
||
/**
|
||
* Update each frame
|
||
*/
|
||
update: function () {
|
||
this.updateTransform();
|
||
},
|
||
|
||
/**
|
||
* @param {Function} cb
|
||
* @param {} context
|
||
*/
|
||
traverse: function (cb, context) {},
|
||
|
||
/**
|
||
* @protected
|
||
*/
|
||
attrKV: function (key, value) {
|
||
if (key === 'position' || key === 'scale' || key === 'origin') {
|
||
// Copy the array
|
||
if (value) {
|
||
var target = this[key];
|
||
|
||
if (!target) {
|
||
target = this[key] = [];
|
||
}
|
||
|
||
target[0] = value[0];
|
||
target[1] = value[1];
|
||
}
|
||
} else {
|
||
this[key] = value;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Hide the element
|
||
*/
|
||
hide: function () {
|
||
this.ignore = true;
|
||
this.__zr && this.__zr.refresh();
|
||
},
|
||
|
||
/**
|
||
* Show the element
|
||
*/
|
||
show: function () {
|
||
this.ignore = false;
|
||
this.__zr && this.__zr.refresh();
|
||
},
|
||
|
||
/**
|
||
* @param {string|Object} key
|
||
* @param {*} value
|
||
*/
|
||
attr: function (key, value) {
|
||
if (typeof key === 'string') {
|
||
this.attrKV(key, value);
|
||
} else if (zrUtil.isObject(key)) {
|
||
for (var name in key) {
|
||
if (key.hasOwnProperty(name)) {
|
||
this.attrKV(name, key[name]);
|
||
}
|
||
}
|
||
}
|
||
|
||
this.dirty(false);
|
||
return this;
|
||
},
|
||
|
||
/**
|
||
* @param {module:zrender/graphic/Path} clipPath
|
||
*/
|
||
setClipPath: function (clipPath) {
|
||
var zr = this.__zr;
|
||
|
||
if (zr) {
|
||
clipPath.addSelfToZr(zr);
|
||
} // Remove previous clip path
|
||
|
||
|
||
if (this.clipPath && this.clipPath !== clipPath) {
|
||
this.removeClipPath();
|
||
}
|
||
|
||
this.clipPath = clipPath;
|
||
clipPath.__zr = zr;
|
||
clipPath.__clipTarget = this;
|
||
this.dirty(false);
|
||
},
|
||
|
||
/**
|
||
*/
|
||
removeClipPath: function () {
|
||
var clipPath = this.clipPath;
|
||
|
||
if (clipPath) {
|
||
if (clipPath.__zr) {
|
||
clipPath.removeSelfFromZr(clipPath.__zr);
|
||
}
|
||
|
||
clipPath.__zr = null;
|
||
clipPath.__clipTarget = null;
|
||
this.clipPath = null;
|
||
this.dirty(false);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Add self from zrender instance.
|
||
* Not recursively because it will be invoked when element added to storage.
|
||
* @param {module:zrender/ZRender} zr
|
||
*/
|
||
addSelfToZr: function (zr) {
|
||
this.__zr = zr; // 添加动画
|
||
|
||
var animators = this.animators;
|
||
|
||
if (animators) {
|
||
for (var i = 0; i < animators.length; i++) {
|
||
zr.animation.addAnimator(animators[i]);
|
||
}
|
||
}
|
||
|
||
if (this.clipPath) {
|
||
this.clipPath.addSelfToZr(zr);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Remove self from zrender instance.
|
||
* Not recursively because it will be invoked when element added to storage.
|
||
* @param {module:zrender/ZRender} zr
|
||
*/
|
||
removeSelfFromZr: function (zr) {
|
||
this.__zr = null; // 移除动画
|
||
|
||
var animators = this.animators;
|
||
|
||
if (animators) {
|
||
for (var i = 0; i < animators.length; i++) {
|
||
zr.animation.removeAnimator(animators[i]);
|
||
}
|
||
}
|
||
|
||
if (this.clipPath) {
|
||
this.clipPath.removeSelfFromZr(zr);
|
||
}
|
||
}
|
||
};
|
||
zrUtil.mixin(Element, Animatable);
|
||
zrUtil.mixin(Element, Transformable);
|
||
zrUtil.mixin(Element, Eventful);
|
||
var _default = Element;
|
||
module.exports = _default; |