244 lines
6.2 KiB
JavaScript
244 lines
6.2 KiB
JavaScript
/**
|
|
* Copyright (c) 2006-2015, JGraph Ltd
|
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
|
*/
|
|
/**
|
|
* Class: mxImageShape
|
|
*
|
|
* Extends <mxShape> to implement an image shape. This shape is registered
|
|
* under <mxConstants.SHAPE_IMAGE> in <mxCellRenderer>.
|
|
*
|
|
* Constructor: mxImageShape
|
|
*
|
|
* Constructs a new image shape.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* bounds - <mxRectangle> that defines the bounds. This is stored in
|
|
* <mxShape.bounds>.
|
|
* image - String that specifies the URL of the image. This is stored in
|
|
* <image>.
|
|
* fill - String that defines the fill color. This is stored in <fill>.
|
|
* stroke - String that defines the stroke color. This is stored in <stroke>.
|
|
* strokewidth - Optional integer that defines the stroke width. Default is
|
|
* 0. This is stored in <strokewidth>.
|
|
*/
|
|
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 <mxShape.apply> to replace the fill and stroke colors with the
|
|
* respective values from <mxConstants.STYLE_IMAGE_BACKGROUND> and
|
|
* <mxConstants.STYLE_IMAGE_BORDER>.
|
|
*
|
|
* Applies the style of the given <mxCellState> to the shape. This
|
|
* implementation assigns the following styles to local fields:
|
|
*
|
|
* - <mxConstants.STYLE_IMAGE_BACKGROUND> => fill
|
|
* - <mxConstants.STYLE_IMAGE_BORDER> => stroke
|
|
*
|
|
* Parameters:
|
|
*
|
|
* state - <mxCellState> 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 <createVml>
|
|
* 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 <mxShape.redraw> 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);
|
|
}
|
|
};
|