Comparing version 4.0.0 to 4.1.0-browser
@@ -129,3 +129,3 @@ var fs = require('fs'), | ||
ifSpecifiedInclude('accessors', 'src/util/named_accessors.mixin.js'), | ||
'src/util/arc.js', | ||
'src/util/path.js', | ||
'src/util/lang_array.js', | ||
@@ -132,0 +132,0 @@ 'src/util/lang_object.js', |
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ | ||
var fabric = fabric || { version: '4.0.0' }; | ||
var fabric = fabric || { version: '4.1.0' }; | ||
if (typeof exports !== 'undefined') { | ||
@@ -5,0 +5,0 @@ exports.fabric = fabric; |
161
package.json
{ | ||
"name": "fabric", | ||
"description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.", | ||
"homepage": "http://fabricjs.com/", | ||
"version": "4.0.0", | ||
"author": "Juriy Zaytsev <kangax@gmail.com>", | ||
"contributors": [ | ||
{ | ||
"name": "Andrea Bogazzi", | ||
"email": "andreabogazzi79@gmail.com" | ||
} | ||
], | ||
"keywords": [ | ||
"canvas", | ||
"graphic", | ||
"graphics", | ||
"SVG", | ||
"node-canvas", | ||
"parser", | ||
"HTML5", | ||
"object model" | ||
], | ||
"browser": { | ||
"canvas": false, | ||
"fs": false, | ||
"jsdom": false, | ||
"jsdom/lib/jsdom/living/generated/utils": false, | ||
"jsdom/lib/jsdom/utils": false, | ||
"http": false, | ||
"https": false, | ||
"xmldom": false, | ||
"url": false | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/fabricjs/fabric.js" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/fabricjs/fabric.js/issues" | ||
}, | ||
"license": "MIT", | ||
"scripts": { | ||
"build": "node build.js modules=ALL requirejs exclude=gestures,accessors", | ||
"build:fast": "node build.js modules=ALL requirejs fast exclude=gestures,accessors", | ||
"build:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm run build_export", | ||
"link:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm link", | ||
"build_with_gestures": "node build.js modules=ALL exclude=accessors", | ||
"build_export": "npm run build:fast && npm run export_dist_to_site && npm run build_with_gestures && npm run export_gesture_to_site", | ||
"test:single": "qunit test/node_test_setup.js test/lib", | ||
"test": "nyc qunit test/node_test_setup.js test/lib test/unit", | ||
"test:visual": "qunit test/node_test_setup.js test/lib test/visual", | ||
"test:visual:single": "qunit test/node_test_setup.js test/lib", | ||
"test:all": "npm run test && npm run test:visual", | ||
"lint": "eslint --config .eslintrc.json src", | ||
"lint_tests": "eslint test/unit --config .eslintrc_tests && eslint test/visual --config .eslintrc_tests", | ||
"export_gesture_to_site": "cp dist/fabric.js ../fabricjs.com/lib/fabric_with_gestures.js", | ||
"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/", | ||
"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", | ||
"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", | ||
"testem": "testem .", | ||
"testem:visual": "testem --file testem-visual.json", | ||
"testem:ci": "testem ci" | ||
}, | ||
"optionalDependencies": { | ||
"canvas": "^2.6.1", | ||
"jsdom": "^15.2.1" | ||
}, | ||
"devDependencies": { | ||
"eslint": "4.18.x", | ||
"nyc": "13.3.x", | ||
"onchange": "^3.x.x", | ||
"qunit": "2.9.2", | ||
"testem": "^1.18.4", | ||
"uglify-js": "3.3.x", | ||
"pixelmatch": "^4.0.2", | ||
"chalk": "^2.4.1" | ||
}, | ||
"engines": { | ||
"node": ">=8.0.0" | ||
}, | ||
"main": "./dist/fabric.js", | ||
"dependencies": {} | ||
} | ||
"name": "fabric", | ||
"description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.", | ||
"homepage": "http://fabricjs.com/", | ||
"version": "4.1.0-browser", | ||
"author": "Juriy Zaytsev <kangax@gmail.com>", | ||
"contributors": [ | ||
{ | ||
"name": "Andrea Bogazzi", | ||
"email": "andreabogazzi79@gmail.com" | ||
} | ||
], | ||
"keywords": [ | ||
"canvas", | ||
"graphic", | ||
"graphics", | ||
"SVG", | ||
"node-canvas", | ||
"parser", | ||
"HTML5", | ||
"object model" | ||
], | ||
"browser": { | ||
"canvas": false, | ||
"fs": false, | ||
"jsdom": false, | ||
"jsdom/lib/jsdom/living/generated/utils": false, | ||
"jsdom/lib/jsdom/utils": false, | ||
"http": false, | ||
"https": false, | ||
"xmldom": false, | ||
"url": false | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/fabricjs/fabric.js" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/fabricjs/fabric.js/issues" | ||
}, | ||
"license": "MIT", | ||
"scripts": { | ||
"build": "node build.js modules=ALL requirejs exclude=gestures,accessors", | ||
"build:fast": "node build.js modules=ALL requirejs fast exclude=gestures,accessors", | ||
"build:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm run build_export", | ||
"link:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm link", | ||
"build_with_gestures": "node build.js modules=ALL exclude=accessors", | ||
"build_export": "npm run build:fast && npm run export_dist_to_site && npm run build_with_gestures && npm run export_gesture_to_site", | ||
"test:single": "qunit test/node_test_setup.js test/lib", | ||
"test": "nyc qunit test/node_test_setup.js test/lib test/unit", | ||
"test:visual": "qunit test/node_test_setup.js test/lib test/visual", | ||
"test:visual:single": "qunit test/node_test_setup.js test/lib", | ||
"test:all": "npm run test && npm run test:visual", | ||
"lint": "eslint --config .eslintrc.json src", | ||
"lint_tests": "eslint test/unit --config .eslintrc_tests && eslint test/visual --config .eslintrc_tests", | ||
"export_gesture_to_site": "cp dist/fabric.js ../fabricjs.com/lib/fabric_with_gestures.js", | ||
"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/", | ||
"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", | ||
"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", | ||
"testem": "testem .", | ||
"testem:visual": "testem --file testem-visual.json", | ||
"testem:ci": "testem ci" | ||
}, | ||
"optionalDependencies": {}, | ||
"devDependencies": { | ||
"eslint": "4.18.x", | ||
"nyc": "13.3.x", | ||
"onchange": "^3.x.x", | ||
"qunit": "2.9.2", | ||
"testem": "^1.18.4", | ||
"uglify-js": "3.3.x", | ||
"pixelmatch": "^4.0.2", | ||
"chalk": "^2.4.1" | ||
}, | ||
"engines": { | ||
"node": ">=8.0.0" | ||
}, | ||
"main": "./dist/fabric.js", | ||
"dependencies": {} | ||
} |
@@ -13,3 +13,4 @@ var cp = require('child_process'); | ||
// allow publishing of pre-releases with beta tag | ||
if (preRelease) { | ||
if (preRelease === 'true') { | ||
console.log('Adding beta tag to NPM publish'); | ||
args = '--tag beta ' + args; | ||
@@ -27,2 +28,4 @@ } | ||
console.log('npm publish ' + args); | ||
// publish -browser version | ||
@@ -29,0 +32,0 @@ cp.execSync('npm publish ' + args); |
@@ -110,2 +110,3 @@ /** | ||
this.canvas.fire('before:path:created', { path: group }); | ||
this.canvas.add(group); | ||
@@ -112,0 +113,0 @@ this.canvas.fire('path:created', { path: group }); |
@@ -282,2 +282,3 @@ (function() { | ||
this.canvas.clearContext(this.canvas.contextTop); | ||
this.canvas.fire('before:path:created', { path: path }); | ||
this.canvas.add(path); | ||
@@ -284,0 +285,0 @@ this.canvas.requestRenderAll(); |
@@ -114,2 +114,3 @@ /** | ||
this.shadow && group.set('shadow', new fabric.Shadow(this.shadow)); | ||
this.canvas.fire('before:path:created', { path: group }); | ||
this.canvas.add(group); | ||
@@ -116,0 +117,0 @@ this.canvas.fire('path:created', { path: group }); |
@@ -453,25 +453,2 @@ (function() { | ||
/** | ||
* Checks if point is contained within an area of given object | ||
* @param {Event} e Event object | ||
* @param {fabric.Object} target Object to test against | ||
* @param {Object} [point] x,y object of point coordinates we want to check. | ||
* @return {Boolean} true if point is contained within an area of given object | ||
*/ | ||
containsPoint: function (e, target, point) { | ||
var ignoreZoom = true, | ||
pointer = point || this.getPointer(e, ignoreZoom), | ||
xy, isTouch = e ? isTouchEvent(e) : false; | ||
if (target.group && target.group === this._activeObject && target.group.type === 'activeSelection') { | ||
xy = this._normalizePointer(target.group, pointer); | ||
} | ||
else { | ||
xy = { x: pointer.x, y: pointer.y }; | ||
} | ||
// http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html | ||
// http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html | ||
return (target.containsPoint(xy) || !!target._findTargetCorner(pointer, isTouch)); | ||
}, | ||
/** | ||
* @private | ||
@@ -588,2 +565,3 @@ */ | ||
* @param {String} action | ||
* @param {Boolean} altKey | ||
*/ | ||
@@ -597,3 +575,3 @@ _shouldCenterTransform: function (target, action, altKey) { | ||
if (action === 'scale' || action === 'scaleX' || action === 'scaleY') { | ||
if (action === 'scale' || action === 'scaleX' || action === 'scaleY' || action === 'resizing') { | ||
centerTransform = this.centeredScaling || target.centeredScaling; | ||
@@ -855,3 +833,6 @@ } | ||
obj.evented && | ||
this.containsPoint(null, obj, pointer)) { | ||
// http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html | ||
// http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html | ||
(obj.containsPoint(pointer) || !!obj._findTargetCorner(pointer)) | ||
) { | ||
if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) { | ||
@@ -883,3 +864,3 @@ var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y); | ||
var objToCheck = objects[i]; | ||
var pointerToUse = objToCheck.group && objToCheck.group.type !== 'activeSelection' ? | ||
var pointerToUse = objToCheck.group ? | ||
this._normalizePointer(objToCheck.group, pointer) : pointer; | ||
@@ -886,0 +867,0 @@ if (this._checkTarget(pointerToUse, objToCheck, pointer)) { |
@@ -15,2 +15,3 @@ (function(global) { | ||
right: LEFT, | ||
center: CENTER, | ||
}, radiansToDegrees = fabric.util.radiansToDegrees, | ||
@@ -53,2 +54,11 @@ sign = (Math.sign || function(x) { return ((x > 0) - (x < 0)) || +x; }); | ||
/** | ||
* Checks if transform is centered | ||
* @param {Object} transform transform data | ||
* @return {Boolean} true if transform is centered | ||
*/ | ||
function isTransformCentered(transform) { | ||
return transform.originX === CENTER && transform.originY === CENTER; | ||
} | ||
/** | ||
* Inspect fabricObject to understand if the current scaling action is allowed | ||
@@ -519,4 +529,9 @@ * @param {fabric.Object} fabricObject the fabric object about to scale | ||
newPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y); | ||
signX = sign(newPoint.x); | ||
signY = sign(newPoint.y); | ||
// use of sign: We use sign to detect change of direction of an action. sign usually change when | ||
// we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling | ||
// by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily | ||
// cross many time the origin point and flip the object. so we need a way to filter out the noise. | ||
// This ternary here should be ok to filter out X scaling when we want Y only and vice versa. | ||
signX = by !== 'y' ? sign(newPoint.x) : 1; | ||
signY = by !== 'x' ? sign(newPoint.y) : 1; | ||
if (!transform.signX) { | ||
@@ -552,7 +567,7 @@ transform.signX = signX; | ||
// if we are scaling by center, we need to double the scale | ||
if (transform.originX === CENTER && transform.originY === CENTER) { | ||
if (isTransformCentered(transform)) { | ||
scaleX *= 2; | ||
scaleY *= 2; | ||
} | ||
if (transform.signX !== signX) { | ||
if (transform.signX !== signX && by !== 'y') { | ||
transform.originX = opposite[transform.originX]; | ||
@@ -562,3 +577,3 @@ scaleX *= -1; | ||
} | ||
if (transform.signY !== signY) { | ||
if (transform.signY !== signY && by !== 'x') { | ||
transform.originY = opposite[transform.originY]; | ||
@@ -672,3 +687,4 @@ scaleY *= -1; | ||
strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1), | ||
newWidth = Math.abs(localPoint.x / target.scaleX) - strokePadding; | ||
multiplier = isTransformCentered(transform) ? 2 : 1, | ||
newWidth = Math.abs(localPoint.x * multiplier / target.scaleX) - strokePadding; | ||
target.set('width', Math.max(newWidth, 0)); | ||
@@ -675,0 +691,0 @@ return true; |
@@ -528,3 +528,5 @@ (function() { | ||
this.aCoords = this.calcACoords(); | ||
this.lineCoords = this.calcLineCoords(); | ||
// in case we are in a group, for how the inner group target check works, | ||
// lineCoords are exactly aCoords. Since the vpt gets absorbed by the normalized pointer. | ||
this.lineCoords = this.group ? this.aCoords : this.calcLineCoords(); | ||
if (skipCorners) { | ||
@@ -531,0 +533,0 @@ return this; |
@@ -107,3 +107,2 @@ (function(global) { | ||
* @private | ||
* @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change | ||
*/ | ||
@@ -402,4 +401,4 @@ _updateObjectsACoords: function() { | ||
this.realizeTransform(object); | ||
delete object.group; | ||
object.setCoords(); | ||
delete object.group; | ||
return this; | ||
@@ -406,0 +405,0 @@ }, |
@@ -542,10 +542,18 @@ (function(global) { | ||
} | ||
var w = this.width, h = this.height, | ||
sW = Math.min(elementToDraw.naturalWidth || elementToDraw.width, w * this._filterScalingX), | ||
sH = Math.min(elementToDraw.naturalHeight || elementToDraw.height, h * this._filterScalingY), | ||
var scaleX = this._filterScalingX, scaleY = this._filterScalingY, | ||
w = this.width, h = this.height, min = Math.min, max = Math.max, | ||
// crop values cannot be lesser than 0. | ||
cropX = max(this.cropX, 0), cropY = max(this.cropY, 0), | ||
elWidth = elementToDraw.naturalWidth || elementToDraw.width, | ||
elHeight = elementToDraw.naturalHeight || elementToDraw.height, | ||
sX = cropX * scaleX, | ||
sY = cropY * scaleY, | ||
// the width height cannot exceed element width/height, starting from the crop offset. | ||
sW = min(w * scaleX, elWidth - sX), | ||
sH = min(h * scaleY, elHeight - sY), | ||
x = -w / 2, y = -h / 2, | ||
sX = Math.max(0, this.cropX * this._filterScalingX), | ||
sY = Math.max(0, this.cropY * this._filterScalingY); | ||
maxDestW = min(w, elWidth / scaleX - cropX), | ||
maxDestH = min(h, elHeight / scaleX - cropY); | ||
elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, w, h); | ||
elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH); | ||
}, | ||
@@ -552,0 +560,0 @@ |
@@ -10,19 +10,3 @@ (function(global) { | ||
_toString = Object.prototype.toString, | ||
drawArc = fabric.util.drawArc, | ||
toFixed = fabric.util.toFixed, | ||
commandLengths = { | ||
m: 2, | ||
l: 2, | ||
h: 1, | ||
v: 1, | ||
c: 6, | ||
s: 4, | ||
q: 4, | ||
t: 2, | ||
a: 7 | ||
}, | ||
repeatedCommands = { | ||
m: 'l', | ||
M: 'L' | ||
}; | ||
toFixed = fabric.util.toFixed; | ||
@@ -70,3 +54,2 @@ if (fabric.Path) { | ||
this.callSuper('initialize', options); | ||
if (!path) { | ||
@@ -79,14 +62,11 @@ path = []; | ||
this.path = fromArray | ||
? path | ||
// one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values) | ||
: path.match && path.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi); | ||
? fabric.util.makePathSimpler(path) | ||
: fabric.util.makePathSimpler( | ||
fabric.util.parsePath(path) | ||
); | ||
if (!this.path) { | ||
return; | ||
} | ||
if (!fromArray) { | ||
this.path = this._parsePath(); | ||
} | ||
fabric.Polyline.prototype._setPositionDimensions.call(this, options); | ||
@@ -101,3 +81,2 @@ }, | ||
var current, // current instruction | ||
previous = null, | ||
subpathStartX = 0, | ||
@@ -109,4 +88,2 @@ subpathStartY = 0, | ||
controlY = 0, // current control point y | ||
tempX, | ||
tempY, | ||
l = -this.pathOffset.x, | ||
@@ -123,8 +100,2 @@ t = -this.pathOffset.y; | ||
case 'l': // lineto, relative | ||
x += current[1]; | ||
y += current[2]; | ||
ctx.lineTo(x + l, y + t); | ||
break; | ||
case 'L': // lineto, absolute | ||
@@ -136,30 +107,2 @@ x = current[1]; | ||
case 'h': // horizontal lineto, relative | ||
x += current[1]; | ||
ctx.lineTo(x + l, y + t); | ||
break; | ||
case 'H': // horizontal lineto, absolute | ||
x = current[1]; | ||
ctx.lineTo(x + l, y + t); | ||
break; | ||
case 'v': // vertical lineto, relative | ||
y += current[1]; | ||
ctx.lineTo(x + l, y + t); | ||
break; | ||
case 'V': // verical lineto, absolute | ||
y = current[1]; | ||
ctx.lineTo(x + l, y + t); | ||
break; | ||
case 'm': // moveTo, relative | ||
x += current[1]; | ||
y += current[2]; | ||
subpathStartX = x; | ||
subpathStartY = y; | ||
ctx.moveTo(x + l, y + t); | ||
break; | ||
case 'M': // moveTo, absolute | ||
@@ -173,19 +116,2 @@ x = current[1]; | ||
case 'c': // bezierCurveTo, relative | ||
tempX = x + current[5]; | ||
tempY = y + current[6]; | ||
controlX = x + current[3]; | ||
controlY = y + current[4]; | ||
ctx.bezierCurveTo( | ||
x + current[1] + l, // x1 | ||
y + current[2] + t, // y1 | ||
controlX + l, // x2 | ||
controlY + t, // y2 | ||
tempX + l, | ||
tempY + t | ||
); | ||
x = tempX; | ||
y = tempY; | ||
break; | ||
case 'C': // bezierCurveTo, absolute | ||
@@ -206,103 +132,11 @@ x = current[5]; | ||
case 's': // shorthand cubic bezierCurveTo, relative | ||
// transform to absolute x,y | ||
tempX = x + current[3]; | ||
tempY = y + current[4]; | ||
if (previous[0].match(/[CcSs]/) === null) { | ||
// If there is no previous command or if the previous command was not a C, c, S, or s, | ||
// the control point is coincident with the current point | ||
controlX = x; | ||
controlY = y; | ||
} | ||
else { | ||
// calculate reflection of previous control points | ||
controlX = 2 * x - controlX; | ||
controlY = 2 * y - controlY; | ||
} | ||
ctx.bezierCurveTo( | ||
controlX + l, | ||
controlY + t, | ||
x + current[1] + l, | ||
y + current[2] + t, | ||
tempX + l, | ||
tempY + t | ||
); | ||
// set control point to 2nd one of this command | ||
// "... the first control point is assumed to be | ||
// the reflection of the second control point on | ||
// the previous command relative to the current point." | ||
controlX = x + current[1]; | ||
controlY = y + current[2]; | ||
x = tempX; | ||
y = tempY; | ||
break; | ||
case 'S': // shorthand cubic bezierCurveTo, absolute | ||
tempX = current[3]; | ||
tempY = current[4]; | ||
if (previous[0].match(/[CcSs]/) === null) { | ||
// If there is no previous command or if the previous command was not a C, c, S, or s, | ||
// the control point is coincident with the current point | ||
controlX = x; | ||
controlY = y; | ||
} | ||
else { | ||
// calculate reflection of previous control points | ||
controlX = 2 * x - controlX; | ||
controlY = 2 * y - controlY; | ||
} | ||
ctx.bezierCurveTo( | ||
controlX + l, | ||
controlY + t, | ||
current[1] + l, | ||
current[2] + t, | ||
tempX + l, | ||
tempY + t | ||
); | ||
x = tempX; | ||
y = tempY; | ||
// set control point to 2nd one of this command | ||
// "... the first control point is assumed to be | ||
// the reflection of the second control point on | ||
// the previous command relative to the current point." | ||
controlX = current[1]; | ||
controlY = current[2]; | ||
break; | ||
case 'q': // quadraticCurveTo, relative | ||
// transform to absolute x,y | ||
tempX = x + current[3]; | ||
tempY = y + current[4]; | ||
controlX = x + current[1]; | ||
controlY = y + current[2]; | ||
ctx.quadraticCurveTo( | ||
controlX + l, | ||
controlY + t, | ||
tempX + l, | ||
tempY + t | ||
); | ||
x = tempX; | ||
y = tempY; | ||
break; | ||
case 'Q': // quadraticCurveTo, absolute | ||
tempX = current[3]; | ||
tempY = current[4]; | ||
ctx.quadraticCurveTo( | ||
current[1] + l, | ||
current[2] + t, | ||
tempX + l, | ||
tempY + t | ||
current[3] + l, | ||
current[4] + t | ||
); | ||
x = tempX; | ||
y = tempY; | ||
x = current[3]; | ||
y = current[4]; | ||
controlX = current[1]; | ||
@@ -312,86 +146,2 @@ controlY = current[2]; | ||
case 't': // shorthand quadraticCurveTo, relative | ||
// transform to absolute x,y | ||
tempX = x + current[1]; | ||
tempY = y + current[2]; | ||
if (previous[0].match(/[QqTt]/) === null) { | ||
// If there is no previous command or if the previous command was not a Q, q, T or t, | ||
// assume the control point is coincident with the current point | ||
controlX = x; | ||
controlY = y; | ||
} | ||
else { | ||
// calculate reflection of previous control point | ||
controlX = 2 * x - controlX; | ||
controlY = 2 * y - controlY; | ||
} | ||
ctx.quadraticCurveTo( | ||
controlX + l, | ||
controlY + t, | ||
tempX + l, | ||
tempY + t | ||
); | ||
x = tempX; | ||
y = tempY; | ||
break; | ||
case 'T': | ||
tempX = current[1]; | ||
tempY = current[2]; | ||
if (previous[0].match(/[QqTt]/) === null) { | ||
// If there is no previous command or if the previous command was not a Q, q, T or t, | ||
// assume the control point is coincident with the current point | ||
controlX = x; | ||
controlY = y; | ||
} | ||
else { | ||
// calculate reflection of previous control point | ||
controlX = 2 * x - controlX; | ||
controlY = 2 * y - controlY; | ||
} | ||
ctx.quadraticCurveTo( | ||
controlX + l, | ||
controlY + t, | ||
tempX + l, | ||
tempY + t | ||
); | ||
x = tempX; | ||
y = tempY; | ||
break; | ||
case 'a': | ||
// TODO: optimize this | ||
drawArc(ctx, x + l, y + t, [ | ||
current[1], | ||
current[2], | ||
current[3], | ||
current[4], | ||
current[5], | ||
current[6] + x + l, | ||
current[7] + y + t | ||
]); | ||
x += current[6]; | ||
y += current[7]; | ||
break; | ||
case 'A': | ||
// TODO: optimize this | ||
drawArc(ctx, x + l, y + t, [ | ||
current[1], | ||
current[2], | ||
current[3], | ||
current[4], | ||
current[5], | ||
current[6] + l, | ||
current[7] + t | ||
]); | ||
x = current[6]; | ||
y = current[7]; | ||
break; | ||
case 'z': | ||
@@ -404,3 +154,2 @@ case 'Z': | ||
} | ||
previous = current; | ||
} | ||
@@ -509,51 +258,2 @@ }, | ||
*/ | ||
_parsePath: function() { | ||
var result = [], | ||
coords = [], | ||
currentPath, | ||
parsed, | ||
re = fabric.rePathCommand, | ||
match, | ||
coordsStr; | ||
for (var i = 0, coordsParsed, len = this.path.length; i < len; i++) { | ||
currentPath = this.path[i]; | ||
coordsStr = currentPath.slice(1).trim(); | ||
coords.length = 0; | ||
while ((match = re.exec(coordsStr))) { | ||
coords.push(match[0]); | ||
} | ||
coordsParsed = [currentPath.charAt(0)]; | ||
for (var j = 0, jlen = coords.length; j < jlen; j++) { | ||
parsed = parseFloat(coords[j]); | ||
if (!isNaN(parsed)) { | ||
coordsParsed.push(parsed); | ||
} | ||
} | ||
var command = coordsParsed[0], | ||
commandLength = commandLengths[command.toLowerCase()], | ||
repeatedCommand = repeatedCommands[command] || command; | ||
if (coordsParsed.length - 1 > commandLength) { | ||
for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) { | ||
result.push([command].concat(coordsParsed.slice(k, k + commandLength))); | ||
command = repeatedCommand; | ||
} | ||
} | ||
else { | ||
result.push(coordsParsed); | ||
} | ||
} | ||
return result; | ||
}, | ||
/** | ||
* @private | ||
*/ | ||
_calcDimensions: function() { | ||
@@ -564,3 +264,2 @@ | ||
current, // current instruction | ||
previous = null, | ||
subpathStartX = 0, | ||
@@ -570,6 +269,2 @@ subpathStartY = 0, | ||
y = 0, // current y | ||
controlX = 0, // current control point x | ||
controlY = 0, // current control point y | ||
tempX, | ||
tempY, | ||
bounds; | ||
@@ -583,8 +278,2 @@ | ||
case 'l': // lineto, relative | ||
x += current[1]; | ||
y += current[2]; | ||
bounds = []; | ||
break; | ||
case 'L': // lineto, absolute | ||
@@ -596,30 +285,2 @@ x = current[1]; | ||
case 'h': // horizontal lineto, relative | ||
x += current[1]; | ||
bounds = []; | ||
break; | ||
case 'H': // horizontal lineto, absolute | ||
x = current[1]; | ||
bounds = []; | ||
break; | ||
case 'v': // vertical lineto, relative | ||
y += current[1]; | ||
bounds = []; | ||
break; | ||
case 'V': // verical lineto, absolute | ||
y = current[1]; | ||
bounds = []; | ||
break; | ||
case 'm': // moveTo, relative | ||
x += current[1]; | ||
y += current[2]; | ||
subpathStartX = x; | ||
subpathStartY = y; | ||
bounds = []; | ||
break; | ||
case 'M': // moveTo, absolute | ||
@@ -633,27 +294,8 @@ x = current[1]; | ||
case 'c': // bezierCurveTo, relative | ||
tempX = x + current[5]; | ||
tempY = y + current[6]; | ||
controlX = x + current[3]; | ||
controlY = y + current[4]; | ||
bounds = fabric.util.getBoundsOfCurve(x, y, | ||
x + current[1], // x1 | ||
y + current[2], // y1 | ||
controlX, // x2 | ||
controlY, // y2 | ||
tempX, | ||
tempY | ||
); | ||
x = tempX; | ||
y = tempY; | ||
break; | ||
case 'C': // bezierCurveTo, absolute | ||
controlX = current[3]; | ||
controlY = current[4]; | ||
bounds = fabric.util.getBoundsOfCurve(x, y, | ||
current[1], | ||
current[2], | ||
controlX, | ||
controlY, | ||
current[3], | ||
current[4], | ||
current[5], | ||
@@ -666,96 +308,8 @@ current[6] | ||
case 's': // shorthand cubic bezierCurveTo, relative | ||
// transform to absolute x,y | ||
tempX = x + current[3]; | ||
tempY = y + current[4]; | ||
if (previous[0].match(/[CcSs]/) === null) { | ||
// If there is no previous command or if the previous command was not a C, c, S, or s, | ||
// the control point is coincident with the current point | ||
controlX = x; | ||
controlY = y; | ||
} | ||
else { | ||
// calculate reflection of previous control points | ||
controlX = 2 * x - controlX; | ||
controlY = 2 * y - controlY; | ||
} | ||
case 'Q': // quadraticCurveTo, absolute | ||
bounds = fabric.util.getBoundsOfCurve(x, y, | ||
controlX, | ||
controlY, | ||
x + current[1], | ||
y + current[2], | ||
tempX, | ||
tempY | ||
); | ||
// set control point to 2nd one of this command | ||
// "... the first control point is assumed to be | ||
// the reflection of the second control point on | ||
// the previous command relative to the current point." | ||
controlX = x + current[1]; | ||
controlY = y + current[2]; | ||
x = tempX; | ||
y = tempY; | ||
break; | ||
case 'S': // shorthand cubic bezierCurveTo, absolute | ||
tempX = current[3]; | ||
tempY = current[4]; | ||
if (previous[0].match(/[CcSs]/) === null) { | ||
// If there is no previous command or if the previous command was not a C, c, S, or s, | ||
// the control point is coincident with the current point | ||
controlX = x; | ||
controlY = y; | ||
} | ||
else { | ||
// calculate reflection of previous control points | ||
controlX = 2 * x - controlX; | ||
controlY = 2 * y - controlY; | ||
} | ||
bounds = fabric.util.getBoundsOfCurve(x, y, | ||
controlX, | ||
controlY, | ||
current[1], | ||
current[2], | ||
tempX, | ||
tempY | ||
); | ||
x = tempX; | ||
y = tempY; | ||
// set control point to 2nd one of this command | ||
// "... the first control point is assumed to be | ||
// the reflection of the second control point on | ||
// the previous command relative to the current point." | ||
controlX = current[1]; | ||
controlY = current[2]; | ||
break; | ||
case 'q': // quadraticCurveTo, relative | ||
// transform to absolute x,y | ||
tempX = x + current[3]; | ||
tempY = y + current[4]; | ||
controlX = x + current[1]; | ||
controlY = y + current[2]; | ||
bounds = fabric.util.getBoundsOfCurve(x, y, | ||
controlX, | ||
controlY, | ||
controlX, | ||
controlY, | ||
tempX, | ||
tempY | ||
); | ||
x = tempX; | ||
y = tempY; | ||
break; | ||
case 'Q': // quadraticCurveTo, absolute | ||
controlX = current[1]; | ||
controlY = current[2]; | ||
bounds = fabric.util.getBoundsOfCurve(x, y, | ||
controlX, | ||
controlY, | ||
controlX, | ||
controlY, | ||
current[1], | ||
current[2], | ||
current[3], | ||
@@ -768,88 +322,2 @@ current[4] | ||
case 't': // shorthand quadraticCurveTo, relative | ||
// transform to absolute x,y | ||
tempX = x + current[1]; | ||
tempY = y + current[2]; | ||
if (previous[0].match(/[QqTt]/) === null) { | ||
// If there is no previous command or if the previous command was not a Q, q, T or t, | ||
// assume the control point is coincident with the current point | ||
controlX = x; | ||
controlY = y; | ||
} | ||
else { | ||
// calculate reflection of previous control point | ||
controlX = 2 * x - controlX; | ||
controlY = 2 * y - controlY; | ||
} | ||
bounds = fabric.util.getBoundsOfCurve(x, y, | ||
controlX, | ||
controlY, | ||
controlX, | ||
controlY, | ||
tempX, | ||
tempY | ||
); | ||
x = tempX; | ||
y = tempY; | ||
break; | ||
case 'T': | ||
tempX = current[1]; | ||
tempY = current[2]; | ||
if (previous[0].match(/[QqTt]/) === null) { | ||
// If there is no previous command or if the previous command was not a Q, q, T or t, | ||
// assume the control point is coincident with the current point | ||
controlX = x; | ||
controlY = y; | ||
} | ||
else { | ||
// calculate reflection of previous control point | ||
controlX = 2 * x - controlX; | ||
controlY = 2 * y - controlY; | ||
} | ||
bounds = fabric.util.getBoundsOfCurve(x, y, | ||
controlX, | ||
controlY, | ||
controlX, | ||
controlY, | ||
tempX, | ||
tempY | ||
); | ||
x = tempX; | ||
y = tempY; | ||
break; | ||
case 'a': | ||
// TODO: optimize this | ||
bounds = fabric.util.getBoundsOfArc(x, y, | ||
current[1], | ||
current[2], | ||
current[3], | ||
current[4], | ||
current[5], | ||
current[6] + x, | ||
current[7] + y | ||
); | ||
x += current[6]; | ||
y += current[7]; | ||
break; | ||
case 'A': | ||
// TODO: optimize this | ||
bounds = fabric.util.getBoundsOfArc(x, y, | ||
current[1], | ||
current[2], | ||
current[3], | ||
current[4], | ||
current[5], | ||
current[6], | ||
current[7] | ||
); | ||
x = current[6]; | ||
y = current[7]; | ||
break; | ||
case 'z': | ||
@@ -861,3 +329,2 @@ case 'Z': | ||
} | ||
previous = current; | ||
bounds.forEach(function (point) { | ||
@@ -864,0 +331,0 @@ aX.push(point.x); |
@@ -881,9 +881,8 @@ (function(global) { | ||
* @private | ||
* @param {String} method | ||
* @param {String} method fillText or strokeText. | ||
* @param {CanvasRenderingContext2D} ctx Context to render on | ||
* @param {String} line Content of the line | ||
* @param {Array} line Content of the line, splitted in an array by grapheme | ||
* @param {Number} left | ||
* @param {Number} top | ||
* @param {Number} lineIndex | ||
* @param {Number} charOffset | ||
*/ | ||
@@ -906,3 +905,3 @@ _renderChars: function(method, ctx, line, left, top, lineIndex) { | ||
// render all the line in one pass without checking | ||
this._renderChar(method, ctx, lineIndex, 0, this.textLines[lineIndex], left, top, lineHeight); | ||
this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top, lineHeight); | ||
ctx.restore(); | ||
@@ -909,0 +908,0 @@ return; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
0
2441038
57132
2