| /** |
| * Base class of all displayable graphic objects |
| * @module zrender/graphic/Displayable |
| */ |
| import * as zrUtil from '../core/util'; |
| import Style from './Style'; |
| import Element from '../Element'; |
| import RectText from './mixin/RectText'; |
| /** |
| * @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); |
| |
| export default Displayable; |