shape.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. define(function(require, exports, module) {
  2. var svg = require('./svg');
  3. var utils = require('../core/utils');
  4. var EventHandler = require('./eventhandler');
  5. var Styled = require('./styled');
  6. var Data = require('./data');
  7. var Matrix = require('./matrix');
  8. var Pen = require('./pen');
  9. var slice = Array.prototype.slice;
  10. var Box = require('./box');
  11. var Shape = require('../core/class').createClass('Shape', {
  12. mixins: [EventHandler, Styled, Data],
  13. constructor: function Shape(tagName) {
  14. this.node = svg.createNode(tagName);
  15. this.node.shape = this;
  16. this.transform = {
  17. translate: null,
  18. rotate: null,
  19. scale: null,
  20. matrix: null
  21. };
  22. this.callMixin();
  23. },
  24. getId: function() {
  25. return this.node.id;
  26. },
  27. setId: function(id) {
  28. this.node.id = id;
  29. return this;
  30. },
  31. getNode: function() {
  32. return this.node;
  33. },
  34. getBoundaryBox: function() {
  35. var box;
  36. try {
  37. box = this.node.getBBox();
  38. } catch (e) {
  39. box = {
  40. x: this.node.clientLeft,
  41. y: this.node.clientTop,
  42. width: this.node.clientWidth,
  43. height: this.node.clientHeight
  44. };
  45. }
  46. return new Box(box);
  47. },
  48. getRenderBox: function(refer) {
  49. var box = this.getBoundaryBox();
  50. var matrix = this.getTransform(refer);
  51. return matrix.transformBox(box);
  52. },
  53. getWidth: function() {
  54. return this.getRenderBox().width;
  55. },
  56. getHeight: function() {
  57. return this.getRenderBox().height;
  58. },
  59. getSize: function() {
  60. var box = this.getRenderBox();
  61. delete box.x;
  62. delete box.y;
  63. return box;
  64. },
  65. setOpacity: function(value) {
  66. this.node.setAttribute('opacity', value);
  67. return this;
  68. },
  69. getOpacity: function() {
  70. var opacity = this.node.getAttribute('opacity');
  71. return opacity ? +opacity : 1;
  72. },
  73. setVisible: function(value) {
  74. if (value) {
  75. this.node.removeAttribute('display');
  76. } else {
  77. this.node.setAttribute('display', 'none');
  78. }
  79. return this;
  80. },
  81. getVisible: function() {
  82. this.node.getAttribute('display');
  83. },
  84. hasAncestor: function(node) {
  85. var parent = this.container;
  86. while (parent) {
  87. if (parent === node) {
  88. return true;
  89. }
  90. parent = parent.container;
  91. }
  92. return false;
  93. },
  94. getTransform: function(refer) {
  95. return Matrix.getCTM(this, refer);
  96. },
  97. clearTransform: function() {
  98. this.node.removeAttribute('transform');
  99. this.transform = {
  100. translate: null,
  101. rotate: null,
  102. scale: null,
  103. matrix: null
  104. };
  105. this.trigger('shapeupdate', {
  106. type: 'transform'
  107. });
  108. return this;
  109. },
  110. _applyTransform: function() {
  111. var t = this.transform,
  112. result = [];
  113. if (t.translate) {
  114. result.push(['translate(', t.translate, ')']);
  115. }
  116. if (t.rotate) {
  117. result.push(['rotate(', t.rotate, ')']);
  118. }
  119. if (t.scale) {
  120. result.push(['scale(', t.scale, ')']);
  121. }
  122. if (t.matrix) {
  123. result.push(['matrix(', t.matrix, ')']);
  124. }
  125. this.node.setAttribute('transform', utils.flatten(result).join(' '));
  126. return this;
  127. },
  128. setMatrix: function(m) {
  129. this.transform.matrix = m;
  130. return this._applyTransform();
  131. },
  132. setTranslate: function(t) {
  133. this.transform.translate = t !== null && slice.call(arguments) || null;
  134. return this._applyTransform();
  135. },
  136. setRotate: function(r) {
  137. this.transform.rotate = r !== null && slice.call(arguments) || null;
  138. return this._applyTransform();
  139. },
  140. setScale: function(s) {
  141. this.transform.scale = s !== null && slice.call(arguments) || null;
  142. return this._applyTransform();
  143. },
  144. translate: function(dx, dy) {
  145. var m = this.transform.matrix || new Matrix();
  146. if (dy === undefined) {
  147. dy = 0;
  148. }
  149. this.transform.matrix = m.translate(dx, dy);
  150. return this._applyTransform();
  151. },
  152. rotate: function(deg) {
  153. var m = this.transform.matrix || new Matrix();
  154. this.transform.matrix = m.rotate(deg);
  155. return this._applyTransform();
  156. },
  157. scale: function(sx, sy) {
  158. var m = this.transform.matrix || new Matrix();
  159. if (sy === undefined) {
  160. sy = sx;
  161. }
  162. this.transform.matrix = m.scale(sx, sy);
  163. return this._applyTransform();
  164. },
  165. skew: function(sx, sy) {
  166. var m = this.transform.matrix || new Matrix();
  167. if (sy === undefined) {
  168. sy = sx;
  169. }
  170. this.transform.matrix = m.skew(sx, sy);
  171. return this._applyTransform();
  172. },
  173. stroke: function(pen, width) {
  174. if (pen && pen.stroke) {
  175. pen.stroke(this);
  176. } else if (pen) {
  177. // 字符串或重写了 toString 的对象
  178. this.node.setAttribute('stroke', pen.toString());
  179. if (width) {
  180. this.node.setAttribute('stroke-width', width);
  181. }
  182. } else if (pen === null) {
  183. this.node.removeAttribute('stroe');
  184. }
  185. return this;
  186. },
  187. fill: function(brush) {
  188. // 字符串或重写了 toString 的对象
  189. if (brush) {
  190. this.node.setAttribute('fill', brush.toString());
  191. }
  192. if (brush === null) {
  193. this.node.removeAttribute('fill');
  194. }
  195. return this;
  196. },
  197. setAttr: function(a, v) {
  198. var me = this;
  199. if (utils.isObject(a)) {
  200. utils.each(a, function(val, key) {
  201. me.setAttr(key, val);
  202. });
  203. }
  204. if (v === undefined || v === null || v === '') {
  205. this.node.removeAttribute(a);
  206. } else {
  207. this.node.setAttribute(a, v);
  208. }
  209. return this;
  210. },
  211. getAttr: function(a) {
  212. return this.node.getAttribute(a);
  213. }
  214. });
  215. return Shape;
  216. });