/** * Copyright (c) 2006-2015, JGraph Ltd * Copyright (c) 2006-2015, Gaudenz Alder */ /** * Class: mxImageShape * * Extends to implement an image shape. This shape is registered * under in . * * Constructor: mxImageShape * * Constructs a new image shape. * * Parameters: * * bounds - that defines the bounds. This is stored in * . * image - String that specifies the URL of the image. This is stored in * . * fill - String that defines the fill color. This is stored in . * stroke - String that defines the stroke color. This is stored in . * strokewidth - Optional integer that defines the stroke width. Default is * 0. This is stored in . */ function mxImageShape(bounds, image, fill, stroke, strokewidth) { mxShape.call(this); this.bounds = bounds; this.image = image; this.fill = fill; this.stroke = stroke; this.strokewidth = (strokewidth != null) ? strokewidth : 1; this.shadow = false; }; /** * Extends mxShape. */ mxUtils.extend(mxImageShape, mxRectangleShape); /** * Variable: preserveImageAspect * * Switch to preserve image aspect. Default is true. */ mxImageShape.prototype.preserveImageAspect = true; /** * Function: getSvgScreenOffset * * Disables offset in IE9 for crisper image output. */ mxImageShape.prototype.getSvgScreenOffset = function() { return 0; }; /** * Function: apply * * Overrides to replace the fill and stroke colors with the * respective values from and * . * * Applies the style of the given to the shape. This * implementation assigns the following styles to local fields: * * - => fill * - => stroke * * Parameters: * * state - of the corresponding cell. */ mxImageShape.prototype.apply = function(state) { mxShape.prototype.apply.apply(this, arguments); this.fill = null; this.stroke = null; this.gradient = null; if (this.style != null) { this.preserveImageAspect = mxUtils.getNumber(this.style, mxConstants.STYLE_IMAGE_ASPECT, 1) == 1; // Legacy support for imageFlipH/V this.flipH = this.flipH || mxUtils.getValue(this.style, 'imageFlipH', 0) == 1; this.flipV = this.flipV || mxUtils.getValue(this.style, 'imageFlipV', 0) == 1; } }; /** * Function: isHtmlAllowed * * Returns true if HTML is allowed for this shape. This implementation always * returns false. */ mxImageShape.prototype.isHtmlAllowed = function() { return !this.preserveImageAspect; }; /** * Function: createHtml * * Creates and returns the HTML DOM node(s) to represent * this shape. This implementation falls back to * so that the HTML creation is optional. */ mxImageShape.prototype.createHtml = function() { var node = document.createElement('div'); node.style.position = 'absolute'; return node; }; /** * Function: isRoundable * * Disables inherited roundable support. */ mxImageShape.prototype.isRoundable = function(c, x, y, w, h) { return false; }; /** * Function: paintVertexShape * * Generic background painting implementation. */ mxImageShape.prototype.paintVertexShape = function(c, x, y, w, h) { if (this.image != null) { var fill = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BACKGROUND, null); var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, null); if (fill != null) { // Stroke rendering required for shadow c.setFillColor(fill); c.setStrokeColor(stroke); c.rect(x, y, w, h); c.fillAndStroke(); } // FlipH/V are implicit via mxShape.updateTransform c.image(x, y, w, h, this.image, this.preserveImageAspect, false, false); var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, null); if (stroke != null) { c.setShadow(false); c.setStrokeColor(stroke); c.rect(x, y, w, h); c.stroke(); } } else { mxRectangleShape.prototype.paintBackground.apply(this, arguments); } }; /** * Function: redraw * * Overrides to preserve the aspect ratio of images. */ mxImageShape.prototype.redrawHtmlShape = function() { this.node.style.left = Math.round(this.bounds.x) + 'px'; this.node.style.top = Math.round(this.bounds.y) + 'px'; this.node.style.width = Math.max(0, Math.round(this.bounds.width)) + 'px'; this.node.style.height = Math.max(0, Math.round(this.bounds.height)) + 'px'; this.node.innerHTML = ''; if (this.image != null) { var fill = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BACKGROUND, ''); var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, ''); this.node.style.backgroundColor = fill; this.node.style.borderColor = stroke; // VML image supports PNG in IE6 var useVml = mxClient.IS_IE6 || ((document.documentMode == null || document.documentMode <= 8) && this.rotation != 0); var img = document.createElement((useVml) ? mxClient.VML_PREFIX + ':image' : 'img'); img.setAttribute('border', '0'); img.style.position = 'absolute'; img.src = this.image; var filter = (this.opacity < 100) ? 'alpha(opacity=' + this.opacity + ')' : ''; this.node.style.filter = filter; if (this.flipH && this.flipV) { filter += 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)'; } else if (this.flipH) { filter += 'progid:DXImageTransform.Microsoft.BasicImage(mirror=1)'; } else if (this.flipV) { filter += 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)'; } if (img.style.filter != filter) { img.style.filter = filter; } if (img.nodeName == 'image') { img.style.rotation = this.rotation; } else if (this.rotation != 0) { // LATER: Add flipV/H support mxUtils.setPrefixedStyle(img.style, 'transform', 'rotate(' + this.rotation + 'deg)'); } else { mxUtils.setPrefixedStyle(img.style, 'transform', ''); } // Known problem: IE clips top line of image for certain angles img.style.width = this.node.style.width; img.style.height = this.node.style.height; this.node.style.backgroundImage = ''; this.node.appendChild(img); } else { this.setTransparentBackgroundImage(this.node); } };