fabric.js/src/rect.class.js

230 lines
6 KiB
JavaScript
Raw Normal View History

(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = { });
if (fabric.Rect) {
console.warn('fabric.Rect is already defined');
return;
}
/**
2010-06-09 22:34:55 +00:00
* @class Rect
* @extends fabric.Object
2010-06-09 22:34:55 +00:00
*/
fabric.Rect = fabric.util.createClass(fabric.Object, /** @scope fabric.Rect.prototype */ {
/**
2012-10-17 09:02:53 +00:00
* Type of the instance
* @property
* @type String
*/
2010-06-09 22:34:55 +00:00
type: 'rect',
/**
2012-10-17 09:02:53 +00:00
* Horizontal border radius
* @property
2012-08-09 10:59:20 +00:00
* @type Number
*/
2012-08-09 10:59:20 +00:00
rx: 0,
/**
2012-10-17 09:02:53 +00:00
* Vertical border radius
2012-08-09 10:59:20 +00:00
* @property
* @type Number
*/
ry: 0,
2010-06-09 22:34:55 +00:00
/**
* Constructor
2010-06-09 22:34:55 +00:00
* @method initialize
* @param options {Object} options object
* @return {Object} thisArg
*/
initialize: function(options) {
options = options || { };
this._initStateProperties();
2010-06-09 22:34:55 +00:00
this.callSuper('initialize', options);
this._initRxRy();
},
/**
* Creates `stateProperties` list on an instance, and adds `fabric.Rect` -specific ones to it
* (such as "rx", "ry", etc.)
* @private
* @method _initStateProperties
*/
_initStateProperties: function() {
this.stateProperties = this.stateProperties.concat(['rx', 'ry']);
},
2010-06-09 22:34:55 +00:00
/**
* @private
* @method _initRxRy
*/
_initRxRy: function() {
if (this.rx && !this.ry) {
this.ry = this.rx;
2010-06-09 22:34:55 +00:00
}
else if (this.ry && !this.rx) {
this.rx = this.ry;
2010-06-09 22:34:55 +00:00
}
},
2010-06-09 22:34:55 +00:00
/**
* @private
* @method _render
* @param ctx {CanvasRenderingContext2D} context to render on
*/
_render: function(ctx) {
var rx = this.rx || 0,
ry = this.ry || 0,
2010-06-09 22:34:55 +00:00
x = -this.width / 2,
y = -this.height / 2,
w = this.width,
h = this.height;
2010-06-09 22:34:55 +00:00
ctx.beginPath();
ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity;
2012-09-06 16:00:36 +00:00
if (this.transformMatrix && this.group) {
ctx.translate(
this.width / 2 + this.x,
this.height / 2 + this.y);
}
if (!this.transformMatrix && this.group) {
ctx.translate(
-this.group.width / 2 + this.width / 2 + this.x,
-this.group.height / 2 + this.height / 2 + this.y);
}
2010-06-09 22:34:55 +00:00
ctx.moveTo(x+rx, y);
ctx.lineTo(x+w-rx, y);
ctx.quadraticCurveTo(x+w, y, x+w, y+ry, x+w, y+ry);
2010-06-09 22:34:55 +00:00
ctx.lineTo(x+w, y+h-ry);
ctx.quadraticCurveTo(x+w,y+h,x+w-rx,y+h,x+w-rx,y+h);
2010-06-09 22:34:55 +00:00
ctx.lineTo(x+rx,y+h);
ctx.quadraticCurveTo(x,y+h,x,y+h-ry,x,y+h-ry);
2010-06-09 22:34:55 +00:00
ctx.lineTo(x,y+ry);
ctx.quadraticCurveTo(x,y,x+rx,y,x+rx,y);
2010-06-09 22:34:55 +00:00
ctx.closePath();
2010-06-09 22:34:55 +00:00
if (this.fill) {
ctx.fill();
}
if (this.strokeDashArray) {
this._renderDashedStroke(ctx);
}
else if (this.stroke) {
2010-06-09 22:34:55 +00:00
ctx.stroke();
}
},
2012-10-17 09:02:53 +00:00
/**
* @method _normalizeLeftTopProperties
* @private
* Since coordinate system differs from that of SVG
*/
2010-06-09 22:34:55 +00:00
_normalizeLeftTopProperties: function(parsedAttributes) {
if (parsedAttributes.left) {
this.set('left', parsedAttributes.left + this.getWidth() / 2);
}
this.set('x', parsedAttributes.left || 0);
2010-06-09 22:34:55 +00:00
if (parsedAttributes.top) {
this.set('top', parsedAttributes.top + this.getHeight() / 2);
}
this.set('y', parsedAttributes.top || 0);
2010-06-09 22:34:55 +00:00
return this;
},
2010-06-09 22:34:55 +00:00
/**
2012-10-17 09:02:53 +00:00
* Returns complexity of an instance
2010-06-09 22:34:55 +00:00
* @method complexity
* @return {Number} complexity
*/
complexity: function() {
return 1;
},
/**
* Returns object representation of an instance
* @method toObject
* @return {Object} object representation of an instance
*/
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
rx: this.get('rx') || 0,
ry: this.get('ry') || 0
});
},
/**
* Returns svg representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
*/
toSVG: function() {
return '<rect ' +
'x="' + (-1 * this.width / 2) + '" y="' + (-1 * this.height / 2) + '" ' +
'rx="' + this.get('rx') + '" ry="' + this.get('ry') + '" ' +
'width="' + this.width + '" height="' + this.height + '" ' +
'style="' + this.getSvgStyles() + '" ' +
'transform="' + this.getSvgTransform() + '" ' +
'/>';
2010-06-09 22:34:55 +00:00
}
});
2010-06-09 22:34:55 +00:00
// TODO (kangax): implement rounded rectangles (both parsing and rendering)
2010-10-19 20:27:24 +00:00
/**
* List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)
* @static
*/
2011-06-14 21:28:54 +00:00
fabric.Rect.ATTRIBUTE_NAMES = 'x y width height rx ry fill fill-opacity opacity stroke stroke-width transform'.split(' ');
2010-06-09 22:34:55 +00:00
/**
* @private
*/
function _setDefaultLeftTopValues(attributes) {
attributes.left = attributes.left || 0;
attributes.top = attributes.top || 0;
return attributes;
}
2010-06-09 22:34:55 +00:00
/**
2010-10-19 20:27:24 +00:00
* Returns fabric.Rect instance from an SVG element
2010-06-09 22:34:55 +00:00
* @static
* @method fabric.Rect.fromElement
2010-06-09 22:34:55 +00:00
* @param element {SVGElement} element to parse
* @param options {Object} options object
* @return {fabric.Rect} instance of fabric.Rect
2010-06-09 22:34:55 +00:00
*/
fabric.Rect.fromElement = function(element, options) {
if (!element) {
return null;
}
var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);
2010-06-09 22:34:55 +00:00
parsedAttributes = _setDefaultLeftTopValues(parsedAttributes);
var rect = new fabric.Rect(fabric.util.object.extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));
2010-06-09 22:34:55 +00:00
rect._normalizeLeftTopProperties(parsedAttributes);
2010-06-09 22:34:55 +00:00
return rect;
};
2010-06-09 22:34:55 +00:00
/**
2010-10-19 20:27:24 +00:00
* Returns fabric.Rect instance from an object representation
2010-06-09 22:34:55 +00:00
* @static
* @method fabric.Rect.fromObject
2010-06-09 22:34:55 +00:00
* @param object {Object} object to create an instance from
* @return {Object} instance of fabric.Rect
2010-06-09 22:34:55 +00:00
*/
fabric.Rect.fromObject = function(object) {
return new fabric.Rect(object);
2010-06-09 22:34:55 +00:00
};
})(typeof exports !== 'undefined' ? exports : this);