abstractgraphics.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. // Copyright 2007 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Graphics utility functions and factory methods.
  16. * @author arv@google.com (Erik Arvidsson)
  17. */
  18. goog.provide('goog.graphics.AbstractGraphics');
  19. goog.require('goog.dom');
  20. goog.require('goog.graphics.AffineTransform');
  21. goog.require('goog.graphics.Element');
  22. goog.require('goog.graphics.EllipseElement');
  23. goog.require('goog.graphics.Fill');
  24. goog.require('goog.graphics.Font');
  25. goog.require('goog.graphics.GroupElement');
  26. goog.require('goog.graphics.Path');
  27. goog.require('goog.graphics.PathElement');
  28. goog.require('goog.graphics.RectElement');
  29. goog.require('goog.graphics.Stroke');
  30. goog.require('goog.graphics.StrokeAndFillElement');
  31. goog.require('goog.graphics.TextElement');
  32. goog.require('goog.math.Coordinate');
  33. goog.require('goog.math.Size');
  34. goog.require('goog.style');
  35. goog.require('goog.ui.Component');
  36. /**
  37. * Base class for the different graphics. You should never construct objects
  38. * of this class. Instead us goog.graphics.createGraphics
  39. * @param {number|string} width The width in pixels or percent.
  40. * @param {number|string} height The height in pixels or percent.
  41. * @param {?number=} opt_coordWidth Optional coordinate system width - if
  42. * omitted or null, defaults to same as width.
  43. * @param {?number=} opt_coordHeight Optional coordinate system height - if
  44. * omitted or null, defaults to same as height.
  45. * @param {goog.dom.DomHelper=} opt_domHelper The DOM helper object for the
  46. * document we want to render in.
  47. * @constructor
  48. * @extends {goog.ui.Component}
  49. */
  50. goog.graphics.AbstractGraphics = function(
  51. width, height, opt_coordWidth, opt_coordHeight, opt_domHelper) {
  52. goog.ui.Component.call(this, opt_domHelper);
  53. /**
  54. * Width of graphics in pixels or percentage points.
  55. * @type {number|string}
  56. * @protected
  57. */
  58. this.width = width;
  59. /**
  60. * Height of graphics in pixels or percentage points.
  61. * @type {number|string}
  62. * @protected
  63. */
  64. this.height = height;
  65. /**
  66. * Width of coordinate system in units.
  67. * @type {?number}
  68. * @protected
  69. */
  70. this.coordWidth = opt_coordWidth || null;
  71. /**
  72. * Height of coordinate system in units.
  73. * @type {?number}
  74. * @protected
  75. */
  76. this.coordHeight = opt_coordHeight || null;
  77. };
  78. goog.inherits(goog.graphics.AbstractGraphics, goog.ui.Component);
  79. /**
  80. * The root level group element.
  81. * @type {goog.graphics.GroupElement?}
  82. * @protected
  83. */
  84. goog.graphics.AbstractGraphics.prototype.canvasElement = null;
  85. /**
  86. * Left coordinate of the view box
  87. * @type {number}
  88. * @protected
  89. */
  90. goog.graphics.AbstractGraphics.prototype.coordLeft = 0;
  91. /**
  92. * Top coordinate of the view box
  93. * @type {number}
  94. * @protected
  95. */
  96. goog.graphics.AbstractGraphics.prototype.coordTop = 0;
  97. /**
  98. * @return {goog.graphics.GroupElement} The root level canvas element.
  99. */
  100. goog.graphics.AbstractGraphics.prototype.getCanvasElement = function() {
  101. return this.canvasElement;
  102. };
  103. /**
  104. * Changes the coordinate size.
  105. * @param {number} coordWidth The coordinate width.
  106. * @param {number} coordHeight The coordinate height.
  107. */
  108. goog.graphics.AbstractGraphics.prototype.setCoordSize = function(
  109. coordWidth, coordHeight) {
  110. this.coordWidth = coordWidth;
  111. this.coordHeight = coordHeight;
  112. };
  113. /**
  114. * @return {goog.math.Size} The coordinate size.
  115. */
  116. goog.graphics.AbstractGraphics.prototype.getCoordSize = function() {
  117. if (this.coordWidth) {
  118. return new goog.math.Size(
  119. this.coordWidth,
  120. /** @type {number} */ (this.coordHeight));
  121. } else {
  122. return this.getPixelSize();
  123. }
  124. };
  125. /**
  126. * Changes the coordinate system position.
  127. * @param {number} left The coordinate system left bound.
  128. * @param {number} top The coordinate system top bound.
  129. */
  130. goog.graphics.AbstractGraphics.prototype.setCoordOrigin = goog.abstractMethod;
  131. /**
  132. * @return {!goog.math.Coordinate} The coordinate system position.
  133. */
  134. goog.graphics.AbstractGraphics.prototype.getCoordOrigin = function() {
  135. return new goog.math.Coordinate(this.coordLeft, this.coordTop);
  136. };
  137. /**
  138. * Change the size of the canvas.
  139. * @param {number} pixelWidth The width in pixels.
  140. * @param {number} pixelHeight The height in pixels.
  141. */
  142. goog.graphics.AbstractGraphics.prototype.setSize = goog.abstractMethod;
  143. /**
  144. * @return {goog.math.Size} The size of canvas.
  145. * @deprecated Use getPixelSize.
  146. */
  147. goog.graphics.AbstractGraphics.prototype.getSize = function() {
  148. return this.getPixelSize();
  149. };
  150. /**
  151. * @return {goog.math.Size?} Returns the number of pixels spanned by the
  152. * surface, or null if the size could not be computed due to the size being
  153. * specified in percentage points and the component not being in the
  154. * document.
  155. */
  156. goog.graphics.AbstractGraphics.prototype.getPixelSize = function() {
  157. if (this.isInDocument()) {
  158. return goog.style.getSize(this.getElement());
  159. }
  160. if (goog.isNumber(this.width) && goog.isNumber(this.height)) {
  161. return new goog.math.Size(this.width, this.height);
  162. }
  163. return null;
  164. };
  165. /**
  166. * @return {number} Returns the number of pixels per unit in the x direction.
  167. */
  168. goog.graphics.AbstractGraphics.prototype.getPixelScaleX = function() {
  169. var pixelSize = this.getPixelSize();
  170. return pixelSize ? pixelSize.width / this.getCoordSize().width : 0;
  171. };
  172. /**
  173. * @return {number} Returns the number of pixels per unit in the y direction.
  174. */
  175. goog.graphics.AbstractGraphics.prototype.getPixelScaleY = function() {
  176. var pixelSize = this.getPixelSize();
  177. return pixelSize ? pixelSize.height / this.getCoordSize().height : 0;
  178. };
  179. /**
  180. * Remove all drawing elements from the graphics.
  181. */
  182. goog.graphics.AbstractGraphics.prototype.clear = goog.abstractMethod;
  183. /**
  184. * Remove a single drawing element from the surface. The default implementation
  185. * assumes a DOM based drawing surface.
  186. * @param {goog.graphics.Element} element The element to remove.
  187. */
  188. goog.graphics.AbstractGraphics.prototype.removeElement = function(element) {
  189. goog.dom.removeNode(element.getElement());
  190. };
  191. /**
  192. * Sets the fill for the given element.
  193. * @param {goog.graphics.StrokeAndFillElement} element The element wrapper.
  194. * @param {goog.graphics.Fill?} fill The fill object.
  195. */
  196. goog.graphics.AbstractGraphics.prototype.setElementFill = goog.abstractMethod;
  197. /**
  198. * Sets the stroke for the given element.
  199. * @param {goog.graphics.StrokeAndFillElement} element The element wrapper.
  200. * @param {goog.graphics.Stroke?} stroke The stroke object.
  201. */
  202. goog.graphics.AbstractGraphics.prototype.setElementStroke = goog.abstractMethod;
  203. /**
  204. * Set the transformation of an element.
  205. *
  206. * If a more general affine transform is needed than this provides
  207. * (e.g. skew and scale) then use setElementAffineTransform.
  208. * @param {goog.graphics.Element} element The element wrapper.
  209. * @param {number} x The x coordinate of the translation transform.
  210. * @param {number} y The y coordinate of the translation transform.
  211. * @param {number} angle The angle of the rotation transform.
  212. * @param {number} centerX The horizontal center of the rotation transform.
  213. * @param {number} centerY The vertical center of the rotation transform.
  214. */
  215. goog.graphics.AbstractGraphics.prototype.setElementTransform =
  216. goog.abstractMethod;
  217. /**
  218. * Set the affine transform of an element.
  219. * @param {!goog.graphics.Element} element The element wrapper.
  220. * @param {!goog.graphics.AffineTransform} affineTransform The
  221. * transformation applied to this element.
  222. */
  223. goog.graphics.AbstractGraphics.prototype.setElementAffineTransform =
  224. goog.abstractMethod;
  225. /**
  226. * Draw a circle
  227. *
  228. * @param {number} cx Center X coordinate.
  229. * @param {number} cy Center Y coordinate.
  230. * @param {number} r Radius length.
  231. * @param {goog.graphics.Stroke?} stroke Stroke object describing the
  232. * stroke.
  233. * @param {goog.graphics.Fill?} fill Fill object describing the fill.
  234. * @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
  235. * append to. If not specified, appends to the main canvas.
  236. *
  237. * @return {goog.graphics.EllipseElement} The newly created element.
  238. */
  239. goog.graphics.AbstractGraphics.prototype.drawCircle = function(
  240. cx, cy, r, stroke, fill, opt_group) {
  241. return this.drawEllipse(cx, cy, r, r, stroke, fill, opt_group);
  242. };
  243. /**
  244. * Draw an ellipse
  245. *
  246. * @param {number} cx Center X coordinate.
  247. * @param {number} cy Center Y coordinate.
  248. * @param {number} rx Radius length for the x-axis.
  249. * @param {number} ry Radius length for the y-axis.
  250. * @param {goog.graphics.Stroke?} stroke Stroke object describing the
  251. * stroke.
  252. * @param {goog.graphics.Fill?} fill Fill object describing the fill.
  253. * @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
  254. * append to. If not specified, appends to the main canvas.
  255. *
  256. * @return {goog.graphics.EllipseElement} The newly created element.
  257. */
  258. goog.graphics.AbstractGraphics.prototype.drawEllipse = goog.abstractMethod;
  259. /**
  260. * Draw a rectangle
  261. *
  262. * @param {number} x X coordinate (left).
  263. * @param {number} y Y coordinate (top).
  264. * @param {number} width Width of rectangle.
  265. * @param {number} height Height of rectangle.
  266. * @param {goog.graphics.Stroke?} stroke Stroke object describing the
  267. * stroke.
  268. * @param {goog.graphics.Fill?} fill Fill object describing the fill.
  269. * @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
  270. * append to. If not specified, appends to the main canvas.
  271. *
  272. * @return {goog.graphics.RectElement} The newly created element.
  273. */
  274. goog.graphics.AbstractGraphics.prototype.drawRect = goog.abstractMethod;
  275. /**
  276. * Draw a text string within a rectangle (drawing is horizontal)
  277. *
  278. * @param {string} text The text to draw.
  279. * @param {number} x X coordinate (left).
  280. * @param {number} y Y coordinate (top).
  281. * @param {number} width Width of rectangle.
  282. * @param {number} height Height of rectangle.
  283. * @param {string} align Horizontal alignment: left (default), center, right.
  284. * @param {string} vAlign Vertical alignment: top (default), center, bottom.
  285. * @param {goog.graphics.Font} font Font describing the font properties.
  286. * @param {goog.graphics.Stroke?} stroke Stroke object describing the
  287. * stroke.
  288. * @param {goog.graphics.Fill?} fill Fill object describing the fill.
  289. * @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
  290. * append to. If not specified, appends to the main canvas.
  291. *
  292. * @return {goog.graphics.TextElement} The newly created element.
  293. */
  294. goog.graphics.AbstractGraphics.prototype.drawText = function(
  295. text, x, y, width, height, align, vAlign, font, stroke, fill, opt_group) {
  296. var baseline = font.size / 2; // Baseline is middle of line
  297. var textY;
  298. if (vAlign == 'bottom') {
  299. textY = y + height - baseline;
  300. } else if (vAlign == 'center') {
  301. textY = y + height / 2;
  302. } else {
  303. textY = y + baseline;
  304. }
  305. return this.drawTextOnLine(
  306. text, x, textY, x + width, textY, align, font, stroke, fill, opt_group);
  307. };
  308. /**
  309. * Draw a text string vertically centered on a given line.
  310. *
  311. * @param {string} text The text to draw.
  312. * @param {number} x1 X coordinate of start of line.
  313. * @param {number} y1 Y coordinate of start of line.
  314. * @param {number} x2 X coordinate of end of line.
  315. * @param {number} y2 Y coordinate of end of line.
  316. * @param {string} align Horizontal alingnment: left (default), center, right.
  317. * @param {goog.graphics.Font} font Font describing the font properties.
  318. * @param {goog.graphics.Stroke?} stroke Stroke object describing the
  319. * stroke.
  320. * @param {goog.graphics.Fill?} fill Fill object describing the fill.
  321. * @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
  322. * append to. If not specified, appends to the main canvas.
  323. *
  324. * @return {goog.graphics.TextElement} The newly created element.
  325. */
  326. goog.graphics.AbstractGraphics.prototype.drawTextOnLine = goog.abstractMethod;
  327. /**
  328. * Draw a path.
  329. *
  330. * @param {!goog.graphics.Path} path The path object to draw.
  331. * @param {goog.graphics.Stroke?} stroke Stroke object describing the
  332. * stroke.
  333. * @param {goog.graphics.Fill?} fill Fill object describing the fill.
  334. * @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
  335. * append to. If not specified, appends to the main canvas.
  336. *
  337. * @return {goog.graphics.PathElement} The newly created element.
  338. */
  339. goog.graphics.AbstractGraphics.prototype.drawPath = goog.abstractMethod;
  340. /**
  341. * Create an empty group of drawing elements.
  342. *
  343. * @param {goog.graphics.GroupElement=} opt_group The group wrapper element to
  344. * append to. If not specified, appends to the main canvas.
  345. *
  346. * @return {goog.graphics.GroupElement} The newly created group.
  347. */
  348. goog.graphics.AbstractGraphics.prototype.createGroup = goog.abstractMethod;
  349. /**
  350. * Create an empty path.
  351. *
  352. * @return {!goog.graphics.Path} The path.
  353. * @deprecated Use {@code new goog.graphics.Path()}.
  354. */
  355. goog.graphics.AbstractGraphics.prototype.createPath = function() {
  356. return new goog.graphics.Path();
  357. };
  358. /**
  359. * Measure and return the width (in pixels) of a given text string.
  360. * Text measurement is needed to make sure a text can fit in the allocated
  361. * area. The way text length is measured is by writing it into a div that is
  362. * after the visible area, measure the div width, and immediately erase the
  363. * written value.
  364. *
  365. * @param {string} text The text string to measure.
  366. * @param {goog.graphics.Font} font The font object describing the font style.
  367. *
  368. * @return {number} The width in pixels of the text strings.
  369. */
  370. goog.graphics.AbstractGraphics.prototype.getTextWidth = goog.abstractMethod;
  371. /**
  372. * @return {boolean} Whether the underlying element can be cloned resulting in
  373. * an accurate reproduction of the graphics contents.
  374. */
  375. goog.graphics.AbstractGraphics.prototype.isDomClonable = function() {
  376. return false;
  377. };
  378. /**
  379. * Start preventing redraws - useful for chaining large numbers of changes
  380. * together. Not guaranteed to do anything - i.e. only use this for
  381. * optimization of a single code path.
  382. */
  383. goog.graphics.AbstractGraphics.prototype.suspend = function() {};
  384. /**
  385. * Stop preventing redraws. If any redraws had been prevented, a redraw will
  386. * be done now.
  387. */
  388. goog.graphics.AbstractGraphics.prototype.resume = function() {};