277 lines
6.6 KiB
JavaScript
277 lines
6.6 KiB
JavaScript
|
var zrUtil = require("../core/util");
|
||
|
|
||
|
var Style = require("./Style");
|
||
|
|
||
|
var Element = require("../Element");
|
||
|
|
||
|
var RectText = require("./mixin/RectText");
|
||
|
|
||
|
/**
|
||
|
* Base class of all displayable graphic objects
|
||
|
* @module zrender/graphic/Displayable
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @alias module:zrender/graphic/Displayable
|
||
|
* @extends module:zrender/Element
|
||
|
* @extends module:zrender/graphic/mixin/RectText
|
||
|
*/
|
||
|
function Displayable(opts) {
|
||
|
opts = opts || {};
|
||
|
Element.call(this, opts); // Extend properties
|
||
|
|
||
|
for (var name in opts) {
|
||
|
if (opts.hasOwnProperty(name) && name !== 'style') {
|
||
|
this[name] = opts[name];
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* @type {module:zrender/graphic/Style}
|
||
|
*/
|
||
|
|
||
|
|
||
|
this.style = new Style(opts.style, this);
|
||
|
this._rect = null; // Shapes for cascade clipping.
|
||
|
// Can only be `null`/`undefined` or an non-empty array, MUST NOT be an empty array.
|
||
|
// because it is easy to only using null to check whether clipPaths changed.
|
||
|
|
||
|
this.__clipPaths = null; // FIXME Stateful must be mixined after style is setted
|
||
|
// Stateful.call(this, opts);
|
||
|
}
|
||
|
|
||
|
Displayable.prototype = {
|
||
|
constructor: Displayable,
|
||
|
type: 'displayable',
|
||
|
|
||
|
/**
|
||
|
* Dirty flag. From which painter will determine if this displayable object needs brush.
|
||
|
* @name module:zrender/graphic/Displayable#__dirty
|
||
|
* @type {boolean}
|
||
|
*/
|
||
|
__dirty: true,
|
||
|
|
||
|
/**
|
||
|
* Whether the displayable object is visible. when it is true, the displayable object
|
||
|
* is not drawn, but the mouse event can still trigger the object.
|
||
|
* @name module:/zrender/graphic/Displayable#invisible
|
||
|
* @type {boolean}
|
||
|
* @default false
|
||
|
*/
|
||
|
invisible: false,
|
||
|
|
||
|
/**
|
||
|
* @name module:/zrender/graphic/Displayable#z
|
||
|
* @type {number}
|
||
|
* @default 0
|
||
|
*/
|
||
|
z: 0,
|
||
|
|
||
|
/**
|
||
|
* @name module:/zrender/graphic/Displayable#z
|
||
|
* @type {number}
|
||
|
* @default 0
|
||
|
*/
|
||
|
z2: 0,
|
||
|
|
||
|
/**
|
||
|
* The z level determines the displayable object can be drawn in which layer canvas.
|
||
|
* @name module:/zrender/graphic/Displayable#zlevel
|
||
|
* @type {number}
|
||
|
* @default 0
|
||
|
*/
|
||
|
zlevel: 0,
|
||
|
|
||
|
/**
|
||
|
* Whether it can be dragged.
|
||
|
* @name module:/zrender/graphic/Displayable#draggable
|
||
|
* @type {boolean}
|
||
|
* @default false
|
||
|
*/
|
||
|
draggable: false,
|
||
|
|
||
|
/**
|
||
|
* Whether is it dragging.
|
||
|
* @name module:/zrender/graphic/Displayable#draggable
|
||
|
* @type {boolean}
|
||
|
* @default false
|
||
|
*/
|
||
|
dragging: false,
|
||
|
|
||
|
/**
|
||
|
* Whether to respond to mouse events.
|
||
|
* @name module:/zrender/graphic/Displayable#silent
|
||
|
* @type {boolean}
|
||
|
* @default false
|
||
|
*/
|
||
|
silent: false,
|
||
|
|
||
|
/**
|
||
|
* If enable culling
|
||
|
* @type {boolean}
|
||
|
* @default false
|
||
|
*/
|
||
|
culling: false,
|
||
|
|
||
|
/**
|
||
|
* Mouse cursor when hovered
|
||
|
* @name module:/zrender/graphic/Displayable#cursor
|
||
|
* @type {string}
|
||
|
*/
|
||
|
cursor: 'pointer',
|
||
|
|
||
|
/**
|
||
|
* If hover area is bounding rect
|
||
|
* @name module:/zrender/graphic/Displayable#rectHover
|
||
|
* @type {string}
|
||
|
*/
|
||
|
rectHover: false,
|
||
|
|
||
|
/**
|
||
|
* Render the element progressively when the value >= 0,
|
||
|
* usefull for large data.
|
||
|
* @type {boolean}
|
||
|
*/
|
||
|
progressive: false,
|
||
|
|
||
|
/**
|
||
|
* @type {boolean}
|
||
|
*/
|
||
|
incremental: false,
|
||
|
|
||
|
/**
|
||
|
* Scale ratio for global scale.
|
||
|
* @type {boolean}
|
||
|
*/
|
||
|
globalScaleRatio: 1,
|
||
|
beforeBrush: function (ctx) {},
|
||
|
afterBrush: function (ctx) {},
|
||
|
|
||
|
/**
|
||
|
* Graphic drawing method.
|
||
|
* @param {CanvasRenderingContext2D} ctx
|
||
|
*/
|
||
|
// Interface
|
||
|
brush: function (ctx, prevEl) {},
|
||
|
|
||
|
/**
|
||
|
* Get the minimum bounding box.
|
||
|
* @return {module:zrender/core/BoundingRect}
|
||
|
*/
|
||
|
// Interface
|
||
|
getBoundingRect: function () {},
|
||
|
|
||
|
/**
|
||
|
* If displayable element contain coord x, y
|
||
|
* @param {number} x
|
||
|
* @param {number} y
|
||
|
* @return {boolean}
|
||
|
*/
|
||
|
contain: function (x, y) {
|
||
|
return this.rectContain(x, y);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @param {Function} cb
|
||
|
* @param {} context
|
||
|
*/
|
||
|
traverse: function (cb, context) {
|
||
|
cb.call(context, this);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* If bounding rect of element contain coord x, y
|
||
|
* @param {number} x
|
||
|
* @param {number} y
|
||
|
* @return {boolean}
|
||
|
*/
|
||
|
rectContain: function (x, y) {
|
||
|
var coord = this.transformCoordToLocal(x, y);
|
||
|
var rect = this.getBoundingRect();
|
||
|
return rect.contain(coord[0], coord[1]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Mark displayable element dirty and refresh next frame
|
||
|
*/
|
||
|
dirty: function () {
|
||
|
this.__dirty = this.__dirtyText = true;
|
||
|
this._rect = null;
|
||
|
this.__zr && this.__zr.refresh();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* If displayable object binded any event
|
||
|
* @return {boolean}
|
||
|
*/
|
||
|
// TODO, events bound by bind
|
||
|
// isSilent: function () {
|
||
|
// return !(
|
||
|
// this.hoverable || this.draggable
|
||
|
// || this.onmousemove || this.onmouseover || this.onmouseout
|
||
|
// || this.onmousedown || this.onmouseup || this.onclick
|
||
|
// || this.ondragenter || this.ondragover || this.ondragleave
|
||
|
// || this.ondrop
|
||
|
// );
|
||
|
// },
|
||
|
|
||
|
/**
|
||
|
* Alias for animate('style')
|
||
|
* @param {boolean} loop
|
||
|
*/
|
||
|
animateStyle: function (loop) {
|
||
|
return this.animate('style', loop);
|
||
|
},
|
||
|
attrKV: function (key, value) {
|
||
|
if (key !== 'style') {
|
||
|
Element.prototype.attrKV.call(this, key, value);
|
||
|
} else {
|
||
|
this.style.set(value);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @param {Object|string} key
|
||
|
* @param {*} value
|
||
|
*/
|
||
|
setStyle: function (key, value) {
|
||
|
this.style.set(key, value);
|
||
|
this.dirty(false);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Use given style object
|
||
|
* @param {Object} obj
|
||
|
*/
|
||
|
useStyle: function (obj) {
|
||
|
this.style = new Style(obj, this);
|
||
|
this.dirty(false);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* The string value of `textPosition` needs to be calculated to a real postion.
|
||
|
* For example, `'inside'` is calculated to `[rect.width/2, rect.height/2]`
|
||
|
* by default. See `contain/text.js#calculateTextPosition` for more details.
|
||
|
* But some coutom shapes like "pin", "flag" have center that is not exactly
|
||
|
* `[width/2, height/2]`. So we provide this hook to customize the calculation
|
||
|
* for those shapes. It will be called if the `style.textPosition` is a string.
|
||
|
* @param {Obejct} [out] Prepared out object. If not provided, this method should
|
||
|
* be responsible for creating one.
|
||
|
* @param {module:zrender/graphic/Style} style
|
||
|
* @param {Object} rect {x, y, width, height}
|
||
|
* @return {Obejct} out The same as the input out.
|
||
|
* {
|
||
|
* x: number. mandatory.
|
||
|
* y: number. mandatory.
|
||
|
* textAlign: string. optional. use style.textAlign by default.
|
||
|
* textVerticalAlign: string. optional. use style.textVerticalAlign by default.
|
||
|
* }
|
||
|
*/
|
||
|
calculateTextPosition: null
|
||
|
};
|
||
|
zrUtil.inherits(Displayable, Element);
|
||
|
zrUtil.mixin(Displayable, RectText); // zrUtil.mixin(Displayable, Stateful);
|
||
|
|
||
|
var _default = Displayable;
|
||
|
module.exports = _default;
|