Merge master

This commit is contained in:
kangax 2012-12-15 17:16:39 +01:00
commit 6ed3dda6f5
33 changed files with 706 additions and 276 deletions

View file

@ -1,6 +1,6 @@
/*! Fabric.js Copyright 2008-2012, Printio (Juriy Zaytsev, Maxim Chernyak) */
var fabric = fabric || { version: "0.9.29" };
var fabric = fabric || { version: "0.9.30" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;

View file

@ -10,7 +10,7 @@ Contributions are very much welcome!
### Goals
- Unit tested (1300+ tests at the moment)
- Unit tested (1400+ tests at the moment)
- Modular (~20 small "classes" and modules)
- Cross-browser
- [Fast](https://github.com/kangax/fabric.js/wiki/Focus-on-speed)
@ -102,6 +102,7 @@ These are the optional modules that could be specified for inclusion, when build
- **image_filters** — Adds support for image filters, such as grayscale of white removal.
- **easing** - Adds support for animation easing functions
- **node** — Adds support for running fabric under node.js, with help of [jsdom](https://github.com/tmpvar/jsdom) and [node-canvas](https://github.com/learnboost/node-canvas) libraries.
- **freedrawing** - Adds support for free drawing
### Examples of use
@ -149,4 +150,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.

483
dist/all.js vendored

File diff suppressed because it is too large Load diff

10
dist/all.min.js vendored

File diff suppressed because one or more lines are too long

BIN
dist/all.min.js.gz vendored

Binary file not shown.

View file

@ -1,7 +1,7 @@
{
"name": "fabric",
"description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.",
"version": "0.9.29",
"version": "0.9.30",
"author": "Juriy Zaytsev <kangax@gmail.com>",
"keywords": ["canvas", "graphic", "graphics", "SVG", "node-canvas", "parser", "HTML5", "object model"],
"repository": "git://github.com/kangax/fabric.js",

View file

@ -1,5 +1,9 @@
fabric.util.object.extend(fabric.StaticCanvas.prototype, {
/**
* Animation duration (in ms) for fx* methods
* @type Number
*/
FX_DURATION: 500,
/**

View file

@ -12,12 +12,14 @@
}
/**
* Circle class
* @class Circle
* @extends fabric.Object
*/
fabric.Circle = fabric.util.createClass(fabric.Object, /** @scope fabric.Circle.prototype */ {
/**
* Type of an object
* @property
* @type String
*/
@ -54,7 +56,7 @@
/**
* Returns svg representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
* @return {String} svg representation of an instance
*/
toSVG: function() {
return ('<circle ' +
@ -133,10 +135,10 @@
* Returns {@link fabric.Circle} instance from an SVG element
* @static
* @method fabric.Circle.fromElement
* @param element {SVGElement} element to parse
* @param options {Object} options object
* @param {SVGElement} element Element to parse
* @param {Object} [options] Options object
* @throws {Error} If value of `r` attribute is missing or invalid
* @return {Object} instance of fabric.Circle
* @return {Object} Instance of fabric.Circle
*/
fabric.Circle.fromElement = function(element, options) {
options || (options = { });

View file

@ -10,12 +10,14 @@
}
/**
* Color class
* The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations;
* {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects.
*
* @class Color
* @memberOf fabric
* @param {String} color optional in hex or rgb(a) format
* @return {fabric.Color} thisArg
*/
function Color(color) {
if (!color) {

View file

@ -12,12 +12,14 @@
}
/**
* Ellipse class
* @class Ellipse
* @extends fabric.Object
*/
fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @scope fabric.Ellipse.prototype */ {
/**
* Type of an object
* @property
* @type String
*/
@ -27,7 +29,7 @@
* Constructor
* @method initialize
* @param {Object} [options] Options object
* @return {Object} thisArg
* @return {fabric.Ellipse} thisArg
*/
initialize: function(options) {
options = options || { };
@ -57,7 +59,7 @@
/**
* Returns svg representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
* @return {String} svg representation of an instance
*/
toSVG: function() {
return [

View file

@ -12,16 +12,21 @@
return;
}
/**
* Free drawing class
* Free Drawer handles scribbling on a fabric canvas
* It converts the hand writting to a SVG Path and adds this path to the canvas
*
* @class FreeDrawing
* @memberOf fabric
*/
fabric.FreeDrawing = fabric.util.createClass({
/**
* Free Drawer handles scribbling on a fabricCanvas.
* It converts the hand writting to a SVG Path and adds this
* path to the canvas.
*
* @metod init
* @param fabricCanvas {FabricCanvas}
*
* Constructor
* @metod initialize
* @param fabricCanvas {fabric.Canvas}
* @return {fabric.FreeDrawing}
*/
initialize: function(fabricCanvas) {
this.canvas = fabricCanvas;
@ -127,9 +132,11 @@
},
/**
* @method getPathBoundingBox
* @param points {Array of points}
*/
* Returns bounding box of a path based on given points
* @method getPathBoundingBox
* @param {Array} points
* @return {Object} object with minx, miny, maxx, maxy
*/
getPathBoundingBox: function(points) {
var xBounds = [],
yBounds = [],
@ -161,9 +168,11 @@
};
},
/**
/**
* Converts points to SVG path
* @method convertPointsToSVGPath
* @param points {Array of points}
* @param {Array} points Array of points
* @return {String} SVG path
*/
convertPointsToSVGPath: function(points, minX, maxX, minY, maxY) {
var path = [];
@ -192,9 +201,7 @@
* and add it to the fabric canvas.
*
* @method _finalizeAndAddPath
*
*/
_finalizeAndAddPath: function() {
this.canvas._isCurrentlyDrawing = false;
var ctx = this.canvas.contextTop;
@ -217,11 +224,11 @@
p.strokeWidth = this.canvas.freeDrawingLineWidth;
this.canvas.add(p);
// set path origin coordinates based on our bouding box
// set path origin coordinates based on our bounding box
var originLeft = this.box.minx + (this.box.maxx - this.box.minx) /2;
var originTop = this.box.miny + (this.box.maxy - this.box.miny) /2;
this.canvas.contextTop.arc(originLeft, originTop, 3);
this.canvas.contextTop.arc(originLeft, originTop, 3, 0, Math.PI * 2);
p.set({ left: originLeft, top: originTop });

View file

@ -24,14 +24,17 @@
}
/**
* Gradient class
* @class Gradient
* @memberOf fabric
*/
fabric.Gradient = fabric.util.createClass(/** @scope fabric.Gradient.prototype */ {
/**
* Constructor
* @method initialize
* @param options optional Options with x1, y1, x2, y2 and colorStops
* @param [options] Options object with x1, y1, x2, y2 and colorStops
* @return {fabric.Gradient} thisArg
*/
initialize: function(options) {
@ -48,6 +51,7 @@
/**
* Returns object representation of a gradient
* @method toObject
* @return {Object}
*/
toObject: function() {
return {
@ -63,6 +67,7 @@
* Returns an instance of CanvasGradient
* @method toLiveGradient
* @param ctx
* @return {CanvasGradient}
*/
toLiveGradient: function(ctx) {
var gradient = ctx.createLinearGradient(
@ -80,6 +85,7 @@
fabric.util.object.extend(fabric.Gradient, {
/**
* Returns {@link fabric.Gradient} instance from an SVG element
* @method fromElement
* @static
* @memberof fabric.Gradient
@ -135,8 +141,11 @@
},
/**
* Returns {@link fabric.Gradient} instance from its object representation
* @method forObject
* @static
* @param obj
* @param [options]
* @memberof fabric.Gradient
*/
forObject: function(obj, options) {

View file

@ -13,6 +13,9 @@
return;
}
// lock-related properties, for use in fabric.Group#get
// to enable locking behavior on group
// when one of its objects has lock-related properties set
var _lockProperties = {
lockMovementX: true,
lockMovementY: true,
@ -23,12 +26,14 @@
};
/**
* Group class
* @class Group
* @extends fabric.Object
*/
fabric.Group = fabric.util.createClass(fabric.Object, /** @scope fabric.Group.prototype */ {
/**
* Type of an object
* @property
* @type String
*/
@ -171,11 +176,25 @@
return this.getObjects().length;
},
/**
* Properties that are delegated to group objects when reading/writing
*/
delegatedProperties: {
fill: true,
opacity: true,
fontFamily: true,
fontWeight: true,
lineHeight: true,
textDecoration: true,
textShadow: true,
backgroundColor: true
},
/**
* @private
*/
_set: function(key, value) {
if (key === 'fill' || key === 'opacity') {
if (key in this.delegatedProperties) {
var i = this.objects.length;
this[key] = value;
while (i--) {
@ -458,12 +477,15 @@
/**
* Makes all of this group's objects grayscale (i.e. calling `toGrayscale` on them)
* @method toGrayscale
* @return {fabric.Group} thisArg
* @chainable
*/
toGrayscale: function() {
var i = this.objects.length;
while (i--) {
this.objects[i].toGrayscale();
}
return this;
},
/**
@ -484,10 +506,10 @@
},
/**
* Returns true if any of the objects have truthy specified property
* @method some
* @param {String} prop Property to check
* @return {Boolean}
* Returns requested property
* @method get
* @param {String} prop Property to get
* @return {Any}
*/
get: function(prop) {
if (prop in _lockProperties) {
@ -510,12 +532,12 @@
});
/**
* Returns fabric.Group instance from an object representation
* Returns {@link fabric.Group} instance from an object representation
* @static
* @method fabric.Group.fromObject
* @param object {Object} object to create a group from
* @param options {Object} options object
* @return {fabric.Group} an instance of fabric.Group
* @param {Object} object Object to create a group from
* @param {Object} [options] Options object
* @return {fabric.Group} An instance of fabric.Group
*/
fabric.Group.fromObject = function(object, callback) {
fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {
@ -524,6 +546,11 @@
});
};
/**
* Indicates that instances of this type are async
* @static
* @type Boolean
*/
fabric.Group.async = true;
})(typeof exports !== 'undefined' ? exports : this);

View file

@ -14,18 +14,14 @@
}
/**
* Image class
* @class Image
* @extends fabric.Object
*/
fabric.Image = fabric.util.createClass(fabric.Object, /** @scope fabric.Image.prototype */ {
/**
* @property
* @type Boolean
*/
active: false,
/**
* Type of an object
* @property
* @type String
*/
@ -34,7 +30,8 @@
/**
* Constructor
* @param {HTMLImageElement | String} element Image element
* @param {Object} options optional
* @param {Object} [options] Options object
* @return {fabric.Image}
*/
initialize: function(element, options) {
options || (options = { });
@ -127,9 +124,9 @@
},
/**
* Returns svg representation of an instance
* Returns SVG representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
* @return {String} svg representation of an instance
*/
toSVG: function() {
return '<g transform="' + this.getSvgTransform() + '">'+
@ -140,7 +137,7 @@
// so that object's center aligns with container's left/top
'transform="translate('+ (-this.width/2) + ' ' + (-this.height/2) + ')" ' +
'width="' + this.width + '" ' +
'height="' + this.height + '"' + '/>'+
'height="' + this.height + '"' + '></image>' +
'</g>';
},
@ -164,7 +161,7 @@
/**
* Returns a clone of an instance
* @mthod clone
* @method clone
* @param {Array} propertiesToInclude
* @param {Function} callback Callback is invoked with a clone as a first argument
*/
@ -176,6 +173,8 @@
* Applies filters assigned to this image (from "filters" array)
* @mthod applyFilters
* @param {Function} callback Callback is invoked when all filters have been applied and new image is generated
* @return {fabric.Image} thisArg
* @chainable
*/
applyFilters: function(callback) {
@ -231,6 +230,7 @@
/**
* @private
* @method _render
* @param ctx
*/
_render: function(ctx) {
ctx.drawImage(
@ -268,7 +268,7 @@
/**
* @private
* @method _initConfig
* @param {Object} options Options object
* @param {Object} [options] Options object
*/
_initConfig: function(options) {
options || (options = { });
@ -292,7 +292,7 @@
/**
* @private
* @method _setWidthHeight
* @param {Object} options Object with width/height properties
* @param {Object} [options] Object with width/height properties
*/
_setWidthHeight: function(options) {
this.width = 'width' in options
@ -321,14 +321,19 @@
*/
fabric.Image.CSS_CANVAS = "canvas-img";
/**
* Alias for getSrc
* @static
* @method getSvgSrc
*/
fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;
/**
* Creates an instance of fabric.Image from its object representation
* @static
* @method fromObject
* @param object {Object}
* @param callback {Function} optional
* @param {Object} object
* @param {Function} [callback] Callback to invoke when an image instance is created
*/
fabric.Image.fromObject = function(object, callback) {
var img = fabric.document.createElement('img'),
@ -397,6 +402,11 @@
fabric.Image.fromURL(parsedAttributes['xlink:href'], callback, extend(parsedAttributes, options));
};
/**
* Indicates that instances of this type are async
* @static
* @type Boolean
*/
fabric.Image.async = true;
})(typeof exports !== 'undefined' ? exports : this);

View file

@ -4,12 +4,14 @@
fabric.Image.filters = { };
/**
* Grayscale image filter class
* @class fabric.Image.filters.Grayscale
* @memberOf fabric.Image.filters
*/
fabric.Image.filters.Grayscale = fabric.util.createClass( /** @scope fabric.Image.filters.Grayscale.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: "Grayscale",
@ -64,6 +66,7 @@ fabric.Image.filters.Grayscale.fromObject = function() {
fabric.Image.filters.RemoveWhite = fabric.util.createClass( /** @scope fabric.Image.filters.RemoveWhite.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: "RemoveWhite",
@ -138,6 +141,7 @@ fabric.Image.filters.RemoveWhite.fromObject = function(object) {
fabric.Image.filters.Invert = fabric.util.createClass( /** @scope fabric.Image.filters.Invert.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: "Invert",
@ -184,6 +188,7 @@ fabric.Image.filters.Invert.fromObject = function() {
fabric.Image.filters.Sepia = fabric.util.createClass( /** @scope fabric.Image.filters.Sepia.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: "Sepia",
@ -231,6 +236,7 @@ fabric.Image.filters.Sepia.fromObject = function() {
fabric.Image.filters.Sepia2 = fabric.util.createClass( /** @scope fabric.Image.filters.Sepia2.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: "Sepia2",
@ -282,6 +288,7 @@ fabric.Image.filters.Sepia2.fromObject = function() {
fabric.Image.filters.Brightness = fabric.util.createClass( /** @scope fabric.Image.filters.Brightness.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: "Brightness",
@ -339,6 +346,7 @@ fabric.Image.filters.Brightness.fromObject = function(object) {
fabric.Image.filters.Noise = fabric.util.createClass( /** @scope fabric.Image.filters.Noise.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: "Noise",
@ -399,6 +407,7 @@ fabric.Image.filters.Noise.fromObject = function(object) {
fabric.Image.filters.GradientTransparency = fabric.util.createClass( /** @scope fabric.Image.filters.GradientTransparency.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: "GradientTransparency",
@ -454,6 +463,7 @@ fabric.Image.filters.GradientTransparency.fromObject = function(object) {
fabric.Image.filters.Tint = fabric.util.createClass( /** @scope fabric.Image.filters.Tint.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: "Tint",
@ -524,6 +534,7 @@ fabric.Image.filters.Tint.fromObject = function(object) {
fabric.Image.filters.Convolute = fabric.util.createClass(/** @scope fabric.Image.filters.Convolute.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: 'Convolute',
@ -633,6 +644,7 @@ fabric.Image.filters.Convolute.fromObject = function(object) {
fabric.Image.filters.Pixelate = fabric.util.createClass(/** @scope fabric.Image.filters.Pixelate.prototype */ {
/**
* Filter type
* @param {String} type
*/
type: 'Pixelate',

View file

@ -12,6 +12,7 @@
}
/**
* Intersection class
* @class Intersection
* @memberOf fabric
*/
@ -26,6 +27,7 @@
fabric.Intersection.prototype = /** @scope fabric.Intersection.prototype */ {
/**
* Constructor
* @method init
* @param {String} status
*/
@ -35,16 +37,18 @@
},
/**
* Appends a point to intersection
* @method appendPoint
* @param {String} status
* @param {fabric.Point} point
*/
appendPoint: function (point) {
this.points.push(point);
},
/**
* Appends points to intersection
* @method appendPoints
* @param {String} status
* @param {Array} points
*/
appendPoints: function (points) {
this.points = this.points.concat(points);

View file

@ -12,12 +12,14 @@
}
/**
* Line class
* @class Line
* @extends fabric.Object
*/
fabric.Line = fabric.util.createClass(fabric.Object, /** @scope fabric.Line.prototype */ {
/**
* Type of an object
* @property
* @type String
*/
@ -26,7 +28,7 @@
/**
* Constructor
* @method initialize
* @param {Array} points Array of points
* @param {Array} [points] Array of points
* @param {Object} [options] Options object
* @return {fabric.Line} thisArg
*/
@ -50,7 +52,7 @@
/**
* @private
* @method _setWidthHeight
* @param {Object} options
* @param {Object} [options] Options
*/
_setWidthHeight: function(options) {
options || (options = { });
@ -128,9 +130,9 @@
},
/**
* Returns svg representation of an instance
* Returns SVG representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
* @return {String} svg representation of an instance
*/
toSVG: function() {
return [

View file

@ -14,6 +14,7 @@
}
/**
* Root object class from which all 2d shape classes inherit from
* @class Object
* @memberOf fabric
*/
@ -69,14 +70,14 @@
height: 0,
/**
* Horizontal scale of an object
* Object scale factor (horizontal)
* @property
* @type Number
*/
scaleX: 1,
/**
* Vertical scale of an object
* Object scale factor (vertical)
* @property
* @type Number
*/
@ -104,7 +105,7 @@
opacity: 1,
/**
* Angle of an object (in degrees)
* Angle of rotation of an object (in degrees)
* @property
* @type Number
*/
@ -132,14 +133,14 @@
padding: 0,
/**
* Color of object's borders (when in active state)
* Border color of an object (when it's active)
* @property
* @type String
*/
borderColor: 'rgba(102,153,255,0.75)',
/**
* Color of object's corners (when in active state)
* Corner color of an object (when it's active)
* @property
* @type String
*/
@ -153,12 +154,14 @@
fill: 'rgb(0,0,0)',
/**
* Fill rule used to fill an object
* @property
* @type String
*/
fillRule: 'source-over',
/**
* Overlay fill (takes precedence over fill value)
* @property
* @type String
*/
@ -179,7 +182,7 @@
strokeWidth: 1,
/**
* Dash pattern of a stroke for this object
* Array specifying dash pattern of an object's stroke
* @property
* @type Array
*/
@ -193,6 +196,7 @@
borderOpacityWhenMoving: 0.4,
/**
* Border scale factor
* @property
* @type Number
*/
@ -296,6 +300,7 @@
},
/**
* Sets object's properties from options
* @method setOptions
* @param {Object} [options]
*/
@ -307,6 +312,7 @@
},
/**
* Transforms context when rendering an object
* @method transform
* @param {CanvasRenderingContext2D} ctx Context
*/
@ -370,7 +376,7 @@
/**
* Returns (dataless) object representation of an instance
* @method toDatalessObject
* @param {Array} propertiesToInclude
* @param {Array} [propertiesToInclude]
* @return {Object} object representation of an instance
*/
toDatalessObject: function(propertiesToInclude) {
@ -381,7 +387,7 @@
/**
* Returns styles-string for svg-export
* @method getSvgStyles
* @return {string}
* @return {String}
*/
getSvgStyles: function() {
return [
@ -396,7 +402,7 @@
/**
* Returns transform-string for svg-export
* @method getSvgTransform
* @return {string}
* @return {String}
*/
getSvgTransform: function() {
var angle = this.getAngle();
@ -514,6 +520,12 @@
return this;
},
/**
* @private
* @method _set
* @param key
* @param value
*/
_set: function(key, value) {
var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY');
@ -553,6 +565,7 @@
},
/**
* Sets sourcePath of an object
* @method setSourcePath
* @param {String} value
* @return {fabric.Object} thisArg
@ -566,7 +579,7 @@
/**
* Basic getter
* @method get
* @param {Any} property
* @param {String} property
* @return {Any} value of a property
*/
get: function(property) {
@ -574,6 +587,7 @@
},
/**
* Renders an object on a specified context
* @method render
* @param {CanvasRenderingContext2D} ctx context to render on
* @param {Boolean} noTransform
@ -1287,6 +1301,7 @@
},
/**
* Returns true if object state (one of its state properties) was changed
* @method hasStateChanged
* @return {Boolean} true if instance' state has changed
*/
@ -1297,6 +1312,7 @@
},
/**
* Saves state of an object
* @method saveState
* @return {fabric.Object} thisArg
* @chainable
@ -1309,6 +1325,7 @@
},
/**
* Setups state of an object
* @method setupState
*/
setupState: function() {
@ -1395,9 +1412,10 @@
},
/**
* Returns true if specified type is identical to the type of an instance
* @method isType
* @param type {String} type to check against
* @return {Boolean} true if specified type is identical to the type of instance
* @return {Boolean}
*/
isType: function(type) {
return this.type === type;
@ -1735,8 +1753,9 @@
},
/**
* Returns complexity of an instance
* @method complexity
* @return {Number}
* @return {Number} complexity
*/
complexity: function() {
return 0;
@ -1754,6 +1773,7 @@
},
/**
* Sets gradient fill of an object
* @method setGradientFill
*/
setGradientFill: function(options) {
@ -1761,6 +1781,7 @@
},
/**
* Animates object's properties
* @method animate
*
* As object multiple properties

View file

@ -1,9 +1,9 @@
fabric.util.object.extend(fabric.Object.prototype, {
/**
* @private
* @method _getAngleValueForStraighten
* @return {Number} angle value
* @private
*/
_getAngleValueForStraighten: function() {
var angle = this.get('angle');
@ -22,6 +22,7 @@ fabric.util.object.extend(fabric.Object.prototype, {
},
/**
* Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer)
* @method straighten
* @return {fabric.Object} thisArg
* @chainable
@ -33,6 +34,7 @@ fabric.util.object.extend(fabric.Object.prototype, {
},
/**
* Same as {@link fabric.Object.prototype.straghten} but with animation
* @method fxStraighten
* @param {Object} callbacks
* - onComplete: invoked on completion
@ -86,7 +88,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
},
/**
* Same as `fabric.Canvas#straightenObject`, but animated
* Same as {@link fabric.Canvas.prototype.straightenObject}, but animated
* @method fxStraightenObject
* @param {fabric.Object} object Object to straighten
* @return {fabric.Canvas} thisArg

View file

@ -320,7 +320,7 @@
* @method parseElements
* @param {Array} elements Array of elements to parse
* @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements)
* @param {Object} options Options object
* @param {Object} [options] Options object
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
*/
function parseElements(elements, callback, options, reviver) {

View file

@ -778,7 +778,7 @@
* @static
* @method fabric.Path.fromElement
* @param {SVGElement} element to parse
* @param {Object} options object
* @param {Object} [options] Options object
* @return {fabric.Path} Instance of fabric.Path
*/
fabric.Path.fromElement = function(element, options) {

View file

@ -15,6 +15,7 @@
}
/**
* Path group class
* @class PathGroup
* @extends fabric.Path
*/
@ -28,17 +29,12 @@
type: 'path-group',
/**
* Fill value
* @property
* @type String
*/
fill: '',
/**
* @property
* @type Boolean
*/
forceFillOverwrite: false,
/**
* Constructor
* @method initialize
@ -109,7 +105,7 @@
/**
* Returns object representation of this path group
* @method toObject
* @param {Array} propertiesToInclude
* @param {Array} [propertiesToInclude]
* @return {Object} object representation of an instance
*/
toObject: function(propertiesToInclude) {
@ -122,7 +118,7 @@
/**
* Returns dataless object representation of this path group
* @method toDatalessObject
* @param {Array} propertiesToInclude
* @param {Array} [propertiesToInclude]
* @return {Object} dataless object representation of an instance
*/
toDatalessObject: function(propertiesToInclude) {
@ -136,7 +132,7 @@
/**
* Returns svg representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
* @return {String} svg representation of an instance
*/
toSVG: function() {
var objects = this.getObjects();
@ -157,11 +153,11 @@
return markup.join('');
},
/**
* Returns a string representation of this path group
* @method toString
* @return {String} string representation of an object
*/
/**
* Returns a string representation of this path group
* @method toString
* @return {String} string representation of an object
*/
toString: function() {
return '#<fabric.PathGroup (' + this.complexity() +
'): { top: ' + this.top + ', left: ' + this.left + ' }>';
@ -180,10 +176,10 @@
},
/**
* Returns number representation of object's complexity
* @method complexity
* @return {Number} complexity
*/
* Returns number representation of object's complexity
* @method complexity
* @return {Number} complexity
*/
complexity: function() {
return this.paths.reduce(function(total, path) {
return total + ((path && path.complexity) ? path.complexity() : 0);

View file

@ -32,9 +32,10 @@
constructor: Point,
/**
* Constructor
* @method init
* @param {Number} x
* @param {Number} y
* @param {Number} x left offset
* @param {Number} y top offset
*/
init: function (x, y) {
this.x = x;
@ -101,60 +102,126 @@
return this;
},
/**
* @method scalarSubtract
* @param {Number} scalar
* @return {fabric.Point}
*/
scalarSubtract: function (scalar) {
return new Point(this.x - scalar, this.y - scalar);
},
/**
* @method scalarSubtractEquals
* @param {Number} scalar
* @return {fabric.Point} thisArg
*/
scalarSubtractEquals: function (scalar) {
this.x -= scalar;
this.y -= scalar;
return this;
},
/**
* @method multiply
* @param {Number} scalar
* @return {fabric.Point}
*/
multiply: function (scalar) {
return new Point(this.x * scalar, this.y * scalar);
},
/**
* @method multiplyEquals
* @param {Number} scalar
* @return {fabric.Point} thisArg
*/
multiplyEquals: function (scalar) {
this.x *= scalar;
this.y *= scalar;
return this;
},
/**
* @method divide
* @param {Number} scalar
* @return {fabric.Point}
*/
divide: function (scalar) {
return new Point(this.x / scalar, this.y / scalar);
},
/**
* @method divideEquals
* @param {Number} scalar
* @return {fabric.Point} thisArg
*/
divideEquals: function (scalar) {
this.x /= scalar;
this.y /= scalar;
return this;
},
/**
* @method eq
* @param {fabric.Point} that
* @return {Boolean}
*/
eq: function (that) {
return (this.x === that.x && this.y === that.y);
},
/**
* @method lt
* @param {fabric.Point} that
* @return {Boolean}
*/
lt: function (that) {
return (this.x < that.x && this.y < that.y);
},
/**
* @method lte
* @param {fabric.Point} that
* @return {Boolean}
*/
lte: function (that) {
return (this.x <= that.x && this.y <= that.y);
},
/**
* @method gt
* @param {fabric.Point} that
* @return {Boolean}
*/
gt: function (that) {
return (this.x > that.x && this.y > that.y);
},
/**
* @method gte
* @param {fabric.Point} that
* @return {Boolean}
*/
gte: function (that) {
return (this.x >= that.x && this.y >= that.y);
},
/**
* @method lerp
* @param {fabric.Point} that
* @param {Number} t
* @return {fabric.Point}
*/
lerp: function (that, t) {
return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t);
},
/**
* @method distanceFrom
* @param {fabric.Point} that
* @return {Number}
*/
distanceFrom: function (that) {
var dx = this.x - that.x,
dy = this.y - that.y;
@ -163,7 +230,7 @@
/**
* Return the point between A (x,y) and B (x,y)
*/
*/
midPointFrom: function (that) {
return new Point(this.x + (that.x - this.x)/2, this.y + (that.y - this.y)/2);
},

View file

@ -14,6 +14,7 @@
}
/**
* Polygon class
* @class Polygon
* @extends fabric.Object
*/
@ -30,7 +31,7 @@
* Constructor
* @method initialize
* @param {Array} points Array of points
* @param {Object} options Options object
* @param {Object} [options] Options object
* @return {fabric.Polygon} thisArg
*/
initialize: function(points, options) {
@ -74,7 +75,7 @@
/**
* Returns svg representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
* @return {String} svg representation of an instance
*/
toSVG: function() {
var points = [];
@ -131,11 +132,11 @@
fabric.Polygon.ATTRIBUTE_NAMES = 'fill fill-opacity opacity stroke stroke-width transform'.split(' ');
/**
* Returns fabric.Polygon instance from an SVG element
* Returns {@link fabric.Polygon} instance from an SVG element
* @static
* @method fabric.Polygon.fromElement
* @param {SVGElement} element Element to parse
* @param {Object} options Options object
* @param {Object} [options] Options object
* @return {fabric.Polygon}
*/
fabric.Polygon.fromElement = function(element, options) {

View file

@ -11,6 +11,7 @@
}
/**
* Polyline class
* @class Polyline
* @extends fabric.Object
*/
@ -56,7 +57,7 @@
},
/**
* Returns svg representation of an instance
* Returns SVG representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
*/

View file

@ -11,6 +11,7 @@
}
/**
* Rectangle class
* @class Rect
* @extends fabric.Object
*/
@ -40,7 +41,7 @@
/**
* Constructor
* @method initialize
* @param options {Object} options object
* @param {Object} [options] Options object
* @return {Object} thisArg
*/
initialize: function(options) {
@ -49,6 +50,9 @@
this._initStateProperties();
this.callSuper('initialize', options);
this._initRxRy();
this.x = 0;
this.y = 0;
},
/**
@ -62,6 +66,7 @@
},
/**
* Initializes rx/ry attributes
* @private
* @method _initRxRy
*/
@ -166,7 +171,7 @@
/**
* Returns svg representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
* @return {String} svg representation of an instance
*/
toSVG: function() {
return '<rect ' +
@ -179,8 +184,6 @@
}
});
// TODO (kangax): implement rounded rectangles (both parsing and rendering)
/**
* List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)
* @static
@ -197,12 +200,12 @@
}
/**
* Returns fabric.Rect instance from an SVG element
* Returns {@link fabric.Rect} instance from an SVG element
* @static
* @method fabric.Rect.fromElement
* @param element {SVGElement} element to parse
* @param options {Object} options object
* @return {fabric.Rect} instance of fabric.Rect
* @param {SVGElement} element Element to parse
* @param {Object} [options] Options object
* @return {fabric.Rect} Instance of fabric.Rect
*/
fabric.Rect.fromElement = function(element, options) {
if (!element) {
@ -219,7 +222,7 @@
};
/**
* Returns fabric.Rect instance from an object representation
* Returns {@link fabric.Rect} instance from an object representation
* @static
* @method fabric.Rect.fromObject
* @param object {Object} object to create an instance from

View file

@ -14,6 +14,7 @@ fabric.util.object.extend(fabric.Object.prototype, {
).split(' '),
/**
* Returns true if state of an object (one if its state properties) was changed
* @method hasStateChanged
* @return {Boolean} true if instance' state has changed
*/
@ -24,6 +25,7 @@ fabric.util.object.extend(fabric.Object.prototype, {
},
/**
* Saves a snapshot of object's state (its state properties)
* @method saveState
* @return {fabric.Object} thisArg
* @chainable
@ -36,6 +38,7 @@ fabric.util.object.extend(fabric.Object.prototype, {
},
/**
* Setups state of an object
* @method setupState
*/
setupState: function() {

View file

@ -244,7 +244,7 @@
/**
* @method _initOptions
* @param {Object} options
* @param {Object} [options]
*/
_initOptions: function (options) {
for (var prop in options) {

View file

@ -13,91 +13,105 @@
}
/**
* Text class
* @class Text
* @extends fabric.Object
*/
fabric.Text = fabric.util.createClass(fabric.Object, /** @scope fabric.Text.prototype */ {
/**
* Font size
* @property
* @type Number
*/
fontSize: 40,
/**
* Font weight (e.g. bold, normal, 400, 600, 800)
* @property
* @type Number
*/
fontWeight: 400,
/**
* Font family
* @property
* @type String
*/
fontFamily: 'Times New Roman',
/**
* Text decoration (e.g. underline, overline)
* @property
* @type String
*/
textDecoration: '',
/**
* Text shadow
* @property
* @type String | null
*/
textShadow: '',
/**
* Determines text alignment. Possible values: "left", "center", or "right".
* Text alignment. Possible values: "left", "center", or "right".
* @property
* @type String
*/
textAlign: 'left',
/**
* Font style (e.g. italic)
* @property
* @type String
*/
fontStyle: '',
/**
* Line height
* @property
* @type Number
*/
lineHeight: 1.3,
/**
* Stroke style. When specified, text is rendered with stroke
* @property
* @type String
*/
strokeStyle: '',
/**
* Stroke width
* @property
* @type Number
*/
strokeWidth: 1,
/**
* Background color of an entire text box
* @property
* @type String
*/
backgroundColor: '',
/**
* Background color of text lines
* @property
* @type String
*/
textBackgroundColor: '',
/**
* URL of a font file, when using Cufon
* @property
* @type String | null
*/
path: null,
/**
* Type of an object
* @property
* @type String
*/
@ -378,6 +392,10 @@
}
},
/**
* @private
* @method _renderTextFill
*/
_renderTextFill: function(ctx, textLines) {
this._boundaries = [ ];
for (var i = 0, len = textLines.length; i < len; i++) {
@ -577,9 +595,9 @@
},
/**
* Returns svg representation of an instance
* Returns SVG representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
* @return {String} svg representation of an instance
*/
toSVG: function() {
@ -618,6 +636,10 @@
].join('');
},
/**
* @private
* @method _getSVGShadows
*/
_getSVGShadows: function(lineTopOffset, textLines) {
var shadowSpans = [], j, i, jlen, ilen, lineTopOffsetMultiplier = 1;
@ -651,6 +673,10 @@
return shadowSpans;
},
/**
* @private
* @method _getSVGTextAndBg
*/
_getSVGTextAndBg: function(lineTopOffset, textLeftOffset, textLines) {
var textSpans = [ ], textBgRects = [ ], i, lineLeftOffset, len, lineTopOffsetMultiplier = 1;
@ -713,8 +739,13 @@
};
},
// Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values
// we work around it by "moving" alpha channel into opacity attribute and setting fill's alpha to 1
/**
* Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values
* we work around it by "moving" alpha channel into opacity attribute and setting fill's alpha to 1
*
* @private
* @method _getFillAttributes
*/
_getFillAttributes: function(value) {
var fillColor = value ? new fabric.Color(value) : '';
if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {

View file

@ -10,12 +10,14 @@
}
/**
* Triangle class
* @class Triangle
* @extends fabric.Object
*/
fabric.Triangle = fabric.util.createClass(fabric.Object, /** @scope fabric.Triangle.prototype */ {
/**
* Type of an object
* @property
* @type String
*/
@ -24,7 +26,7 @@
/**
* Constructor
* @method initialize
* @param options {Object} options object
* @param {Object} [options] Options object
* @return {Object} thisArg
*/
initialize: function(options) {
@ -69,9 +71,9 @@
},
/**
* Returns svg representation of an instance
* Returns SVG representation of an instance
* @method toSVG
* @return {string} svg representation of an instance
* @return {String} svg representation of an instance
*/
toSVG: function() {

View file

@ -189,30 +189,20 @@
}
return {
x: event.clientX + scrollLeft,
y: event.clientY + scrollTop
x: pointerX(event) + scrollLeft,
y: pointerY(event) + scrollTop
};
}
var pointerX = function(event) {
var docElement = fabric.document.documentElement,
body = fabric.document.body || { scrollLeft: 0 };
// looks like in IE (<9) clientX at certain point (apparently when mouseup fires on VML element)
// is represented as COM object, with all the consequences, like "unknown" type and error on [[Get]]
// need to investigate later
return event.pageX || ((typeof event.clientX !== 'unknown' ? event.clientX : 0) +
(docElement.scrollLeft || body.scrollLeft) -
(docElement.clientLeft || 0));
return (typeof event.clientX !== 'unknown' ? event.clientX : 0);
};
var pointerY = function(event) {
var docElement = fabric.document.documentElement,
body = fabric.document.body || { scrollTop: 0 };
return event.pageY || ((typeof event.clientY !== 'unknown' ? event.clientY : 0) +
(docElement.scrollTop || body.scrollTop) -
(docElement.clientTop || 0));
return (typeof event.clientY !== 'unknown' ? event.clientY : 0);
};
if (fabric.isTouchSupported) {

View file

@ -233,8 +233,8 @@
* @memberOf fabric.util
* @method groupSVGElements
* @param {Array} elements
* @param {Object} options optional
* @return {String} path optional
* @param {Object} [options] Options object
* @return {fabric.Object|fabric.PathGroup}
*/
function groupSVGElements(elements, options, path) {
var object = elements.length > 1

View file

@ -1,9 +1,25 @@
(function() {
var path = require("path");
QUnit.module('fabric.util');
function K (x) { return x }
function getAbsolutePath(path) {
var isAbsolute = /^https?:/.test(path);
if (isAbsolute) return path;
var imgEl = _createImageElement();
imgEl.src = path;
var src = imgEl.src;
imgEl = null;
return src;
}
var IMG_URL = fabric.isLikelyNode
? path.join(__dirname, '../fixtures/', 'very_large_image.jpg')
: getAbsolutePath('../fixtures/very_large_image.jpg');
test('fabric.util.toFixed', function(){
ok(typeof fabric.util.toFixed == 'function');
@ -387,7 +403,13 @@
objectPassedToCallback,
NodeCanvasImage = require('canvas').Image;
fabric.util.loadImage('../fixtures/very_large_image.jpg', function(obj) {
if (IMG_URL.indexOf('/home/travis') === 0) {
// image can not be accessed on travis so we're returning early
start();
return;
}
fabric.util.loadImage(IMG_URL, function(obj) {
callbackInvoked = true;
objectPassedToCallback = obj;
});