mxImageShape.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /**
  2. * Copyright (c) 2006-2015, JGraph Ltd
  3. * Copyright (c) 2006-2015, Gaudenz Alder
  4. */
  5. /**
  6. * Class: mxImageShape
  7. *
  8. * Extends <mxShape> to implement an image shape. This shape is registered
  9. * under <mxConstants.SHAPE_IMAGE> in <mxCellRenderer>.
  10. *
  11. * Constructor: mxImageShape
  12. *
  13. * Constructs a new image shape.
  14. *
  15. * Parameters:
  16. *
  17. * bounds - <mxRectangle> that defines the bounds. This is stored in
  18. * <mxShape.bounds>.
  19. * image - String that specifies the URL of the image. This is stored in
  20. * <image>.
  21. * fill - String that defines the fill color. This is stored in <fill>.
  22. * stroke - String that defines the stroke color. This is stored in <stroke>.
  23. * strokewidth - Optional integer that defines the stroke width. Default is
  24. * 0. This is stored in <strokewidth>.
  25. */
  26. function mxImageShape(bounds, image, fill, stroke, strokewidth)
  27. {
  28. mxShape.call(this);
  29. this.bounds = bounds;
  30. this.image = image;
  31. this.fill = fill;
  32. this.stroke = stroke;
  33. this.strokewidth = (strokewidth != null) ? strokewidth : 1;
  34. this.shadow = false;
  35. };
  36. /**
  37. * Extends mxShape.
  38. */
  39. mxUtils.extend(mxImageShape, mxRectangleShape);
  40. /**
  41. * Variable: preserveImageAspect
  42. *
  43. * Switch to preserve image aspect. Default is true.
  44. */
  45. mxImageShape.prototype.preserveImageAspect = true;
  46. /**
  47. * Function: getSvgScreenOffset
  48. *
  49. * Disables offset in IE9 for crisper image output.
  50. */
  51. mxImageShape.prototype.getSvgScreenOffset = function()
  52. {
  53. return 0;
  54. };
  55. /**
  56. * Function: apply
  57. *
  58. * Overrides <mxShape.apply> to replace the fill and stroke colors with the
  59. * respective values from <mxConstants.STYLE_IMAGE_BACKGROUND> and
  60. * <mxConstants.STYLE_IMAGE_BORDER>.
  61. *
  62. * Applies the style of the given <mxCellState> to the shape. This
  63. * implementation assigns the following styles to local fields:
  64. *
  65. * - <mxConstants.STYLE_IMAGE_BACKGROUND> => fill
  66. * - <mxConstants.STYLE_IMAGE_BORDER> => stroke
  67. *
  68. * Parameters:
  69. *
  70. * state - <mxCellState> of the corresponding cell.
  71. */
  72. mxImageShape.prototype.apply = function(state)
  73. {
  74. mxShape.prototype.apply.apply(this, arguments);
  75. this.fill = null;
  76. this.stroke = null;
  77. this.gradient = null;
  78. if (this.style != null)
  79. {
  80. this.preserveImageAspect = mxUtils.getNumber(this.style, mxConstants.STYLE_IMAGE_ASPECT, 1) == 1;
  81. // Legacy support for imageFlipH/V
  82. this.flipH = this.flipH || mxUtils.getValue(this.style, 'imageFlipH', 0) == 1;
  83. this.flipV = this.flipV || mxUtils.getValue(this.style, 'imageFlipV', 0) == 1;
  84. }
  85. };
  86. /**
  87. * Function: isHtmlAllowed
  88. *
  89. * Returns true if HTML is allowed for this shape. This implementation always
  90. * returns false.
  91. */
  92. mxImageShape.prototype.isHtmlAllowed = function()
  93. {
  94. return !this.preserveImageAspect;
  95. };
  96. /**
  97. * Function: createHtml
  98. *
  99. * Creates and returns the HTML DOM node(s) to represent
  100. * this shape. This implementation falls back to <createVml>
  101. * so that the HTML creation is optional.
  102. */
  103. mxImageShape.prototype.createHtml = function()
  104. {
  105. var node = document.createElement('div');
  106. node.style.position = 'absolute';
  107. return node;
  108. };
  109. /**
  110. * Function: isRoundable
  111. *
  112. * Disables inherited roundable support.
  113. */
  114. mxImageShape.prototype.isRoundable = function(c, x, y, w, h)
  115. {
  116. return false;
  117. };
  118. /**
  119. * Function: paintVertexShape
  120. *
  121. * Generic background painting implementation.
  122. */
  123. mxImageShape.prototype.paintVertexShape = function(c, x, y, w, h)
  124. {
  125. if (this.image != null)
  126. {
  127. var fill = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BACKGROUND, null);
  128. var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, null);
  129. if (fill != null)
  130. {
  131. // Stroke rendering required for shadow
  132. c.setFillColor(fill);
  133. c.setStrokeColor(stroke);
  134. c.rect(x, y, w, h);
  135. c.fillAndStroke();
  136. }
  137. // FlipH/V are implicit via mxShape.updateTransform
  138. c.image(x, y, w, h, this.image, this.preserveImageAspect, false, false);
  139. var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, null);
  140. if (stroke != null)
  141. {
  142. c.setShadow(false);
  143. c.setStrokeColor(stroke);
  144. c.rect(x, y, w, h);
  145. c.stroke();
  146. }
  147. }
  148. else
  149. {
  150. mxRectangleShape.prototype.paintBackground.apply(this, arguments);
  151. }
  152. };
  153. /**
  154. * Function: redraw
  155. *
  156. * Overrides <mxShape.redraw> to preserve the aspect ratio of images.
  157. */
  158. mxImageShape.prototype.redrawHtmlShape = function()
  159. {
  160. this.node.style.left = Math.round(this.bounds.x) + 'px';
  161. this.node.style.top = Math.round(this.bounds.y) + 'px';
  162. this.node.style.width = Math.max(0, Math.round(this.bounds.width)) + 'px';
  163. this.node.style.height = Math.max(0, Math.round(this.bounds.height)) + 'px';
  164. this.node.innerHTML = '';
  165. if (this.image != null)
  166. {
  167. var fill = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BACKGROUND, '');
  168. var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, '');
  169. this.node.style.backgroundColor = fill;
  170. this.node.style.borderColor = stroke;
  171. // VML image supports PNG in IE6
  172. var useVml = mxClient.IS_IE6 || ((document.documentMode == null || document.documentMode <= 8) && this.rotation != 0);
  173. var img = document.createElement((useVml) ? mxClient.VML_PREFIX + ':image' : 'img');
  174. img.setAttribute('border', '0');
  175. img.style.position = 'absolute';
  176. img.src = this.image;
  177. var filter = (this.opacity < 100) ? 'alpha(opacity=' + this.opacity + ')' : '';
  178. this.node.style.filter = filter;
  179. if (this.flipH && this.flipV)
  180. {
  181. filter += 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';
  182. }
  183. else if (this.flipH)
  184. {
  185. filter += 'progid:DXImageTransform.Microsoft.BasicImage(mirror=1)';
  186. }
  187. else if (this.flipV)
  188. {
  189. filter += 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)';
  190. }
  191. if (img.style.filter != filter)
  192. {
  193. img.style.filter = filter;
  194. }
  195. if (img.nodeName == 'image')
  196. {
  197. img.style.rotation = this.rotation;
  198. }
  199. else if (this.rotation != 0)
  200. {
  201. // LATER: Add flipV/H support
  202. mxUtils.setPrefixedStyle(img.style, 'transform', 'rotate(' + this.rotation + 'deg)');
  203. }
  204. else
  205. {
  206. mxUtils.setPrefixedStyle(img.style, 'transform', '');
  207. }
  208. // Known problem: IE clips top line of image for certain angles
  209. img.style.width = this.node.style.width;
  210. img.style.height = this.node.style.height;
  211. this.node.style.backgroundImage = '';
  212. this.node.appendChild(img);
  213. }
  214. else
  215. {
  216. this.setTransparentBackgroundImage(this.node);
  217. }
  218. };
  219. __mxOutput.mxImageShape = typeof mxImageShape !== 'undefined' ? mxImageShape : undefined;