mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-04 03:45:58 -05:00
Merge branch 'develop'
This commit is contained in:
commit
48c8eacf0b
27 changed files with 1670 additions and 1429 deletions
|
@ -41,4 +41,4 @@ script:
|
||||||
- gulp minify
|
- gulp minify
|
||||||
- gulp test
|
- gulp test
|
||||||
- gulp zip
|
- gulp zip
|
||||||
- '[ "${TRAVIS_BRANCH}" = "develop" ] && [ "${TRAVIS_NODE_VERSION}" = "stable" ] && travis/deploy-prebuilt.sh'
|
- '[ "${TRAVIS_BRANCH}" = "develop" ] && [ "${TRAVIS_NODE_VERSION}" = "stable" ] && travis/deploy-prebuilt.sh || true'
|
||||||
|
|
16
README.md
16
README.md
|
@ -51,17 +51,17 @@ generally not recommended to install Node.js through OS-supplied package
|
||||||
managers, as the its development cycles move fast and these versions are often
|
managers, as the its development cycles move fast and these versions are often
|
||||||
out-of-date.
|
out-of-date.
|
||||||
|
|
||||||
|
On macOS, [Homebrew](http://brew.sh/) is a good option if one version of
|
||||||
|
Node.js that is kept up to date with `brew upgrade` is enough:
|
||||||
|
<http://treehouse.github.io/installation-guides/mac/node-mac.html>
|
||||||
|
|
||||||
[NVM](https://github.com/creationix/nvm) can be used instead to install and
|
[NVM](https://github.com/creationix/nvm) can be used instead to install and
|
||||||
maintain multiple versions of Node.js on the same platform, as often required by
|
maintain multiple versions of Node.js on the same platform, as often required by
|
||||||
different projects:
|
different projects:
|
||||||
<https://nodesource.com/blog/installing-node-js-tutorial-using-nvm-on-mac-os-x-and-ubuntu/>
|
<https://nodesource.com/blog/installing-node-js-tutorial-using-nvm-on-mac-os-x-and-ubuntu/>
|
||||||
|
|
||||||
on OSX, [Homebrew](http://brew.sh/) is also a good option if one version of
|
Homebrew is recommended on macOS also if you intend to install Paper.js with
|
||||||
Node.js that is kept up to date with `brew update` is enough:
|
rendering to the Canvas on Node.js, as described in the next paragraph.
|
||||||
<http://treehouse.github.io/installation-guides/mac/node-mac.html>
|
|
||||||
|
|
||||||
Homebrew is recommended on OSX also if you intend to install Paper.js for
|
|
||||||
Node.js, as described in the next paragraph.
|
|
||||||
|
|
||||||
For Linux, see <http://nodejs.org/download/> to locate 32-bit and 64-bit Node.js
|
For Linux, see <http://nodejs.org/download/> to locate 32-bit and 64-bit Node.js
|
||||||
binaries as well as sources, or use NVM, as described in the paragraph above.
|
binaries as well as sources, or use NVM, as described in the paragraph above.
|
||||||
|
@ -83,14 +83,14 @@ different one:
|
||||||
In order to install `paper-jsdom-canvas`, you need the [Cairo Graphics
|
In order to install `paper-jsdom-canvas`, you need the [Cairo Graphics
|
||||||
library](http://cairographics.org/) installed in your system:
|
library](http://cairographics.org/) installed in your system:
|
||||||
|
|
||||||
##### Installing Cairo and Pango on OSX:
|
##### Installing Cairo and Pango on macOS:
|
||||||
|
|
||||||
The easiest way to install Cairo is through [Homebrew](http://brew.sh/), by
|
The easiest way to install Cairo is through [Homebrew](http://brew.sh/), by
|
||||||
issuing the command:
|
issuing the command:
|
||||||
|
|
||||||
brew install cairo pango
|
brew install cairo pango
|
||||||
|
|
||||||
Note that currently there is an issue on OSX with Cairo. If the above causes
|
Note that currently there is an issue on macOS with Cairo. If the above causes
|
||||||
errors, the following will most likely fix it:
|
errors, the following will most likely fix it:
|
||||||
|
|
||||||
PKG_CONFIG_PATH=/opt/X11/lib/pkgconfig/ npm install paper
|
PKG_CONFIG_PATH=/opt/X11/lib/pkgconfig/ npm install paper
|
||||||
|
|
827
dist/paper-core.js
vendored
827
dist/paper-core.js
vendored
File diff suppressed because it is too large
Load diff
827
dist/paper-full.js
vendored
827
dist/paper-full.js
vendored
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,7 @@
|
||||||
var clones = 30;
|
var clones = 30;
|
||||||
var angle = 360 / clones;
|
var angle = 360 / clones;
|
||||||
|
|
||||||
for(var i = 0; i < clones; i++) {
|
for (var i = 0; i < clones; i++) {
|
||||||
var clonedPath = circlePath.clone();
|
var clonedPath = circlePath.clone();
|
||||||
clonedPath.rotate(angle * i, circlePath.bounds.topLeft);
|
clonedPath.rotate(angle * i, circlePath.bounds.topLeft);
|
||||||
};
|
};
|
||||||
|
|
|
@ -120,7 +120,7 @@
|
||||||
function getEqualizerBands(data) {
|
function getEqualizerBands(data) {
|
||||||
var bands = [];
|
var bands = [];
|
||||||
var amount = Math.sqrt(data.length) / 2;
|
var amount = Math.sqrt(data.length) / 2;
|
||||||
for(var i = 0; i < amount; i++) {
|
for (var i = 0; i < amount; i++) {
|
||||||
var start = Math.pow(2, i) - 1;
|
var start = Math.pow(2, i) - 1;
|
||||||
var end = start * 2 + 1;
|
var end = start * 2 + 1;
|
||||||
var sum = 0;
|
var sum = 0;
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
function removeSmallBits(path) {
|
function removeSmallBits(path) {
|
||||||
var averageLength = path.length / path.segments.length;
|
var averageLength = path.length / path.segments.length;
|
||||||
var min = path.length / 50;
|
var min = path.length / 50;
|
||||||
for(var i = path.segments.length - 1; i >= 0; i--) {
|
for (var i = path.segments.length - 1; i >= 0; i--) {
|
||||||
var segment = path.segments[i];
|
var segment = path.segments[i];
|
||||||
var cur = segment.point;
|
var cur = segment.point;
|
||||||
var nextSegment = segment.next;
|
var nextSegment = segment.next;
|
||||||
|
@ -69,8 +69,8 @@
|
||||||
function generateBeeHivePoints(size, loose) {
|
function generateBeeHivePoints(size, loose) {
|
||||||
var points = [];
|
var points = [];
|
||||||
var col = view.size / size;
|
var col = view.size / size;
|
||||||
for(var i = -1; i < size.width + 1; i++) {
|
for (var i = -1; i < size.width + 1; i++) {
|
||||||
for(var j = -1; j < size.height + 1; j++) {
|
for (var j = -1; j < size.height + 1; j++) {
|
||||||
var point = new Point(i, j) / new Point(size) * view.size + col / 2;
|
var point = new Point(i, j) / new Point(size) * view.size + col / 2;
|
||||||
if (j % 2)
|
if (j % 2)
|
||||||
point += new Point(col.width / 2, 0);
|
point += new Point(col.width / 2, 0);
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
var clones = 30;
|
var clones = 30;
|
||||||
var angle = 360 / clones;
|
var angle = 360 / clones;
|
||||||
|
|
||||||
for(var i = 0; i < clones; i++) {
|
for (var i = 0; i < clones; i++) {
|
||||||
var clonedPath = circlePath.clone();
|
var clonedPath = circlePath.clone();
|
||||||
clonedPath.rotate(angle * i, circlePath.bounds.topLeft);
|
clonedPath.rotate(angle * i, circlePath.bounds.topLeft);
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,13 +36,15 @@ gulp.task('publish', function() {
|
||||||
if (options.branch !== 'develop') {
|
if (options.branch !== 'develop') {
|
||||||
throw new Error('Publishing is only allowed on the develop branch.');
|
throw new Error('Publishing is only allowed on the develop branch.');
|
||||||
}
|
}
|
||||||
|
// publish:website comes before publish:release, so paperjs.zip file is gone
|
||||||
|
// before npm publish:
|
||||||
return run(
|
return run(
|
||||||
'publish:json',
|
'publish:json',
|
||||||
'publish:dist',
|
'publish:dist',
|
||||||
'publish:packages',
|
'publish:packages',
|
||||||
'publish:commit',
|
'publish:commit',
|
||||||
'publish:release',
|
|
||||||
'publish:website',
|
'publish:website',
|
||||||
|
'publish:release',
|
||||||
'publish:load'
|
'publish:load'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -115,8 +117,18 @@ gulp.task('publish:website', function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('publish:website:build',
|
gulp.task('publish:website:build', [
|
||||||
['publish:website:docs', 'publish:website:zip', 'publish:website:lib']);
|
'publish:website:json', 'publish:website:docs',
|
||||||
|
'publish:website:zip', 'publish:website:assets'
|
||||||
|
]);
|
||||||
|
|
||||||
|
gulp.task('publish:website:json', ['publish:version'], function() {
|
||||||
|
return gulp.src([sitePath + '/package.json'])
|
||||||
|
.pipe(jsonEditor({
|
||||||
|
version: options.version
|
||||||
|
}, jsonOptions))
|
||||||
|
.pipe(gulp.dest(sitePath));
|
||||||
|
});
|
||||||
|
|
||||||
gulp.task('publish:website:docs:clean', function() {
|
gulp.task('publish:website:docs:clean', function() {
|
||||||
return del([ referencePath + '/*' ], { force: true });
|
return del([ referencePath + '/*' ], { force: true });
|
||||||
|
@ -135,7 +147,10 @@ gulp.task('publish:website:zip', ['publish:version'], function() {
|
||||||
.pipe(gulp.dest(downloadPath));
|
.pipe(gulp.dest(downloadPath));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('publish:website:lib', ['publish:version'], function() {
|
gulp.task('publish:website:assets', function() {
|
||||||
|
// Always delete the old asset first, in case it's a symlink which Gulp
|
||||||
|
// doesn't handle well.
|
||||||
|
fs.unlinkSync(assetPath + '/paper.js');
|
||||||
return gulp.src('dist/paper-full.js')
|
return gulp.src('dist/paper-full.js')
|
||||||
.pipe(rename({ basename: 'paper' }))
|
.pipe(rename({ basename: 'paper' }))
|
||||||
.pipe(gulp.dest(assetPath));
|
.pipe(gulp.dest(assetPath));
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "paper",
|
"name": "paper",
|
||||||
"version": "0.11.2",
|
"version": "0.11.3",
|
||||||
"description": "The Swiss Army Knife of Vector Graphics Scripting",
|
"description": "The Swiss Army Knife of Vector Graphics Scripting",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "http://paperjs.org",
|
"homepage": "http://paperjs.org",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/paperjs/paper.js"
|
"url": "https://github.com/paperjs/paper.js"
|
||||||
},
|
},
|
||||||
"bugs": "https://github.com/paperjs/paper.js/issues",
|
"bugs": "https://github.com/paperjs/paper.js/issues",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
"run-sequence": "^1.2.2",
|
"run-sequence": "^1.2.2",
|
||||||
"source-map-support": "^0.4.0",
|
"source-map-support": "^0.4.0",
|
||||||
"stats.js": "0.16.0",
|
"stats.js": "0.16.0",
|
||||||
"straps": "^2.1.0"
|
"straps": "^3.0.1"
|
||||||
},
|
},
|
||||||
"browser": {
|
"browser": {
|
||||||
"canvas": false,
|
"canvas": false,
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit bab27f25fed8d78f072d8f9a9f68da61e7d1e975
|
Subproject commit fc7ac57828aefadff29f7559a5e39f88d35b0c66
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2e257a436e1cfec74ca6ffe4828a761ec058b42f
|
Subproject commit 18feab4d8968339c60d8610584ab3574c49d7a91
|
|
@ -377,7 +377,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
|
||||||
* @param {Matrix} matrix the matrix to append
|
* @param {Matrix} matrix the matrix to append
|
||||||
* @return {Matrix} this matrix, modified
|
* @return {Matrix} this matrix, modified
|
||||||
*/
|
*/
|
||||||
append: function(mx) {
|
append: function(mx, _dontNotify) {
|
||||||
if (mx) {
|
if (mx) {
|
||||||
var a1 = this._a,
|
var a1 = this._a,
|
||||||
b1 = this._b,
|
b1 = this._b,
|
||||||
|
@ -395,7 +395,8 @@ var Matrix = Base.extend(/** @lends Matrix# */{
|
||||||
this._d = b2 * b1 + d2 * d1;
|
this._d = b2 * b1 + d2 * d1;
|
||||||
this._tx += tx2 * a1 + ty2 * c1;
|
this._tx += tx2 * a1 + ty2 * c1;
|
||||||
this._ty += tx2 * b1 + ty2 * d1;
|
this._ty += tx2 * b1 + ty2 * d1;
|
||||||
this._changed();
|
if (!_dontNotify)
|
||||||
|
this._changed();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
@ -407,7 +408,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
|
||||||
* @param {Matrix} matrix the matrix to prepend
|
* @param {Matrix} matrix the matrix to prepend
|
||||||
* @return {Matrix} this matrix, modified
|
* @return {Matrix} this matrix, modified
|
||||||
*/
|
*/
|
||||||
prepend: function(mx) {
|
prepend: function(mx, _dontNotify) {
|
||||||
if (mx) {
|
if (mx) {
|
||||||
var a1 = this._a,
|
var a1 = this._a,
|
||||||
b1 = this._b,
|
b1 = this._b,
|
||||||
|
@ -427,7 +428,8 @@ var Matrix = Base.extend(/** @lends Matrix# */{
|
||||||
this._d = c2 * c1 + d2 * d1;
|
this._d = c2 * c1 + d2 * d1;
|
||||||
this._tx = a2 * tx1 + b2 * ty1 + tx2;
|
this._tx = a2 * tx1 + b2 * ty1 + tx2;
|
||||||
this._ty = c2 * tx1 + d2 * ty1 + ty2;
|
this._ty = c2 * tx1 + d2 * ty1 + ty2;
|
||||||
this._changed();
|
if (!_dontNotify)
|
||||||
|
this._changed();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
@ -671,7 +673,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to decompose the affine transformation described by this matrix
|
* Attempts to decompose the affine transformation described by this matrix
|
||||||
* into `scaling`, `rotation` and `shearing`, and returns an object with
|
* into `scaling`, `rotation` and `skewing`, and returns an object with
|
||||||
* these properties if it succeeded, `null` otherwise.
|
* these properties if it succeeded, `null` otherwise.
|
||||||
*
|
*
|
||||||
* @return {Object} the decomposed matrix, or `null` if decomposition is not
|
* @return {Object} the decomposed matrix, or `null` if decomposition is not
|
||||||
|
|
|
@ -141,6 +141,12 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
|
||||||
}
|
}
|
||||||
this._set(x, y, width, height);
|
this._set(x, y, width, height);
|
||||||
read = arguments.__index;
|
read = arguments.__index;
|
||||||
|
// arguments.__filtered wouldn't survive the function call even if a
|
||||||
|
// previous arguments list was passed through Function#apply().
|
||||||
|
// Return it on the object instead, see Base.read()
|
||||||
|
var filtered = arguments.__filtered;
|
||||||
|
if (filtered)
|
||||||
|
this.__filtered = filtered;
|
||||||
}
|
}
|
||||||
if (this.__read)
|
if (this.__read)
|
||||||
this.__read = read;
|
this.__read = read;
|
||||||
|
|
1058
src/core/Base.js
1058
src/core/Base.js
File diff suppressed because it is too large
Load diff
|
@ -17,8 +17,6 @@
|
||||||
// global one in the whole scope.
|
// global one in the whole scope.
|
||||||
|
|
||||||
paper = new (PaperScope.inject(Base.exports, {
|
paper = new (PaperScope.inject(Base.exports, {
|
||||||
// Mark fields as enumerable so PaperScope.inject can pick them up
|
|
||||||
enumerable: true,
|
|
||||||
Base: Base,
|
Base: Base,
|
||||||
Numerical: Numerical,
|
Numerical: Numerical,
|
||||||
Key: Key,
|
Key: Key,
|
||||||
|
|
|
@ -26,11 +26,8 @@ var HitResult = Base.extend(/** @lends HitResult# */{
|
||||||
// Inject passed values, so we can be flexible about the HitResult
|
// Inject passed values, so we can be flexible about the HitResult
|
||||||
// properties.
|
// properties.
|
||||||
// This allows the definition of getters too, e.g. for 'pixel'.
|
// This allows the definition of getters too, e.g. for 'pixel'.
|
||||||
if (values) {
|
if (values)
|
||||||
// Make enumerable so toString() works.
|
|
||||||
values.enumerable = true;
|
|
||||||
this.inject(values);
|
this.inject(values);
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
189
src/item/Item.js
189
src/item/Item.js
|
@ -827,14 +827,14 @@ new function() { // Injection scope for various item event handlers
|
||||||
opts.cacheItem = this;
|
opts.cacheItem = this;
|
||||||
// If we're caching bounds, pass on this item as cacheItem, so
|
// If we're caching bounds, pass on this item as cacheItem, so
|
||||||
// the children can setup _boundsCache structures for it.
|
// the children can setup _boundsCache structures for it.
|
||||||
var bounds = this._getCachedBounds(hasMatrix && matrix, opts);
|
var rect = this._getCachedBounds(hasMatrix && matrix, opts).rect;
|
||||||
// If we're returning '#bounds', create a LinkedRectangle that uses
|
// If we're returning '#bounds', create a LinkedRectangle that uses
|
||||||
// the setBounds() setter to update the Item whenever the bounds are
|
// the setBounds() setter to update the Item whenever the bounds are
|
||||||
// changed:
|
// changed:
|
||||||
return !arguments.length
|
return !arguments.length
|
||||||
? new LinkedRectangle(bounds.x, bounds.y, bounds.width,
|
? new LinkedRectangle(rect.x, rect.y, rect.width, rect.height,
|
||||||
bounds.height, this, 'setBounds')
|
this, 'setBounds')
|
||||||
: bounds;
|
: rect;
|
||||||
},
|
},
|
||||||
|
|
||||||
setBounds: function(/* rect */) {
|
setBounds: function(/* rect */) {
|
||||||
|
@ -889,6 +889,14 @@ new function() { // Injection scope for various item event handlers
|
||||||
return Item._getBounds(children, matrix, options);
|
return Item._getBounds(children, matrix, options);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getBoundsCacheKey: function(options, internal) {
|
||||||
|
return [
|
||||||
|
options.stroke ? 1 : 0,
|
||||||
|
options.handle ? 1 : 0,
|
||||||
|
internal ? 1 : 0
|
||||||
|
].join('');
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private method that deals with the calling of _getBounds, recursive
|
* Private method that deals with the calling of _getBounds, recursive
|
||||||
* matrix concatenation and handles all the complicated caching mechanisms.
|
* matrix concatenation and handles all the complicated caching mechanisms.
|
||||||
|
@ -904,29 +912,43 @@ new function() { // Injection scope for various item event handlers
|
||||||
cacheItem = options.cacheItem,
|
cacheItem = options.cacheItem,
|
||||||
_matrix = internal ? null : this._matrix._orNullIfIdentity(),
|
_matrix = internal ? null : this._matrix._orNullIfIdentity(),
|
||||||
// Create a key for caching, reflecting all bounds options.
|
// Create a key for caching, reflecting all bounds options.
|
||||||
cacheKey = cacheItem && (!matrix || matrix.equals(_matrix)) && [
|
cacheKey = cacheItem && (!matrix || matrix.equals(_matrix))
|
||||||
options.stroke ? 1 : 0,
|
&& this._getBoundsCacheKey(options, internal),
|
||||||
options.handle ? 1 : 0,
|
bounds = this._bounds;
|
||||||
internal ? 1 : 0
|
|
||||||
].join('');
|
|
||||||
// NOTE: This needs to happen before returning cached values, since even
|
// NOTE: This needs to happen before returning cached values, since even
|
||||||
// then, _boundsCache needs to be kept up-to-date.
|
// then, _boundsCache needs to be kept up-to-date.
|
||||||
Item._updateBoundsCache(this._parent || this._symbol, cacheItem);
|
Item._updateBoundsCache(this._parent || this._symbol, cacheItem);
|
||||||
if (cacheKey && this._bounds && cacheKey in this._bounds)
|
if (cacheKey && bounds && cacheKey in bounds) {
|
||||||
return this._bounds[cacheKey].rect.clone();
|
var cached = bounds[cacheKey];
|
||||||
var bounds = this._getBounds(matrix || _matrix, options);
|
return {
|
||||||
|
rect: cached.rect.clone(),
|
||||||
|
nonscaling: cached.nonscaling
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var res = this._getBounds(matrix || _matrix, options),
|
||||||
|
// Support two versions of _getBounds(): One that directly returns a
|
||||||
|
// Rectangle, and one that returns a bounds object with nonscaling.
|
||||||
|
rect = res.rect || res,
|
||||||
|
style = this._style,
|
||||||
|
nonscaling = res.nonscaling || style.hasStroke()
|
||||||
|
&& !style.getStrokeScaling();
|
||||||
// If we can cache the result, update the _bounds cache structure
|
// If we can cache the result, update the _bounds cache structure
|
||||||
// before returning
|
// before returning
|
||||||
if (cacheKey) {
|
if (cacheKey) {
|
||||||
if (!this._bounds)
|
if (!bounds) {
|
||||||
this._bounds = {};
|
this._bounds = bounds = {};
|
||||||
var cached = this._bounds[cacheKey] = {
|
}
|
||||||
rect: bounds.clone(),
|
var cached = bounds[cacheKey] = {
|
||||||
|
rect: rect.clone(),
|
||||||
|
nonscaling: nonscaling,
|
||||||
// Mark as internal, so Item#transform() won't transform it
|
// Mark as internal, so Item#transform() won't transform it
|
||||||
internal: internal
|
internal: internal
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return bounds;
|
return {
|
||||||
|
rect: rect,
|
||||||
|
nonscaling: nonscaling
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1005,7 +1027,10 @@ new function() { // Injection scope for various item event handlers
|
||||||
var x1 = Infinity,
|
var x1 = Infinity,
|
||||||
x2 = -x1,
|
x2 = -x1,
|
||||||
y1 = x1,
|
y1 = x1,
|
||||||
y2 = x2;
|
y2 = x2,
|
||||||
|
nonscaling = false;
|
||||||
|
// NOTE: As soon as one child-item has non-scaling strokes, the full
|
||||||
|
// bounds need to be considered non-scaling for caching purposes.
|
||||||
options = options || {};
|
options = options || {};
|
||||||
for (var i = 0, l = items.length; i < l; i++) {
|
for (var i = 0, l = items.length; i < l; i++) {
|
||||||
var item = items[i];
|
var item = items[i];
|
||||||
|
@ -1013,17 +1038,23 @@ new function() { // Injection scope for various item event handlers
|
||||||
// Pass true for noInternal, since even when getting
|
// Pass true for noInternal, since even when getting
|
||||||
// internal bounds for this item, we need to apply the
|
// internal bounds for this item, we need to apply the
|
||||||
// matrices to its children.
|
// matrices to its children.
|
||||||
var rect = item._getCachedBounds(
|
var bounds = item._getCachedBounds(
|
||||||
matrix && matrix.appended(item._matrix), options, true);
|
matrix && matrix.appended(item._matrix), options, true),
|
||||||
|
rect = bounds.rect;
|
||||||
x1 = Math.min(rect.x, x1);
|
x1 = Math.min(rect.x, x1);
|
||||||
y1 = Math.min(rect.y, y1);
|
y1 = Math.min(rect.y, y1);
|
||||||
x2 = Math.max(rect.x + rect.width, x2);
|
x2 = Math.max(rect.x + rect.width, x2);
|
||||||
y2 = Math.max(rect.y + rect.height, y2);
|
y2 = Math.max(rect.y + rect.height, y2);
|
||||||
|
if (bounds.nonscaling)
|
||||||
|
nonscaling = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return isFinite(x1)
|
return {
|
||||||
|
rect: isFinite(x1)
|
||||||
? new Rectangle(x1, y1, x2 - x1, y2 - y1)
|
? new Rectangle(x1, y1, x2 - x1, y2 - y1)
|
||||||
: new Rectangle();
|
: new Rectangle(),
|
||||||
|
nonscaling: nonscaling
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1122,8 +1153,22 @@ new function() { // Injection scope for various item event handlers
|
||||||
scaling = Point.read(arguments, 0, { clone: true, readNull: true });
|
scaling = Point.read(arguments, 0, { clone: true, readNull: true });
|
||||||
if (current && scaling && !current.equals(scaling)) {
|
if (current && scaling && !current.equals(scaling)) {
|
||||||
// See #setRotation() for preservation of _decomposed.
|
// See #setRotation() for preservation of _decomposed.
|
||||||
var decomposed = this._decomposed;
|
var rotation = this.getRotation(),
|
||||||
this.scale(scaling.x / current.x, scaling.y / current.y);
|
decomposed = this._decomposed,
|
||||||
|
matrix = new Matrix(),
|
||||||
|
center = this.getPosition(true);
|
||||||
|
// Create a matrix in which the scaling is applied in the non-
|
||||||
|
// rotated state, so it is always applied before the rotation.
|
||||||
|
// TODO: What about skewing? Do we need separately stored values for
|
||||||
|
// these properties, and apply them separately from the matrix?
|
||||||
|
matrix.translate(center);
|
||||||
|
if (rotation)
|
||||||
|
matrix.rotate(rotation);
|
||||||
|
matrix.scale(scaling.x / current.x, scaling.y / current.y);
|
||||||
|
if (rotation)
|
||||||
|
matrix.rotate(-rotation);
|
||||||
|
matrix.translate(center.negate());
|
||||||
|
this.transform(matrix);
|
||||||
if (decomposed) {
|
if (decomposed) {
|
||||||
decomposed.scaling = scaling;
|
decomposed.scaling = scaling;
|
||||||
this._decomposed = decomposed;
|
this._decomposed = decomposed;
|
||||||
|
@ -3376,11 +3421,9 @@ new function() { // Injection scope for hit-test functions shared with project
|
||||||
// 'lines'. Default: ['objects', 'children']
|
// 'lines'. Default: ['objects', 'children']
|
||||||
transform: function(matrix, _applyMatrix, _applyRecursively,
|
transform: function(matrix, _applyMatrix, _applyRecursively,
|
||||||
_setApplyMatrix) {
|
_setApplyMatrix) {
|
||||||
// If no matrix is provided, or the matrix is the identity, we might
|
|
||||||
// still have some work to do in case _applyMatrix is true
|
|
||||||
if (matrix && matrix.isIdentity())
|
|
||||||
matrix = null;
|
|
||||||
var _matrix = this._matrix,
|
var _matrix = this._matrix,
|
||||||
|
// If no matrix is provided, or the matrix is the identity, we might
|
||||||
|
// still have some work to do in case _applyMatrix is true
|
||||||
transform = matrix && !matrix.isIdentity(),
|
transform = matrix && !matrix.isIdentity(),
|
||||||
applyMatrix = (_applyMatrix || this._applyMatrix)
|
applyMatrix = (_applyMatrix || this._applyMatrix)
|
||||||
// Don't apply _matrix if the result of concatenating with
|
// Don't apply _matrix if the result of concatenating with
|
||||||
|
@ -3398,30 +3441,8 @@ new function() { // Injection scope for hit-test functions shared with project
|
||||||
// non-invertible. This is then used again in setBounds to restore.
|
// non-invertible. This is then used again in setBounds to restore.
|
||||||
if (!matrix.isInvertible() && _matrix.isInvertible())
|
if (!matrix.isInvertible() && _matrix.isInvertible())
|
||||||
_matrix._backup = _matrix.getValues();
|
_matrix._backup = _matrix.getValues();
|
||||||
_matrix.prepend(matrix);
|
// Pass `true` for _dontNotify, as we're handling this after.
|
||||||
}
|
_matrix.prepend(matrix, true);
|
||||||
// Call #_transformContent() now, if we need to directly apply the
|
|
||||||
// internal _matrix transformations to the item's content.
|
|
||||||
// Application is not possible on Raster, PointText, SymbolItem, since
|
|
||||||
// the matrix is where the actual transformation state is stored.
|
|
||||||
if (applyMatrix) {
|
|
||||||
if (this._transformContent(_matrix, _applyRecursively,
|
|
||||||
_setApplyMatrix)) {
|
|
||||||
var pivot = this._pivot;
|
|
||||||
if (pivot)
|
|
||||||
_matrix._transformPoint(pivot, pivot, true);
|
|
||||||
// Reset the internal matrix to the identity transformation if
|
|
||||||
// it was possible to apply it.
|
|
||||||
_matrix.reset(true);
|
|
||||||
// Set the internal _applyMatrix flag to true if we're told to
|
|
||||||
// do so
|
|
||||||
if (_setApplyMatrix && this._canApplyMatrix)
|
|
||||||
this._applyMatrix = true;
|
|
||||||
} else {
|
|
||||||
applyMatrix = transform = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (transform) {
|
|
||||||
// When a new matrix was applied, we also need to transform gradient
|
// When a new matrix was applied, we also need to transform gradient
|
||||||
// color points. These always need transforming, regardless of
|
// color points. These always need transforming, regardless of
|
||||||
// #applyMatrix, as they are defined in the parent's coordinate
|
// #applyMatrix, as they are defined in the parent's coordinate
|
||||||
|
@ -3438,39 +3459,65 @@ new function() { // Injection scope for hit-test functions shared with project
|
||||||
if (strokeColor)
|
if (strokeColor)
|
||||||
strokeColor.transform(matrix);
|
strokeColor.transform(matrix);
|
||||||
}
|
}
|
||||||
|
// Call #_transformContent() now, if we need to directly apply the
|
||||||
|
// internal _matrix transformations to the item's content.
|
||||||
|
// Application is not possible on Raster, PointText, SymbolItem, since
|
||||||
|
// the matrix is where the actual transformation state is stored.
|
||||||
|
if (applyMatrix && (applyMatrix = this._transformContent(_matrix,
|
||||||
|
_applyRecursively, _setApplyMatrix))) {
|
||||||
|
// Pivot is provided in the parent's coordinate system, so transform
|
||||||
|
// it along too.
|
||||||
|
var pivot = this._pivot;
|
||||||
|
if (pivot)
|
||||||
|
_matrix._transformPoint(pivot, pivot, true);
|
||||||
|
// Reset the internal matrix to the identity transformation if
|
||||||
|
// it was possible to apply it, but do not notify owner of change.
|
||||||
|
_matrix.reset(true);
|
||||||
|
// Set the internal _applyMatrix flag to true if we're told to
|
||||||
|
// do so
|
||||||
|
if (_setApplyMatrix && this._canApplyMatrix)
|
||||||
|
this._applyMatrix = true;
|
||||||
|
}
|
||||||
// Calling _changed will clear _bounds and _position, but depending
|
// Calling _changed will clear _bounds and _position, but depending
|
||||||
// on matrix we can calculate and set them again, so preserve them.
|
// on matrix we can calculate and set them again, so preserve them.
|
||||||
var bounds = this._bounds,
|
var bounds = this._bounds,
|
||||||
position = this._position;
|
position = this._position;
|
||||||
// We always need to call _changed since we're caching bounds on all
|
if (transform || applyMatrix) {
|
||||||
// items, including Group.
|
this._changed(/*#=*/Change.GEOMETRY);
|
||||||
this._changed(/*#=*/Change.GEOMETRY);
|
}
|
||||||
// Detect matrices that contain only translations and scaling
|
// Detect matrices that contain only translations and scaling
|
||||||
// and transform the cached _bounds and _position without having to
|
// and transform the cached _bounds and _position without having to
|
||||||
// fully recalculate each time.
|
// fully recalculate each time.
|
||||||
var decomp = bounds && matrix && matrix.decompose();
|
var decomp = transform && bounds && matrix.decompose();
|
||||||
if (decomp && !decomp.shearing && decomp.rotation % 90 === 0) {
|
if (decomp && decomp.skewing.isZero() && decomp.rotation % 90 === 0) {
|
||||||
// Transform the old bound by looping through all the cached bounds
|
// Transform the old bound by looping through all the cached
|
||||||
// in _bounds and transform each.
|
// bounds in _bounds and transform each.
|
||||||
for (var key in bounds) {
|
for (var key in bounds) {
|
||||||
var cache = bounds[key];
|
var cache = bounds[key];
|
||||||
// If these are internal bounds, only transform them if this
|
// If any item involved in the determination of these bounds has
|
||||||
// item applied its matrix.
|
// non-scaling strokes, delete the cache now as it can't be
|
||||||
if (applyMatrix || !cache.internal) {
|
// preserved through the transformation.
|
||||||
|
if (cache.nonscaling) {
|
||||||
|
delete bounds[key];
|
||||||
|
} else if (applyMatrix || !cache.internal) {
|
||||||
|
// If these are internal bounds, only transform them if this
|
||||||
|
// item applied its matrix.
|
||||||
var rect = cache.rect;
|
var rect = cache.rect;
|
||||||
matrix._transformBounds(rect, rect);
|
matrix._transformBounds(rect, rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If we have cached bounds, update _position again as its
|
|
||||||
// center. We need to take into account _boundsGetter here too, in
|
|
||||||
// case another getter is assigned to it, e.g. 'getStrokeBounds'.
|
|
||||||
var getter = this._boundsGetter,
|
|
||||||
rect = bounds[getter && getter.getBounds || getter || 'getBounds'];
|
|
||||||
if (rect)
|
|
||||||
this._position = rect.getCenter(true);
|
|
||||||
this._bounds = bounds;
|
this._bounds = bounds;
|
||||||
} else if (matrix && position) {
|
// If we have cached bounds, try to determine _position as its
|
||||||
// Transform position as well.
|
// center. Use _boundsOptions do get the cached default bounds.
|
||||||
|
var cached = bounds[this._getBoundsCacheKey(
|
||||||
|
this._boundsOptions || {})];
|
||||||
|
if (cached) {
|
||||||
|
this._position = cached.rect.getCenter(true);
|
||||||
|
}
|
||||||
|
} else if (transform && position && this._pivot) {
|
||||||
|
// If the item has a pivot defined, it means that the default
|
||||||
|
// position defined as the center of the bounds won't shift with
|
||||||
|
// arbitrary transformations and we can therefore update _position:
|
||||||
this._position = matrix._transformPoint(position, position);
|
this._position = matrix._transformPoint(position, position);
|
||||||
}
|
}
|
||||||
// Allow chaining here, since transform() is related to Matrix functions
|
// Allow chaining here, since transform() is related to Matrix functions
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
// The paper.js version.
|
// The paper.js version.
|
||||||
// NOTE: Adjust value here before calling `gulp publish`, which then updates and
|
// NOTE: Adjust value here before calling `gulp publish`, which then updates and
|
||||||
// publishes the various JSON package files automatically.
|
// publishes the various JSON package files automatically.
|
||||||
var version = '0.11.2';
|
var version = '0.11.3';
|
||||||
|
|
||||||
// If this file is loaded in the browser, we're in load.js mode.
|
// If this file is loaded in the browser, we're in load.js mode.
|
||||||
var load = typeof window === 'object';
|
var load = typeof window === 'object';
|
||||||
|
|
|
@ -1955,7 +1955,7 @@ new function() { // Scope for bezier intersection using fat-line clipping
|
||||||
// Calculate the curve values of the rotated curve.
|
// Calculate the curve values of the rotated curve.
|
||||||
rv = [],
|
rv = [],
|
||||||
roots = [];
|
roots = [];
|
||||||
for(var i = 0; i < 8; i += 2) {
|
for (var i = 0; i < 8; i += 2) {
|
||||||
var x = v[i] - px,
|
var x = v[i] - px,
|
||||||
y = v[i + 1] - py;
|
y = v[i + 1] - py;
|
||||||
rv.push(
|
rv.push(
|
||||||
|
|
|
@ -51,9 +51,9 @@ new function() {
|
||||||
if (!Numerical.isZero(scale.x - 1)
|
if (!Numerical.isZero(scale.x - 1)
|
||||||
|| !Numerical.isZero(scale.y - 1))
|
|| !Numerical.isZero(scale.y - 1))
|
||||||
parts.push('scale(' + formatter.point(scale) +')');
|
parts.push('scale(' + formatter.point(scale) +')');
|
||||||
if (skew && skew.x)
|
if (skew.x)
|
||||||
parts.push('skewX(' + formatter.number(skew.x) + ')');
|
parts.push('skewX(' + formatter.number(skew.x) + ')');
|
||||||
if (skew && skew.y)
|
if (skew.y)
|
||||||
parts.push('skewY(' + formatter.number(skew.y) + ')');
|
parts.push('skewY(' + formatter.number(skew.y) + ')');
|
||||||
attrs.transform = parts.join(' ');
|
attrs.transform = parts.join(' ');
|
||||||
} else {
|
} else {
|
||||||
|
@ -115,8 +115,9 @@ new function() {
|
||||||
if (length > 2) {
|
if (length > 2) {
|
||||||
type = item._closed ? 'polygon' : 'polyline';
|
type = item._closed ? 'polygon' : 'polyline';
|
||||||
var parts = [];
|
var parts = [];
|
||||||
for(var i = 0; i < length; i++)
|
for (var i = 0; i < length; i++) {
|
||||||
parts.push(formatter.point(segments[i]._point));
|
parts.push(formatter.point(segments[i]._point));
|
||||||
|
}
|
||||||
attrs.points = parts.join(' ');
|
attrs.points = parts.join(' ');
|
||||||
} else {
|
} else {
|
||||||
type = 'line';
|
type = 'line';
|
||||||
|
@ -416,6 +417,7 @@ new function() {
|
||||||
? new Rectangle([0, 0], view.getViewSize())
|
? new Rectangle([0, 0], view.getViewSize())
|
||||||
: bounds === 'content'
|
: bounds === 'content'
|
||||||
? Item._getBounds(children, matrix, { stroke: true })
|
? Item._getBounds(children, matrix, { stroke: true })
|
||||||
|
.rect
|
||||||
: Rectangle.read([bounds], 0, { readNull: true }),
|
: Rectangle.read([bounds], 0, { readNull: true }),
|
||||||
attrs = {
|
attrs = {
|
||||||
version: '1.1',
|
version: '1.1',
|
||||||
|
|
|
@ -115,9 +115,9 @@ var PointText = TextItem.extend(/** @lends PointText# */{
|
||||||
x -= width / (justification === 'center' ? 2: 1);
|
x -= width / (justification === 'center' ? 2: 1);
|
||||||
// Until we don't have baseline measuring, assume 1 / 4 leading as a
|
// Until we don't have baseline measuring, assume 1 / 4 leading as a
|
||||||
// rough guess:
|
// rough guess:
|
||||||
var bounds = new Rectangle(x,
|
var rect = new Rectangle(x,
|
||||||
numLines ? - 0.75 * leading : 0,
|
numLines ? - 0.75 * leading : 0,
|
||||||
width, numLines * leading);
|
width, numLines * leading);
|
||||||
return matrix ? matrix._transformBounds(bounds, bounds) : bounds;
|
return matrix ? matrix._transformBounds(rect, rect) : rect;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -125,7 +125,7 @@ var Numerical = new function() {
|
||||||
/**
|
/**
|
||||||
* The machine epsilon for a double precision (Javascript Number) is
|
* The machine epsilon for a double precision (Javascript Number) is
|
||||||
* 2.220446049250313e-16. (try this in the js console:
|
* 2.220446049250313e-16. (try this in the js console:
|
||||||
* (function(){for(var e=1;1<1+e/2;)e/=2;return e}())
|
* (function(){ for (var e = 1; 1 < 1+e/2;) e/=2; return e }())
|
||||||
*
|
*
|
||||||
* The constant MACHINE_EPSILON here refers to the constants δ and ε
|
* The constant MACHINE_EPSILON here refers to the constants δ and ε
|
||||||
* such that, the error introduced by addition, multiplication on a
|
* such that, the error introduced by addition, multiplication on a
|
||||||
|
|
|
@ -1271,12 +1271,11 @@ new function() { // Injection scope for event handling on the browser
|
||||||
point, prevPoint)
|
point, prevPoint)
|
||||||
// Next handle the hit-item, if it's different from the drag-item
|
// Next handle the hit-item, if it's different from the drag-item
|
||||||
// and not a descendant of it (in which case it would already have
|
// and not a descendant of it (in which case it would already have
|
||||||
// received an event in the call above). Use fallbacks to translate
|
// received an event in the call above).
|
||||||
// mousedrag to mousemove, since drag is handled above.
|
|
||||||
|| hitItem && hitItem !== dragItem
|
|| hitItem && hitItem !== dragItem
|
||||||
&& !hitItem.isDescendant(dragItem)
|
&& !hitItem.isDescendant(dragItem)
|
||||||
&& emitMouseEvent(hitItem, null, fallbacks[type] || type, event,
|
&& emitMouseEvent(hitItem, null, type, event, point, prevPoint,
|
||||||
point, prevPoint, dragItem)
|
dragItem)
|
||||||
// Lastly handle the mouse events on the view, if we're still here.
|
// Lastly handle the mouse events on the view, if we're still here.
|
||||||
|| emitMouseEvent(view, dragItem || hitItem || view, type, event,
|
|| emitMouseEvent(view, dragItem || hitItem || view, type, event,
|
||||||
point, prevPoint));
|
point, prevPoint));
|
||||||
|
|
|
@ -876,3 +876,56 @@ test('Item#pivot', function() {
|
||||||
equals(path2.pivot, pivot.add(difference),
|
equals(path2.pivot, pivot.add(difference),
|
||||||
'Changing position of an item with applyMatrix = true should change pivot');
|
'Changing position of an item with applyMatrix = true should change pivot');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Item#position with irregular shape, #pivot and rotation', function() {
|
||||||
|
var path1 = new Path([ [0, 0], [200, 100], [0, 100] ]);
|
||||||
|
var path2 = path1.clone();
|
||||||
|
path2.pivot = path2.position;
|
||||||
|
equals(path1.position, new Point(100, 50),
|
||||||
|
'path1.position, before rotation');
|
||||||
|
path1.rotate(45);
|
||||||
|
equals(path1.position, new Point(64.64466, 50),
|
||||||
|
'path1.position, after rotation');
|
||||||
|
equals(path2.position, new Point(100, 50),
|
||||||
|
'path2.position with pivot, before rotation');
|
||||||
|
path2.rotate(45);
|
||||||
|
equals(path2.position, new Point(100, 50),
|
||||||
|
'path2.position with pivot, after rotation');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Item#scaling, #rotation', function() {
|
||||||
|
var expected = new Rectangle(100, 50, 100, 200);
|
||||||
|
|
||||||
|
var rect1 = new Path.Rectangle({
|
||||||
|
from: [100, 100],
|
||||||
|
to: [200, 200],
|
||||||
|
applyMatrix: false
|
||||||
|
});
|
||||||
|
var rect2 = rect1.clone();
|
||||||
|
|
||||||
|
rect1.scaling = [2, 1];
|
||||||
|
rect1.rotation = 90;
|
||||||
|
equals(rect1.bounds, expected,
|
||||||
|
'rect1.bounds, setting rect1.scaling before rect1.rotation');
|
||||||
|
|
||||||
|
rect2.rotation = 90;
|
||||||
|
rect2.scaling = [2, 1];
|
||||||
|
equals(rect2.bounds, expected,
|
||||||
|
'rect2.bounds, setting rect2.scaling before rect2.rotation');
|
||||||
|
|
||||||
|
var shape1 = new Shape.Rectangle({
|
||||||
|
from: [100, 100],
|
||||||
|
to: [200, 200]
|
||||||
|
});
|
||||||
|
var shape2 = shape1.clone();
|
||||||
|
|
||||||
|
shape1.scaling = [2, 1];
|
||||||
|
shape1.rotation = 90;
|
||||||
|
equals(shape1.bounds, expected,
|
||||||
|
'shape1.bounds, setting shape1.scaling before shape1.rotation');
|
||||||
|
|
||||||
|
shape2.rotation = 90;
|
||||||
|
shape2.scaling = [2, 1];
|
||||||
|
equals(shape2.bounds, expected,
|
||||||
|
'shape2.bounds, setting shape2.scaling before shape2.rotation');
|
||||||
|
});
|
||||||
|
|
|
@ -694,12 +694,15 @@ test('path.strokeBounds with applyMatrix disabled', function() {
|
||||||
strokeColor: 'red',
|
strokeColor: 'red',
|
||||||
strokeWidth: 10
|
strokeWidth: 10
|
||||||
});
|
});
|
||||||
equals(path.strokeBounds, new Rectangle(5, 5, 30, 30), 'path.strokeBounds, applyMatrix enabled');
|
equals(path.strokeBounds, new Rectangle(5, 5, 30, 30),
|
||||||
|
'path.strokeBounds, applyMatrix enabled');
|
||||||
path.applyMatrix = false;
|
path.applyMatrix = false;
|
||||||
equals(path.strokeBounds, new Rectangle(5, 5, 30, 30), 'path.strokeBounds, applyMatrix disabled');
|
equals(path.strokeBounds, new Rectangle(5, 5, 30, 30),
|
||||||
|
'path.strokeBounds, applyMatrix disabled');
|
||||||
path.scale([4, 2], [0, 0]);
|
path.scale([4, 2], [0, 0]);
|
||||||
var expected = new Rectangle(20, 10, 120, 60);
|
var expected = new Rectangle(20, 10, 120, 60);
|
||||||
equals(path.strokeBounds, expected, 'path.strokeBounds after scaling, applyMatrix disabled');
|
equals(path.strokeBounds, expected,
|
||||||
|
'path.strokeBounds after scaling, applyMatrix disabled');
|
||||||
function testHitResult() {
|
function testHitResult() {
|
||||||
// Hit-testing needs to handle applyMatrix disabled with stroke scaling,
|
// Hit-testing needs to handle applyMatrix disabled with stroke scaling,
|
||||||
// even when hit-testing on "distorted" stroke joins:
|
// even when hit-testing on "distorted" stroke joins:
|
||||||
|
@ -714,10 +717,29 @@ test('path.strokeBounds with applyMatrix disabled', function() {
|
||||||
testHitResult();
|
testHitResult();
|
||||||
path.applyMatrix = true;
|
path.applyMatrix = true;
|
||||||
expected = new Rectangle(35, 15, 90, 50);
|
expected = new Rectangle(35, 15, 90, 50);
|
||||||
equals(path.strokeBounds, expected, 'path.strokeBounds after scaling, applyMatrix enabled');
|
equals(path.strokeBounds, expected,
|
||||||
|
'path.strokeBounds after scaling, applyMatrix enabled');
|
||||||
testHitResult();
|
testHitResult();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('TEST', function() {
|
||||||
|
var path = new Path.Rectangle({
|
||||||
|
applyMatrix: false,
|
||||||
|
point: [10, 10],
|
||||||
|
size: [20, 20],
|
||||||
|
strokeScaling: true,
|
||||||
|
strokeColor: 'red',
|
||||||
|
strokeWidth: 10
|
||||||
|
});
|
||||||
|
path.scale([4, 2], [0, 0]);
|
||||||
|
equals(path.strokeBounds, new Rectangle(20, 10, 120, 60),
|
||||||
|
'path.strokeBounds after scaling, applyMatrix disabled');
|
||||||
|
path.applyMatrix = true;
|
||||||
|
equals(path.strokeBounds, new Rectangle(35, 15, 90, 50),
|
||||||
|
'path.strokeBounds after scaling, applyMatrix enabled');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
test('symbolItem.bounds with strokeScaling disabled', function() {
|
test('symbolItem.bounds with strokeScaling disabled', function() {
|
||||||
var path = new Path.Rectangle({
|
var path = new Path.Rectangle({
|
||||||
size: [20, 20],
|
size: [20, 20],
|
||||||
|
|
|
@ -154,7 +154,7 @@ test('transform test 1', function() {
|
||||||
var clones = 30;
|
var clones = 30;
|
||||||
var angle = 360 / clones;
|
var angle = 360 / clones;
|
||||||
|
|
||||||
for(var i = 0; i < clones; i++) {
|
for (var i = 0; i < clones; i++) {
|
||||||
var clonedPath = circlePath.clone();
|
var clonedPath = circlePath.clone();
|
||||||
clonedPath.rotate(angle * i, circlePath.bounds.topLeft);
|
clonedPath.rotate(angle * i, circlePath.bounds.topLeft);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue