Displayable.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /**
  2. * Base class of all displayable graphic objects
  3. * @module zrender/graphic/Displayable
  4. */
  5. import * as zrUtil from '../core/util';
  6. import Style from './Style';
  7. import Element from '../Element';
  8. import RectText from './mixin/RectText';
  9. /**
  10. * @alias module:zrender/graphic/Displayable
  11. * @extends module:zrender/Element
  12. * @extends module:zrender/graphic/mixin/RectText
  13. */
  14. function Displayable(opts) {
  15. opts = opts || {};
  16. Element.call(this, opts);
  17. // Extend properties
  18. for (var name in opts) {
  19. if (
  20. opts.hasOwnProperty(name)
  21. && name !== 'style'
  22. ) {
  23. this[name] = opts[name];
  24. }
  25. }
  26. /**
  27. * @type {module:zrender/graphic/Style}
  28. */
  29. this.style = new Style(opts.style, this);
  30. this._rect = null;
  31. // Shapes for cascade clipping.
  32. // Can only be `null`/`undefined` or an non-empty array, MUST NOT be an empty array.
  33. // because it is easy to only using null to check whether clipPaths changed.
  34. this.__clipPaths = null;
  35. // FIXME Stateful must be mixined after style is setted
  36. // Stateful.call(this, opts);
  37. }
  38. Displayable.prototype = {
  39. constructor: Displayable,
  40. type: 'displayable',
  41. /**
  42. * Dirty flag. From which painter will determine if this displayable object needs brush.
  43. * @name module:zrender/graphic/Displayable#__dirty
  44. * @type {boolean}
  45. */
  46. __dirty: true,
  47. /**
  48. * Whether the displayable object is visible. when it is true, the displayable object
  49. * is not drawn, but the mouse event can still trigger the object.
  50. * @name module:/zrender/graphic/Displayable#invisible
  51. * @type {boolean}
  52. * @default false
  53. */
  54. invisible: false,
  55. /**
  56. * @name module:/zrender/graphic/Displayable#z
  57. * @type {number}
  58. * @default 0
  59. */
  60. z: 0,
  61. /**
  62. * @name module:/zrender/graphic/Displayable#z
  63. * @type {number}
  64. * @default 0
  65. */
  66. z2: 0,
  67. /**
  68. * The z level determines the displayable object can be drawn in which layer canvas.
  69. * @name module:/zrender/graphic/Displayable#zlevel
  70. * @type {number}
  71. * @default 0
  72. */
  73. zlevel: 0,
  74. /**
  75. * Whether it can be dragged.
  76. * @name module:/zrender/graphic/Displayable#draggable
  77. * @type {boolean}
  78. * @default false
  79. */
  80. draggable: false,
  81. /**
  82. * Whether is it dragging.
  83. * @name module:/zrender/graphic/Displayable#draggable
  84. * @type {boolean}
  85. * @default false
  86. */
  87. dragging: false,
  88. /**
  89. * Whether to respond to mouse events.
  90. * @name module:/zrender/graphic/Displayable#silent
  91. * @type {boolean}
  92. * @default false
  93. */
  94. silent: false,
  95. /**
  96. * If enable culling
  97. * @type {boolean}
  98. * @default false
  99. */
  100. culling: false,
  101. /**
  102. * Mouse cursor when hovered
  103. * @name module:/zrender/graphic/Displayable#cursor
  104. * @type {string}
  105. */
  106. cursor: 'pointer',
  107. /**
  108. * If hover area is bounding rect
  109. * @name module:/zrender/graphic/Displayable#rectHover
  110. * @type {string}
  111. */
  112. rectHover: false,
  113. /**
  114. * Render the element progressively when the value >= 0,
  115. * usefull for large data.
  116. * @type {boolean}
  117. */
  118. progressive: false,
  119. /**
  120. * @type {boolean}
  121. */
  122. incremental: false,
  123. /**
  124. * Scale ratio for global scale.
  125. * @type {boolean}
  126. */
  127. globalScaleRatio: 1,
  128. beforeBrush: function (ctx) {},
  129. afterBrush: function (ctx) {},
  130. /**
  131. * Graphic drawing method.
  132. * @param {CanvasRenderingContext2D} ctx
  133. */
  134. // Interface
  135. brush: function (ctx, prevEl) {},
  136. /**
  137. * Get the minimum bounding box.
  138. * @return {module:zrender/core/BoundingRect}
  139. */
  140. // Interface
  141. getBoundingRect: function () {},
  142. /**
  143. * If displayable element contain coord x, y
  144. * @param {number} x
  145. * @param {number} y
  146. * @return {boolean}
  147. */
  148. contain: function (x, y) {
  149. return this.rectContain(x, y);
  150. },
  151. /**
  152. * @param {Function} cb
  153. * @param {} context
  154. */
  155. traverse: function (cb, context) {
  156. cb.call(context, this);
  157. },
  158. /**
  159. * If bounding rect of element contain coord x, y
  160. * @param {number} x
  161. * @param {number} y
  162. * @return {boolean}
  163. */
  164. rectContain: function (x, y) {
  165. var coord = this.transformCoordToLocal(x, y);
  166. var rect = this.getBoundingRect();
  167. return rect.contain(coord[0], coord[1]);
  168. },
  169. /**
  170. * Mark displayable element dirty and refresh next frame
  171. */
  172. dirty: function () {
  173. this.__dirty = this.__dirtyText = true;
  174. this._rect = null;
  175. this.__zr && this.__zr.refresh();
  176. },
  177. /**
  178. * If displayable object binded any event
  179. * @return {boolean}
  180. */
  181. // TODO, events bound by bind
  182. // isSilent: function () {
  183. // return !(
  184. // this.hoverable || this.draggable
  185. // || this.onmousemove || this.onmouseover || this.onmouseout
  186. // || this.onmousedown || this.onmouseup || this.onclick
  187. // || this.ondragenter || this.ondragover || this.ondragleave
  188. // || this.ondrop
  189. // );
  190. // },
  191. /**
  192. * Alias for animate('style')
  193. * @param {boolean} loop
  194. */
  195. animateStyle: function (loop) {
  196. return this.animate('style', loop);
  197. },
  198. attrKV: function (key, value) {
  199. if (key !== 'style') {
  200. Element.prototype.attrKV.call(this, key, value);
  201. }
  202. else {
  203. this.style.set(value);
  204. }
  205. },
  206. /**
  207. * @param {Object|string} key
  208. * @param {*} value
  209. */
  210. setStyle: function (key, value) {
  211. this.style.set(key, value);
  212. this.dirty(false);
  213. return this;
  214. },
  215. /**
  216. * Use given style object
  217. * @param {Object} obj
  218. */
  219. useStyle: function (obj) {
  220. this.style = new Style(obj, this);
  221. this.dirty(false);
  222. return this;
  223. },
  224. /**
  225. * The string value of `textPosition` needs to be calculated to a real postion.
  226. * For example, `'inside'` is calculated to `[rect.width/2, rect.height/2]`
  227. * by default. See `contain/text.js#calculateTextPosition` for more details.
  228. * But some coutom shapes like "pin", "flag" have center that is not exactly
  229. * `[width/2, height/2]`. So we provide this hook to customize the calculation
  230. * for those shapes. It will be called if the `style.textPosition` is a string.
  231. * @param {Obejct} [out] Prepared out object. If not provided, this method should
  232. * be responsible for creating one.
  233. * @param {module:zrender/graphic/Style} style
  234. * @param {Object} rect {x, y, width, height}
  235. * @return {Obejct} out The same as the input out.
  236. * {
  237. * x: number. mandatory.
  238. * y: number. mandatory.
  239. * textAlign: string. optional. use style.textAlign by default.
  240. * textVerticalAlign: string. optional. use style.textVerticalAlign by default.
  241. * }
  242. */
  243. calculateTextPosition: null
  244. };
  245. zrUtil.inherits(Displayable, Element);
  246. zrUtil.mixin(Displayable, RectText);
  247. // zrUtil.mixin(Displayable, Stateful);
  248. export default Displayable;