fabric.js/src/shadow.class.js
2014-10-26 22:42:55 +01:00

179 lines
5 KiB
JavaScript

(function(global) {
'use strict';
var fabric = global.fabric || (global.fabric = { });
if (fabric.Shadow) {
fabric.warn('fabric.Shadow is already defined.');
return;
}
/**
* Shadow class
* @class fabric.Shadow
* @see {@link http://fabricjs.com/shadows/|Shadow demo}
* @see {@link fabric.Shadow#initialize} for constructor definition
*/
fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ {
/**
* Shadow color
* @type String
* @default
*/
color: 'rgb(0,0,0)',
/**
* Shadow blur
* @type Number
*/
blur: 0,
/**
* Shadow horizontal offset
* @type Number
* @default
*/
offsetX: 0,
/**
* Shadow vertical offset
* @type Number
* @default
*/
offsetY: 0,
/**
* Whether the shadow should affect stroke operations
* @type Boolean
* @default
*/
affectStroke: false,
/**
* Indicates whether toObject should include default values
* @type Boolean
* @default
*/
includeDefaultValues: true,
/**
* Constructor
* @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetX properties or string (e.g. "rgba(0,0,0,0.2) 2px 2px 10px, "2px 2px 10px rgba(0,0,0,0.2)")
* @return {fabric.Shadow} thisArg
*/
initialize: function(options) {
if (typeof options === 'string') {
options = this._parseShadow(options);
}
for (var prop in options) {
this[prop] = options[prop];
}
this.id = fabric.Object.__uid++;
},
/**
* @private
* @param {String} shadow Shadow value to parse
* @return {Object} Shadow object with color, offsetX, offsetY and blur
*/
_parseShadow: function(shadow) {
var shadowStr = shadow.trim(),
offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [ ],
color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)';
return {
color: color.trim(),
offsetX: parseInt(offsetsAndBlur[1], 10) || 0,
offsetY: parseInt(offsetsAndBlur[2], 10) || 0,
blur: parseInt(offsetsAndBlur[3], 10) || 0
};
},
/**
* Returns a string representation of an instance
* @see http://www.w3.org/TR/css-text-decor-3/#text-shadow
* @return {String} Returns CSS3 text-shadow declaration
*/
toString: function() {
return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');
},
/* _TO_SVG_START_ */
/**
* Returns SVG representation of a shadow
* @param {fabric.Object} object
* @return {String} SVG representation of a shadow
*/
toSVG: function(object) {
var mode = 'SourceAlpha', fBoxX = 40, fBoxY = 40;
if (object && (object.fill === this.color || object.stroke === this.color)) {
mode = 'SourceGraphic';
}
if (object.width && object.height) {
//http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
// we add some extra space to filter box to contain the blur ( 20 )
fBoxX = Math.abs(this.offsetX / object.getWidth()) * 100 + 20;
fBoxY = Math.abs(this.offsetY / object.getHeight()) * 100 + 20;
}
return (
'<filter id="SVGID_' + this.id + '" y="-' + fBoxY + '%" height="' + (100 + 2 * fBoxY) + '%" ' +
'x="-' + fBoxX + '%" width="' + (100 + 2 * fBoxX) + '%" ' + '>\n' +
'\t<feGaussianBlur in="' + mode + '" stdDeviation="' +
(this.blur ? this.blur / 3 : 0) +
'"></feGaussianBlur>\n' +
'\t<feOffset dx="' + this.offsetX + '" dy="' + this.offsetY + '"></feOffset>\n' +
'\t<feMerge>\n' +
'\t\t<feMergeNode></feMergeNode>\n' +
'\t\t<feMergeNode in="SourceGraphic"></feMergeNode>\n' +
'\t</feMerge>\n' +
'</filter>\n');
},
/* _TO_SVG_END_ */
/**
* Returns object representation of a shadow
* @return {Object} Object representation of a shadow instance
*/
toObject: function() {
if (this.includeDefaultValues) {
return {
color: this.color,
blur: this.blur,
offsetX: this.offsetX,
offsetY: this.offsetY
};
}
var obj = { }, proto = fabric.Shadow.prototype;
if (this.color !== proto.color) {
obj.color = this.color;
}
if (this.blur !== proto.blur) {
obj.blur = this.blur;
}
if (this.offsetX !== proto.offsetX) {
obj.offsetX = this.offsetX;
}
if (this.offsetY !== proto.offsetY) {
obj.offsetY = this.offsetY;
}
return obj;
}
});
/**
* Regex matching shadow offsetX, offsetY and blur (ex: "2px 2px 10px rgba(0,0,0,0.2)", "rgb(0,255,0) 2px 2px")
* @static
* @field
* @memberOf fabric.Shadow
*/
fabric.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/;
})(typeof exports !== 'undefined' ? exports : this);