diff --git a/.gitignore b/.gitignore
index b1f31aab..57a51e92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
-node_modules
.DS_Store
+/node_modules/
+/npm-debug.log
before_commit
diff --git a/.jshintrc b/.jshintrc
index bc589f4d..c05b47de 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -1,49 +1,41 @@
{
"globals": {
+ "ActiveXObject": true,
+ "Cufon": true,
"define": true,
+ "Event": true,
"exports": true,
"fabric": true,
- "Cufon": true,
- "Event": true,
- "G_vmlCanvasManager": true,
- "ActiveXObject": true
+ "G_vmlCanvasManager": true
},
- "node": true,
- "es5": false,
"browser": true,
-
- "boss": false,
- "curly": false,
- "debug": false,
- "devel": false,
"eqeqeq": true,
"eqnull": true,
"evil": true,
"expr": true,
"forin": false,
"immed": true,
+ "lastsemic": true,
"laxbreak": true,
"loopfunc": true,
"multistr": true,
"newcap": true,
"noarg": true,
+ "node": true,
"noempty": false,
- "nonew": false,
"nomen": false,
+ "nonew": false,
"onevar": false,
"plusplus": false,
- "regexp": false,
- "undef": true,
- "sub": true,
"strict": false,
- "white": false,
+ "sub": true,
+ "undef": true,
"unused": true,
- "lastsemic": true,
- // "maxparams": 4
// "maxcomplexity": 7
- // "maxlen": 100
"maxdepth": 4,
+ // "maxlen": 100
+ // "maxparams": 4
"maxstatements": 30
}
diff --git a/README.md b/README.md
index 743fb12e..1d2b22cf 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,8 @@
[](https://codeclimate.com/repos/526a0ed089af7e6cf2001389/feed)
[](https://coveralls.io/r/kangax/fabric.js?branch=master)
-[](https://gemnasium.com/kangax/fabric.js)
+[](https://david-dm.org/kangax/fabric.js)
+[](https://david-dm.org/kangax/fabric.js#info=devDependencies)
**Fabric.js** is a framework that makes it easy to work with HTML5 canvas element. It is an **interactive object model** on top of canvas element. It is also an **SVG-to-canvas parser**.
@@ -160,29 +161,29 @@ For example:
#### Adding red rectangle to canvas
```html
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
-
-
+ canvas.add(rect);
+
+
+
```
### Helping Fabric
@@ -231,4 +232,3 @@ SOFTWARE.
[](https://bitdeli.com/free "Bitdeli Badge")
-
diff --git a/lib/excanvas-diff.patch b/lib/excanvas-diff.patch
index 2b7d64cc..37ad3c8b 100644
--- a/lib/excanvas-diff.patch
+++ b/lib/excanvas-diff.patch
@@ -6,7 +6,7 @@ Index: excanvas.js
o2.arcScaleX_ = o1.arcScaleX_;
o2.arcScaleY_ = o1.arcScaleY_;
o2.lineScale_ = o1.lineScale_;
-+ o2.rotation_ = o1.rotation_; // used for images
++ o2.rotation_ = o1.rotation_; // used for images
}
var colorData = {
@@ -14,7 +14,7 @@ Index: excanvas.js
this.arcScaleX_ = 1;
this.arcScaleY_ = 1;
this.lineScale_ = 1;
-+ this.rotation_ = 0;
++ this.rotation_ = 0;
}
var contextPrototype = CanvasRenderingContext2D_.prototype;
@@ -26,10 +26,10 @@ Index: excanvas.js
+ contextPrototype.drawImage = function(image) {
var dx, dy, dw, dh, sx, sy, sw, sh;
-
-+
++
+ // to fix new Image() we check the existance of runtimeStyle
+ var rts = image.runtimeStyle.width;
-+
++
// to find the original width we overide the width and height
- var oldRuntimeWidth = image.runtimeStyle.width;
- var oldRuntimeHeight = image.runtimeStyle.height;
@@ -38,25 +38,25 @@ Index: excanvas.js
+ if(rts) {
+ var oldRuntimeWidth = image.runtimeStyle.width;
+ var oldRuntimeHeight = image.runtimeStyle.height;
-+
++
+ image.runtimeStyle.width = 'auto';
-+ image.runtimeStyle.height = 'auto';
++ image.runtimeStyle.height = 'auto';
+ }
// get the original size
var w = image.width;
var h = image.height;
-
-+
++
// and remove overides
- image.runtimeStyle.width = oldRuntimeWidth;
- image.runtimeStyle.height = oldRuntimeHeight;
-
+ if(rts) {
+ image.runtimeStyle.width = oldRuntimeWidth;
-+ image.runtimeStyle.height = oldRuntimeHeight;
++ image.runtimeStyle.height = oldRuntimeHeight;
+ }
-+
++
if (arguments.length == 3) {
dx = arguments[1];
dy = arguments[2];
@@ -64,9 +64,9 @@ Index: excanvas.js
var W = 10;
var H = 10;
-+
++
+ var scaleX = scaleY = 1;
-+
++
+ // FIX: divs give better quality then vml image and also fixes transparent PNG's
+ vmlStr.push(' ');
+ }
-+
-+
++
++
+ // Apply scales to width and height
+ vmlStr.push('
');
-+
-+ // Close the crop div if necessary
++
++ // Close the crop div if necessary
+ if (sx || sy) vmlStr.push('
');
-+
++
+ vmlStr.push('
');
-+
++
+ this.element_.insertAdjacentHTML('beforeEnd', vmlStr.join(''));
};
@@ -176,8 +176,8 @@ Index: excanvas.js
var c = mc(aRot);
var s = ms(aRot);
-+ this.rotation_ += aRot;
-+
++ this.rotation_ += aRot;
++
var m1 = [
[c, s, 0],
[-s, c, 0],
@@ -188,7 +188,7 @@ Index: excanvas.js
- this.textMeasureEl_.style.font = this.font;
+ // FIX: Apply current font style to textMeasureEl to get correct size
+ var fontStyle = getComputedStyle(processFontStyle(this.font), this.element_),
-+ fontStyleString = buildStyle(fontStyle);
++ fontStyleString = buildStyle(fontStyle);
+ this.textMeasureEl_.style.font = fontStyleString;
+
// Don't use innerHTML or innerText because they allow markup/whitespace.
diff --git a/lib/excanvas.js b/lib/excanvas.js
index a6dceecb..b95043cf 100644
--- a/lib/excanvas.js
+++ b/lib/excanvas.js
@@ -253,7 +253,7 @@ if (!document.createElement('canvas').getContext) {
o2.arcScaleX_ = o1.arcScaleX_;
o2.arcScaleY_ = o1.arcScaleY_;
o2.lineScale_ = o1.lineScale_;
- o2.rotation_ = o1.rotation_; // used for images
+ o2.rotation_ = o1.rotation_; // used for images
}
var colorData = {
@@ -604,7 +604,7 @@ if (!document.createElement('canvas').getContext) {
this.arcScaleX_ = 1;
this.arcScaleY_ = 1;
this.lineScale_ = 1;
- this.rotation_ = 0;
+ this.rotation_ = 0;
}
var contextPrototype = CanvasRenderingContext2D_.prototype;
@@ -771,29 +771,29 @@ if (!document.createElement('canvas').getContext) {
contextPrototype.drawImage = function(image) {
var dx, dy, dw, dh, sx, sy, sw, sh;
-
+
// to fix new Image() we check the existance of runtimeStyle
var rts = image.runtimeStyle.width;
-
+
// to find the original width we overide the width and height
if(rts) {
var oldRuntimeWidth = image.runtimeStyle.width;
var oldRuntimeHeight = image.runtimeStyle.height;
-
+
image.runtimeStyle.width = 'auto';
- image.runtimeStyle.height = 'auto';
+ image.runtimeStyle.height = 'auto';
}
// get the original size
var w = image.width;
var h = image.height;
-
+
// and remove overides
if(rts) {
image.runtimeStyle.width = oldRuntimeWidth;
- image.runtimeStyle.height = oldRuntimeHeight;
+ image.runtimeStyle.height = oldRuntimeHeight;
}
-
+
if (arguments.length == 3) {
dx = arguments[1];
dy = arguments[2];
@@ -830,9 +830,9 @@ if (!document.createElement('canvas').getContext) {
var W = 10;
var H = 10;
-
+
var scaleX = scaleY = 1;
-
+
// FIX: divs give better quality then vml image and also fixes transparent PNG's
vmlStr.push(' ');
}
-
-
+
+
// Apply scales to width and height
vmlStr.push('
');
-
- // Close the crop div if necessary
+
+ // Close the crop div if necessary
if (sx || sy) vmlStr.push('
');
-
+
vmlStr.push('
');
-
+
this.element_.insertAdjacentHTML('beforeEnd', vmlStr.join(''));
};
@@ -1198,8 +1198,8 @@ if (!document.createElement('canvas').getContext) {
var c = mc(aRot);
var s = ms(aRot);
- this.rotation_ += aRot;
-
+ this.rotation_ += aRot;
+
var m1 = [
[c, s, 0],
[-s, c, 0],
@@ -1355,7 +1355,7 @@ if (!document.createElement('canvas').getContext) {
this.textMeasureEl_.innerHTML = '';
// FIX: Apply current font style to textMeasureEl to get correct size
var fontStyle = getComputedStyle(processFontStyle(this.font), this.element_),
- fontStyleString = buildStyle(fontStyle);
+ fontStyleString = buildStyle(fontStyle);
this.textMeasureEl_.style.font = fontStyleString;
// Don't use innerHTML or innerText because they allow markup/whitespace.
diff --git a/lib/json2.js b/lib/json2.js
index a43520a6..deb88ec9 100644
--- a/lib/json2.js
+++ b/lib/json2.js
@@ -1,6 +1,6 @@
/*
json2.js
- 2011-10-19
+ 2014-02-04
Public Domain.
@@ -159,8 +159,7 @@
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
-var JSON;
-if (!JSON) {
+if (typeof JSON !== 'object') {
JSON = {};
}
@@ -174,8 +173,7 @@ if (!JSON) {
if (typeof Date.prototype.toJSON !== 'function') {
- /** @ignore */
- Date.prototype.toJSON = function (key) {
+ Date.prototype.toJSON = function () {
return isFinite(this.valueOf())
? this.getUTCFullYear() + '-' +
@@ -189,25 +187,16 @@ if (!JSON) {
String.prototype.toJSON =
Number.prototype.toJSON =
- /** @ignore */
- Boolean.prototype.toJSON = function (key) {
+ Boolean.prototype.toJSON = function () {
return this.valueOf();
};
}
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ var cx,
+ escapable,
gap,
indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- },
+ meta,
rep;
@@ -359,7 +348,16 @@ if (!JSON) {
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
- /** @ignore */
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ };
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
@@ -407,7 +405,7 @@ if (!JSON) {
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
- /** @ignore */
+ cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
@@ -488,4 +486,4 @@ if (!JSON) {
throw new SyntaxError('JSON.parse');
};
}
-}());
\ No newline at end of file
+}());
diff --git a/lib/screenshot.png b/lib/screenshot.png
index 27c2b3b7..1135d4cd 100644
Binary files a/lib/screenshot.png and b/lib/screenshot.png differ
diff --git a/package.json b/package.json
index 41862e7a..1e3ff676 100644
--- a/package.json
+++ b/package.json
@@ -4,12 +4,29 @@
"homepage": "http://fabricjs.com/",
"version": "1.4.4",
"author": "Juriy Zaytsev ",
- "keywords": ["canvas", "graphic", "graphics", "SVG", "node-canvas", "parser", "HTML5", "object model"],
- "repository": "git://github.com/kangax/fabric.js",
- "licenses": [{
- "type": "MIT",
- "url": "http://github.com/kangax/fabric.js/raw/master/LICENSE"
- }],
+ "keywords": [
+ "canvas",
+ "graphic",
+ "graphics",
+ "SVG",
+ "node-canvas",
+ "parser",
+ "HTML5",
+ "object model"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/kangax/fabric.js"
+ },
+ "bugs": {
+ "url": "https://github.com/kangax/fabric.js/issues"
+ },
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "https://github.com/kangax/fabric.js/raw/master/LICENSE"
+ }
+ ],
"scripts": {
"build": "node build.js modules=ALL exclude=json,cufon,gestures",
"test": "node test.js && jshint src"
@@ -20,12 +37,14 @@
"xmldom": "0.1.x"
},
"devDependencies": {
- "qunit": "0.5.x",
- "jshint": "2.4.x",
- "uglify-js": "2.4.x",
+ "execSync": "0.0.x",
"jscs": "1.2.x",
- "execSync": "0.0.x"
+ "jshint": "2.4.x",
+ "qunit": "0.5.x",
+ "uglify-js": "2.4.x"
+ },
+ "engines": {
+ "node": ">=0.4.0 && <1.0.0"
},
- "engines": { "node": ">=0.4.0 && <1.0.0" },
"main": "./dist/fabric.js"
}
diff --git a/src/canvas.class.js b/src/canvas.class.js
index 7c1a66a3..4b040283 100644
--- a/src/canvas.class.js
+++ b/src/canvas.class.js
@@ -820,7 +820,7 @@
else {
cssScale = {
width: this.upperCanvasEl.width / bounds.width,
- height: this.upperCanvasEl.height / bounds.height,
+ height: this.upperCanvasEl.height / bounds.height
};
}
return {
diff --git a/src/shapes/line.class.js b/src/shapes/line.class.js
index 2d1b519e..52309ed9 100644
--- a/src/shapes/line.class.js
+++ b/src/shapes/line.class.js
@@ -119,12 +119,12 @@
origin: 'originX',
axis1: 'x1',
axis2: 'x2',
- dimension: 'width',
+ dimension: 'width'
},
{ // possible values of origin
nearest: 'left',
center: 'center',
- farthest: 'right',
+ farthest: 'right'
}
),
@@ -137,12 +137,12 @@
origin: 'originY',
axis1: 'y1',
axis2: 'y2',
- dimension: 'height',
+ dimension: 'height'
},
{ // possible values of origin
nearest: 'top',
center: 'center',
- farthest: 'bottom',
+ farthest: 'bottom'
}
),
diff --git a/test/lib/event.simulate.js b/test/lib/event.simulate.js
index 290f873d..74194a8d 100644
--- a/test/lib/event.simulate.js
+++ b/test/lib/event.simulate.js
@@ -1,6 +1,6 @@
/**
* simulateEvent(@element, eventName[, options]) -> Element
- *
+ *
* - @element: element to fire event on
* - eventName: name of event to fire (only MouseEvents and HTMLEvents interfaces are supported)
* - options: optional object to fine-tune event properties - pointerX, pointerY, ctrlKey, etc.
@@ -29,44 +29,44 @@
bubbles: true,
cancelable: true
};
-
+
global.simulateEvent = function(element, eventName) {
-
+
var options = extendObject(extendObject({ }, defaultOptions), arguments[2] || { }),
- oEvent,
+ oEvent,
eventType;
-
+
element = typeof element == 'string' ? document.getElementById(element) : element;
-
+
for (var name in eventMatchers) {
if (eventMatchers[name].test(eventName)) {
- eventType = name;
- break;
+ eventType = name;
+ break;
}
}
-
+
if (!eventType) {
throw new SyntaxError('This event is not supported');
}
-
+
if (document.createEvent) {
try {
- // Opera doesn't support event types like "KeyboardEvent",
+ // Opera doesn't support event types like "KeyboardEvent",
// but allows to create event of type "HTMLEvents", then fire key event on it
oEvent = document.createEvent(eventType);
}
catch(err) {
oEvent = document.createEvent('HTMLEvents');
}
-
+
if (eventType == 'HTMLEvents') {
oEvent.initEvent(eventName, options.bubbles, options.cancelable);
}
else if (eventType === 'KeyboardEvent') {
// TODO (kangax): this needs to be tested
if (oEvent.initKeyEvent) {
- oEvent.initKeyEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
- options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.keyCode,
+ oEvent.initKeyEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
+ options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.keyCode,
options.charCode);
}
else if (oEvent.initEvent) {
@@ -74,7 +74,7 @@
}
}
else {
- oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
+ oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element);
}