fabric 5.1.0 → 5.2.2-browser

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/event.js CHANGED
@@ -237,7 +237,7 @@ var eventManager = function(target, type, listener, configure, trigger, fromOver
237
237
  }
238
238
  return createBatchCommands(events);
239
239
  } else if (type.indexOf("on") === 0) { // to support things like "onclick" instead of "click"
240
- type = type.substr(2);
240
+ type = type.slice(2);
241
241
  }
242
242
 
243
243
  // Ensure listener is a function.
@@ -1368,7 +1368,7 @@ root.gesture = function(conf) {
1368
1368
  var dx = touch.move.x - self.x;
1369
1369
  var dy = touch.move.y - self.y;
1370
1370
  var distance = Math.sqrt(dx * dx + dy * dy);
1371
- // If touch start.distance from centroid is 0, scale should not be updated.
1371
+ // If touch start.distance from centroid is 0, scale should not be updated.
1372
1372
  // This prevents dividing by 0 in cases where start.distance is oddly 0.
1373
1373
  if (start.distance !== 0) {
1374
1374
  scale += distance / start.distance;
package/package.json CHANGED
@@ -1,91 +1,89 @@
1
1
  {
2
- "name": "fabric",
3
- "description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.",
4
- "homepage": "http://fabricjs.com/",
5
- "version": "5.1.0",
6
- "author": "Juriy Zaytsev <kangax@gmail.com>",
7
- "contributors": [
8
- {
9
- "name": "Andrea Bogazzi",
10
- "email": "andreabogazzi79@gmail.com"
11
- },
12
- {
13
- "name": "Steve Eberhardt",
14
- "email": "melchiar2@gmail.com"
15
- }
16
- ],
17
- "keywords": [
18
- "canvas",
19
- "graphic",
20
- "graphics",
21
- "SVG",
22
- "node-canvas",
23
- "parser",
24
- "HTML5",
25
- "object model"
26
- ],
27
- "browser": {
28
- "canvas": false,
29
- "fs": false,
30
- "jsdom": false,
31
- "jsdom/lib/jsdom/living/generated/utils": false,
32
- "jsdom/lib/jsdom/utils": false,
33
- "http": false,
34
- "https": false,
35
- "xmldom": false,
36
- "url": false
37
- },
38
- "repository": {
39
- "type": "git",
40
- "url": "https://github.com/fabricjs/fabric.js"
41
- },
42
- "bugs": {
43
- "url": "https://github.com/fabricjs/fabric.js/issues"
44
- },
45
- "license": "MIT",
46
- "scripts": {
47
- "changelog": "auto-changelog -o change-output.md --unreleased-only",
48
- "build": "node build.js modules=ALL requirejs exclude=gestures,accessors,erasing",
49
- "build:fast": "node build.js modules=ALL requirejs fast exclude=gestures,accessors,erasing",
50
- "build:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm run build_export",
51
- "link:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm link",
52
- "build_with_gestures": "node build.js modules=ALL exclude=accessors",
53
- "build_export": "npm run build:fast && npm run export_dist_to_site",
54
- "test:single": "qunit test/node_test_setup.js test/lib",
55
- "test:coverage": "nyc --silent qunit test/node_test_setup.js test/lib test/unit",
56
- "test:visual:coverage": "nyc --silent --no-clean qunit test/node_test_setup.js test/lib test/visual",
57
- "coverage:report": "nyc report --reporter=lcov --reporter=text",
58
- "test": "qunit test/node_test_setup.js test/lib test/unit",
59
- "test:visual": "qunit test/node_test_setup.js test/lib test/visual",
60
- "test:visual:single": "qunit test/node_test_setup.js test/lib",
61
- "test:all": "npm run test && npm run test:visual",
62
- "lint": "eslint --config .eslintrc.json src",
63
- "lint_tests": "eslint test/unit --config .eslintrc_tests && eslint test/visual --config .eslintrc_tests",
64
- "export_gesture_to_site": "cp dist/fabric.js ../fabricjs.com/lib/fabric_with_gestures.js",
65
- "export_dist_to_site": "cp dist/fabric.js ../fabricjs.com/lib/fabric.js && cp package.json ../fabricjs.com/lib/package.json && cp -r src HEADER.js lib ../fabricjs.com/build/files/",
66
- "export_tests_to_site": "cp test/unit/*.js ../fabricjs.com/test/unit && cp -r test/visual/* ../fabricjs.com/test/visual && cp -r test/fixtures/* ../fabricjs.com/test/fixtures && cp -r test/lib/* ../fabricjs.com/test/lib",
67
- "all": "npm run build && npm run test && npm run test:visual && npm run lint && npm run lint_tests && npm run export_dist_to_site && npm run export_tests_to_site",
68
- "testem": "testem .",
69
- "testem:ci": "testem ci"
70
- },
71
- "optionalDependencies": {
72
- "canvas": "^2.8.0",
73
- "jsdom": "^19.0.0"
74
- },
75
- "devDependencies": {
76
- "auto-changelog": "^2.3.0",
77
- "chalk": "^2.4.1",
78
- "eslint": "4.18.x",
79
- "nyc": "^15.1.0",
80
- "onchange": "^7.1.0",
81
- "pixelmatch": "^4.0.2",
82
- "qunit": "^2.13.0",
83
- "testem": "^3.2.0",
84
- "uglify-js": "3.3.x"
85
- },
86
- "engines": {
87
- "node": ">=14.0.0"
88
- },
89
- "main": "./dist/fabric.js",
90
- "dependencies": {}
91
- }
2
+ "name": "fabric",
3
+ "description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.",
4
+ "homepage": "http://fabricjs.com/",
5
+ "version": "5.2.2-browser",
6
+ "author": "Juriy Zaytsev <kangax@gmail.com>",
7
+ "contributors": [
8
+ {
9
+ "name": "Andrea Bogazzi",
10
+ "email": "andreabogazzi79@gmail.com"
11
+ },
12
+ {
13
+ "name": "Steve Eberhardt",
14
+ "email": "melchiar2@gmail.com"
15
+ }
16
+ ],
17
+ "keywords": [
18
+ "canvas",
19
+ "graphic",
20
+ "graphics",
21
+ "SVG",
22
+ "node-canvas",
23
+ "parser",
24
+ "HTML5",
25
+ "object model"
26
+ ],
27
+ "browser": {
28
+ "canvas": false,
29
+ "fs": false,
30
+ "jsdom": false,
31
+ "jsdom/lib/jsdom/living/generated/utils": false,
32
+ "jsdom/lib/jsdom/utils": false,
33
+ "http": false,
34
+ "https": false,
35
+ "xmldom": false,
36
+ "url": false
37
+ },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/fabricjs/fabric.js"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/fabricjs/fabric.js/issues"
44
+ },
45
+ "license": "MIT",
46
+ "scripts": {
47
+ "changelog": "auto-changelog -o change-output.md --unreleased-only",
48
+ "build": "node build.js modules=ALL requirejs exclude=gestures,accessors,erasing",
49
+ "build:fast": "node build.js modules=ALL requirejs fast exclude=gestures,accessors,erasing",
50
+ "build:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm run build_export",
51
+ "link:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm link",
52
+ "build_with_gestures": "node build.js modules=ALL exclude=accessors",
53
+ "build_export": "npm run build:fast && npm run export_dist_to_site",
54
+ "test:single": "qunit test/node_test_setup.js test/lib",
55
+ "test:coverage": "nyc --silent qunit test/node_test_setup.js test/lib test/unit",
56
+ "test:visual:coverage": "nyc --silent --no-clean qunit test/node_test_setup.js test/lib test/visual",
57
+ "coverage:report": "nyc report --reporter=lcov --reporter=text",
58
+ "test": "qunit --require ./test/node_test_setup.js test/lib test/unit",
59
+ "test:visual": "qunit test/node_test_setup.js test/lib test/visual",
60
+ "test:visual:single": "qunit test/node_test_setup.js test/lib",
61
+ "test:all": "npm run test && npm run test:visual",
62
+ "lint": "eslint --config .eslintrc.json src",
63
+ "lint_tests": "eslint test/unit --config .eslintrc_tests && eslint test/visual --config .eslintrc_tests",
64
+ "export_gesture_to_site": "cp dist/fabric.js ../fabricjs.com/lib/fabric_with_gestures.js",
65
+ "export_dist_to_site": "cp dist/fabric.js ../fabricjs.com/lib/fabric.js && cp package.json ../fabricjs.com/lib/package.json && cp -r src HEADER.js lib ../fabricjs.com/build/files/",
66
+ "export_tests_to_site": "cp test/unit/*.js ../fabricjs.com/test/unit && cp -r test/visual/* ../fabricjs.com/test/visual && cp -r test/fixtures/* ../fabricjs.com/test/fixtures && cp -r test/lib/* ../fabricjs.com/test/lib",
67
+ "all": "npm run build && npm run test && npm run test:visual && npm run lint && npm run lint_tests && npm run export_dist_to_site && npm run export_tests_to_site",
68
+ "testem": "testem .",
69
+ "testem:ci": "testem ci"
70
+ },
71
+ "optionalDependencies": {},
72
+ "devDependencies": {
73
+ "auto-changelog": "^2.3.0",
74
+ "chalk": "^2.4.1",
75
+ "deep-object-diff": "^1.1.7",
76
+ "eslint": "4.18.x",
77
+ "nyc": "^15.1.0",
78
+ "onchange": "^7.1.0",
79
+ "pixelmatch": "^4.0.2",
80
+ "qunit": "^2.17.2",
81
+ "testem": "^3.2.0",
82
+ "uglify-js": "3.3.x"
83
+ },
84
+ "engines": {
85
+ "node": ">=14.0.0"
86
+ },
87
+ "main": "./dist/fabric.js",
88
+ "dependencies": {}
89
+ }
@@ -507,7 +507,7 @@
507
507
  _isSelectionKeyPressed: function(e) {
508
508
  var selectionKeyPressed = false;
509
509
 
510
- if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') {
510
+ if (Array.isArray(this.selectionKey)) {
511
511
  selectionKeyPressed = !!this.selectionKey.find(function(key) { return e[key] === true; });
512
512
  }
513
513
  else {
@@ -933,6 +933,14 @@
933
933
  this.contextTop = upperCanvasEl.getContext('2d');
934
934
  },
935
935
 
936
+ /**
937
+ * Returns context of top canvas where interactions are drawn
938
+ * @returns {CanvasRenderingContext2D}
939
+ */
940
+ getTopContext: function () {
941
+ return this.contextTop;
942
+ },
943
+
936
944
  /**
937
945
  * @private
938
946
  */
@@ -26,7 +26,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
26
26
  return fabric.util.animate({
27
27
  target: this,
28
28
  startValue: object.left,
29
- endValue: this.getCenter().left,
29
+ endValue: this.getCenterPoint().x,
30
30
  duration: this.FX_DURATION,
31
31
  onChange: function(value) {
32
32
  object.set('left', value);
@@ -59,7 +59,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
59
59
  return fabric.util.animate({
60
60
  target: this,
61
61
  startValue: object.top,
62
- endValue: this.getCenter().top,
62
+ endValue: this.getCenterPoint().y,
63
63
  duration: this.FX_DURATION,
64
64
  onChange: function(value) {
65
65
  object.set('top', value);
@@ -152,14 +152,6 @@
152
152
  _target && target.fire('mouseout', { e: e });
153
153
  });
154
154
  this._hoveredTargets = [];
155
-
156
- if (this._iTextInstances) {
157
- this._iTextInstances.forEach(function(obj) {
158
- if (obj.isEditing) {
159
- obj.hiddenTextarea.focus();
160
- }
161
- });
162
- }
163
155
  },
164
156
 
165
157
  /**
@@ -12,6 +12,10 @@
12
12
  var _getSvgCommons = fabric.Object.prototype.getSvgCommons;
13
13
  var __createBaseClipPathSVGMarkup = fabric.Object.prototype._createBaseClipPathSVGMarkup;
14
14
  var __createBaseSVGMarkup = fabric.Object.prototype._createBaseSVGMarkup;
15
+
16
+ fabric.Object.prototype.cacheProperties.push('eraser');
17
+ fabric.Object.prototype.stateProperties.push('eraser');
18
+
15
19
  /**
16
20
  * @fires erasing:end
17
21
  */
@@ -142,7 +142,7 @@
142
142
  // if we have charSpacing, we render char by char
143
143
  actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);
144
144
  nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);
145
- timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle);
145
+ timeToRender = fabric.util.hasStyleChanged(actualStyle, nextStyle, true);
146
146
  }
147
147
  if (timeToRender) {
148
148
  style = this._getStyleDeclaration(lineIndex, i) || { };
@@ -386,6 +386,9 @@
386
386
  return;
387
387
  }
388
388
 
389
+ // regain focus
390
+ document.activeElement !== this.hiddenTextarea && this.hiddenTextarea.focus();
391
+
389
392
  var newSelectionStart = this.getSelectionStartFromPointer(options.e),
390
393
  currentStart = this.selectionStart,
391
394
  currentEnd = this.selectionEnd;
@@ -520,7 +520,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
520
520
  this[prop] += direction === 'Left' ? -1 : 1;
521
521
  return true;
522
522
  }
523
- if (typeof newValue !== undefined && this[prop] !== newValue) {
523
+ if (typeof newValue !== 'undefined' && this[prop] !== newValue) {
524
524
  this[prop] = newValue;
525
525
  return true;
526
526
  }
package/src/parser.js CHANGED
@@ -78,8 +78,7 @@
78
78
  }
79
79
 
80
80
  function normalizeValue(attr, value, parentAttributes, fontSize) {
81
- var isArray = Object.prototype.toString.call(value) === '[object Array]',
82
- parsed;
81
+ var isArray = Array.isArray(value), parsed;
83
82
 
84
83
  if ((attr === 'fill' || attr === 'stroke') && value === 'none') {
85
84
  value = '';
@@ -477,7 +476,7 @@
477
476
  return;
478
477
  }
479
478
 
480
- var xlink = xlinkAttribute.substr(1),
479
+ var xlink = xlinkAttribute.slice(1),
481
480
  x = el.getAttribute('x') || 0,
482
481
  y = el.getAttribute('y') || 0,
483
482
  el2 = elementById(doc, xlink).cloneNode(true),
@@ -749,7 +748,7 @@
749
748
  function recursivelyParseGradientsXlink(doc, gradient) {
750
749
  var gradientsAttrs = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy'],
751
750
  xlinkAttr = 'xlink:href',
752
- xLink = gradient.getAttribute(xlinkAttr).substr(1),
751
+ xLink = gradient.getAttribute(xlinkAttr).slice(1),
753
752
  referencedGradient = elementById(doc, xLink);
754
753
  if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {
755
754
  recursivelyParseGradientsXlink(doc, referencedGradient);
@@ -569,18 +569,25 @@
569
569
  // it has to be an url or something went wrong.
570
570
  fabric.loadSVGFromURL(objects, function (elements) {
571
571
  var group = fabric.util.groupSVGElements(elements, object, objects);
572
+ var clipPath = options.clipPath;
573
+ delete options.clipPath;
572
574
  group.set(options);
573
- callback && callback(group);
575
+ if (clipPath) {
576
+ fabric.util.enlivenObjects([clipPath], function(elivenedObjects) {
577
+ group.clipPath = elivenedObjects[0];
578
+ callback && callback(group);
579
+ });
580
+ }
581
+ else {
582
+ callback && callback(group);
583
+ }
574
584
  });
575
585
  return;
576
586
  }
577
587
  fabric.util.enlivenObjects(objects, function (enlivenedObjects) {
578
- var options = fabric.util.object.clone(object, true);
579
- delete options.objects;
580
588
  fabric.util.enlivenObjectEnlivables(object, options, function () {
581
589
  callback && callback(new fabric.Group(enlivenedObjects, options, true));
582
590
  });
583
591
  });
584
592
  };
585
-
586
593
  })(typeof exports !== 'undefined' ? exports : this);
@@ -510,14 +510,17 @@
510
510
  * @param {function} [callback] invoked with new instance as argument
511
511
  */
512
512
  fabric.IText.fromObject = function(object, callback) {
513
- parseDecoration(object);
514
- if (object.styles) {
515
- for (var i in object.styles) {
516
- for (var j in object.styles[i]) {
517
- parseDecoration(object.styles[i][j]);
513
+ var styles = fabric.util.stylesFromArray(object.styles, object.text);
514
+ //copy object to prevent mutation
515
+ var objCopy = Object.assign({}, object, { styles: styles });
516
+ parseDecoration(objCopy);
517
+ if (objCopy.styles) {
518
+ for (var i in objCopy.styles) {
519
+ for (var j in objCopy.styles[i]) {
520
+ parseDecoration(objCopy.styles[i][j]);
518
521
  }
519
522
  }
520
523
  }
521
- fabric.Object._fromObject('IText', object, callback, 'text');
524
+ fabric.Object._fromObject('IText', objCopy, callback, 'text');
522
525
  };
523
526
  })();
@@ -912,11 +912,9 @@
912
912
  if (object[prop] === prototype[prop]) {
913
913
  delete object[prop];
914
914
  }
915
- var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' &&
916
- Object.prototype.toString.call(prototype[prop]) === '[object Array]';
917
-
918
915
  // basically a check for [] === []
919
- if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {
916
+ if (Array.isArray(object[prop]) && Array.isArray(prototype[prop])
917
+ && object[prop].length === 0 && prototype[prop].length === 0) {
920
918
  delete object[prop];
921
919
  }
922
920
  });
@@ -1092,7 +1090,7 @@
1092
1090
 
1093
1091
  renderCache: function(options) {
1094
1092
  options = options || {};
1095
- if (!this._cacheCanvas) {
1093
+ if (!this._cacheCanvas || !this._cacheContext) {
1096
1094
  this._createCacheCanvas();
1097
1095
  }
1098
1096
  if (this.isCacheDirty()) {
@@ -1107,6 +1105,7 @@
1107
1105
  */
1108
1106
  _removeCacheCanvas: function() {
1109
1107
  this._cacheCanvas = null;
1108
+ this._cacheContext = null;
1110
1109
  this.cacheWidth = 0;
1111
1110
  this.cacheHeight = 0;
1112
1111
  },
@@ -1265,7 +1264,7 @@
1265
1264
  if (this.isNotVisible()) {
1266
1265
  return false;
1267
1266
  }
1268
- if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) {
1267
+ if (this._cacheCanvas && this._cacheContext && !skipCanvas && this._updateCacheCanvas()) {
1269
1268
  // in this case the context is already cleared.
1270
1269
  return true;
1271
1270
  }
@@ -1274,7 +1273,7 @@
1274
1273
  (this.clipPath && this.clipPath.absolutePositioned) ||
1275
1274
  (this.statefullCache && this.hasStateChanged('cacheProperties'))
1276
1275
  ) {
1277
- if (this._cacheCanvas && !skipCanvas) {
1276
+ if (this._cacheCanvas && this._cacheContext && !skipCanvas) {
1278
1277
  var width = this.cacheWidth / this.zoomX;
1279
1278
  var height = this.cacheHeight / this.zoomY;
1280
1279
  this._cacheContext.clearRect(-width / 2, -height / 2, width, height);
@@ -1808,7 +1807,7 @@
1808
1807
  * @return {Boolean}
1809
1808
  */
1810
1809
  isType: function(type) {
1811
- return this.type === type;
1810
+ return arguments.length > 1 ? Array.from(arguments).includes(this.type) : this.type === type;
1812
1811
  },
1813
1812
 
1814
1813
  /**
@@ -7,7 +7,6 @@
7
7
  max = fabric.util.array.max,
8
8
  extend = fabric.util.object.extend,
9
9
  clone = fabric.util.object.clone,
10
- _toString = Object.prototype.toString,
11
10
  toFixed = fabric.util.toFixed;
12
11
 
13
12
  if (fabric.Path) {
@@ -61,10 +60,8 @@
61
60
  * @param {Object} [options] Options object
62
61
  */
63
62
  _setPath: function (path, options) {
64
- var fromArray = _toString.call(path) === '[object Array]';
65
-
66
63
  this.path = fabric.util.makePathSimpler(
67
- fromArray ? path : fabric.util.parsePath(path)
64
+ Array.isArray(path) ? path : fabric.util.parsePath(path)
68
65
  );
69
66
 
70
67
  fabric.Polyline.prototype._setPositionDimensions.call(this, options || {});
@@ -343,7 +340,15 @@
343
340
  fabric.loadSVGFromURL(pathUrl, function (elements) {
344
341
  var path = elements[0];
345
342
  path.setOptions(object);
346
- callback && callback(path);
343
+ if (object.clipPath) {
344
+ fabric.util.enlivenObjects([object.clipPath], function(elivenedObjects) {
345
+ path.clipPath = elivenedObjects[0];
346
+ callback && callback(path);
347
+ });
348
+ }
349
+ else {
350
+ callback && callback(path);
351
+ }
347
352
  });
348
353
  }
349
354
  else {
@@ -1079,7 +1079,7 @@
1079
1079
  // if we have charSpacing, we render char by char
1080
1080
  actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);
1081
1081
  nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);
1082
- timeToRender = this._hasStyleChanged(actualStyle, nextStyle);
1082
+ timeToRender = fabric.util.hasStyleChanged(actualStyle, nextStyle, false);
1083
1083
  }
1084
1084
  if (timeToRender) {
1085
1085
  if (path) {
@@ -1249,34 +1249,6 @@
1249
1249
  return this;
1250
1250
  },
1251
1251
 
1252
- /**
1253
- * @private
1254
- * @param {Object} prevStyle
1255
- * @param {Object} thisStyle
1256
- */
1257
- _hasStyleChanged: function(prevStyle, thisStyle) {
1258
- return prevStyle.fill !== thisStyle.fill ||
1259
- prevStyle.stroke !== thisStyle.stroke ||
1260
- prevStyle.strokeWidth !== thisStyle.strokeWidth ||
1261
- prevStyle.fontSize !== thisStyle.fontSize ||
1262
- prevStyle.fontFamily !== thisStyle.fontFamily ||
1263
- prevStyle.fontWeight !== thisStyle.fontWeight ||
1264
- prevStyle.fontStyle !== thisStyle.fontStyle ||
1265
- prevStyle.deltaY !== thisStyle.deltaY;
1266
- },
1267
-
1268
- /**
1269
- * @private
1270
- * @param {Object} prevStyle
1271
- * @param {Object} thisStyle
1272
- */
1273
- _hasStyleChangedForSvg: function(prevStyle, thisStyle) {
1274
- return this._hasStyleChanged(prevStyle, thisStyle) ||
1275
- prevStyle.overline !== thisStyle.overline ||
1276
- prevStyle.underline !== thisStyle.underline ||
1277
- prevStyle.linethrough !== thisStyle.linethrough;
1278
- },
1279
-
1280
1252
  /**
1281
1253
  * @private
1282
1254
  * @param {Number} lineIndex index text line
@@ -1538,8 +1510,7 @@
1538
1510
  toObject: function(propertiesToInclude) {
1539
1511
  var allProperties = additionalProps.concat(propertiesToInclude);
1540
1512
  var obj = this.callSuper('toObject', allProperties);
1541
- // styles will be overridden with a properly cloned structure
1542
- obj.styles = clone(this.styles, true);
1513
+ obj.styles = fabric.util.stylesToArray(this.styles, this.text);
1543
1514
  if (obj.path) {
1544
1515
  obj.path = this.path.toObject();
1545
1516
  }
@@ -1705,6 +1676,7 @@
1705
1676
  var objectCopy = clone(object), path = object.path;
1706
1677
  delete objectCopy.path;
1707
1678
  return fabric.Object._fromObject('Text', objectCopy, function(textInstance) {
1679
+ textInstance.styles = fabric.util.stylesFromArray(object.styles, object.text);
1708
1680
  if (path) {
1709
1681
  fabric.Object._fromObject('Path', path, function(pathInstance) {
1710
1682
  textInstance.set('path', pathInstance);
@@ -453,6 +453,9 @@
453
453
  * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created
454
454
  */
455
455
  fabric.Textbox.fromObject = function(object, callback) {
456
- return fabric.Object._fromObject('Textbox', object, callback, 'text');
456
+ var styles = fabric.util.stylesFromArray(object.styles, object.text);
457
+ //copy object to prevent mutation
458
+ var objCopy = Object.assign({}, object, { styles: styles });
459
+ return fabric.Object._fromObject('Textbox', objCopy, callback, 'text');
457
460
  };
458
461
  })(typeof exports !== 'undefined' ? exports : this);
@@ -1027,6 +1027,7 @@
1027
1027
  * Returns coordinates of a center of canvas.
1028
1028
  * Returned value is an object with top and left properties
1029
1029
  * @return {Object} object with "top" and "left" number values
1030
+ * @deprecated migrate to `getCenterPoint`
1030
1031
  */
1031
1032
  getCenter: function () {
1032
1033
  return {
@@ -1035,13 +1036,21 @@
1035
1036
  };
1036
1037
  },
1037
1038
 
1039
+ /**
1040
+ * Returns coordinates of a center of canvas.
1041
+ * @return {fabric.Point}
1042
+ */
1043
+ getCenterPoint: function () {
1044
+ return new fabric.Point(this.width / 2, this.height / 2);
1045
+ },
1046
+
1038
1047
  /**
1039
1048
  * Centers object horizontally in the canvas
1040
1049
  * @param {fabric.Object} object Object to center horizontally
1041
1050
  * @return {fabric.Canvas} thisArg
1042
1051
  */
1043
1052
  centerObjectH: function (object) {
1044
- return this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y));
1053
+ return this._centerObject(object, new fabric.Point(this.getCenterPoint().x, object.getCenterPoint().y));
1045
1054
  },
1046
1055
 
1047
1056
  /**
@@ -1051,7 +1060,7 @@
1051
1060
  * @chainable
1052
1061
  */
1053
1062
  centerObjectV: function (object) {
1054
- return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top));
1063
+ return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenterPoint().y));
1055
1064
  },
1056
1065
 
1057
1066
  /**
@@ -1061,9 +1070,8 @@
1061
1070
  * @chainable
1062
1071
  */
1063
1072
  centerObject: function(object) {
1064
- var center = this.getCenter();
1065
-
1066
- return this._centerObject(object, new fabric.Point(center.left, center.top));
1073
+ var center = this.getCenterPoint();
1074
+ return this._centerObject(object, center);
1067
1075
  },
1068
1076
 
1069
1077
  /**
@@ -1074,7 +1082,6 @@
1074
1082
  */
1075
1083
  viewportCenterObject: function(object) {
1076
1084
  var vpCenter = this.getVpCenter();
1077
-
1078
1085
  return this._centerObject(object, vpCenter);
1079
1086
  },
1080
1087
 
@@ -1108,9 +1115,9 @@
1108
1115
  * @chainable
1109
1116
  */
1110
1117
  getVpCenter: function() {
1111
- var center = this.getCenter(),
1118
+ var center = this.getCenterPoint(),
1112
1119
  iVpt = invertTransform(this.viewportTransform);
1113
- return transformPoint({ x: center.left, y: center.top }, iVpt);
1120
+ return transformPoint(center, iVpt);
1114
1121
  },
1115
1122
 
1116
1123
  /**
@@ -26,7 +26,7 @@
26
26
  var normalizedProperty = (property === 'float' || property === 'cssFloat')
27
27
  ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat')
28
28
  : property;
29
- elementStyle[normalizedProperty] = styles[property];
29
+ elementStyle.setProperty(normalizedProperty, styles[property]);
30
30
  }
31
31
  }
32
32
  return element;