diff --git a/.travis.yml b/.travis.yml
index 0954607e..036ee4f9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,13 +1,12 @@
language: node_js
# Follow https://github.com/nodejs/LTS to decide when to remove a version
node_js:
-- 9
+# Stable version is temporarily disabled due to a bug in resemblejs package with
+# node v12 (https://github.com/orgs/paperjs/teams/contributors/discussions/12).
+# - stable
+# - 11
+- 10
- 8
-# 6.13 and 6.14 causing unreasonable errors in SymbolDefinition.initialize.
-# https://travis-ci.org/paperjs/paper.js/jobs/434854796
-# To avoid these versions, we specify version to 6.12 as temporary solution.
-# See https://github.com/paperjs/paper.js/issues/1523
-- 6.12
sudo: false
env:
matrix:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c8b5b5ff..7df06fcb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,83 @@
# Change Log
+## `0.12.3`
+
+### Fixed
+
+- Fix regression in `Color` change propagation (#1672, #1674).
+- SVG Export: Fix viewport size of exported `Symbol` (#1668).
+- Handle non-invertible matrices in `Item#contains()` (#1651).
+- Improve documentation for `Item#clipMask` (#1673).
+- Improve TypeScript definitions (#1659, #1663, #1664, #1667)
+
+### Added
+
+- Add documentation for `Item#internalBounds`.
+
+## `0.12.2`
+
+### Fixed
+
+- Fix drawing with compound-paths as clip-items (#1361).
+- Fix drawing of path selection with small handle size (#1327).
+- Do not ignore `Group#clipItem.matrix` in `Group#internalBounds` (#1427).
+- Correctly calculate bounds with nested empty items (#1467).
+- Fix color change propagation on groups (#1152).
+- Fix `Path#arcTo()` where `from` and `to` points are equal (#1613).
+- Improve `new Raster(size[, position])` constructor (#1621).
+- SVG Export: Fix error when `Item#matrix` is not invertible (#1580).
+- SVG Export: Include missing viewBox attribute (#1576).
+- SVG Import: Use correct default values for gradients (#1632, #1660).
+- SVG Import: Add basic `` support (#1597).
+- JSON Import: Prevent `Item#insert()` method from being overridden (#1392).
+- PaperScript: Fix issues with increment/decrement operators (#1450, #1611).
+
+## `0.12.1`
+
+### Added
+
+- Add TypeScript definition, automatically generated from JSDoc comments
+ (#1612).
+- Support `new Raster(size[, position])` constructor.
+- Expose `Raster#context` accessor.
+- Implement `Raster#clear()` method to clear associated canvas context.
+- Node.js: Add support for Node.js v11 and v12.
+
+### Fixed
+
+- Fix parsing of CSS colors with spaces in parentheses (#1629).
+- Improve `Color.random()` documentation.
+- Fix `Tween#then()` documentation.
+
+### Removed
+
+- Node.js: Remove support for Node.js v6.
+
+## `0.12.0`
+
+### News
+
+Another release, another new member on the team: Please welcome
+[@arnoson](https://github.com/arnoson), who has worked hard on the all new
+animation support, exposed through the `Tween` class and its various methods on
+the `Item` class, see below for details:
+
+### Added
+
+- Add new `Tween` class and related methods on `Item`, to animate and
+ interpolate their various properties, including colors, sub-properties, etc.:
+ `Item#tween(from, to, options)`, `Item#tween(to, options)`,
+ `Item#tween(options)`, `Item#tweenFrom(from, options)`,
+ `Item#tweenTo(to, options)`
+
+### Fixed
+
+- Only draw Raster if image is not empty (#1320).
+- Emit mousedrag events on correct items when covered by other items (#1465).
+- Fix drawing issues of bounds and position with `Group#selectedColor` (#1571).
+- Fix `Item.once()` to actually only emit event once.
+- Various documentation fixes and improvements (#1399).
+
## `0.11.8`
### News
@@ -59,6 +137,7 @@ the fixes and additions from the past two weeks:
## `0.11.5`
### Fixed
+
- Fix `Curve#isSelected()` to correctly reflect the state of `#handle1` (#1378).
- Key Events: Fix auto-filling issue on Chrome (#1358, #1365).
- Boolean: Check that overlaps are on the right path (#1321).
@@ -71,38 +150,42 @@ the fixes and additions from the past two weeks:
## `0.11.4`
### Changed
+
- Node.js: Add support for v8, and keep testing v4, v6, v7 in Travis CI.
## `0.11.3`
### Fixed
-- Mouse Events: Fix item-based `doubleclick` events (#1316).
+- Mouse Events: Fix item-based `doubleclick` events (#1316).
- Overhaul the caching of bounds and matrix decomposition, improving reliability
of `Item#rotation` and `#scaling` and fixing situations caused by wrongly
caching `Item#position` and `#bounds` values.
-
- Prevent consumed properties in object literal constructors from being set on
the instance.
### Changed
+
- Make all functions and accessors enumerable on all Paper.js classes.
## `0.11.2`
### Fixed
+
- PaperScript: Fix a parsing error in math operations without white-space
(#1314).
## `0.11.1`
### Fixed
+
- Bring back deactivation of Node.js modules on browsers. This has most probably
broken Webpack bundling in `0.11.0`.
## `0.11.0`
### Changed
+
- Separate `paper` module on NPM into: `paper`, `paper-jsdom` and
`paper-jsdom-canvas` (#1252):
- `paper` is the main library, and can be used directly in a browser
@@ -115,12 +198,14 @@ the fixes and additions from the past two weeks:
[jsdom](https://github.com/tmpvar/jsdom).
### Added
+
- PaperScript: Support newer, external versions of Acorn.js for PaperScript
parsing, opening the doors to ES 2015 (#1183, #1275).
- Hit Tests: Implement `options.position` to hit `Item#position` (#1249).
- Split `Item#copyTo()` into `#addTo()` and `#copyTo()`.
### Fixed
+
- Intersections: Bring back special handling of curve end-points (#1284).
- Intersections: Correctly handle `Item#applyMatrix = false` (#1289).
- Boolean: Bring back on-path winding handling (#1281).
@@ -154,6 +239,7 @@ the fixes and additions from the past two weeks:
## `0.10.3`
### Changed
+
- Node.js: Support v7, and keep testing v4 up to v7 in Travis CI.
- Node.js: Loosely couple Node.js / Electron code to `Canvas` module, and treat
its absence like a headless web worker context in the browser (#1103).
@@ -178,6 +264,7 @@ the fixes and additions from the past two weeks:
`#reorient()` (#973).
### Added
+
- Implement `Path#divideAt(location)`, in analogy to `Curve#divideAt(location)`.
- Add `PathItem#compare()` as a way to compare the geometry of two paths to see
if they describe the same shape, handling cases where paths start in different
@@ -196,6 +283,7 @@ the fixes and additions from the past two weeks:
(#1004, #1177).
### Fixed
+
- Many improvements to boolean operations:
- Improve performance of boolean operations when there no actual crossings
between the paths, but paths may be contained within each other.
@@ -236,17 +324,20 @@ the fixes and additions from the past two weeks:
(#632).
### Removed
+
- Remove `Numerical.TOLERANCE = 1e-6` as there is no internal use for it
anymore.
## `0.10.2`
### Fixed
+
- Get published version to work correctly in Bower again.
## `0.10.1`
### Fixed
+
- Correct a few issues with documentation and NPM publishing that slipped
through in the `0.10.0` release.
@@ -284,6 +375,7 @@ Thank you all for using Paper.js, submitting bugs and ideas, and all those that
contribute to the code.
### Changed
+
- Significant overhaul and improvements of boolean path operations
`PathItem#unite()`, `#subtract()`, `#intersect()`, `#exclude()`, `#divide()`:
- Improve handling of self-intersecting paths and non-zero fill-rules.
@@ -300,7 +392,7 @@ contribute to the code.
- `Curve#getParameterAt(offset)` → `#getTimeAt(offset)`
- `Curve#getParameterOf(point)` → `getTimeOf(point)`
- `Curve#getPointAt(time, true)` → `#getPointAtTime(time)`
- - `Curve#getTangentAt(time, true)` → `#getTangenttTime(time)`
+ - `Curve#getTangentAt(time, true)` → `#getTangentAtTime(time)`
- `Curve#getNormalAt(time, true)` → `#getNormalAtTime(time)`
- `Curve#getCurvatureAt(time, true)` → `#getCurvatureAtTime(time)`
- `CurveLocation#parameter` → `#time`
@@ -360,6 +452,7 @@ contribute to the code.
`Color` (#1043).
### Added
+
- Use unified code-base for browsers, Node.js, Electron, and anything
in-between, and enable npm install for browser use (#739).
- Start using automatic code testing and deployment of prebuilt versions through
@@ -424,6 +517,7 @@ contribute to the code.
- Add `Raster#loaded` to reflect the loading state of its image.
### Fixed
+
- Fix calculations of `Item#strokeBounds` for all possible combinations of
`Item#strokeScaling` and `Item#applyMatrix` for `Path`, `Shape` and
`SymbolItem`, along with correct handling of such strokes in Item#hitTest()
@@ -502,10 +596,11 @@ contribute to the code.
`Numerical.solveCubic()` for edge-cases (#1085).
### Removed
+
- Canvas attributes "resize" and "data-paper-resize" no longer cause paper to
resize the canvas when the viewport size changes; Additional CSS styles are
required since `0.9.22`, e.g.:
-
+
```css
/* Scale canvas with resize attribute to full size */
canvas[resize] {
@@ -520,6 +615,7 @@ contribute to the code.
It is replaced by `Project#addLayer()` and `Project#insertLayer()`.
### Deprecated
+
- `#windingRule` on `Item` and `Style` → `#fillRule`
- `Curve#getNormalAt(time, true)` → `#getNormalAtTime(true)`
- `Curve#divide()` → `#divideAt(offset)` / `#divideAtTime(time)`
@@ -527,7 +623,7 @@ contribute to the code.
- `Curve#getParameterAt(offset)` → `#getTimeAt(offset)`
- `Curve#getParameterOf(point)` → `getTimeOf(point)`
- `Curve#getPointAt(time, true)` → `#getPointAtTime(time)`
-- `Curve#getTangentAt(time, true)` → `#getTangenttTime(time)`
+- `Curve#getTangentAt(time, true)` → `#getTangentAtTime(time)`
- `Curve#getNormalAt(time, true)` → `#getNormalAtTime(time)`
- `Curve#getCurvatureAt(time, true)` → `#getCurvatureAtTime(time)`
- `CurveLocation#parameter` → `#time`
diff --git a/LICENSE.txt b/LICENSE.txt
index 28c2e83f..6b6c439e 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,5 +1,5 @@
-Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
-http://scratchdisk.com/ & http://jonathanpuckey.com/
+Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+http://scratchdisk.com/ & https://puckey.studio/
All rights reserved.
The MIT License (MIT)
diff --git a/README.md b/README.md
index 70ee71e5..97f720a1 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@ If you want to work with Paper.js, simply download the latest "stable" version
from [http://paperjs.org/download/](http://paperjs.org/download/)
- Website:
+- Questions:
- Discussion forum:
- Mainline source code:
- Twitter: [@paperjs](https://twitter.com/paperjs)
diff --git a/examples/Node.js/Raster.js b/examples/Node.js/Raster.js
index e3a28d68..0309ae03 100644
--- a/examples/Node.js/Raster.js
+++ b/examples/Node.js/Raster.js
@@ -24,7 +24,7 @@ raster.onLoad = function() {
var fs = require('fs');
var svg = new paper.XMLSerializer().serializeToString(project.exportSVG());
- fs.writeFile(path.resolve('./out.svg'),svg, function (err) {
+ fs.writeFile(path.resolve('./out.svg'), svg, function (err) {
if (err) throw err;
console.log('Saved!');
});
diff --git a/examples/Node.js/SvgExport.js b/examples/Node.js/SvgExport.js
index a0ae8365..5d9c236a 100644
--- a/examples/Node.js/SvgExport.js
+++ b/examples/Node.js/SvgExport.js
@@ -45,7 +45,7 @@ with (paper) {
var svg = project.exportSVG({ asString: true });
console.log(svg);
- fs.writeFile(path.resolve('./out.svg'),svg, function (err) {
+ fs.writeFile(path.resolve('./out.svg'), svg, function (err) {
if (err) throw err;
console.log('Saved!');
});
diff --git a/gulp/jsdoc b/gulp/jsdoc
index 2533ac8e..6c10a800 160000
--- a/gulp/jsdoc
+++ b/gulp/jsdoc
@@ -1 +1 @@
-Subproject commit 2533ac8e1863262f3c28cd29bc940c6d2ecdf147
+Subproject commit 6c10a800e2acafdb50b8493c6a67e5cbeec91f10
diff --git a/gulp/tasks/build.js b/gulp/tasks/build.js
index ba2397e7..48ee18ca 100644
--- a/gulp/tasks/build.js
+++ b/gulp/tasks/build.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/gulp/tasks/dist.js b/gulp/tasks/dist.js
index 17ba87bd..e69e861c 100644
--- a/gulp/tasks/dist.js
+++ b/gulp/tasks/dist.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -22,6 +22,7 @@ gulp.task('zip', ['clean:zip', 'dist'], function() {
gulp.src([
'dist/paper-full*.js',
'dist/paper-core*.js',
+ 'dist/paper.d.ts',
'dist/node/**/*',
'LICENSE.txt',
'examples/**/*',
diff --git a/gulp/tasks/docs.js b/gulp/tasks/docs.js
index 01953df9..6e20068d 100644
--- a/gulp/tasks/docs.js
+++ b/gulp/tasks/docs.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -14,14 +14,15 @@ var gulp = require('gulp'),
del = require('del'),
rename = require('gulp-rename'),
shell = require('gulp-shell'),
- options = require('../utils/options.js');
+ options = require('../utils/options.js'),
+ run = require('run-sequence');
var docOptions = {
local: 'docs', // Generates the offline docs
server: 'serverdocs' // Generates the website templates for the online docs
};
-gulp.task('docs', ['docs:local', 'build:full'], function() {
+gulp.task('docs', ['docs:local', 'docs:typescript', 'build:full'], function() {
return gulp.src('dist/paper-full.js')
.pipe(rename({ basename: 'paper' }))
.pipe(gulp.dest('dist/docs/assets/js/'));
@@ -32,15 +33,58 @@ Object.keys(docOptions).forEach(function(name) {
var mode = docOptions[name];
return gulp.src('src')
.pipe(shell(
- ['java -cp jsrun.jar:lib/* JsRun app/run.js',
- ' -c=conf/', name, '.conf ',
- ' -D="renderMode:', mode, '" ',
- ' -D="version:', options.version, '"'].join(''),
+ [
+ 'java -cp jsrun.jar:lib/* JsRun app/run.js',
+ ' -c=conf/', name, '.conf ',
+ ' -D="renderMode:', mode, '" ',
+ ' -D="version:', options.version, '"'
+ ].join(''),
{ cwd: 'gulp/jsdoc' })
- )
+ );
});
gulp.task('clean:docs:' + name, function() {
- return del([ 'dist/' + docOptions[name] + '/**' ]);
+ return del(['dist/' + docOptions[name] + '/**']);
});
});
+
+// The goal of the typescript task is to automatically generate a type
+// definition for the library.
+gulp.task('docs:typescript', function(callback) {
+ run(
+ 'docs:typescript:clean:before',
+ 'docs:typescript:build',
+ 'docs:typescript:clean:after',
+ callback
+ );
+});
+// First clean eventually existing type definition...
+gulp.task('docs:typescript:clean:before', function() {
+ return del('dist/paper.d.ts');
+});
+// ...then build the definition...
+gulp.task('docs:typescript:build', function() {
+ // First parse JSDoc comments and store parsed data in a temporary file...
+ return gulp.src('src')
+ .pipe(shell(
+ [
+ 'java -cp jsrun.jar:lib/* JsRun app/run.js',
+ ' -c=conf/typescript.conf ',
+ ' -D="file:../../gulp/typescript/typescript-definition-data.json"',
+ ' -D="version:', options.version, '"',
+ ' -D="date:', options.date, '"'
+ ].join(''),
+ { cwd: 'gulp/jsdoc' })
+ )
+ // ...then generate definition from parsed data...
+ .pipe(shell('node gulp/typescript/typescript-definition-generator.js'))
+ // ...finally test the definition by compiling a typescript file.
+ .pipe(shell('node node_modules/typescript/bin/tsc --project gulp/typescript'));
+});
+// ...finally remove all unneeded temporary files that were used for building.
+gulp.task('docs:typescript:clean:after', function() {
+ return del([
+ 'gulp/typescript/typescript-definition-data.json',
+ 'gulp/typescript/typescript-definition-test.js'
+ ]);
+});
diff --git a/gulp/tasks/jshint.js b/gulp/tasks/jshint.js
index 382f9154..987c96f4 100644
--- a/gulp/tasks/jshint.js
+++ b/gulp/tasks/jshint.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/gulp/tasks/load.js b/gulp/tasks/load.js
index 1d301aab..d985e74a 100644
--- a/gulp/tasks/load.js
+++ b/gulp/tasks/load.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/gulp/tasks/minify.js b/gulp/tasks/minify.js
index b55318bc..28d1b1aa 100644
--- a/gulp/tasks/minify.js
+++ b/gulp/tasks/minify.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/gulp/tasks/publish.js b/gulp/tasks/publish.js
index d1b07c37..25d37a00 100644
--- a/gulp/tasks/publish.js
+++ b/gulp/tasks/publish.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -32,20 +32,21 @@ var packages = ['paper-jsdom', 'paper-jsdom-canvas'],
end_with_newline: true
};
-gulp.task('publish', function() {
+gulp.task('publish', function(callback) {
if (options.branch !== 'develop') {
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(
+ run(
'publish:json',
'publish:dist',
'publish:packages',
'publish:commit',
'publish:website',
'publish:release',
- 'publish:load'
+ 'publish:load',
+ callback
);
});
@@ -108,11 +109,12 @@ packages.forEach(function(name) {
});
});
-gulp.task('publish:website', function() {
+gulp.task('publish:website', function(callback) {
if (fs.lstatSync(sitePath).isDirectory()) {
- return run(
+ run(
'publish:website:build',
- 'publish:website:push'
+ 'publish:website:push',
+ callback
);
}
});
diff --git a/gulp/tasks/test.js b/gulp/tasks/test.js
index 1982e46c..1ec61697 100644
--- a/gulp/tasks/test.js
+++ b/gulp/tasks/test.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/gulp/tasks/watch.js b/gulp/tasks/watch.js
index 5864e895..28a4dbdd 100644
--- a/gulp/tasks/watch.js
+++ b/gulp/tasks/watch.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/gulp/typescript/tsconfig.json b/gulp/typescript/tsconfig.json
new file mode 100644
index 00000000..7fbc4091
--- /dev/null
+++ b/gulp/typescript/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "target": "ES5",
+ "strictNullChecks": true
+ },
+ "files" : [
+ "typescript-definition-test.ts"
+ ]
+}
diff --git a/gulp/typescript/typescript-definition-generator.js b/gulp/typescript/typescript-definition-generator.js
new file mode 100644
index 00000000..7a8df070
--- /dev/null
+++ b/gulp/typescript/typescript-definition-generator.js
@@ -0,0 +1,339 @@
+/**
+ * This script generates a type definition by taking JSDoc roughly parsed data,
+ * formatting it and passing it to a mustache template.
+ */
+
+const fs = require('fs');
+const mustache = require('mustache');
+
+// Retrieve JSDoc data.
+const data = JSON.parse(fs.readFileSync(__dirname + '/typescript-definition-data.json', 'utf8'));
+const classes = data.classes;
+
+// Format classes.
+classes.forEach(cls => {
+ // Format class.
+ // Store name as `className` and not simply `name`, to avoid name conflict
+ // in static constructors block.
+ cls.className = cls._name;
+ // Store closest parent if there is one.
+ cls.extends = cls.inheritsFrom && cls.inheritsFrom.length > 0
+ ? cls.inheritsFrom[0]
+ : null;
+ // Store comment using class tag as description.
+ cls.comment = formatComment(cls.comment, 'class');
+
+ // Build a filter for deprecated or inherited methods or properties.
+ const filter = it => !it.deprecated && it.memberOf == cls.alias && !it.isNamespace;
+
+ // Format properties.
+ cls.properties = cls.properties
+ .filter(filter)
+ .map(it => ({
+ name: it._name,
+ type: formatType(it.type, { isProperty: true, isSettableProperty: !it.readOnly }),
+ static: formatStatic(it.isStatic),
+ readOnly: formatReadOnly(it.readOnly),
+ comment: formatComment(it.comment)
+ }));
+
+ // Format methods.
+ const methods = cls.methods
+ .filter(filter)
+ .map(it => {
+ const name = formatMethodName(it._name);
+ const isStaticConstructor = it.isStatic && it.isConstructor;
+ return {
+ name: name,
+ // Constructors don't need return type.
+ type: !it.isConstructor
+ ? formatType(getMethodReturnType(it), { isMethodReturnType: true })
+ : '',
+ static: formatStatic(it.isStatic),
+ // This flag is only used below to filter methods.
+ isStaticConstructor: isStaticConstructor,
+ comment: formatComment(it.comment, 'desc', it.isConstructor),
+ params: it._params
+ ? it._params
+ // Filter internal parameters (starting with underscore).
+ .filter(it => !/^_/.test(it.name))
+ .map(it => formatParameter(it, isStaticConstructor && cls))
+ .join(', ')
+ : ''
+ };
+ })
+ .sort(sortMethods);
+
+ // Divide methods in 2 parts: static constructors and other. Because static
+ // constructors need a special syntax in type definition.
+ cls.methods = [];
+ cls.staticConstructors = [];
+ methods.forEach(method => {
+ if (method.isStaticConstructor) {
+ // Group static constructors by method name.
+ let staticConstructors = cls.staticConstructors.find(it => it.name === method.name);
+ if (!staticConstructors) {
+ staticConstructors = {
+ name: method.name,
+ constructors: []
+ };
+ cls.staticConstructors.push(staticConstructors);
+ }
+ staticConstructors.constructors.push(method);
+ } else {
+ cls.methods.push(method);
+ }
+ });
+ // Store a conveniance flag to check whether class has static constructors.
+ cls.hasStaticConstructors = cls.staticConstructors.length > 0;
+});
+
+// PaperScope class needs to be handled slightly differently because it "owns"
+// all the other classes as properties. Eg. we can do `new paperScope.Path()`.
+// So we add a `classesPointers` property that the template will use.
+const paperScopeClass = classes.find(_ => _.className === 'PaperScope');
+paperScopeClass.classesPointers = classes.filter(_ => _.className !== 'PaperScope').map(_ => ({ name: _.className }));
+
+// Since paper.js module is at the same time a PaperScope instance, we need to
+// duplicate PaperScope instance properties and methods in the module scope.
+// For that, we expose a special variable to the template.
+const paperInstance = { ...paperScopeClass };
+// We filter static properties and methods for module scope.
+paperInstance.properties = paperInstance.properties.filter(_ => !_.static);
+paperInstance.methods = paperInstance.methods.filter(_ => !_.static && _.name !== 'constructor');
+
+// Format data trough a mustache template.
+// Prepare data for the template.
+const context = {
+ paperInstance: paperInstance,
+ classes: classes,
+ version: data.version,
+ date: data.date,
+ // {{#doc}} blocks are used in template to automatically generate a JSDoc
+ // comment with a custom indent.
+ doc: () => formatJSDoc
+};
+// Retrieve template content.
+const template = fs.readFileSync(__dirname + '/typescript-definition-template.mustache', 'utf8');
+// Render template.
+const output = mustache.render(template, context);
+// Write output in a file.
+fs.writeFileSync(__dirname + '/../../dist/paper.d.ts', output, 'utf8');
+
+
+//
+// METHODS
+//
+
+function formatReadOnly(isReadOnly) {
+ return isReadOnly ? 'readonly ' : null;
+}
+
+function formatStatic(isStatic) {
+ return isStatic ? 'static ' : null;
+}
+
+function formatType(type, options) {
+ return ': ' + parseType(type, options);
+}
+
+function parseType(type, options) {
+ // Always return a type even if input type is empty. In that case, return
+ // `void` for method return type and `any` for the rest.
+ if (!type) {
+ return options.isMethodReturnType ? 'void' : 'any';
+ }
+ // Prefer `any[]` over `Array` to be more consistent with other types.
+ if (type === 'Array') {
+ return 'any[]';
+ }
+ // Handle any type: `*` => `any`
+ type = type.replace('*', 'any');
+ // Check if type is a "rest" type (meaning that an infinite number of
+ // parameter of this type can be passed). In that case, we need to remove
+ // `...` prefix and add `[]` as a suffix:
+ // - `...Type` => `Type[]`
+ // - `...(TypeA|TypeB)` => `(TypeA|TypeB)[]`
+ const isRestType = type.startsWith('...');
+ if (isRestType) {
+ type = type.replace(/^\.\.\./, '');
+ }
+ // Handle multiple types possibility by splitting on `|` then re-joining
+ // back parsed types.
+ type = type.split('|').map(splittedType => {
+ // Get type without array suffix `[]` for easier matching.
+ const singleType = splittedType.replace(/(\[\])+$/, '');
+ // Handle eventual type conflict in static constructors block. For
+ // example, in `Path.Rectangle(rectangle: Rectangle)` method,
+ // `rectangle` parameter type must be mapped to `paper.Rectangle` as it
+ // is declared inside a `Path` namespace and would otherwise be wrongly
+ // assumed as being the type of `Path.Rectangle` class.
+ if (options.staticConstructorClass && options.staticConstructorClass.methods.find(it => it.isStatic && it.isConstructor && formatMethodName(it._name) === singleType)
+ ) {
+ return 'paper.' + splittedType;
+ }
+ // Convert primitive types to their lowercase equivalent to suit
+ // typescript best practices.
+ if (['Number', 'String', 'Boolean', 'Object'].indexOf(singleType) >= 0) {
+ splittedType = splittedType.toLowerCase();
+ }
+ // Properties `object` type need to be turned into `any` to avoid
+ // errors when reading object properties. Eg. if `property` is of type
+ // `object`, `property.key` access is forbidden.
+ if (options.isProperty && splittedType === 'object') {
+ return 'any';
+ }
+ return splittedType;
+ }).join(' | ');
+ if (isRestType) {
+ type += '[]';
+ }
+
+ // We declare settable properties as nullable to be compatible with
+ // TypeScript `strictNullChecks` option (#1664).
+ if (options.isSettableProperty && type !== 'any') {
+ type += ' | null';
+ }
+
+ return type;
+}
+
+function formatMethodName(methodName) {
+ // Overloaded methods were parsed as `method^0`, `method^1`... here, we
+ // turn them back to `method` as typescript allow overloading.
+ methodName = methodName.replace(/\^[0-9]+$/, '');
+ // Real contructors are called `initialize` in the library.
+ methodName = methodName.replace(/^initialize$/, 'constructor');
+ return methodName;
+}
+
+function formatParameter(param, staticConstructorClass) {
+ let content = '';
+ // Handle rest parameter pattern `...Type`. Parameter name needs to be
+ // prefixed with `...` as in ES6. E.g. `...parameter: type[]`.
+ if (param.type.match(/^\.\.\.(.+)$/)) {
+ content += '...';
+ }
+ content += formatParameterName(param.name);
+ // Optional parameters are formatted as: `parameter?: type`.
+ if (param.isOptional) {
+ content += '?';
+ }
+ content += formatType(param.type, { staticConstructorClass });
+ return content;
+}
+
+function formatParameterName(parameterName) {
+ // Avoid usage of reserved keyword as parameter name.
+ // E.g. `function` => `callback`.
+ if (parameterName === 'function') {
+ return 'callback';
+ }
+ return parameterName;
+}
+
+function formatComment(comment, descriptionTagName = 'desc', skipReturn = false) {
+ const tags = comment.tags;
+ let content = '';
+
+ // Retrieve description tag.
+ const descriptionTag = tags.find(it => it.title === descriptionTagName);
+ if (descriptionTag) {
+ // Don't display group titles.
+ content += descriptionTag.desc.replace(/\{@grouptitle .+?\}/g, '').trim();
+ }
+
+ // Preserve some of the JSDoc tags that can be usefull even in type
+ // definition. Format their values to make sure that only informations
+ // that make sense are kept. E.g. method parameters types are already
+ // provided in the signature...
+ content += formatCommentTags(tags, 'see');
+ content += formatCommentTags(tags, 'option');
+ content += formatCommentTags(tags, 'param', it => it.name + ' - ' + it.desc);
+
+ if (!skipReturn) {
+ content += formatCommentTags(tags, 'return', it => it.desc.trim().replace(/^\{|\}$/g, '').replace(/@([a-zA-Z]+)/, '$1'));
+ }
+
+ // Make sure links are followable (e.g. by IDEs) by removing parameters.
+ // {@link Class#method(param)} => {@link Class#method}
+ content = content.replace(/(\{@link [^\}]+?)\(.*?\)(\})/g, '$1$2');
+
+ content = content.trim();
+ return content;
+}
+
+function formatCommentTags(tags, tagName, formatter) {
+ let content = '';
+ // Default formatter simply outputs description.
+ formatter = formatter || (it => it.desc);
+ // Only keep tags that have a description.
+ tags = tags.filter(it => it.desc && it.title === tagName);
+ if (tags.length > 0) {
+ content += '\n';
+ // Display tag as it was in original JSDoc, followed by formatted value.
+ tags.forEach(it => content += '\n@' + tagName + ' ' + formatter(it));
+ }
+ return content;
+}
+
+/**
+ * This outputs a JSDoc comment indented at the given offset and including the
+ * parsed comment for current mustache block.
+ * @param {Number} offset the number of spaces to use for indentation
+ * @param {Function} render the mustache render method
+ * @return {string} the formatted JSDoc comment
+ */
+function formatJSDoc(offset, render) {
+ // First render current block comment. Use `{{&}}` syntax to make sure
+ // special characters are not escaped.
+ let content = render('{{&comment}}');
+ if (!content) {
+ return '';
+ }
+
+ // Build indentation.
+ offset = parseInt(offset);
+ if (offset > 0) {
+ offset++;
+ }
+ const indentation = new Array(offset).join(' ');
+
+ // Prefix each line with the indentation.
+ content = content.split('\n')
+ .map(_ => indentation + ' * ' + _)
+ .join('\n');
+
+ // Wrap content in JSDoc delimiters: `/**` and `*/`.
+ return '/** \n' + content + '\n' + indentation + ' */';
+}
+
+function getMethodReturnType(method) {
+ return method.returnType || method.returns.length > 0 && method.returns[0].type;
+}
+
+function sortMethods(methodA, methodB) {
+ // This places constructors before other methods as it is a best practice.
+ // This also place constructors with only one object parameter after other
+ // constructors to avoid type inference errors due to constructors
+ // overloading order. E.g. if `constructor(object: object)` is defined
+ // before `constructor(instance: Class)`, calling `constructor(instance)`
+ // will always be mapped to `contructor(object: object)`, since everything
+ // is an object in JavaScript. This is problematic because most of Paper.js
+ // classes have a constructor accepting an object.
+ const aIsContructor = methodA.name === 'constructor';
+ const bIsContructor = methodB.name === 'constructor';
+ if (aIsContructor && bIsContructor) {
+ if (methodA.params === 'object: object') {
+ return 1;
+ }
+ if (methodB.params === 'object: object') {
+ return -1;
+ }
+ } else if (aIsContructor) {
+ return -1;
+ } else if (bIsContructor) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/gulp/typescript/typescript-definition-template.mustache b/gulp/typescript/typescript-definition-template.mustache
new file mode 100644
index 00000000..3de46bcc
--- /dev/null
+++ b/gulp/typescript/typescript-definition-template.mustache
@@ -0,0 +1,70 @@
+/*!
+ * Paper.js v{{version}} - The Swiss Army Knife of Vector Graphics Scripting.
+ * http://paperjs.org/
+ *
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
+ *
+ * Distributed under the MIT license. See LICENSE file for details.
+ *
+ * All rights reserved.
+ *
+ * Date: {{date}}
+ *
+ * This is an auto-generated type definition.
+ */
+
+declare module paper {
+ {{#paperInstance}}
+ {{#properties}}
+ {{#doc}}4{{/doc}}
+ let {{name}}{{type}}
+
+ {{/properties}}
+
+ {{#methods}}
+ {{#doc}}4{{/doc}}
+ function {{name}}({{params}}){{type}}
+
+ {{/methods}}
+ {{/paperInstance}}
+
+ {{#classes}}
+
+ {{#doc}}4{{/doc}}
+ class {{className}} {{#extends}}extends {{extends}}{{/extends}} {
+ {{#properties}}
+ {{#doc}}8{{/doc}}
+ {{static}}{{readOnly}}{{name}}{{type}}
+
+ {{/properties}}
+ {{#classesPointers}}
+ {{name}}: typeof {{name}}
+ {{/classesPointers}}
+
+ {{#methods}}
+ {{#doc}}8{{/doc}}
+ {{static}}{{name}}({{params}}){{type}}
+
+ {{/methods}}
+ }
+ {{#hasStaticConstructors}}
+ namespace {{className}} {
+ {{#staticConstructors}}
+
+ class {{name}} extends {{className}} {
+ {{#constructors}}
+ {{#doc}}12{{/doc}}
+ constructor({{params}})
+
+ {{/constructors}}
+ }
+ {{/staticConstructors}}
+ }
+ {{/hasStaticConstructors}}
+ {{/classes}}
+}
+
+declare module 'paper' {
+ export = paper
+}
diff --git a/gulp/typescript/typescript-definition-test.ts b/gulp/typescript/typescript-definition-test.ts
new file mode 100644
index 00000000..0d0cead4
--- /dev/null
+++ b/gulp/typescript/typescript-definition-test.ts
@@ -0,0 +1,1206 @@
+///
+
+/**
+ * This file is used as a way to test auto-generated typescript definition
+ * validity. For now, this only check that calling methods as they are defined
+ * in online documentation does not throw error in typescript compilation.
+ *
+ * Todo: add more advanced type checking by using either:
+ * - typescript compiler check: `let result:type = methodCall()`
+ * - dedicated testing library like: https://github.com/Microsoft/dtslint
+ */
+
+import * as paper from 'paper';
+
+
+//
+// Utility variables
+//
+
+let point = {} as paper.Point;
+let size = {} as paper.Size;
+let rectangle = {} as paper.Rectangle;
+let matrix = {} as paper.Matrix;
+let project = {} as paper.Project;
+let item = {} as paper.Item;
+let layer = {} as paper.Layer;
+let group = {} as paper.Group;
+let shape = {} as paper.Shape;
+let raster = {} as paper.Raster;
+let pathItem = {} as paper.PathItem;
+let path = {} as paper.Path;
+let compoundPath = {} as paper.CompoundPath;
+let segment = {} as paper.Segment;
+let curve = {} as paper.Curve;
+let curveLocation = {} as paper.CurveLocation;
+let symbolDefinition = {} as paper.SymbolDefinition;
+let symbolItem = {} as paper.SymbolItem;
+let style = {} as paper.Style;
+let color = {} as paper.Color;
+let gradient = {} as paper.Gradient;
+let gradientStop = {} as paper.GradientStop;
+let textItem = {} as paper.TextItem;
+let pointText = {} as paper.PointText;
+let view = {} as paper.View;
+let event = {} as paper.Event;
+let mouseEvent = {} as paper.MouseEvent;
+let tool = {} as paper.Tool;
+let toolEvent = {} as paper.ToolEvent;
+let keyEvent = {} as paper.KeyEvent;
+let paperScope = {} as paper.PaperScope;
+let callback = {} as () => {};
+let hitResult = {} as paper.HitResult;
+let object = {} as object;
+
+
+//
+// Classes
+//
+
+//
+// Point
+//
+
+new paper.Point(0, 0);
+new paper.Point([ 0, 0 ]);
+new paper.Point({ x: 0, y: 0 });
+new paper.Point(size);
+new paper.Point(point);
+point.x;
+point.y;
+point.length;
+point.angle;
+point.angleInRadians;
+point.quadrant;
+point.selected;
+point.set(0, 0);
+point.set([ 0, 0 ]);
+point.set({ x: 0, y: 0 });
+point.set(size);
+point.set(point);
+point.equals(point);
+point.clone();
+point.toString();
+point.getAngle(point);
+point.getAngleInRadians(point);
+point.getDirectedAngle(point);
+point.getDistance(point, true);
+point.normalize();
+point.normalize(0);
+point.rotate(0, point);
+point.transform(matrix);
+point.isInside(rectangle);
+point.isClose(point, 0);
+point.isCollinear(point);
+point.isOrthogonal(point);
+point.isZero();
+point.isNaN();
+point.isInQuadrant(0);
+point.dot(point);
+point.cross(point);
+point.project(point);
+point.round();
+point.ceil();
+point.floor();
+point.abs();
+point.add(0);
+point.add(point);
+point.subtract(0);
+point.subtract(point);
+point.multiply(0);
+point.multiply(point);
+point.divide(0);
+point.divide(point);
+point.modulo(0);
+point.modulo(point);
+paper.Point.min(point, point);
+paper.Point.max(point, point);
+paper.Point.random();
+
+
+//
+// Size
+//
+
+
+new paper.Size(0, 0);
+new paper.Size([ 0, 0 ]);
+new paper.Size({ width: 0, height: 0 });
+new paper.Size(size);
+new paper.Size(point);
+size.width;
+size.height;
+size.set(0, 0);
+size.set([ 0, 0 ]);
+size.set({ x: 0, y: 0 });
+size.set(size);
+size.set(point);
+size.equals(size);
+size.clone();
+size.toString();
+size.isZero();
+size.isNaN();
+size.round();
+size.ceil();
+size.floor();
+size.abs();
+size.add(0);
+size.add(size);
+size.subtract(0);
+size.subtract(size);
+size.multiply(0);
+size.multiply(size);
+size.divide(0);
+size.divide(size);
+size.modulo(0);
+size.modulo(size);
+paper.Size.min(size, size);
+paper.Size.max(size, size);
+paper.Size.random();
+
+
+//
+// Rectangle
+//
+
+
+new paper.Rectangle(point, size);
+new paper.Rectangle({ point: point, size: size });
+new paper.Rectangle(0, 0, 0, 0);
+new paper.Rectangle(point, point);
+new paper.Rectangle(rectangle);
+rectangle.x;
+rectangle.y;
+rectangle.width;
+rectangle.height;
+rectangle.point;
+rectangle.size;
+rectangle.left;
+rectangle.top;
+rectangle.right;
+rectangle.bottom;
+rectangle.center;
+rectangle.topLeft;
+rectangle.topRight;
+rectangle.bottomLeft;
+rectangle.bottomRight;
+rectangle.leftCenter;
+rectangle.topCenter;
+rectangle.rightCenter;
+rectangle.bottomCenter;
+rectangle.area;
+rectangle.selected;
+rectangle.set(point, size);
+rectangle.set({ point: point, size: size });
+rectangle.set(0, 0, 0, 0);
+rectangle.set(point, point);
+rectangle.set(rectangle);
+rectangle.clone();
+rectangle.equals(rectangle);
+rectangle.toString();
+rectangle.isEmpty();
+rectangle.contains(point);
+rectangle.contains(rectangle);
+rectangle.intersects(rectangle);
+rectangle.intersects(rectangle, 0);
+rectangle.intersect(rectangle);
+rectangle.unite(rectangle);
+rectangle.include(point);
+rectangle.expand(0);
+rectangle.expand(0, 0);
+rectangle.scale(0);
+rectangle.scale(0, 0);
+
+
+//
+// Matrix
+//
+
+new paper.Matrix();
+new paper.Matrix(0, 0, 0, 0, 0, 0);
+new paper.Matrix([ 0, 0, 0, 0, 0, 0 ]);
+new paper.Matrix(matrix);
+matrix.a;
+matrix.b;
+matrix.c;
+matrix.d;
+matrix.tx;
+matrix.ty;
+matrix.values;
+matrix.translation;
+matrix.scaling;
+matrix.rotation;
+matrix.set(0, 0, 0, 0, 0, 0);
+matrix.set([ 0, 0, 0, 0, 0, 0 ]);
+matrix.set(matrix);
+matrix.clone();
+matrix.equals(matrix);
+matrix.toString();
+matrix.reset();
+matrix.apply();
+matrix.apply(true);
+matrix.translate(point);
+matrix.translate(0, 0);
+matrix.scale(0);
+matrix.scale(0, point);
+matrix.scale(0, 0);
+matrix.scale(0, 0, point);
+matrix.rotate(0, point);
+matrix.rotate(0, 0, 0);
+matrix.shear(point);
+matrix.shear(point, point);
+matrix.shear(0, 0);
+matrix.shear(0, 0, point);
+matrix.skew(point);
+matrix.skew(point, point);
+matrix.skew(0, 0);
+matrix.skew(0, 0, point);
+matrix.append(matrix);
+matrix.prepend(matrix);
+matrix.appended(matrix);
+matrix.prepended(matrix);
+matrix.invert();
+matrix.inverted();
+matrix.isIdentity();
+matrix.isInvertible();
+matrix.isSingular();
+matrix.transform(point);
+matrix.transform([ 0, 0 ], [ 0, 0 ], 0);
+matrix.inverseTransform(point);
+matrix.decompose();
+matrix.applyToContext({} as CanvasRenderingContext2D);
+
+
+//
+// Project
+//
+
+new paper.Project({} as HTMLCanvasElement);
+new paper.Project('');
+new paper.Project(size);
+project.view;
+project.currentStyle;
+project.index;
+project.layers;
+project.activeLayer;
+project.symbolDefinitions;
+project.selectedItems;
+project.activate();
+project.clear();
+project.isEmpty();
+project.remove();
+project.selectAll();
+project.deselectAll();
+project.addLayer(layer);
+project.insertLayer(0, layer);
+project.hitTest(point);
+project.hitTest(point, {});
+project.hitTestAll(point);
+project.hitTestAll(point, {});
+project.getItems({});
+project.getItems(callback);
+project.getItem({});
+project.getItem(callback);
+project.exportJSON();
+project.exportJSON({});
+project.importJSON('');
+project.exportSVG();
+project.exportSVG({});
+project.importSVG('');
+project.importSVG({} as SVGElement);
+project.importSVG('', {});
+project.importSVG('', callback);
+
+
+//
+// Item
+//
+
+item.id;
+item.className;
+item.name;
+item.style;
+item.locked;
+item.visible;
+item.blendMode;
+item.opacity;
+item.selected;
+item.clipMask;
+item.data;
+item.position;
+item.pivot;
+item.bounds;
+item.strokeBounds;
+item.handleBounds;
+item.rotation;
+item.scaling;
+item.matrix;
+item.globalMatrix;
+item.viewMatrix;
+item.applyMatrix;
+item.project;
+item.view;
+item.layer;
+item.parent;
+item.children;
+item.firstChild;
+item.lastChild;
+item.nextSibling;
+item.previousSibling;
+item.index;
+item.strokeColor;
+item.strokeWidth;
+item.strokeCap;
+item.strokeJoin;
+item.dashOffset;
+item.strokeScaling;
+item.dashArray;
+item.miterLimit;
+item.fillColor;
+item.fillColor && item.fillColor.red;
+item.fillRule;
+item.shadowColor;
+item.shadowBlur;
+item.shadowOffset;
+item.selectedColor;
+item.onFrame;
+item.onMouseDown;
+item.onMouseDrag;
+item.onMouseUp;
+item.onClick;
+item.onDoubleClick;
+item.onMouseMove;
+item.onMouseEnter;
+item.onMouseLeave;
+item.set({});
+item.clone();
+item.clone({});
+item.copyContent(item);
+item.copyAttributes(item, true);
+item.rasterize();
+item.rasterize(0);
+item.rasterize(0, true);
+item.contains(point);
+item.isInside(rectangle);
+item.intersects(item);
+item.hitTest(point);
+item.hitTest(point, {});
+item.hitTestAll(point);
+item.hitTestAll(point, {});
+item.matches({});
+item.matches(callback);
+item.matches(name, {});
+item.getItems({});
+item.getItems(callback);
+item.getItem({});
+item.getItem(callback);
+item.exportJSON();
+item.exportJSON({});
+item.importJSON('');
+item.exportSVG();
+item.exportSVG({});
+item.importSVG('');
+item.importSVG({} as SVGElement);
+item.importSVG('', {});
+item.importSVG('', callback);
+item.addChild(item);
+item.insertChild(0, item);
+item.addChildren([ item ]);
+item.insertChildren(0, [ item ]);
+item.insertAbove(item);
+item.insertBelow(item);
+item.sendToBack();
+item.bringToFront();
+item.addTo(group);
+item.copyTo(group);
+item.reduce({});
+item.remove();
+item.replaceWith(item);
+item.removeChildren();
+item.removeChildren(0);
+item.removeChildren(0, 0);
+item.reverseChildren();
+item.isEmpty();
+item.hasFill();
+item.hasStroke();
+item.hasShadow();
+item.hasChildren();
+item.isInserted();
+item.isAbove(item);
+item.isBelow(item);
+item.isParent(item);
+item.isChild(item);
+item.isDescendant(item);
+item.isAncestor(item);
+item.isSibling(item);
+item.isGroupedWith(item);
+item.translate(point);
+item.rotate(0);
+item.rotate(0, point);
+item.scale(0);
+item.scale(0, point);
+item.scale(0, 0);
+item.scale(0, 0, point);
+item.shear(point);
+item.shear(point, point);
+item.shear(0, 0);
+item.shear(0, 0, point);
+item.skew(point);
+item.skew(point, point);
+item.skew(0, 0);
+item.skew(0, 0, point);
+item.transform(matrix);
+item.globalToLocal(point);
+item.localToGlobal(point);
+item.parentToLocal(point);
+item.localToParent(point);
+item.fitBounds(rectangle);
+item.fitBounds(rectangle, true);
+item.on('', callback);
+item.on({});
+item.off('', callback);
+item.off({});
+item.emit('', event);
+item.responds('');
+item.removeOn({});
+item.removeOnMove();
+item.removeOnDown();
+item.removeOnDrag();
+item.removeOnUp();
+
+
+//
+// Layer
+//
+
+new paper.Layer([ item ]);
+new paper.Layer({});
+layer.activate();
+
+
+//
+// Group
+//
+
+new paper.Group([ item ]);
+new paper.Group({});
+group.clipped;
+
+
+//
+// Shape
+//
+
+new paper.Shape.Circle(point, 0);
+new paper.Shape.Circle({});
+new paper.Shape.Rectangle(rectangle);
+new paper.Shape.Rectangle(rectangle, size);
+new paper.Shape.Rectangle(point, size);
+new paper.Shape.Rectangle(point, point);
+new paper.Shape.Rectangle({});
+new paper.Shape.Ellipse(rectangle);
+new paper.Shape.Ellipse({});
+shape.type;
+shape.size;
+shape.radius;
+shape.toPath();
+shape.toPath(true);
+
+
+//
+// Raster
+//
+
+new paper.Raster();
+new paper.Raster({} as HTMLImageElement);
+new paper.Raster({} as HTMLCanvasElement);
+new paper.Raster('');
+new paper.Raster('', point);
+raster.size;
+raster.width;
+raster.height;
+raster.loaded;
+raster.resolution;
+raster.image;
+raster.canvas;
+raster.context;
+raster.source;
+raster.crossOrigin;
+raster.smoothing;
+raster.onLoad;
+raster.onLoad = () => {};
+raster.onLoad = null;
+raster.onError;
+raster.getSubCanvas(rectangle);
+raster.getSubRaster(rectangle);
+raster.toDataURL();
+raster.drawImage({} as HTMLImageElement, point);
+raster.getAverageColor(path);
+raster.getAverageColor(rectangle);
+raster.getAverageColor(point);
+raster.getPixel(0, 0);
+raster.getPixel(point);
+raster.setPixel(0, 0, color);
+raster.setPixel(point, color);
+raster.createImageData(size);
+raster.getImageData(rectangle);
+raster.setImageData({} as ImageData, point);
+
+
+//
+// HitResult
+//
+
+hitResult.type;
+hitResult.name;
+hitResult.item;
+hitResult.location;
+hitResult.color;
+hitResult.segment;
+hitResult.point;
+
+
+//
+// PathItem
+//
+
+pathItem.interiorPoint;
+pathItem.clockwise;
+pathItem.pathData;
+pathItem.unite(path);
+pathItem.unite(path, {});
+pathItem.intersect(path);
+pathItem.intersect(path, {});
+pathItem.subtract(path);
+pathItem.subtract(path, {});
+pathItem.exclude(path);
+pathItem.exclude(path, {});
+pathItem.divide(path);
+pathItem.divide(path, {});
+pathItem.reorient();
+pathItem.reorient(true);
+pathItem.reorient(true, true);
+pathItem.getIntersections(path);
+pathItem.getIntersections(path, callback);
+pathItem.getCrossings(path);
+pathItem.getNearestLocation(point);
+pathItem.getNearestPoint(point);
+pathItem.reverse();
+pathItem.flatten();
+pathItem.flatten(0);
+pathItem.smooth();
+pathItem.smooth({});
+pathItem.simplify();
+pathItem.simplify(0);
+pathItem.interpolate(path, path, 0);
+pathItem.compare(path);
+pathItem.moveTo(point);
+pathItem.lineTo(point);
+pathItem.arcTo(point, point);
+pathItem.arcTo(point);
+pathItem.arcTo(point, true);
+pathItem.curveTo(point, point);
+pathItem.curveTo(point, point, 0);
+pathItem.cubicCurveTo(point, point, point);
+pathItem.quadraticCurveTo(point, point);
+pathItem.closePath();
+pathItem.moveBy(point);
+pathItem.lineBy(point);
+pathItem.arcBy(point, point);
+pathItem.arcBy(point);
+pathItem.arcBy(point, true);
+pathItem.curveBy(point, point);
+pathItem.curveBy(point, point, 0);
+pathItem.cubicCurveBy(point, point, point);
+pathItem.quadraticCurveBy(point, point);
+paper.PathItem.create('');
+paper.PathItem.create([ [ 0 ] ]);
+paper.PathItem.create({});
+
+
+//
+// Path
+//
+
+new paper.Path();
+new paper.Path([ segment ]);
+new paper.Path(object);
+new paper.Path('');
+new paper.Path.Line(point, point);
+new paper.Path.Line(object);
+new paper.Path.Circle(point, 0);
+new paper.Path.Circle(object);
+new paper.Path.Rectangle(rectangle);
+new paper.Path.Rectangle(rectangle, size);
+new paper.Path.Rectangle(point, size);
+new paper.Path.Rectangle(point, point);
+new paper.Path.Rectangle(object);
+new paper.Path.Ellipse(rectangle);
+new paper.Path.Ellipse(object);
+new paper.Path.Arc(point, point, point);
+new paper.Path.Arc(object);
+new paper.Path.RegularPolygon(point, 0, 0);
+new paper.Path.RegularPolygon(object);
+new paper.Path.Star(point, 0, 0, 0);
+new paper.Path.Star(object);
+path.segments;
+path.firstSegment;
+path.lastSegment;
+path.curves;
+path.firstCurve;
+path.lastCurve;
+path.closed;
+path.length;
+path.area;
+path.fullySelected;
+path.add(segment);
+path.add(point);
+path.add([0,0]);
+path.add(segment, point, [0,0]);
+path.insert(0, segment);
+path.addSegments([ segment ]);
+path.insertSegments(0, [ segment ]);
+path.removeSegment(0);
+path.removeSegments();
+path.removeSegments(0);
+path.removeSegments(0, 0);
+path.hasHandles();
+path.clearHandles();
+path.divideAt(curveLocation);
+path.splitAt(curveLocation);
+path.join(path);
+path.join(path, 0);
+path.reduce(object);
+path.toShape();
+path.toShape(true);
+path.getLocationOf(point);
+path.getOffsetOf(point);
+path.getLocationAt(0);
+path.getPointAt(0);
+path.getTangentAt(0);
+path.getNormalAt(0);
+path.getWeightedTangentAt(0);
+path.getWeightedNormalAt(0);
+path.getCurvatureAt(0);
+path.getOffsetsWithTangent(point);
+
+
+//
+// CompoundPath
+//
+
+new paper.CompoundPath(object);
+new paper.CompoundPath('');
+compoundPath.closed;
+compoundPath.firstSegment;
+compoundPath.lastSegment;
+compoundPath.curves;
+compoundPath.firstCurve;
+compoundPath.lastCurve;
+compoundPath.area;
+compoundPath.length;
+
+
+//
+// Segment
+//
+
+new paper.Segment();
+new paper.Segment(point);
+new paper.Segment(point, point);
+new paper.Segment(point, point, point);
+new paper.Segment(object);
+segment.point;
+segment.handleIn;
+segment.handleOut;
+segment.selected;
+segment.index;
+segment.path;
+segment.curve;
+segment.location;
+segment.next;
+segment.previous;
+segment.hasHandles();
+segment.isSmooth();
+segment.clearHandles();
+segment.smooth();
+segment.smooth(object);
+segment.isFirst();
+segment.isLast();
+segment.reverse();
+segment.reversed();
+segment.remove();
+segment.toString();
+segment.transform(matrix);
+segment.interpolate(segment, segment, 0);
+
+
+//
+// Curve
+//
+
+new paper.Curve(segment, segment);
+new paper.Curve(point, point, point, point);
+curve.point1;
+curve.point2;
+curve.handle1;
+curve.handle2;
+curve.segment1;
+curve.segment2;
+curve.path;
+curve.index;
+curve.next;
+curve.previous;
+curve.selected;
+curve.values;
+curve.points;
+curve.length;
+curve.area;
+curve.bounds;
+curve.strokeBounds;
+curve.handleBounds;
+curve.clone();
+curve.toString();
+curve.classify();
+curve.remove();
+curve.isFirst();
+curve.isLast();
+curve.getPart(0, 0);
+curve.divideAt(curveLocation);
+curve.divideAtTime(0);
+curve.splitAt(curveLocation);
+curve.splitAtTime(0);
+curve.reversed();
+curve.clearHandles();
+curve.hasHandles();
+curve.hasLength();
+curve.hasLength(0);
+curve.isStraight();
+curve.isLinear();
+curve.isCollinear(curve);
+curve.isHorizontal();
+curve.isVertical();
+curve.getLocationAt(0);
+curve.getLocationAtTime(0);
+curve.getTimeAt(0);
+curve.getTimeAt(0, 0);
+curve.getTimesWithTangent(point);
+curve.getOffsetAtTime(0);
+curve.getLocationOf(point);
+curve.getOffsetOf(point);
+curve.getTimeOf(point);
+curve.getNearestLocation(point);
+curve.getNearestPoint(point);
+curve.getPointAt(curveLocation);
+curve.getTangentAt(curveLocation);
+curve.getNormalAt(curveLocation);
+curve.getWeightedTangentAt(curveLocation);
+curve.getWeightedNormalAt(curveLocation);
+curve.getCurvatureAt(curveLocation);
+curve.getPointAtTime(0);
+curve.getTangentAtTime(0);
+curve.getNormalAtTime(0);
+curve.getWeightedTangentAtTime(0);
+curve.getWeightedNormalAtTime(0);
+curve.getCurvatureAtTime(0);
+curve.getIntersections(curve);
+
+
+//
+// CurveLocation
+//
+
+new paper.CurveLocation(curve, 0);
+new paper.CurveLocation(curve, 0, point);
+curveLocation.segment;
+curveLocation.curve;
+curveLocation.path;
+curveLocation.index;
+curveLocation.time;
+curveLocation.point;
+curveLocation.offset;
+curveLocation.curveOffset;
+curveLocation.intersection;
+curveLocation.tangent;
+curveLocation.normal;
+curveLocation.curvature;
+curveLocation.distance;
+curveLocation.equals(curveLocation);
+curveLocation.toString();
+curveLocation.isTouching();
+curveLocation.isCrossing();
+curveLocation.hasOverlap();
+
+
+//
+// SymbolDefinition
+//
+
+new paper.SymbolDefinition(item);
+new paper.SymbolDefinition(item, true);
+symbolDefinition.project;
+symbolDefinition.item;
+symbolDefinition.place();
+symbolDefinition.place(point);
+symbolDefinition.clone();
+symbolDefinition.equals(symbolDefinition);
+
+
+//
+// SymbolItem
+//
+
+new paper.SymbolItem(symbolDefinition);
+new paper.SymbolItem(item);
+new paper.SymbolItem(symbolDefinition, point);
+symbolItem.definition;
+
+
+//
+// Style
+//
+
+new paper.Style(object);
+style.view;
+style.strokeColor;
+style.strokeWidth;
+style.strokeCap;
+style.strokeJoin;
+style.strokeScaling;
+style.dashOffset;
+style.dashArray;
+style.miterLimit;
+style.fillColor;
+style.fillRule;
+style.shadowColor;
+style.shadowBlur;
+style.shadowOffset;
+style.selectedColor;
+style.fontFamily;
+style.fontWeight;
+style.fontSize;
+style.leading;
+style.justification;
+
+
+//
+// Color
+//
+
+new paper.Color(0, 0, 0);
+new paper.Color(0, 0, 0, 0);
+new paper.Color(0);
+new paper.Color(0, 0);
+new paper.Color(object);
+new paper.Color('');
+new paper.Color(gradient, point, point);
+new paper.Color(gradient, point, point, point);
+color.type;
+color.components;
+color.alpha;
+color.red;
+color.green;
+color.blue;
+color.gray;
+color.hue;
+color.saturation;
+color.brightness;
+color.lightness;
+color.gradient;
+color.highlight;
+color.set(0, 0, 0);
+color.set(0, 0, 0, 0);
+color.set(0);
+color.set(0, 0);
+color.set(object);
+color.set(color);
+color.set(gradient, point, point);
+color.set(gradient, point, point, point);
+color.convert('');
+color.hasAlpha();
+color.equals(color);
+color.clone();
+color.toString();
+color.toCSS(true);
+color.transform(matrix);
+color.add(0);
+color.add(color);
+color.subtract(0);
+color.subtract(color);
+color.multiply(0);
+color.multiply(color);
+color.divide(0);
+color.divide(color);
+paper.Color.random();
+
+
+//
+// Gradient
+//
+
+gradient.stops;
+gradient.radial;
+gradient.clone();
+gradient.equals(gradient);
+
+
+//
+// GradientStop
+//
+
+new paper.GradientStop();
+new paper.GradientStop(color);
+new paper.GradientStop(color, 0);
+gradientStop.offset;
+gradientStop.color;
+gradientStop.clone();
+
+
+//
+// TextItem
+//
+
+textItem.content;
+textItem.fontFamily;
+textItem.fontWeight;
+textItem.fontSize;
+textItem.leading;
+textItem.justification;
+
+
+//
+// PointText
+//
+
+new paper.PointText(point);
+new paper.PointText(object);
+pointText.point;
+
+
+//
+// View
+//
+
+view.autoUpdate;
+view.element;
+view.pixelRatio;
+view.resolution;
+view.viewSize;
+view.bounds;
+view.size;
+view.center;
+view.zoom;
+view.rotation;
+view.scaling;
+view.matrix;
+view.onFrame;
+view.onResize;
+view.onMouseDown;
+view.onMouseDrag;
+view.onMouseUp;
+view.onClick;
+view.onDoubleClick;
+view.onMouseMove;
+view.onMouseEnter;
+view.onMouseLeave;
+view.remove();
+view.update();
+view.requestUpdate();
+view.play();
+view.pause();
+view.isVisible();
+view.isInserted();
+view.translate(point);
+view.rotate(0);
+view.rotate(0, point);
+view.scale(0);
+view.scale(0, point);
+view.scale(0, 0);
+view.scale(0, 0, point);
+view.shear(point);
+view.shear(point, point);
+view.shear(0, 0);
+view.shear(0, 0, point);
+view.skew(point);
+view.skew(point, point);
+view.skew(0, 0);
+view.skew(0, 0, point);
+view.transform(matrix);
+view.projectToView(point);
+view.viewToProject(point);
+view.getEventPoint(event);
+view.on('', callback);
+view.on(object);
+view.off('', callback);
+view.off(object);
+view.emit('', event);
+view.responds('');
+
+
+//
+// Event
+//
+
+event.timeStamp;
+event.modifiers;
+event.modifiers.shift;
+event.preventDefault();
+event.stopPropagation();
+event.stop();
+
+
+//
+// MouseEvent
+//
+
+mouseEvent.type;
+mouseEvent.point;
+mouseEvent.target;
+mouseEvent.currentTarget;
+mouseEvent.delta;
+mouseEvent.toString();
+
+
+//
+// Tool
+//
+
+tool.minDistance;
+tool.maxDistance;
+tool.fixedDistance;
+tool.onMouseDown;
+tool.onMouseDrag;
+tool.onMouseMove;
+tool.onMouseUp;
+tool.onKeyDown;
+tool.onKeyUp;
+tool.activate();
+tool.remove();
+tool.on('', callback);
+tool.on(object);
+tool.off('', callback);
+tool.off(object);
+tool.emit('', event);
+tool.responds('');
+
+
+//
+// ToolEvent
+//
+
+toolEvent.type;
+toolEvent.point;
+toolEvent.lastPoint;
+toolEvent.downPoint;
+toolEvent.middlePoint;
+toolEvent.delta;
+toolEvent.count;
+toolEvent.item;
+toolEvent.toString();
+
+
+//
+// Key
+//
+
+paper.Key.modifiers;
+paper.Key.isDown('');
+
+
+//
+// KeyEvent
+//
+
+keyEvent.type;
+keyEvent.character;
+keyEvent.key;
+keyEvent.toString();
+
+
+//
+// PaperScope
+//
+
+new paper.PaperScope();
+paperScope.version;
+paperScope.settings;
+paperScope.settings = null;
+paperScope.project;
+paperScope.projects;
+paperScope.view;
+paperScope.tool;
+paperScope.tools;
+paperScope.execute('');
+paperScope.execute('', object);
+paperScope.install(object);
+paperScope.setup('');
+paperScope.setup({} as HTMLCanvasElement);
+paperScope.setup(size);
+paperScope.activate();
+paper.PaperScope.get(0);
+new paperScope.Color('');
+new paperScope.CompoundPath('');
+new paperScope.Curve(segment, segment);
+new paperScope.CurveLocation(curve, 0);
+new paperScope.Event();
+new paperScope.Gradient();
+new paperScope.GradientStop();
+new paperScope.Group();
+new paperScope.HitResult();
+new paperScope.Item();
+new paperScope.Key();
+new paperScope.KeyEvent();
+new paperScope.Layer();
+new paperScope.Matrix();
+new paperScope.MouseEvent();
+new paperScope.PaperScript();
+new paperScope.Path();
+new paperScope.PathItem();
+new paperScope.Point(0, 0);
+new paperScope.PointText(point);
+new paperScope.Project(size);
+new paperScope.Raster();
+new paperScope.Rectangle(point, size);
+new paperScope.Segment();
+new paperScope.Shape();
+new paperScope.Size(0,0);
+new paperScope.Style(object);
+new paperScope.SymbolDefinition(item);
+new paperScope.SymbolItem(symbolDefinition);
+new paperScope.TextItem();
+new paperScope.Tool();
+new paperScope.ToolEvent();
+new paperScope.Tween(object, object, object, 0);
+new paperScope.View();
+
+
+//
+// Global PaperScope instance
+//
+
+paper.version;
+paper.settings;
+paper.project;
+paper.projects;
+paper.view;
+paper.tool;
+paper.tools;
+paper.execute('');
+paper.execute('', object);
+paper.install(object);
+paper.setup('');
+paper.setup({} as HTMLCanvasElement);
+paper.setup(size);
+paper.activate();
+
+
+//
+// PaperScript
+//
+
+paper.PaperScript.compile('');
+paper.PaperScript.compile('', object);
+paper.PaperScript.execute('', paperScope);
+paper.PaperScript.execute('', paperScope, object);
+paper.PaperScript.load();
+paper.PaperScript.load({} as HTMLScriptElement);
diff --git a/gulp/utils/error.js b/gulp/utils/error.js
index cfd92c58..b61b9a82 100644
--- a/gulp/utils/error.js
+++ b/gulp/utils/error.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/gulp/utils/options.js b/gulp/utils/options.js
index b9e4a414..09b48cc4 100644
--- a/gulp/utils/options.js
+++ b/gulp/utils/options.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -24,9 +24,10 @@ options.date = git('log -1 --pretty=format:%ad');
options.branch = git('rev-parse --abbrev-ref HEAD');
// If a specific branch is requested, quit without errors if we don't match.
-if (argv.branch && argv.branch !== options.branch) {
- console.log('Branch "' + options.branch + '" does not match "' +
- argv.branch + '". There is nothing to do here.');
+var ensureBranch = argv['ensure-branch'];
+if (ensureBranch && ensureBranch !== options.branch) {
+ console.log('Branch "' + options.branch + '" does not match requested "' +
+ ensureBranch + '". There is nothing to do here.');
process.exit(0);
}
diff --git a/gulpfile.js b/gulpfile.js
index 0e6e6fc3..ecb7f8d1 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/package.json b/package.json
index b7951e6a..e157fdcc 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@scratch/paper",
- "version": "0.11.8",
+ "version": "0.12.3",
"description": "The Swiss Army Knife of Vector Graphics Scripting",
"license": "MIT",
"homepage": "http://paperjs.org",
@@ -9,11 +9,13 @@
"url": "https://github.com/paperjs/paper.js"
},
"bugs": "https://github.com/paperjs/paper.js/issues",
- "contributors": ["Jürg Lehni (http://scratchdisk.com)", "Jonathan Puckey (http://studiomoniker.com)"],
+ "contributors": [
+ "Jürg Lehni (http://scratchdisk.com)",
+ "Jonathan Puckey (http://studiomoniker.com)"
+ ],
"main": "dist/paper-full.js",
+ "types": "dist/paper.d.ts",
"scripts": {
- "precommit": "gulp jshint --branch develop",
- "prepush": "gulp test --branch develop",
"build": "gulp build",
"dist": "gulp dist",
"zip": "gulp zip",
@@ -22,44 +24,22 @@
"jshint": "gulp jshint",
"test": "gulp test"
},
- "files": ["AUTHORS.md", "CHANGELOG.md", "dist/", "examples/", "LICENSE.txt", "README.md"],
+ "files": [
+ "AUTHORS.md",
+ "CHANGELOG.md",
+ "dist/",
+ "examples/",
+ "LICENSE.txt",
+ "README.md"
+ ],
"engines": {
- "node": ">=4.0.0"
+ "node": ">=8.0.0"
},
- "devDependencies": {
- "acorn": "~0.5.0",
- "canvas-prebuilt": "^2.0.0-alpha.14",
- "del": "^2.2.1",
- "gulp": "^3.9.1",
- "gulp-cached": "^1.1.0",
- "gulp-git-streamed": "^2.8.1",
- "gulp-jshint": "^2.0.0",
- "gulp-json-editor": "^2.2.1",
- "gulp-prepro": "^2.4.0",
- "gulp-qunits": "^2.1.1",
- "gulp-rename": "^1.2.2",
- "gulp-shell": "^0.5.2",
- "gulp-symlink": "^2.1.4",
- "gulp-uglify": "^1.5.4",
- "gulp-uncomment": "^0.3.0",
- "gulp-util": "^3.0.7",
- "gulp-webserver": "^0.9.1",
- "gulp-whitespace": "^0.1.0",
- "gulp-zip": "^3.2.0",
- "husky": "^0.11.4",
- "jsdom": "^9.4.0",
- "jshint": "^2.9.2",
- "jshint-summary": "^0.4.0",
- "merge-stream": "^1.0.0",
- "minimist": "^1.2.0",
- "prepro": "^2.4.0",
- "qunitjs": "^1.23.0",
- "require-dir": "^0.3.0",
- "resemblejs": "^2.2.1",
- "run-sequence": "^1.2.2",
- "source-map-support": "^0.4.0",
- "stats.js": "0.16.0",
- "straps": "^3.0.1"
+ "husky": {
+ "hooks": {
+ "pre-commit": "gulp jshint --ensure-branch develop",
+ "pre-push": "gulp test --ensure-branch develop"
+ }
},
"browser": {
"canvas": false,
@@ -69,5 +49,58 @@
"./dist/node/self.js": false,
"./dist/node/extend.js": false
},
- "keywords": ["vector", "graphic", "graphics", "2d", "geometry", "bezier", "curve", "curves", "path", "paths", "canvas", "svg", "paper", "paper.js", "paperjs"]
+ "devDependencies": {
+ "acorn": "~0.5.0",
+ "canvas": "^2.6.0",
+ "del": "^4.1.0",
+ "gulp": "^3.9.1",
+ "gulp-cached": "^1.1.0",
+ "gulp-git-streamed": "^2.8.1",
+ "gulp-jshint": "^2.1.0",
+ "gulp-json-editor": "^2.5.2",
+ "gulp-prepro": "^2.4.0",
+ "gulp-qunits": "^2.1.2",
+ "gulp-rename": "^1.4.0",
+ "gulp-shell": "^0.7.0",
+ "gulp-symlink": "^2.1.4",
+ "gulp-uglify": "^1.5.4",
+ "gulp-uncomment": "^0.3.0",
+ "gulp-util": "^3.0.7",
+ "gulp-webserver": "^0.9.1",
+ "gulp-whitespace": "^0.1.0",
+ "gulp-zip": "^3.2.0",
+ "husky": "^2.3.0",
+ "jsdom": "^15.1.1",
+ "jshint": "^2.10.2",
+ "jshint-summary": "^0.4.0",
+ "merge-stream": "^2.0.0",
+ "minimist": "^1.2.0",
+ "mustache": "^3.0.1",
+ "prepro": "^2.4.0",
+ "qunitjs": "^1.23.0",
+ "require-dir": "^1.2.0",
+ "resemblejs": "^3.2.3",
+ "run-sequence": "^2.2.1",
+ "source-map-support": "^0.5.12",
+ "stats.js": "0.17.0",
+ "straps": "^3.0.1",
+ "typescript": "^3.1.6"
+ },
+ "keywords": [
+ "vector",
+ "graphic",
+ "graphics",
+ "2d",
+ "geometry",
+ "bezier",
+ "curve",
+ "curves",
+ "path",
+ "paths",
+ "canvas",
+ "svg",
+ "paper",
+ "paper.js",
+ "paperjs"
+ ]
}
diff --git a/packages/paper-jsdom b/packages/paper-jsdom
index f601084f..0fb6283f 160000
--- a/packages/paper-jsdom
+++ b/packages/paper-jsdom
@@ -1 +1 @@
-Subproject commit f601084fc319734d0bf47da700d6b6bff95260ba
+Subproject commit 0fb6283f0955b8ee92fc9ac8838f167ea4a965d2
diff --git a/packages/paper-jsdom-canvas b/packages/paper-jsdom-canvas
index a07b7d14..1e276564 160000
--- a/packages/paper-jsdom-canvas
+++ b/packages/paper-jsdom-canvas
@@ -1 +1 @@
-Subproject commit a07b7d149f02e980dfd837cd595f5000a9d5e052
+Subproject commit 1e276564106e5a29a6e00115c7e703cfc1fc2b09
diff --git a/src/anim/Tween.js b/src/anim/Tween.js
new file mode 100644
index 00000000..790fee86
--- /dev/null
+++ b/src/anim/Tween.js
@@ -0,0 +1,398 @@
+/*
+ * Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
+ * http://paperjs.org/
+ *
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
+ *
+ * Distributed under the MIT license. See LICENSE file for details.
+ *
+ * All rights reserved.
+ */
+
+/**
+ * @name Tween
+ *
+ * @class Allows tweening `Object` properties between two states for a given
+ * duration. To tween properties on Paper.js {@link Item} instances,
+ * {@link Item#tween(from, to, options)} can be used, which returns created
+ * tween instance.
+ *
+ * @see Item#tween(from, to, options)
+ * @see Item#tween(to, options)
+ * @see Item#tween(options)
+ * @see Item#tweenTo(to, options)
+ * @see Item#tweenFrom(from, options)
+ */
+var Tween = Base.extend(Emitter, /** @lends Tween# */{
+ _class: 'Tween',
+
+ statics: {
+ easings: {
+ // no easing, no acceleration
+ linear: function(t) {
+ return t;
+ },
+
+ // accelerating from zero velocity
+ easeInQuad: function(t) {
+ return t * t;
+ },
+
+ // decelerating to zero velocity
+ easeOutQuad: function(t) {
+ return t * (2 - t);
+ },
+
+ // acceleration until halfway, then deceleration
+ easeInOutQuad: function(t) {
+ return t < 0.5
+ ? 2 * t * t
+ : -1 + 2 * (2 - t) * t;
+ },
+
+ // accelerating from zero velocity
+ easeInCubic: function(t) {
+ return t * t * t;
+ },
+
+ // decelerating to zero velocity
+ easeOutCubic: function(t) {
+ return --t * t * t + 1;
+ },
+
+ // acceleration until halfway, then deceleration
+ easeInOutCubic: function(t) {
+ return t < 0.5
+ ? 4 * t * t * t
+ : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
+ },
+
+ // accelerating from zero velocity
+ easeInQuart: function(t) {
+ return t * t * t * t;
+ },
+
+ // decelerating to zero velocity
+ easeOutQuart: function(t) {
+ return 1 - (--t) * t * t * t;
+ },
+
+ // acceleration until halfway, then deceleration
+ easeInOutQuart: function(t) {
+ return t < 0.5
+ ? 8 * t * t * t * t
+ : 1 - 8 * (--t) * t * t * t;
+ },
+
+ // accelerating from zero velocity
+ easeInQuint: function(t) {
+ return t * t * t * t * t;
+ },
+
+ // decelerating to zero velocity
+ easeOutQuint: function(t) {
+ return 1 + --t * t * t * t * t;
+ },
+
+ // acceleration until halfway, then deceleration
+ easeInOutQuint: function(t) {
+ return t < 0.5
+ ? 16 * t * t * t * t * t
+ : 1 + 16 * (--t) * t * t * t * t;
+ }
+ }
+ },
+
+ /**
+ * Creates a new tween.
+ *
+ * @param {Object} object the object to tween the properties on
+ * @param {Object} from the state at the start of the tweening
+ * @param {Object} to the state at the end of the tweening
+ * @param {Number} duration the duration of the tweening
+ * @param {String|Function} [easing='linear'] the type of the easing
+ * function or the easing function
+ * @param {Boolean} [start=true] whether to start tweening automatically
+ * @return {Tween} the newly created tween
+ */
+ initialize: function Tween(object, from, to, duration, easing, start) {
+ this.object = object;
+ var type = typeof easing;
+ var isFunction = type === 'function';
+ this.type = isFunction
+ ? type
+ : type === 'string'
+ ? easing
+ : 'linear';
+ this.easing = isFunction ? easing : Tween.easings[this.type];
+ this.duration = duration;
+ this.running = false;
+
+ this._then = null;
+ this._startTime = null;
+ var state = from || to;
+ this._keys = state ? Object.keys(state) : [];
+ this._parsedKeys = this._parseKeys(this._keys);
+ this._from = state && this._getState(from);
+ this._to = state && this._getState(to);
+ if (start !== false) {
+ this.start();
+ }
+ },
+
+ /**
+ * Set a function that will be executed when the tween completes.
+ * @param {Function} function the function to execute when the tween
+ * completes
+ * @return {Tween}
+ *
+ * @example {@paperscript}
+ * // Tweens chaining:
+ * var circle = new Path.Circle({
+ * center: view.center,
+ * radius: 40,
+ * fillColor: 'blue'
+ * });
+ * // Tween color from blue to red.
+ * var tween = circle.tweenTo({ fillColor: 'red' }, 2000);
+ * // When the first tween completes...
+ * tween.then(function() {
+ * // ...tween color back to blue.
+ * circle.tweenTo({ fillColor: 'blue' }, 2000);
+ * });
+ */
+ then: function(then) {
+ this._then = then;
+ return this;
+ },
+
+ /**
+ * Start tweening.
+ * @return {Tween}
+ *
+ * @example {@paperscript}
+ * // Manually start tweening.
+ * var circle = new Path.Circle({
+ * center: view.center,
+ * radius: 40,
+ * fillColor: 'blue'
+ * });
+ * var tween = circle.tweenTo(
+ * { fillColor: 'red' },
+ * { duration: 2000, start: false }
+ * );
+ * tween.start();
+ */
+ start: function() {
+ this._startTime = null;
+ this.running = true;
+ return this;
+ },
+
+ /**
+ * Stop tweening.
+ * @return {Tween}
+ *
+ * @example {@paperscript}
+ * // Stop a tween before it completes.
+ * var circle = new Path.Circle({
+ * center: view.center,
+ * radius: 40,
+ * fillColor: 'blue'
+ * });
+ * // Start tweening from blue to red for 2 seconds.
+ * var tween = circle.tweenTo({ fillColor: 'red' }, 2000);
+ * // After 1 second...
+ * setTimeout(function(){
+ * // ...stop tweening.
+ * tween.stop();
+ * }, 1000);
+ */
+ stop: function() {
+ this.running = false;
+ return this;
+ },
+
+ // DOCS: Document Tween#update(progress)
+ update: function(progress) {
+ if (this.running) {
+ if (progress > 1) {
+ // always finish the animation
+ progress = 1;
+ this.running = false;
+ }
+
+ var factor = this.easing(progress),
+ keys = this._keys,
+ getValue = function(value) {
+ return typeof value === 'function'
+ ? value(factor, progress)
+ : value;
+ };
+ for (var i = 0, l = keys && keys.length; i < l; i++) {
+ var key = keys[i],
+ from = getValue(this._from[key]),
+ to = getValue(this._to[key]),
+ // Some paper objects have math functions (e.g.: Point,
+ // Color) which can directly be used to do the tweening.
+ value = (from && to && from.__add && to.__add)
+ ? to.__subtract(from).__multiply(factor).__add(from)
+ : ((to - from) * factor) + from;
+ this._setProperty(this._parsedKeys[key], value);
+ }
+
+ if (!this.running && this._then) {
+ // TODO Look into what should be returned.
+ this._then(this.object);
+ }
+ if (this.responds('update')) {
+ this.emit('update', new Base({
+ progress: progress,
+ factor: factor
+ }));
+ }
+ }
+ return this;
+ },
+
+ /**
+ * {@grouptitle Event Handlers}
+ *
+ * The function to be called when the tween is updated. It receives an
+ * object as its sole argument, containing the current progress of the
+ * tweening and the factor calculated by the easing function.
+ *
+ * @name Tween#onUpdate
+ * @property
+ * @type Function
+ *
+ * @example {@paperscript}
+ * // Display tween progression values:
+ * var circle = new Path.Circle({
+ * center: view.center,
+ * radius: 40,
+ * fillColor: 'blue'
+ * });
+ * var tween = circle.tweenTo(
+ * { fillColor: 'red' },
+ * {
+ * duration: 2000,
+ * easing: 'easeInCubic'
+ * }
+ * );
+ * var progressText = new PointText(view.center + [60, -10]);
+ * var factorText = new PointText(view.center + [60, 10]);
+ *
+ * // Install event using onUpdate() property:
+ * tween.onUpdate = function(event) {
+ * progressText.content = 'progress: ' + event.progress.toFixed(2);
+ * };
+ *
+ * // Install event using on('update') method:
+ * tween.on('update', function(event) {
+ * factorText.content = 'factor: ' + event.factor.toFixed(2);
+ * });
+ */
+ _events: {
+ onUpdate: {}
+ },
+
+ _handleFrame: function(time) {
+ var startTime = this._startTime,
+ progress = startTime
+ ? (time - startTime) / this.duration
+ : 0;
+ if (!startTime) {
+ this._startTime = time;
+ }
+ this.update(progress);
+ },
+
+ _getState: function(state) {
+ var keys = this._keys,
+ result = {};
+ for (var i = 0, l = keys.length; i < l; i++) {
+ var key = keys[i],
+ path = this._parsedKeys[key],
+ current = this._getProperty(path),
+ value;
+ if (state) {
+ var resolved = this._resolveValue(current, state[key]);
+ // Temporarily set the resolved value, so we can retrieve the
+ // coerced value from paper's internal magic.
+ this._setProperty(path, resolved);
+ value = this._getProperty(path);
+ // Clone the value if possible to prevent future changes.
+ value = value && value.clone ? value.clone() : value;
+ this._setProperty(path, current);
+ } else {
+ // We want to get the current state at the time of the call, so
+ // we have to clone if possible to prevent future changes.
+ value = current && current.clone ? current.clone() : current;
+ }
+ result[key] = value;
+ }
+ return result;
+ },
+
+ _resolveValue: function(current, value) {
+ if (value) {
+ if (Array.isArray(value) && value.length === 2) {
+ var operator = value[0];
+ return (
+ operator &&
+ operator.match &&
+ // We're (unnecessarily) escaping '*/' here to not confuse
+ // the ol' JSDoc parser...
+ operator.match(/^[+\-\*\/]=/)
+ )
+ ? this._calculate(current, operator[0], value[1])
+ : value;
+ } else if (typeof value === 'string') {
+ var match = value.match(/^[+\-*/]=(.*)/);
+ if (match) {
+ var parsed = JSON.parse(match[1].replace(
+ /(['"])?([a-zA-Z0-9_]+)(['"])?:/g,
+ '"$2": '
+ ));
+ return this._calculate(current, value[0], parsed);
+ }
+ }
+ }
+ return value;
+ },
+
+ _calculate: function(left, operator, right) {
+ return paper.PaperScript.calculateBinary(left, operator, right);
+ },
+
+ _parseKeys: function(keys) {
+ var parsed = {};
+ for (var i = 0, l = keys.length; i < l; i++) {
+ var key = keys[i],
+ path = key
+ // Convert from JS property access notation to JSON pointer:
+ .replace(/\.([^.]*)/g, '/$1')
+ // Expand array property access notation ([])
+ .replace(/\[['"]?([^'"\]]*)['"]?\]/g, '/$1');
+ parsed[key] = path.split('/');
+ }
+ return parsed;
+ },
+
+ _getProperty: function(path, offset) {
+ var obj = this.object;
+ for (var i = 0, l = path.length - (offset || 0); i < l && obj; i++) {
+ obj = obj[path[i]];
+ }
+ return obj;
+ },
+
+ _setProperty: function(path, value) {
+ var dest = this._getProperty(path, 1);
+ if (dest) {
+ dest[path[path.length - 1]] = value;
+ }
+ }
+});
diff --git a/src/basic/Line.js b/src/basic/Line.js
index fc08eb71..84893fd8 100644
--- a/src/basic/Line.js
+++ b/src/basic/Line.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -12,8 +12,8 @@
/**
* @name Line
- *
* @class The Line object represents..
+ * @private
*/
var Line = Base.extend(/** @lends Line# */{
_class: 'Line',
diff --git a/src/basic/Matrix.js b/src/basic/Matrix.js
index 32d4d75c..5ac409ab 100644
--- a/src/basic/Matrix.js
+++ b/src/basic/Matrix.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -104,6 +104,8 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* also work for calls of `set()`.
*
* @function
+ * @param {...*} values
+ * @return {Point}
*/
set: '#initialize',
@@ -183,7 +185,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* Attempts to apply the matrix to the content of item that it belongs to,
* meaning its transformation is baked into the item's content or children.
*
- * @param {Boolean} recursively controls whether to apply transformations
+ * @param {Boolean} [recursively=true] controls whether to apply transformations
* recursively on children
* @return {Boolean} {@true if the matrix was applied}
*/
@@ -449,7 +451,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
/**
* Returns a new matrix as the result of prepending the specified matrix
* to this matrix. This is the equivalent of multiplying
- * `(specified matrix) s* (this matrix)`.
+ * `(specified matrix) * (this matrix)`.
*
* @param {Matrix} matrix the matrix to prepend
* @return {Matrix} the newly created matrix
@@ -498,15 +500,15 @@ var Matrix = Base.extend(/** @lends Matrix# */{
},
/**
- * @deprecated use use {@link #append(matrix)} instead.
+ * @deprecated use {@link #append(matrix)} instead.
*/
concatenate: '#append',
/**
- * @deprecated use use {@link #prepend(matrix)} instead.
+ * @deprecated use {@link #prepend(matrix)} instead.
*/
preConcatenate: '#prepend',
/**
- * @deprecated use use {@link #appended(matrix)} instead.
+ * @deprecated use {@link #appended(matrix)} instead.
*/
chain: '#appended',
@@ -644,6 +646,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* Inverse transforms a point and returns the result.
*
* @param {Point} point the point to be transformed
+ * @return {Point}
*/
inverseTransform: function(/* point */) {
return this._inverseTransform(Point.read(arguments));
diff --git a/src/basic/Point.js b/src/basic/Point.js
index e9b260dd..9765162a 100644
--- a/src/basic/Point.js
+++ b/src/basic/Point.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -170,6 +170,8 @@ var Point = Base.extend(/** @lends Point# */{
* for calls of `set()`.
*
* @function
+ * @param {...*} values
+ * @return {Point}
*/
set: '#initialize',
@@ -768,7 +770,7 @@ var Point = Base.extend(/** @lends Point# */{
*
* @param {Number} quadrant the quadrant to check against
* @return {Boolean} {@true if either x or y are not a number}
- * @see #getQuadrant()
+ * @see #quadrant
*/
isInQuadrant: function(q) {
// Map quadrant to x & y coordinate pairs and multiply with coordinates,
diff --git a/src/basic/Rectangle.js b/src/basic/Rectangle.js
index 0a2cae29..09a388aa 100644
--- a/src/basic/Rectangle.js
+++ b/src/basic/Rectangle.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -73,7 +73,7 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
* Creates a new rectangle object from the passed rectangle object.
*
* @name Rectangle#initialize
- * @param {Rectangle} rt
+ * @param {Rectangle} rectangle
*/
initialize: function Rectangle(arg0, arg1, arg2, arg3) {
var type = typeof arg0,
@@ -159,6 +159,8 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
* constructors also work for calls of `set()`.
*
* @function
+ * @param {...*} values
+ * @return {Rectangle}
*/
set: '#initialize',
@@ -201,6 +203,7 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
/**
* Returns a copy of the rectangle.
+ * @return {Rectangle}
*/
clone: function() {
return new Rectangle(this.x, this.y, this.width, this.height);
@@ -772,6 +775,8 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
* Rectangle#contains(point)} returns `false` for that point.
*
* @param {Point} point
+ * @return {Rectangle} the smallest rectangle that contains both the
+ * original rectangle and the specified point
*/
include: function(/* point */) {
var point = Point.read(arguments);
@@ -783,17 +788,18 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
},
/**
- * Expands the rectangle by the specified amount in horizontal and
- * vertical directions.
+ * Returns a new rectangle expanded by the specified amount in horizontal
+ * and vertical directions.
*
* @name Rectangle#expand
* @function
* @param {Number|Size|Point} amount the amount to expand the rectangle in
* both directions
+ * @return {Rectangle} the expanded rectangle
*/
/**
- * Expands the rectangle by the specified amounts in horizontal and
- * vertical directions.
+ * Returns a new rectangle expanded by the specified amounts in horizontal
+ * and vertical directions.
*
* @name Rectangle#expand
* @function
@@ -801,6 +807,7 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
* direction
* @param {Number} ver the amount to expand the rectangle in vertical
* direction
+ * @return {Rectangle} the expanded rectangle
*/
expand: function(/* amount */) {
var amount = Size.read(arguments),
@@ -811,21 +818,23 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
},
/**
- * Scales the rectangle by the specified amount from its center.
+ * Returns a new rectangle scaled by the specified amount from its center.
*
* @name Rectangle#scale
* @function
* @param {Number} amount
+ * @return {Rectangle} the scaled rectangle
*/
/**
- * Scales the rectangle in horizontal direction by the specified `hor`
- * amount and in vertical direction by the specified `ver` amount from its
- * center.
+ * Returns a new rectangle scaled in horizontal direction by the specified
+ * `hor` amount and in vertical direction by the specified `ver` amount
+ * from its center.
*
* @name Rectangle#scale
* @function
* @param {Number} hor
* @param {Number} ver
+ * @return {Rectangle} the scaled rectangle
*/
scale: function(hor, ver) {
return this.expand(this.width * hor - this.width,
diff --git a/src/basic/Size.js b/src/basic/Size.js
index af10e6b5..ba2e3f0b 100644
--- a/src/basic/Size.js
+++ b/src/basic/Size.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -130,6 +130,8 @@ var Size = Base.extend(/** @lends Size# */{
* for calls of `set()`.
*
* @function
+ * @param {...*} values
+ * @return {Size}
*/
set: '#initialize',
@@ -158,7 +160,7 @@ var Size = Base.extend(/** @lends Size# */{
* Checks whether the width and height of the size are equal to those of the
* supplied size.
*
- * @param {Size}
+ * @param {Size} size the size to compare to
* @return {Boolean}
*
* @example
@@ -176,6 +178,7 @@ var Size = Base.extend(/** @lends Size# */{
/**
* Returns a copy of the size.
+ * @return {Size}
*/
clone: function() {
return new Size(this.width, this.height);
diff --git a/src/canvas/BlendMode.js b/src/canvas/BlendMode.js
index d3342bd8..ac9ea7d3 100644
--- a/src/canvas/BlendMode.js
+++ b/src/canvas/BlendMode.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/canvas/CanvasProvider.js b/src/canvas/CanvasProvider.js
index dd9ced59..3ac0aac0 100644
--- a/src/canvas/CanvasProvider.js
+++ b/src/canvas/CanvasProvider.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/canvas/ProxyContext.js b/src/canvas/ProxyContext.js
index b709bbde..5a403b48 100644
--- a/src/canvas/ProxyContext.js
+++ b/src/canvas/ProxyContext.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/constants.js b/src/constants.js
index b360edf0..0c84dbcf 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/core/Base.js b/src/core/Base.js
index 834c940f..52d963af 100644
--- a/src/core/Base.js
+++ b/src/core/Base.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -558,8 +558,16 @@ statics: /** @lends Base */{
if (args.length === 1 && obj instanceof Item
&& (useTarget || !(obj instanceof Layer))) {
var arg = args[0];
- if (Base.isPlainObject(arg))
+ if (Base.isPlainObject(arg)) {
arg.insert = false;
+ // When using target, make sure the `item.insert()`
+ // method is not overridden with the `arg.insert`
+ // property that was just set. Pass an exclude
+ // object to the call of `obj.set()` below (#1392).
+ if (useTarget) {
+ args = args.concat([{ insert: true }]);
+ }
+ }
}
// When reusing an object, initialize it through #set()
// instead of the constructor function:
diff --git a/src/core/Emitter.js b/src/core/Emitter.js
index 0ad43233..0e9724d1 100644
--- a/src/core/Emitter.js
+++ b/src/core/Emitter.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -68,9 +68,9 @@ var Emitter = {
},
once: function(type, func) {
- return this.on(type, function() {
+ return this.on(type, function handler() {
func.apply(this, arguments);
- this.off(type, func);
+ this.off(type, handler);
});
},
diff --git a/src/core/PaperScope.js b/src/core/PaperScope.js
index e60b834b..2d4f9670 100644
--- a/src/core/PaperScope.js
+++ b/src/core/PaperScope.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -87,7 +87,7 @@ var PaperScope = Base.extend(/** @lends PaperScope# */{
// here: { chrome: true, webkit: false }, Mozilla missing is the
// only difference to jQuery.browser
user.replace(
- /(opera|chrome|safari|webkit|firefox|msie|trident|atom|node)\/?\s*([.\d]+)(?:.*version\/([.\d]+))?(?:.*rv\:v?([.\d]+))?/g,
+ /(opera|chrome|safari|webkit|firefox|msie|trident|atom|node|jsdom)\/?\s*([.\d]+)(?:.*version\/([.\d]+))?(?:.*rv\:v?([.\d]+))?/g,
function(match, n, v1, v2, rv) {
// Do not set additional browsers once chrome is detected.
if (!agent.chrome) {
@@ -95,7 +95,7 @@ var PaperScope = Base.extend(/** @lends PaperScope# */{
/^(node|trident)$/.test(n) ? rv : v1;
agent.version = v;
agent.versionNumber = parseFloat(v);
- n = n === 'trident' ? 'msie' : n;
+ n = { trident: 'msie', jsdom: 'node' }[n] || n;
agent.name = n;
agent[n] = true;
}
@@ -112,6 +112,7 @@ var PaperScope = Base.extend(/** @lends PaperScope# */{
* The version of Paper.js, as a string.
*
* @type String
+ * @readonly
*/
version: /*#=*/__options.version,
@@ -200,7 +201,7 @@ var PaperScope = Base.extend(/** @lends PaperScope# */{
* mapping, in case the code that's passed in has already been mingled.
*
* @param {String} code the PaperScript code
- * @param {Object} [option] the compilation options
+ * @param {Object} [options] the compilation options
*/
execute: function(code, options) {
/*#*/ if (__options.paperScript) {
diff --git a/src/core/PaperScopeItem.js b/src/core/PaperScopeItem.js
index f03b8904..8aa31a8b 100644
--- a/src/core/PaperScopeItem.js
+++ b/src/core/PaperScopeItem.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/core/PaperScript.js b/src/core/PaperScript.js
index 152ded69..ca1f393e 100644
--- a/src/core/PaperScript.js
+++ b/src/core/PaperScript.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -127,7 +127,7 @@ Base.exports.PaperScript = function() {
* mapping, in case the code that's passed in has already been mingled.
*
* @param {String} code the PaperScript code
- * @param {Object} [option] the compilation options
+ * @param {Object} [options] the compilation options
* @return {Object} an object holding the compiled PaperScript translated
* into JavaScript code along with source-maps and other information.
*/
@@ -177,7 +177,7 @@ Base.exports.PaperScript = function() {
var start = getOffset(node.range[0]),
end = getOffset(node.range[1]),
insert = 0;
- // Sort insertions by their offset, so getOffest() can do its thing
+ // Sort insertions by their offset, so getOffset() can do its thing
for (var i = insertions.length - 1; i >= 0; i--) {
if (start > insertions[i][0]) {
insert = i + 1;
@@ -256,12 +256,19 @@ Base.exports.PaperScript = function() {
exp = '__$__(' + arg + ', "' + node.operator[0]
+ '", 1)',
str = arg + ' = ' + exp;
- // If this is not a prefixed update expression
- // (++a, --a), assign the old value before updating it.
- if (!node.prefix
- && (parentType === 'AssignmentExpression'
- || parentType === 'VariableDeclarator')) {
- // Handle special issue #691 where the old value is
+ if (node.prefix) {
+ // A prefixed update expression (++a / --a),
+ // wrap expression in paranthesis. See #1611
+ str = '(' + str + ')';
+ } else if (
+ // A suffixed update expression (a++, a--),
+ // assign the old value before updating it.
+ // See #691, #1450
+ parentType === 'AssignmentExpression' ||
+ parentType === 'VariableDeclarator' ||
+ parentType === 'BinaryExpression'
+ ) {
+ // Handle special case where the old value is
// assigned to itself, and the expression is just
// executed after, e.g.: `var x = ***; x = x++;`
if (getCode(parent.left || parent.id) === arg)
@@ -323,7 +330,7 @@ Base.exports.PaperScript = function() {
// Source-map support:
// Encodes a Variable Length Quantity as a Base64 string.
- // See: http://www.html5rocks.com/en/tutorials/developertools/sourcemaps
+ // See: https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/
function encodeVLQ(value) {
var res = '',
base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
@@ -441,8 +448,8 @@ Base.exports.PaperScript = function() {
*
* @param {String} code the PaperScript code
* @param {PaperScope} scope the scope for which the code is executed
- * @param {Object} [option] the compilation options
- * @return the exports defined in the executed code
+ * @param {Object} [options] the compilation options
+ * @return {Object} the exports defined in the executed code
*/
function execute(code, scope, options) {
// Set currently active scope.
@@ -484,7 +491,7 @@ Base.exports.PaperScript = function() {
}
}
}
- expose({ __$__: __$__, $__: $__, paper: scope, view: view, tool: tool },
+ expose({ __$__: __$__, $__: $__, paper: scope, tool: tool },
true);
expose(scope);
// Add a fake `module.exports` object so PaperScripts can export things.
@@ -657,7 +664,9 @@ Base.exports.PaperScript = function() {
compile: compile,
execute: execute,
load: load,
- parse: parse
+ parse: parse,
+ calculateBinary: __$__,
+ calculateUnary: $__
};
// Pass on `this` as the binding object, so we can reference Acorn both in
// development and in the built library.
diff --git a/src/docs/global.js b/src/docs/global.js
index 4d8c8a82..29de23d9 100644
--- a/src/docs/global.js
+++ b/src/docs/global.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -39,7 +39,7 @@
*
* The project for which the PaperScript is executed.
*
- * Note that when working with mulitple projects, this does not necessarily
+ * Note that when working with multiple projects, this does not necessarily
* reflect the currently active project. For this, use
* {@link PaperScope#project} instead.
*
@@ -57,19 +57,20 @@
/**
* The reference to the project's view.
*
- * Note that when working with mulitple projects, this does not necessarily
+ * Note that when working with multiple projects, this does not necessarily
* reflect the view of the currently active project. For this, use
* {@link PaperScope#view} instead.
*
* @name view
* @type View
+ * @readonly
*/
/**
* The reference to the tool object which is automatically created when global
* tool event handlers are defined.
*
- * Note that when working with mulitple tools, this does not necessarily
+ * Note that when working with multiple tools, this does not necessarily
* reflect the currently active tool. For this, use {@link PaperScope#tool}
* instead.
*
diff --git a/src/dom/DomElement.js b/src/dom/DomElement.js
index 035f6cab..6b92c895 100644
--- a/src/dom/DomElement.js
+++ b/src/dom/DomElement.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/dom/DomEvent.js b/src/dom/DomEvent.js
index c6786006..56ac214f 100644
--- a/src/dom/DomEvent.js
+++ b/src/dom/DomEvent.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/event/Event.js b/src/event/Event.js
index 5beca73c..297282e0 100644
--- a/src/event/Event.js
+++ b/src/event/Event.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/event/Key.js b/src/event/Key.js
index c8746429..be425b42 100644
--- a/src/event/Key.js
+++ b/src/event/Key.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/event/KeyEvent.js b/src/event/KeyEvent.js
index c20af658..b19539db 100644
--- a/src/event/KeyEvent.js
+++ b/src/event/KeyEvent.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/event/MouseEvent.js b/src/event/MouseEvent.js
index 93859adb..6700cba3 100644
--- a/src/event/MouseEvent.js
+++ b/src/event/MouseEvent.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/export.js b/src/export.js
index 0ac7f578..dc4d5d9e 100644
--- a/src/export.js
+++ b/src/export.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/init.js b/src/init.js
index 3e726c91..58d76e46 100644
--- a/src/init.js
+++ b/src/init.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/item/ChangeFlag.js b/src/item/ChangeFlag.js
index fd1aaede..4592c2c1 100644
--- a/src/item/ChangeFlag.js
+++ b/src/item/ChangeFlag.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/item/Group.js b/src/item/Group.js
index f9e36070..c3bd085c 100644
--- a/src/item/Group.js
+++ b/src/item/Group.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -171,8 +171,7 @@ var Group = Item.extend(/** @lends Group# */{
_getBounds: function _getBounds(matrix, options) {
var clipItem = this._getClipItem();
return clipItem
- ? clipItem._getCachedBounds(
- matrix && matrix.appended(clipItem._matrix),
+ ? clipItem._getCachedBounds(clipItem._matrix.prepended(matrix),
Base.set({}, options, { stroke: false }))
: _getBounds.base.call(this, matrix, options);
},
diff --git a/src/item/HitResult.js b/src/item/HitResult.js
index 460ee4b0..ee804160 100644
--- a/src/item/HitResult.js
+++ b/src/item/HitResult.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/item/Item.js b/src/item/Item.js
index 6e2dfc63..5ba11339 100644
--- a/src/item/Item.js
+++ b/src/item/Item.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -658,8 +658,8 @@ new function() { // Injection scope for various item event handlers
/**
* Specifies whether the item defines a clip mask. This can only be set on
- * paths, compound paths, and text frame objects, and only if the item is
- * already contained within a clipping group.
+ * paths and compound paths, and only if the item is already contained
+ * within a clipping group.
*
* @bean
* @type Boolean
@@ -1075,7 +1075,9 @@ new function() { // Injection scope for various item event handlers
options = options || {};
for (var i = 0, l = items.length; i < l; i++) {
var item = items[i];
- if (item._visible && !item.isEmpty()) {
+ // Item is handled if it is visible and not recursively empty.
+ // This avoid errors with nested empty groups (#1467).
+ if (item._visible && !item.isEmpty(true)) {
// Pass true for noInternal, since even when getting
// internal bounds for this item, we need to apply the
// matrices to its children.
@@ -1120,6 +1122,17 @@ new function() { // Injection scope for various item event handlers
* @type Rectangle
*/
+ /**
+ * The bounding rectangle of the item without any matrix transformations.
+ *
+ * Typical use case would be drawing a frame around the object where you
+ * want to draw something of the same size, position, rotation, and scaling,
+ * like a selection frame.
+ *
+ * @name Item#internalBounds
+ * @type Rectangle
+ */
+
/**
* The rough bounding rectangle of the item that is sure to include all of
* the drawing, including stroke width.
@@ -1805,11 +1818,15 @@ new function() { // Injection scope for various item event handlers
* }
*
* @param {Point} point the point to check for
+ * @return {Boolean}
*/
contains: function(/* point */) {
// See CompoundPath#_contains() for the reason for !!
- return !!this._contains(
- this._matrix._inverseTransform(Point.read(arguments)));
+ var matrix = this._matrix;
+ return (
+ matrix.isInvertible() &&
+ !!this._contains(matrix._inverseTransform(Point.read(arguments)))
+ );
},
_contains: function(point) {
@@ -2353,6 +2370,7 @@ new function() { // Injection scope for hit-test functions shared with project
* items can have children.
*
* @param {String} json the JSON data to import from
+ * @return {Item}
*/
importJSON: function(json) {
// Try importing into `this`. If another item is returned, try adding
@@ -2388,7 +2406,8 @@ new function() { // Injection scope for hit-test functions shared with project
* kept as a link to their external URL.
*
* @param {Object} [options] the export options
- * @return {SVGElement} the item converted to an SVG node
+ * @return {SVGElement|String} the item converted to an SVG node or a
+ * `String` depending on `option.asString` value
*/
/**
@@ -2772,6 +2791,7 @@ new function() { // Injection scope for hit-test functions shared with project
* Replaces this item with the provided new item which will takes its place
* in the project hierarchy instead.
*
+ * @param {Item} item the item that will replace this item
* @return {Boolean} {@true if the item was replaced}
*/
replaceWith: function(item) {
@@ -2840,11 +2860,23 @@ new function() { // Injection scope for hit-test functions shared with project
* no children, a {@link TextItem} with no text content and a {@link Path}
* with no segments all are considered empty.
*
+ * @param {Boolean} [recursively=false] whether an item with children should be
+ * considered empty if all its descendants are empty
* @return Boolean
*/
- isEmpty: function() {
+ isEmpty: function(recursively) {
var children = this._children;
- return !children || !children.length;
+ var numChildren = children ? children.length : 0;
+ if (recursively) {
+ // In recursive check, item is empty if all its children are empty.
+ for (var i = 0; i < numChildren; i++) {
+ if (!children[i].isEmpty(recursively)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return !numChildren;
},
/**
@@ -3194,7 +3226,7 @@ new function() { // Injection scope for hit-test functions shared with project
*
* @name Item#dashArray
* @property
- * @type Array
+ * @type Number[]
* @default []
*/
@@ -4417,8 +4449,10 @@ new function() { // Injection scope for hit-test functions shared with project
this._draw(ctx, param, viewMatrix, strokeMatrix);
ctx.restore();
matrices.pop();
- if (param.clip && !param.dontFinish)
- ctx.clip();
+ if (param.clip && !param.dontFinish) {
+ // Pass fill-rule to handle clipping with compound-paths (#1361).
+ ctx.clip(this.getFillRule());
+ }
// If a temporary canvas was created, composite it onto the main canvas:
if (!direct) {
// Use BlendMode.process even for processing normal blendMode with
@@ -4672,4 +4706,176 @@ new function() { // Injection scope for hit-test functions shared with project
}
return this;
}
-}));
+}), /** @lends Item# */{
+ /**
+ * {@grouptitle Tweening Functions}
+ *
+ * Tween item between two states.
+ *
+ * @name Item#tween
+ *
+ * @option options.duration {Number} the duration of the tweening
+ * @option [options.easing='linear'] {Function|String} an easing function or the type
+ * of the easing: {@values 'linear' 'easeInQuad' 'easeOutQuad'
+ * 'easeInOutQuad' 'easeInCubic' 'easeOutCubic' 'easeInOutCubic'
+ * 'easeInQuart' 'easeOutQuart' 'easeInOutQuart' 'easeInQuint'
+ * 'easeOutQuint' 'easeInOutQuint'}
+ * @option [options.start=true] {Boolean} whether to start tweening automatically
+ *
+ * @function
+ * @param {Object} from the state at the start of the tweening
+ * @param {Object} to the state at the end of the tweening
+ * @param {Object|Number} options the options or the duration
+ * @return {Tween}
+ *
+ * @example {@paperscript height=100}
+ * // Tween fillColor:
+ * var path = new Path.Circle({
+ * radius: view.bounds.height * 0.4,
+ * center: view.center
+ * });
+ * path.tween(
+ * { fillColor: 'blue' },
+ * { fillColor: 'red' },
+ * 3000
+ * );
+ * @example {@paperscript height=100}
+ * // Tween rotation:
+ * var path = new Shape.Rectangle({
+ * fillColor: 'red',
+ * center: [50, view.center.y],
+ * size: [60, 60]
+ * });
+ * path.tween({
+ * rotation: 180,
+ * 'position.x': view.bounds.width - 50,
+ * 'fillColor.hue': '+= 90'
+ * }, {
+ * easing: 'easeInOutCubic',
+ * duration: 2000
+ * });
+ */
+ /**
+ * Tween item to a state.
+ *
+ * @name Item#tween
+ *
+ * @function
+ * @param {Object} to the state at the end of the tweening
+ * @param {Object|Number} options the options or the duration
+ * @return {Tween}
+ *
+ * @example {@paperscript height=200}
+ * // Tween a nested property with relative values
+ * var path = new Path.Rectangle({
+ * size: [100, 100],
+ * position: view.center,
+ * fillColor: 'red',
+ * });
+ *
+ * var delta = { x: path.bounds.width / 2, y: 0 };
+ *
+ * path.tween({
+ * 'segments[1].point': ['+=', delta],
+ * 'segments[2].point.x': '-= 50'
+ * }, 3000);
+ *
+ * @see Item#tween(from, to, options)
+ */
+ /**
+ * Tween item.
+ *
+ * @name Item#tween
+ *
+ * @function
+ * @param {Object|Number} options the options or the duration
+ * @return {Tween}
+ *
+ * @see Item#tween(from, to, options)
+ *
+ * @example {@paperscript height=100}
+ * // Start an empty tween and just use the update callback:
+ * var path = new Path.Circle({
+ * fillColor: 'blue',
+ * radius: view.bounds.height * 0.4,
+ * center: view.center,
+ * });
+ * var pathFrom = path.clone({ insert: false })
+ * var pathTo = new Path.Rectangle({
+ * position: view.center,
+ * rectangle: path.bounds,
+ * insert: false
+ * });
+ * path.tween(2000).onUpdate = function(event) {
+ * path.interpolate(pathFrom, pathTo, event.factor)
+ * };
+ */
+ tween: function(from, to, options) {
+ if (!options) {
+ // If there are only two or one arguments, shift arguments to the
+ // left by one (omit `from`):
+ options = to;
+ to = from;
+ from = null;
+ if (!options) {
+ options = to;
+ to = null;
+ }
+ }
+ var easing = options && options.easing,
+ start = options && options.start,
+ duration = options != null && (
+ typeof options === 'number' ? options : options.duration
+ ),
+ tween = new Tween(this, from, to, duration, easing, start);
+ function onFrame(event) {
+ tween._handleFrame(event.time * 1000);
+ if (!tween.running) {
+ this.off('frame', onFrame);
+ }
+ }
+ if (duration) {
+ this.on('frame', onFrame);
+ }
+ return tween;
+ },
+
+ /**
+ *
+ * Tween item to a state.
+ *
+ * @function
+ * @param {Object} to the state at the end of the tweening
+ * @param {Object|Number} options the options or the duration
+ * @return {Tween}
+ *
+ * @see Item#tween(to, options)
+ */
+ tweenTo: function(to, options) {
+ return this.tween(null, to, options);
+ },
+
+ /**
+ *
+ * Tween item from a state to its state before the tweening.
+ *
+ * @function
+ * @param {Object} from the state at the start of the tweening
+ * @param {Object|Number} options the options or the duration
+ * @return {Tween}
+ *
+ * @see Item#tween(from, to, options)
+ *
+ * @example {@paperscript height=100}
+ * // Tween fillColor from red to the path's initial fillColor:
+ * var path = new Path.Circle({
+ * fillColor: 'blue',
+ * radius: view.bounds.height * 0.4,
+ * center: view.center
+ * });
+ * path.tweenFrom({ fillColor: 'red' }, { duration: 1000 });
+ */
+ tweenFrom: function(from, options) {
+ return this.tween(from, null, options);
+ }
+});
diff --git a/src/item/ItemSelection.js b/src/item/ItemSelection.js
index 94d75180..4b928e4c 100644
--- a/src/item/ItemSelection.js
+++ b/src/item/ItemSelection.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/item/Layer.js b/src/item/Layer.js
index 5650f505..5229b1cb 100644
--- a/src/item/Layer.js
+++ b/src/item/Layer.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/item/Project.js b/src/item/Project.js
index 8a7ad5c4..8d69d55e 100644
--- a/src/item/Project.js
+++ b/src/item/Project.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -133,7 +133,7 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
/**
* Checks whether the project has any content or not.
*
- * @return Boolean
+ * @return {Boolean}
*/
isEmpty: function() {
return !this._children.length;
@@ -348,7 +348,7 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
* {@link #layers} list.
*
* @param {Number} index the index at which to insert the layer
- * @param {Item} item the item to be inserted in the project
+ * @param {Layer} layer the layer to be inserted in the project
* @return {Layer} the added layer, or `null` if adding was not possible
*/
insertLayer: function(index, layer) {
@@ -745,6 +745,7 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
* {@link Project#clear()} to do so.
*
* @param {String} json the JSON data to import from
+ * @return {Item} the imported item
*/
importJSON: function(json) {
this.activate();
@@ -781,7 +782,8 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
* kept as a link to their external URL.
*
* @param {Object} [options] the export options
- * @return {SVGElement} the project converted to an SVG node
+ * @return {SVGElement|String} the project converted to an SVG node or a
+ * `String` depending on `option.asString` value
*/
/**
diff --git a/src/item/Raster.js b/src/item/Raster.js
index c7a6cd39..b90b6060 100644
--- a/src/item/Raster.js
+++ b/src/item/Raster.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -18,6 +18,7 @@
* @extends Item
*/
var Raster = Item.extend(/** @lends Raster# */{
+}, /** @lends Raster# */{
_class: 'Raster',
_applyMatrix: false,
_canApplyMatrix: false,
@@ -31,15 +32,19 @@ var Raster = Item.extend(/** @lends Raster# */{
// Prioritize `crossOrigin` over `source`:
_prioritize: ['crossOrigin'],
_smoothing: false,
+ // Enforce creation of beans, as bean getters have hidden parameters.
+ // See #getContext(_change) below.
+ beans: true,
// TODO: Implement type, width, height.
// TODO: Have SymbolItem & Raster inherit from a shared class?
/**
* Creates a new raster item from the passed argument, and places it in the
- * active layer. `object` can either be a DOM Image, a Canvas, or a string
+ * active layer. `source` can either be a DOM Image, a Canvas, or a string
* describing the URL to load the image from, or the ID of a DOM element to
* get the image from (either a DOM Image or a Canvas).
*
+ * @name Raster#initialize
* @param {HTMLImageElement|HTMLCanvasElement|String} [source] the source of
* the raster
* @param {Point} [position] the center position at which the raster item is
@@ -77,22 +82,64 @@ var Raster = Item.extend(/** @lends Raster# */{
* raster.scale(0.5);
* raster.rotate(10);
*/
- initialize: function Raster(object, position) {
- // Support two forms of item initialization: Passing one object literal
- // describing all the different properties to be set, or an image
- // (object) and a point where it should be placed (point).
+ /**
+ * Creates a new empty raster of the given size, and places it in the
+ * active layer.
+ *
+ * @name Raster#initialize
+ * @param {Size} size the size of the raster
+ * @param {Point} [position] the center position at which the raster item is
+ * placed
+ *
+ * @example {@paperscript height=150}
+ * // Creating an empty raster and fill it with random pixels:
+ * var width = 100;
+ * var height = 100;
+ *
+ * // Create an empty raster placed at view center.
+ * var raster = new Raster(new Size(width, height), view.center);
+ *
+ * // For all of its pixels...
+ * for (var i = 0; i < width; i++) {
+ * for (var j = 0; j < height; j++) {
+ * // ...set a random color.
+ * raster.setPixel(i, j, Color.random());
+ * }
+ * }
+ */
+ initialize: function Raster(source, position) {
+ // Support three forms of item initialization:
+ // - One object literal describing all the different properties.
+ // - An image (Image|Canvas|String) and an optional position (Point).
+ // - A size (Size) describing the canvas that will be created and an
+ // optional position (Point).
// If _initialize can set properties through object literal, we're done.
- // Otherwise we need to check the type of object:
- if (!this._initialize(object,
- position !== undefined && Point.read(arguments, 1))) {
- // object can be an image, canvas, URL or DOM-ID:
- var image = typeof object === 'string'
- ? document.getElementById(object) : object;
+ // Otherwise we need to check the type of object: var image,
+ if (!this._initialize(source,
+ position !== undefined && Point.read(arguments))) {
+ var image,
+ type = typeof source,
+ object = type === 'string'
+ ? document.getElementById(source)
+ : type === 'object'
+ ? source
+ : null;
+ if (object && object !== Item.NO_INSERT) {
+ if (object.getContent || object.naturalHeight != null) {
+ image = object;
+ } else if (object) {
+ // See if the arguments describe the raster size:
+ var size = Size.read(arguments);
+ if (!size.isZero()) {
+ image = CanvasProvider.getCanvas(size);
+ }
+ }
+ }
if (image) {
// #setImage() handles both canvas and image types.
this.setImage(image);
} else {
- this.setSource(object);
+ this.setSource(source);
}
}
if (!this._size) {
@@ -305,7 +352,7 @@ var Raster = Item.extend(/** @lends Raster# */{
* case `null` is returned instead.
*
* @bean
- * @type HTMLCanvasELement
+ * @type HTMLCanvasElement
*/
getCanvas: function() {
if (!this._canvas) {
@@ -330,15 +377,15 @@ var Raster = Item.extend(/** @lends Raster# */{
* The Canvas 2D drawing context of the raster.
*
* @bean
- * @type Context
+ * @type CanvasRenderingContext2D
*/
- getContext: function(modify) {
+ getContext: function(_change) {
if (!this._context)
this._context = this.getCanvas().getContext('2d');
// Support a hidden parameter that indicates if the context will be used
- // to modify the Raster object. We can notify such changes ahead since
+ // to change the Raster object. We can notify such changes ahead since
// they are only used afterwards for redrawing.
- if (modify) {
+ if (_change) {
// Also set _image to null since the Raster stops representing it.
// NOTE: This should theoretically be in our own _changed() handler
// for ChangeFlag.PIXELS, but since it's only happening in one place
@@ -386,7 +433,11 @@ var Raster = Item.extend(/** @lends Raster# */{
crossOrigin = this._crossOrigin;
if (crossOrigin)
image.crossOrigin = crossOrigin;
- image.src = src;
+ // Prevent setting image source to `null`, as this isn't supported by
+ // browsers, and it would actually throw exceptions in JSDOM.
+ // TODO: Look into fixing this bug in JSDOM.
+ if (src)
+ image.src = src;
this.setImage(image);
},
@@ -463,7 +514,7 @@ var Raster = Item.extend(/** @lends Raster# */{
* @param {Rectangle} rect the boundaries of the sub image in pixel
* coordinates
*
- * @return {HTMLCanvasELement} the sub image as a Canvas object
+ * @return {HTMLCanvasElement} the sub image as a Canvas object
*/
getSubCanvas: function(/* rect */) {
var rect = Rectangle.read(arguments),
@@ -519,7 +570,7 @@ var Raster = Item.extend(/** @lends Raster# */{
/**
* Draws an image on the raster.
*
- * @param {HTMLImageELement|HTMLCanvasELement} image
+ * @param {HTMLImageElement|HTMLCanvasElement} image
* @param {Point} point the offset of the image as a point in pixel
* coordinates
*/
@@ -614,8 +665,8 @@ var Raster = Item.extend(/** @lends Raster# */{
*
* @name Raster#getPixel
* @function
- * @param x the x offset of the pixel in pixel coordinates
- * @param y the y offset of the pixel in pixel coordinates
+ * @param {Number} x the x offset of the pixel in pixel coordinates
+ * @param {Number} y the y offset of the pixel in pixel coordinates
* @return {Color} the color of the pixel
*/
/**
@@ -623,7 +674,8 @@ var Raster = Item.extend(/** @lends Raster# */{
*
* @name Raster#getPixel
* @function
- * @param point the offset of the pixel as a point in pixel coordinates
+ * @param {Point} point the offset of the pixel as a point in pixel
+ * coordinates
* @return {Color} the color of the pixel
*/
getPixel: function(/* point */) {
@@ -639,17 +691,18 @@ var Raster = Item.extend(/** @lends Raster# */{
*
* @name Raster#setPixel
* @function
- * @param x the x offset of the pixel in pixel coordinates
- * @param y the y offset of the pixel in pixel coordinates
- * @param color the color that the pixel will be set to
+ * @param {Number} x the x offset of the pixel in pixel coordinates
+ * @param {Number} y the y offset of the pixel in pixel coordinates
+ * @param {Color} color the color that the pixel will be set to
*/
/**
* Sets the color of the specified pixel to the specified color.
*
* @name Raster#setPixel
* @function
- * @param point the offset of the pixel as a point in pixel coordinates
- * @param color the color that the pixel will be set to
+ * @param {Point} point the offset of the pixel as a point in pixel
+ * coordinates
+ * @param {Color} color the color that the pixel will be set to
*/
setPixel: function(/* point, color */) {
var point = Point.read(arguments),
@@ -666,6 +719,14 @@ var Raster = Item.extend(/** @lends Raster# */{
ctx.putImageData(imageData, point.x, point.y);
},
+ /**
+ * Clears the image, if it is backed by a canvas.
+ */
+ clear: function() {
+ var size = this._size;
+ this.getContext(true).clearRect(0, 0, size.width + 1, size.height + 1);
+ },
+
// DOCS: document Raster#createImageData
/**
* {@grouptitle Image Data}
@@ -761,7 +822,8 @@ var Raster = Item.extend(/** @lends Raster# */{
_draw: function(ctx, param, viewMatrix) {
var element = this.getElement();
- if (element) {
+ // Only draw if image is not empty (#1320).
+ if (element && element.width > 0 && element.height > 0) {
// Handle opacity for Rasters separately from the rest, since
// Rasters never draw a stroke. See Item#draw().
ctx.globalAlpha = this._opacity;
diff --git a/src/item/Shape.js b/src/item/Shape.js
index 184362a9..fed35b8e 100644
--- a/src/item/Shape.js
+++ b/src/item/Shape.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/item/SymbolDefinition.js b/src/item/SymbolDefinition.js
index 9e79b27d..3e907fb2 100644
--- a/src/item/SymbolDefinition.js
+++ b/src/item/SymbolDefinition.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -140,7 +140,7 @@ var SymbolDefinition = Base.extend(/** @lends SymbolDefinition# */{
/**
* Returns a copy of the symbol.
*
- * @return {Symbol}
+ * @return {SymbolDefinition}
*/
clone: function() {
return new SymbolDefinition(this._item.clone(false));
@@ -149,7 +149,7 @@ var SymbolDefinition = Base.extend(/** @lends SymbolDefinition# */{
/**
* Checks whether the symbol's definition is equal to the supplied symbol.
*
- * @param {Symbol} symbol
+ * @param {SymbolDefinition} symbol
* @return {Boolean} {@true if they are equal}
*/
equals: function(symbol) {
diff --git a/src/item/SymbolItem.js b/src/item/SymbolItem.js
index 3e78646c..437789f2 100644
--- a/src/item/SymbolItem.js
+++ b/src/item/SymbolItem.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -31,7 +31,9 @@ var SymbolItem = Item.extend(/** @lends SymbolItem# */{
/**
* Creates a new symbol item.
*
- * @param {Symbol} definition the symbol definition to place
+ * @name SymbolItem#initialize
+ * @param {SymbolDefinition|Item} definition the definition to place or an
+ * item to place as a symbol
* @param {Point} [point] the center point of the placed symbol
*
* @example {@paperscript split=true height=240}
diff --git a/src/load.js b/src/load.js
index 59e08c7c..d1f4dd7b 100644
--- a/src/load.js
+++ b/src/load.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -38,11 +38,10 @@ if (typeof window === 'object') {
} else {
// Some native javascript classes have name collisions with Paper.js
// classes. Store them to be able to use them later in tests.
- NativeClasses = {
- Event: Event,
- MouseEvent: MouseEvent
+ this.nativeClasses = {
+ Event: window.Event,
+ MouseEvent: window.MouseEvent
};
-
include('options.js');
// Load constants.js, required by the on-the-fly preprocessing:
include('constants.js');
diff --git a/src/net/Http.js b/src/net/Http.js
index 012f6b92..0e9b867f 100644
--- a/src/net/Http.js
+++ b/src/net/Http.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/node/canvas.js b/src/node/canvas.js
index fcb96540..335f3873 100644
--- a/src/node/canvas.js
+++ b/src/node/canvas.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -18,7 +18,7 @@
module.exports = function(self, requireName) {
var Canvas;
try {
- Canvas = require('canvas');
+ Canvas = require('canvas').Canvas;
} catch(error) {
// Remove `self.window`, so we still have the global `self` reference,
// but no `window` object:
diff --git a/src/node/extend.js b/src/node/extend.js
index d2e1ef66..a950e4b3 100644
--- a/src/node/extend.js
+++ b/src/node/extend.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/node/self.js b/src/node/self.js
index b6e47d8f..2ec77404 100644
--- a/src/node/self.js
+++ b/src/node/self.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -37,15 +37,13 @@ try {
if (jsdom) {
// Create our document and window objects through jsdom.
/* global document:true, window:true */
- var document = jsdom.jsdom('', {
+ var document = new jsdom.JSDOM('', {
// Use the current working directory as the document's origin, so
// requests to local files work correctly with CORS.
url: 'file://' + process.cwd() + '/',
- features: {
- FetchExternalResources: ['img', 'script']
- }
+ resources: 'usable'
});
- self = document.defaultView;
+ self = document.window;
require('./canvas.js')(self, requireName);
require('./xml.js')(self);
} else {
diff --git a/src/node/xml.js b/src/node/xml.js
index 2a02ae7e..74087246 100644
--- a/src/node/xml.js
+++ b/src/node/xml.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/options.js b/src/options.js
index 5ec47207..603cd7ca 100644
--- a/src/options.js
+++ b/src/options.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -17,7 +17,7 @@
// The paper.js version.
// NOTE: Adjust value here before calling `gulp publish`, which then updates and
// publishes the various JSON package files automatically.
-var version = '0.11.8';
+var version = '0.12.3';
// If this file is loaded in the browser, we're in load.js mode.
var load = typeof window === 'object';
diff --git a/src/paper.js b/src/paper.js
index f2c6d327..fc00e683 100644
--- a/src/paper.js
+++ b/src/paper.js
@@ -2,8 +2,8 @@
* Paper.js v*#=*__options.version - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -15,7 +15,7 @@
*
* Straps.js - Class inheritance library with support for bean-style accessors
*
- * Copyright (c) 2006 - 2016 Juerg Lehni
+ * Copyright (c) 2006 - 2019 Juerg Lehni
* http://scratchdisk.com/
*
* Distributed under the MIT license.
@@ -23,7 +23,7 @@
***
*
* Acorn.js
- * http://marijnhaverbeke.nl/acorn/
+ * https://marijnhaverbeke.nl/acorn/
*
* Acorn is a tiny, fast JavaScript parser written in JavaScript,
* created by Marijn Haverbeke and released under an MIT license.
@@ -102,6 +102,8 @@ var paper = function(self, undefined) {
/*#*/ include('tool/ToolEvent.js');
/*#*/ include('tool/Tool.js');
+/*#*/ include('anim/Tween.js');
+
/*#*/ include('net/Http.js');
/*#*/ include('canvas/CanvasProvider.js');
diff --git a/src/path/CompoundPath.js b/src/path/CompoundPath.js
index 115af3a9..d47b90b4 100644
--- a/src/path/CompoundPath.js
+++ b/src/path/CompoundPath.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -161,7 +161,7 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
*
* @bean
* @type Boolean
- * @see Path#isClosed()
+ * @see Path#closed
*/
isClosed: function() {
var children = this._children;
@@ -193,7 +193,7 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
/**
* The last Segment contained within the compound-path, a short-cut to
- * calling {@link Path#lastChild} on {@link Item#lastChild}.
+ * calling {@link Path#lastSegment} on {@link Item#lastChild}.
*
* @bean
* @type Segment
diff --git a/src/path/Curve.js b/src/path/Curve.js
index 1c5b6714..26798499 100644
--- a/src/path/Curve.js
+++ b/src/path/Curve.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -1476,7 +1476,7 @@ new function() { // Scope for methods that require private functions
// 2: normal, 1st derivative
// 3: curvature, 1st derivative & 2nd derivative
// Prevent tangents and normals of length 0:
- // http://stackoverflow.com/questions/10506868/
+ // https://stackoverflow.com/questions/10506868/
if (t < tMin) {
x = cx;
y = cy;
@@ -1698,7 +1698,7 @@ new function() { // Scope for methods that require private functions
* Peaks are locations sharing some qualities of curvature extrema but
* are cheaper to compute. They fulfill their purpose here quite well.
* See:
- * http://math.stackexchange.com/questions/1954845/bezier-curvature-extrema
+ * https://math.stackexchange.com/questions/1954845/bezier-curvature-extrema
*
* @param {Number[]} v the curve values array
* @return {Number[]} the roots of all found peaks
diff --git a/src/path/CurveLocation.js b/src/path/CurveLocation.js
index cd878d45..19b31dc9 100644
--- a/src/path/CurveLocation.js
+++ b/src/path/CurveLocation.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -147,7 +147,7 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
* The path that this locations is situated on.
*
* @bean
- * @type Item
+ * @type Path
*/
getPath: function() {
var curve = this.getCurve();
@@ -159,7 +159,7 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
* it is part of a {@link Path} item.
*
* @bean
- * @type Index
+ * @type Number
*/
getIndex: function() {
var curve = this.getCurve();
@@ -284,7 +284,7 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
* @bean
* @type Number
* @see Curve#getNearestLocation(point)
- * @see Path#getNearestLocation(point)
+ * @see PathItem#getNearestLocation(point)
*/
getDistance: function() {
return this._distance;
diff --git a/src/path/Path.Constructors.js b/src/path/Path.Constructors.js
index 3cc23b9d..ea92ee16 100644
--- a/src/path/Path.Constructors.js
+++ b/src/path/Path.Constructors.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/path/Path.js b/src/path/Path.js
index e188bee4..820f8d23 100644
--- a/src/path/Path.js
+++ b/src/path/Path.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -75,7 +75,6 @@ var Path = PathItem.extend(/** @lends Path# */{
* Creates a new path item from SVG path-data and places it at the top of
* the active layer.
*
- * @param
* @name Path#initialize
* @param {String} pathData the SVG path-data that describes the geometry
* of this path
@@ -484,9 +483,11 @@ var Path = PathItem.extend(/** @lends Path# */{
* Adds one or more segments to the end of the {@link #segments} array of
* this path.
*
- * @param {Segment|Point} segment the segment or point to be added.
- * @return {Segment} the added segment. This is not necessarily the same
- * object, e.g. if the segment to be added already belongs to another path
+ * @param {...(Segment|Point|Number[])} segment the segment or point to be
+ * added.
+ * @return {Segment|Segment[]} the added segment(s). This is not necessarily
+ * the same object, e.g. if the segment to be added already belongs to
+ * another path.
*
* @example {@paperscript}
* // Adding segments to a path using point objects:
@@ -1215,6 +1216,8 @@ var Path = PathItem.extend(/** @lends Path# */{
/**
* Reduces the path by removing curves that have a length of 0,
* and unnecessary segments between two collinear flat curves.
+ *
+ * @return {Path} the reduced path
*/
reduce: function(options) {
var curves = this.getCurves(),
@@ -2172,11 +2175,13 @@ new function() { // Scope for drawing
// SegmentPoint objects maybe seem a bit tedious but is worth the benefit in
// performance.
- function drawHandles(ctx, segments, matrix, size, isFullySelected) {
- if (size === 0) {
- return;
- }
+ function drawHandles(ctx, segments, matrix, size) {
+ // Only draw if size is not null or negative.
+ if (size <= 0) return;
+
var half = size / 2,
+ miniSize = size - 2,
+ miniHalf = half - 1,
coords = new Array(6),
pX, pY;
@@ -2470,9 +2475,10 @@ new function() { // PostScript-style drawing commands
// #2: arcTo(through, to)
through = to;
to = Point.read(arguments);
- } else {
+ } else if (!from.equals(to)) {
// #3: arcTo(to, radius, rotation, clockwise, large)
- // Drawing arcs in SVG style:
+ // Draw arc in SVG style, but only if `from` and `to` are not
+ // equal (#1613).
var radius = Size.read(arguments),
isZero = Numerical.isZero;
// If rx = 0 or ry = 0 then this arc is treated as a
@@ -2481,7 +2487,7 @@ new function() { // PostScript-style drawing commands
if (isZero(radius.width) || isZero(radius.height))
return this.lineTo(to);
// See for an explanation of the following calculations:
- // http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
+ // https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
var rotation = Base.read(arguments),
clockwise = !!Base.read(arguments),
large = !!Base.read(arguments),
@@ -2568,47 +2574,49 @@ new function() { // PostScript-style drawing commands
extent += extent < 0 ? 360 : -360;
}
}
- var epsilon = /*#=*/Numerical.GEOMETRIC_EPSILON,
- ext = abs(extent),
- // Calculate the amount of segments required to approximate over
- // `extend` degrees (extend / 90), but prevent ceil() from
- // rounding up small imprecisions by subtracting epsilon first.
- count = ext >= 360 ? 4 : Math.ceil((ext - epsilon) / 90),
- inc = extent / count,
- half = inc * Math.PI / 360,
- z = 4 / 3 * Math.sin(half) / (1 + Math.cos(half)),
- segments = [];
- for (var i = 0; i <= count; i++) {
- // Explicitly use to point for last segment, since depending
- // on values the calculation adds imprecision:
- var pt = to,
- out = null;
- if (i < count) {
- out = vector.rotate(90).multiply(z);
- if (matrix) {
- pt = matrix._transformPoint(vector);
- out = matrix._transformPoint(vector.add(out))
- .subtract(pt);
+ if (extent) {
+ var epsilon = /*#=*/Numerical.GEOMETRIC_EPSILON,
+ ext = abs(extent),
+ // Calculate amount of segments required to approximate over
+ // `extend` degrees (extend / 90), but prevent ceil() from
+ // rounding up small imprecisions by subtracting epsilon.
+ count = ext >= 360 ? 4 : Math.ceil((ext - epsilon) / 90),
+ inc = extent / count,
+ half = inc * Math.PI / 360,
+ z = 4 / 3 * Math.sin(half) / (1 + Math.cos(half)),
+ segments = [];
+ for (var i = 0; i <= count; i++) {
+ // Explicitly use to point for last segment, since depending
+ // on values the calculation adds imprecision:
+ var pt = to,
+ out = null;
+ if (i < count) {
+ out = vector.rotate(90).multiply(z);
+ if (matrix) {
+ pt = matrix._transformPoint(vector);
+ out = matrix._transformPoint(vector.add(out))
+ .subtract(pt);
+ } else {
+ pt = center.add(vector);
+ }
+ }
+ if (!i) {
+ // Modify startSegment
+ current.setHandleOut(out);
} else {
- pt = center.add(vector);
+ // Add new Segment
+ var _in = vector.rotate(-90).multiply(z);
+ if (matrix) {
+ _in = matrix._transformPoint(vector.add(_in))
+ .subtract(pt);
+ }
+ segments.push(new Segment(pt, _in, out));
}
+ vector = vector.rotate(inc);
}
- if (!i) {
- // Modify startSegment
- current.setHandleOut(out);
- } else {
- // Add new Segment
- var _in = vector.rotate(-90).multiply(z);
- if (matrix) {
- _in = matrix._transformPoint(vector.add(_in))
- .subtract(pt);
- }
- segments.push(new Segment(pt, _in, out));
- }
- vector = vector.rotate(inc);
+ // Add all segments at once at the end for higher performance
+ this._add(segments);
}
- // Add all segments at once at the end for higher performance
- this._add(segments);
},
lineBy: function(/* to */) {
@@ -2846,8 +2854,9 @@ statics: {
normal1 = curve1.getNormalAtTime(1).multiply(radius)
.transform(strokeMatrix),
normal2 = curve2.getNormalAtTime(0).multiply(radius)
- .transform(strokeMatrix);
- if (normal1.getDirectedAngle(normal2) < 0) {
+ .transform(strokeMatrix),
+ angle = normal1.getDirectedAngle(normal2);
+ if (angle < 0 || angle >= 180) {
normal1 = normal1.negate();
normal2 = normal2.negate();
}
diff --git a/src/path/PathFitter.js b/src/path/PathFitter.js
index b9d10300..27361e69 100644
--- a/src/path/PathFitter.js
+++ b/src/path/PathFitter.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/path/PathFlattener.js b/src/path/PathFlattener.js
index 1df208a4..2f7899d1 100644
--- a/src/path/PathFlattener.js
+++ b/src/path/PathFlattener.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/path/PathItem.Boolean.js b/src/path/PathItem.Boolean.js
index f4f098e4..018555aa 100644
--- a/src/path/PathItem.Boolean.js
+++ b/src/path/PathItem.Boolean.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -25,7 +25,7 @@
* @author Harikrishnan Gopalakrishnan
* @author Jan Boesenberg
* @author Juerg Lehni
- * http://hkrish.com/playground/paperjs/booleanStudy.html
+ * https://hkrish.com/playground/paperjs/booleanStudy.html
*/
PathItem.inject(new function() {
var min = Math.min,
@@ -1125,7 +1125,7 @@ PathItem.inject(new function() {
/**
* Splits the geometry of this path along the geometry of the specified
* path returns the result as a new group item. This is equivalent to
- * calling {@link #subtract(path)} and {@link #subtract(path)} and
+ * calling {@link #subtract(path)} and {@link #intersect(path)} and
* putting the results into a new group.
*
* @option [options.insert=true] {Boolean} whether the resulting item
@@ -1156,7 +1156,7 @@ PathItem.inject(new function() {
* amount of resulting paths allows so, otherwise a new path /
* compound-path is created, replacing the current one.
*
- * @return {PahtItem} the resulting path item
+ * @return {PathItem} the resulting path item
*/
resolveCrossings: function() {
var children = this._children,
@@ -1278,7 +1278,7 @@ PathItem.inject(new function() {
* @param {Boolean} [clockwise] if provided, the orientation of the root
* paths will be set to the orientation specified by `clockwise`,
* otherwise the orientation of the largest root child is used.
- * @return {PahtItem} a reference to the item itself, reoriented
+ * @return {PathItem} a reference to the item itself, reoriented
*/
reorient: function(nonZero, clockwise) {
var children = this._children;
diff --git a/src/path/PathItem.js b/src/path/PathItem.js
index ed9037c1..e7ff2d17 100644
--- a/src/path/PathItem.js
+++ b/src/path/PathItem.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -102,8 +102,8 @@ var PathItem = Item.extend(/** @lends PathItem# */{
*
* @bean
* @type Boolean
- * @see Path#getArea()
- * @see CompoundPath#getArea()
+ * @see Path#area
+ * @see CompoundPath#area
*/
isClockwise: function() {
return this.getArea() >= 0;
@@ -345,6 +345,8 @@ var PathItem = Item.extend(/** @lends PathItem# */{
* crossing each other, as opposed to simply touching.
*
* @param {PathItem} path the other item to find the crossings with
+ * @return {CurveLocation[]} the locations of all crossings between the
+ * paths
* @see #getIntersections(path)
*/
getCrossings: function(path) {
diff --git a/src/path/Segment.js b/src/path/Segment.js
index 298065ec..4fa11d0f 100644
--- a/src/path/Segment.js
+++ b/src/path/Segment.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -234,8 +234,8 @@ var Segment = Base.extend(/** @lends Segment# */{
* Checks if the segment has any curve handles set.
*
* @return {Boolean} {@true if the segment has handles set}
- * @see Segment#getHandleIn()
- * @see Segment#getHandleOut()
+ * @see Segment#handleIn
+ * @see Segment#handleOut
* @see Curve#hasHandles()
* @see Path#hasHandles()
*/
@@ -554,6 +554,9 @@ var Segment = Base.extend(/** @lends Segment# */{
return this._path ? !!this._path.removeSegment(this._index) : false;
},
+ /**
+ * @return {Segment}
+ */
clone: function() {
return new Segment(this._point, this._handleIn, this._handleOut);
},
diff --git a/src/path/SegmentPoint.js b/src/path/SegmentPoint.js
index 2289bda0..a6bf3428 100644
--- a/src/path/SegmentPoint.js
+++ b/src/path/SegmentPoint.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/path/SegmentSelection.js b/src/path/SegmentSelection.js
index 559ef294..abe4af55 100644
--- a/src/path/SegmentSelection.js
+++ b/src/path/SegmentSelection.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/style/Color.js b/src/style/Color.js
index 05f4691f..6cf4d737 100644
--- a/src/style/Color.js
+++ b/src/style/Color.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -80,7 +80,7 @@ var Color = Base.extend(new function() {
} else if (match = string.match(/^(rgb|hsl)a?\((.*)\)$/)) {
// RGB / RGBA or HSL / HSLA
type = match[1];
- components = match[2].split(/[,\s]+/g);
+ components = match[2].trim().split(/[,\s]+/g);
var isHSL = type === 'hsl';
for (var i = 0, l = Math.min(components.length, 4); i < l; i++) {
var component = components[i];
@@ -691,6 +691,8 @@ var Color = Base.extend(new function() {
* constructors also work for calls of `set()`.
*
* @function
+ * @param {...*} values
+ * @return {Color}
*/
set: '#initialize',
@@ -709,8 +711,13 @@ var Color = Base.extend(new function() {
*/
_changed: function() {
this._canvasStyle = null;
- if (this._owner)
- this._owner._changed(/*#=*/Change.STYLE);
+ if (this._owner) {
+ if (this._setter) {
+ this._owner[this._setter](this);
+ } else {
+ this._owner._changed(/*#=*/Change.STYLE);
+ }
+ }
},
/**
@@ -729,7 +736,7 @@ var Color = Base.extend(new function() {
},
/**
- * Converts the color another type.
+ * Converts the color to another type.
*
* @param {String} type the color type to convert to. Possible values:
* {@values 'rgb', 'gray', 'hsb', 'hsl'}
@@ -1183,9 +1190,35 @@ var Color = Base.extend(new function() {
// Export for backward compatibility code below.
_types: types,
+ /**
+ * Returns a color object with random {@link #red}, {@link #green}
+ * and {@link #blue} values between `0` and `1`.
+ *
+ * @return {Color} the newly created color object
+ * @static
+ *
+ * @example {@paperscript}
+ * var circle = new Path.Circle(view.center, 50);
+ * // Set a random color as circle fill color.
+ * circle.fillColor = Color.random();
+ */
random: function() {
var random = Math.random;
return new Color(random(), random(), random());
+ },
+
+ _setOwner: function(color, owner, setter) {
+ if (color) {
+ // Clone color if owner changes:
+ if (color._owner && owner && color._owner !== owner) {
+ color = color.clone();
+ }
+ if (!color._owner ^ !owner) {
+ color._owner = owner || null;
+ color._setter = setter || null;
+ }
+ }
+ return color;
}
}
});
diff --git a/src/style/Gradient.js b/src/style/Gradient.js
index 4fd6b6ea..512a835b 100644
--- a/src/style/Gradient.js
+++ b/src/style/Gradient.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/style/GradientStop.js b/src/style/GradientStop.js
index 96e78464..b1d2d427 100644
--- a/src/style/GradientStop.js
+++ b/src/style/GradientStop.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -175,12 +175,10 @@ var GradientStop = Base.extend(/** @lends GradientStop# */{
},
setColor: function(/* color */) {
- // Make sure newly set colors are cloned, since they can only have
- // one owner.
- var color = Color.read(arguments, 0, { clone: true });
- if (color)
- color._owner = this;
- this._color = color;
+ // Clear old color owner before setting new one:
+ Color._setOwner(this._color, null);
+ this._color = Color._setOwner(Color.read(arguments, 0), this,
+ 'setColor');
this._changed();
},
diff --git a/src/style/Style.js b/src/style/Style.js
index f8e10280..b30e090a 100644
--- a/src/style/Style.js
+++ b/src/style/Style.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -162,29 +162,35 @@ var Style = Base.extend(new function() {
// raw value is stored, and conversion only happens in the getter.
fields[set] = function(value) {
var owner = this._owner,
- children = owner && owner._children;
+ children = owner && owner._children,
+ applyToChildren = children && children.length > 0
+ && !(owner instanceof CompoundPath);
// Only unify styles on children of Groups, excluding CompoundPaths.
- if (children && children.length > 0
- && !(owner instanceof CompoundPath)) {
+ if (applyToChildren) {
for (var i = 0, l = children.length; i < l; i++)
children[i]._style[set](value);
- } else if (key in this._defaults) {
+ }
+ // Always store selectedColor in item _values to make sure that
+ // group selected bounds and position color is coherent whether it
+ // has children or not when the value is set.
+ if ((key === 'selectedColor' || !applyToChildren)
+ && key in this._defaults) {
var old = this._values[key];
if (old !== value) {
if (isColor) {
// The old value may be a native string or other color
// description that wasn't coerced to a color object yet
- if (old && old._owner !== undefined) {
- old._owner = undefined;
+ if (old) {
+ Color._setOwner(old, null);
old._canvasStyle = null;
}
if (value && value.constructor === Color) {
- // Clone color if it already has an owner.
// NOTE: If value is not a Color, it is only
// converted and cloned in the getter further down.
- if (value._owner)
- value = value.clone();
- value._owner = owner;
+ value = Color._setOwner(value, owner,
+ // Only provide a color-setter if the style
+ // is to be applied to the children:
+ applyToChildren && set);
}
}
// NOTE: We do not convert the values to Colors in the
@@ -201,29 +207,13 @@ var Style = Base.extend(new function() {
fields[get] = function(_dontMerge) {
var owner = this._owner,
children = owner && owner._children,
+ applyToChildren = children && children.length > 0
+ && !(owner instanceof CompoundPath),
value;
// If the owner has children, walk through all of them and see if
// they all have the same style.
- // If true is passed for _dontMerge, don't merge children styles
- if (key in this._defaults && (!children || !children.length
- || _dontMerge || owner instanceof CompoundPath)) {
- var value = this._values[key];
- if (value === undefined) {
- value = this._defaults[key];
- if (value && value.clone)
- value = value.clone();
- } else {
- var ctor = isColor ? Color : isPoint ? Point : null;
- if (ctor && !(value && value.constructor === ctor)) {
- // Convert to a Color / Point, and stored result of the
- // conversion.
- this._values[key] = value = ctor.read([value], 0,
- { readNull: true, clone: true });
- if (value && isColor)
- value._owner = owner;
- }
- }
- } else if (children) {
+ // If true is passed for _dontMerge, don't merge children styles.
+ if (applyToChildren && !_dontMerge) {
for (var i = 0, l = children.length; i < l; i++) {
var childValue = children[i]._style[get]();
if (!i) {
@@ -234,6 +224,30 @@ var Style = Base.extend(new function() {
return undefined;
}
}
+ } else if (key in this._defaults) {
+ var value = this._values[key];
+ if (value === undefined) {
+ value = this._defaults[key];
+ // Clone defaults if available:
+ if (value && value.clone) {
+ value = value.clone();
+ }
+ } else {
+ var ctor = isColor ? Color : isPoint ? Point : null;
+ if (ctor && !(value && value.constructor === ctor)) {
+ // Convert to a Color / Point, and stored result of the
+ // conversion.
+ this._values[key] = value = ctor.read([value], 0,
+ { readNull: true, clone: true });
+ }
+ }
+ }
+ if (value && isColor) {
+ // Color._setOwner() may clone the color if it already has a
+ // different owner (e.g. resulting from `childValue` above).
+ // Only provide a color-setter if the style is to be applied to
+ // the children:
+ value = Color._setOwner(value, owner, applyToChildren && set);
}
return value;
};
@@ -530,7 +544,7 @@ var Style = Base.extend(new function() {
*
* @name Style#dashArray
* @property
- * @type Array
+ * @type Number[]
* @default []
*/
diff --git a/src/svg/SvgElement.js b/src/svg/SvgElement.js
index df34143c..f345dc50 100644
--- a/src/svg/SvgElement.js
+++ b/src/svg/SvgElement.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/svg/SvgExport.js b/src/svg/SvgExport.js
index 672f2f8f..f6b16d12 100644
--- a/src/svg/SvgExport.js
+++ b/src/svg/SvgExport.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -29,11 +29,16 @@ new function() {
// in rotate(). To do so, SVG requries us to inverse transform the
// translation point by the matrix itself, since they are provided
// in local coordinates.
- matrix = matrix._shiftless();
- var point = matrix._inverseTransform(trans);
+ var point;
+ if (matrix.isInvertible()) {
+ matrix = matrix._shiftless();
+ point = matrix._inverseTransform(trans);
+ trans = null;
+ } else {
+ point = new Point();
+ }
attrs[center ? 'cx' : 'x'] = point.x;
attrs[center ? 'cy' : 'y'] = point.y;
- trans = null;
}
if (!matrix.isIdentity()) {
// See if we can decompose the matrix and can formulate it as a
@@ -177,7 +182,7 @@ new function() {
definition = item._definition,
node = getDefinition(definition, 'symbol'),
definitionItem = definition._item,
- bounds = definitionItem.getBounds();
+ bounds = definitionItem.getStrokeBounds();
if (!node) {
node = SvgElement.create('symbol', {
viewBox: formatter.rectangle(bounds)
@@ -450,7 +455,7 @@ new function() {
if (rect) {
attrs.width = rect.width;
attrs.height = rect.height;
- if (rect.x || rect.y)
+ if (rect.x || rect.x === 0 || rect.y || rect.y === 0)
attrs.viewBox = formatter.rectangle(rect);
}
var node = SvgElement.create('svg', attrs, formatter),
diff --git a/src/svg/SvgImport.js b/src/svg/SvgImport.js
index 9b97668b..9fcf6101 100644
--- a/src/svg/SvgImport.js
+++ b/src/svg/SvgImport.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -22,11 +22,12 @@ new function() {
var definitions = {},
rootSize;
- function getValue(node, name, isString, allowNull, allowPercent) {
+ function getValue(node, name, isString, allowNull, allowPercent,
+ defaultValue) {
// Interpret value as number. Never return NaN, but 0 instead.
// If the value is a sequence of numbers, parseFloat will
// return the first occurring number, which is enough for now.
- var value = SvgElement.get(node, name),
+ var value = SvgElement.get(node, name) || defaultValue,
res = value == null
? allowNull
? null
@@ -43,9 +44,9 @@ new function() {
: res;
}
- function getPoint(node, x, y, allowNull, allowPercent) {
- x = getValue(node, x || 'x', false, allowNull, allowPercent);
- y = getValue(node, y || 'y', false, allowNull, allowPercent);
+ function getPoint(node, x, y, allowNull, allowPercent, defaultX, defaultY) {
+ x = getValue(node, x || 'x', false, allowNull, allowPercent, defaultX);
+ y = getValue(node, y || 'y', false, allowNull, allowPercent, defaultY);
return allowNull && (x == null || y == null) ? null
: new Point(x, y);
}
@@ -168,13 +169,16 @@ new function() {
'userSpaceOnUse';
// Allow percentages in all values if scaleToBounds is true:
if (radial) {
- origin = getPoint(node, 'cx', 'cy', false, scaleToBounds);
+ origin = getPoint(node, 'cx', 'cy', false, scaleToBounds,
+ '50%', '50%');
destination = origin.add(
- getValue(node, 'r', false, false, scaleToBounds), 0);
+ getValue(node, 'r', false, false, scaleToBounds, '50%'), 0);
highlight = getPoint(node, 'fx', 'fy', true, scaleToBounds);
} else {
- origin = getPoint(node, 'x1', 'y1', false, scaleToBounds);
- destination = getPoint(node, 'x2', 'y2', false, scaleToBounds);
+ origin = getPoint(node, 'x1', 'y1', false, scaleToBounds,
+ '0%', '0%');
+ destination = getPoint(node, 'x2', 'y2', false, scaleToBounds,
+ '100%', '0%');
}
var color = applyAttributes(
new Color(gradient, origin, destination, highlight), node);
@@ -196,23 +200,23 @@ new function() {
return importNode(child, options, isRoot);
}
},
- // http://www.w3.org/TR/SVG/struct.html#Groups
+ // https://www.w3.org/TR/SVG/struct.html#Groups
g: importGroup,
- // http://www.w3.org/TR/SVG/struct.html#NewDocument
+ // https://www.w3.org/TR/SVG/struct.html#NewDocument
svg: importGroup,
clippath: importGroup,
- // http://www.w3.org/TR/SVG/shapes.html#PolygonElement
+ // https://www.w3.org/TR/SVG/shapes.html#PolygonElement
polygon: importPoly,
- // http://www.w3.org/TR/SVG/shapes.html#PolylineElement
+ // https://www.w3.org/TR/SVG/shapes.html#PolylineElement
polyline: importPoly,
- // http://www.w3.org/TR/SVG/paths.html
+ // https://www.w3.org/TR/SVG/paths.html
path: importPath,
- // http://www.w3.org/TR/SVG/pservers.html#LinearGradients
+ // https://www.w3.org/TR/SVG/pservers.html#LinearGradients
lineargradient: importGradient,
- // http://www.w3.org/TR/SVG/pservers.html#RadialGradients
+ // https://www.w3.org/TR/SVG/pservers.html#RadialGradients
radialgradient: importGradient,
- // http://www.w3.org/TR/SVG/struct.html#ImageElement
+ // https://www.w3.org/TR/SVG/struct.html#ImageElement
image: function (node) {
var raster = new Raster(getValue(node, 'href', true));
raster.on('load', function() {
@@ -228,17 +232,17 @@ new function() {
return raster;
},
- // http://www.w3.org/TR/SVG/struct.html#SymbolElement
+ // https://www.w3.org/TR/SVG/struct.html#SymbolElement
symbol: function(node, type, options, isRoot) {
return new SymbolDefinition(
// Pass true for dontCenter:
importGroup(node, type, options, isRoot), true);
},
- // http://www.w3.org/TR/SVG/struct.html#DefsElement
+ // https://www.w3.org/TR/SVG/struct.html#DefsElement
defs: importGroup,
- // http://www.w3.org/TR/SVG/struct.html#UseElement
+ // https://www.w3.org/TR/SVG/struct.html#UseElement
use: function(node) {
// Note the namespaced xlink:href attribute is just called href
// as a property on node.
@@ -258,14 +262,14 @@ new function() {
: null;
},
- // http://www.w3.org/TR/SVG/shapes.html#InterfaceSVGCircleElement
+ // https://www.w3.org/TR/SVG/shapes.html#InterfaceSVGCircleElement
circle: function(node) {
return new Shape.Circle(
getPoint(node, 'cx', 'cy'),
getValue(node, 'r'));
},
- // http://www.w3.org/TR/SVG/shapes.html#InterfaceSVGEllipseElement
+ // https://www.w3.org/TR/SVG/shapes.html#InterfaceSVGEllipseElement
ellipse: function(node) {
// We only use object literal notation where the default one is not
// supported (e.g. center / radius fo Shape.Ellipse).
@@ -275,7 +279,7 @@ new function() {
});
},
- // http://www.w3.org/TR/SVG/shapes.html#RectElement
+ // https://www.w3.org/TR/SVG/shapes.html#RectElement
rect: function(node) {
return new Shape.Rectangle(new Rectangle(
getPoint(node),
@@ -283,7 +287,7 @@ new function() {
), getSize(node, 'rx', 'ry'));
},
- // http://www.w3.org/TR/SVG/shapes.html#LineElement
+ // https://www.w3.org/TR/SVG/shapes.html#LineElement
line: function(node) {
return new Path.Line(
getPoint(node, 'x1', 'y1'),
@@ -345,7 +349,11 @@ new function() {
text.setContent(lines.join('\n'));
return text;
}
- }
+ },
+
+ // https://www.w3.org/TR/SVG/struct.html#SwitchElement
+ // Conditional attributes are ignored and all children are rendered.
+ switch: importGroup
};
// Attributes and Styles
@@ -356,7 +364,7 @@ new function() {
function applyTransform(item, value, name, node) {
if (item.transform) {
- // http://www.w3.org/TR/SVG/types.html#DataTypeTransformList
+ // https://www.w3.org/TR/SVG/types.html#DataTypeTransformList
// Parse SVG transform string. First we split at /)\s*/, to separate
// commands
var transforms = (node.getAttribute(name) || '').split(/\)\s*/g),
@@ -399,8 +407,8 @@ new function() {
}
function applyOpacity(item, value, name) {
- // http://www.w3.org/TR/SVG/painting.html#FillOpacityProperty
- // http://www.w3.org/TR/SVG/painting.html#StrokeOpacityProperty
+ // https://www.w3.org/TR/SVG/painting.html#FillOpacityProperty
+ // https://www.w3.org/TR/SVG/painting.html#StrokeOpacityProperty
var key = name === 'fill-opacity' ? 'getFillColor' : 'getStrokeColor',
color = item[key] && item[key]();
if (color)
@@ -442,7 +450,7 @@ new function() {
},
'clip-path': function(item, value) {
- // http://www.w3.org/TR/SVG/masking.html#ClipPathProperty
+ // https://www.w3.org/TR/SVG/masking.html#ClipPathProperty
var clip = getDefinition(value);
if (clip) {
clip = clip.clone();
@@ -474,20 +482,20 @@ new function() {
},
'stop-color': function(item, value) {
- // http://www.w3.org/TR/SVG/pservers.html#StopColorProperty
+ // https://www.w3.org/TR/SVG/pservers.html#StopColorProperty
if (item.setColor)
item.setColor(value);
},
'stop-opacity': function(item, value) {
- // http://www.w3.org/TR/SVG/pservers.html#StopOpacityProperty
+ // https://www.w3.org/TR/SVG/pservers.html#StopOpacityProperty
// NOTE: It is important that this is applied after stop-color!
if (item._color)
item._color.setAlpha(parseFloat(value));
},
offset: function(item, value) {
- // http://www.w3.org/TR/SVG/pservers.html#StopElementOffsetAttribute
+ // https://www.w3.org/TR/SVG/pservers.html#StopElementOffsetAttribute
if (item.setOffset) {
var percent = value.match(/(.*)%$/);
item.setOffset(percent ? percent[1] / 100 : parseFloat(value));
@@ -495,7 +503,7 @@ new function() {
},
viewBox: function(item, value, name, node, styles) {
- // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
+ // https://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
// TODO: implement preserveAspectRatio attribute
// viewBox will be applied both to the group that's created for the
// content in SymbolDefinition#item, and the SymbolItem itself.
diff --git a/src/svg/SvgStyles.js b/src/svg/SvgStyles.js
index af1827e2..9d8bab08 100644
--- a/src/svg/SvgStyles.js
+++ b/src/svg/SvgStyles.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/text/PointText.js b/src/text/PointText.js
index 762a8288..ccc1fd8e 100644
--- a/src/text/PointText.js
+++ b/src/text/PointText.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/text/TextItem.js b/src/text/TextItem.js
index b6d56bfe..11cc315d 100644
--- a/src/text/TextItem.js
+++ b/src/text/TextItem.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/tool/Tool.js b/src/tool/Tool.js
index e3c409e1..69699f09 100644
--- a/src/tool/Tool.js
+++ b/src/tool/Tool.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/tool/ToolEvent.js b/src/tool/ToolEvent.js
index 128de506..b9747459 100644
--- a/src/tool/ToolEvent.js
+++ b/src/tool/ToolEvent.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/util/Formatter.js b/src/util/Formatter.js
index 2b73c5ba..58fded28 100644
--- a/src/util/Formatter.js
+++ b/src/util/Formatter.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/util/Numerical.js b/src/util/Numerical.js
index b2b3adfd..54d4c5db 100644
--- a/src/util/Numerical.js
+++ b/src/util/Numerical.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/util/UID.js b/src/util/UID.js
index 9aac04c0..0c315f26 100644
--- a/src/util/UID.js
+++ b/src/util/UID.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/src/view/CanvasView.js b/src/view/CanvasView.js
index 3afdfa68..85eecfb3 100644
--- a/src/view/CanvasView.js
+++ b/src/view/CanvasView.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -49,7 +49,7 @@ var CanvasView = View.extend(/** @lends CanvasView# */{
this._pixelRatio = 1;
if (!/^off|false$/.test(PaperScope.getAttribute(canvas, 'hidpi'))) {
// Hi-DPI Canvas support based on:
- // http://www.html5rocks.com/en/tutorials/canvas/hidpi/
+ // https://www.html5rocks.com/en/tutorials/canvas/hidpi/
var deviceRatio = window.devicePixelRatio || 1,
backingStoreRatio = DomElement.getPrefixed(ctx,
'backingStorePixelRatio') || 1;
@@ -88,6 +88,10 @@ var CanvasView = View.extend(/** @lends CanvasView# */{
}
},
+ getContext: function() {
+ return this._context;
+ },
+
/**
* Converts the provide size in any of the units allowed in the browser to
* pixels.
@@ -124,7 +128,7 @@ var CanvasView = View.extend(/** @lends CanvasView# */{
/**
* Updates the view if there are changes. Note that when using built-in
- * event hanlders for interaction, animation and load events, this method is
+ * event handlers for interaction, animation and load events, this method is
* invoked for you automatically at the end.
*
* @return {Boolean} {@true if the view was updated}
diff --git a/src/view/View.js b/src/view/View.js
index 281670f1..13291df6 100644
--- a/src/view/View.js
+++ b/src/view/View.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -522,7 +522,7 @@ var View = Base.extend(Emitter, /** @lends View# */{
*
* @bean
* @type Number
- * @see #getScaling()
+ * @see #scaling
*/
getZoom: function() {
var scaling = this._decompose().scaling;
@@ -559,7 +559,7 @@ var View = Base.extend(Emitter, /** @lends View# */{
*
* @bean
* @type Point
- * @see #getZoom()
+ * @see #zoom
*/
getScaling: function() {
var scaling = this._decompose().scaling;
@@ -1496,7 +1496,7 @@ new function() { // Injection scope for event handling on the browser
updateFocus: updateFocus,
/**
- * Clear all events handling state informations. Made for testing
+ * Clear all events handling state information. Made for testing
* purpose, to have a way to start with a fresh state before each
* test.
* @private
diff --git a/test/assets/gradients-3.svg b/test/assets/gradients-3.svg
new file mode 100644
index 00000000..854ccf5a
--- /dev/null
+++ b/test/assets/gradients-3.svg
@@ -0,0 +1,17 @@
+
+
diff --git a/test/assets/gradients-4.svg b/test/assets/gradients-4.svg
new file mode 100644
index 00000000..98fc5380
--- /dev/null
+++ b/test/assets/gradients-4.svg
@@ -0,0 +1,9 @@
+
diff --git a/test/helpers.js b/test/helpers.js
index 4ccc68ba..28e8be91 100644
--- a/test/helpers.js
+++ b/test/helpers.js
@@ -2,19 +2,21 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
* All rights reserved.
*/
-var isNode = typeof global === 'object',
- isPhantom = typeof window === 'object' && !!window.callPhantom,
+// We call our variable `isNodeContext` because resemble.js exposes a global
+// `isNode` function which would override it and break node check.
+var isNodeContext = typeof global === 'object',
+ isPhantomContext = typeof window === 'object' && !!window.callPhantom,
scope;
-if (isNode) {
+if (isNodeContext) {
scope = global;
// Resemble.js needs the Image constructor global.
global.Image = paper.window.Image;
@@ -35,14 +37,11 @@ if (isNode) {
}
// Some native javascript classes have name collisions with Paper.js classes.
-// If they have not already been stored in src/load.js, we dot it now.
-if (!isNode && typeof NativeClasses === 'undefined')
-{
- NativeClasses = {
- Event: Event,
- MouseEvent: MouseEvent
- };
-}
+// If they have not already been stored in `src/load.js`, do it now:
+var nativeClasses = this.nativeClasses || {
+ Event: this.Event || {},
+ MouseEvent: this.MouseEvent || {}
+};
// The unit-tests expect the paper classes to be global.
paper.install(scope);
@@ -107,7 +106,7 @@ var equals = function(actual, expected, message, options) {
|| type === 'boolean' && 'Boolean'
|| type === 'undefined' && 'Undefined'
|| Array.isArray(expected) && 'Array'
- || expected instanceof window.Element && 'Element' // handle DOM Elements
+ || expected instanceof window.Element && 'Element' // DOM Elements
|| (cls = expected && expected._class) // check _class 2nd last
|| type === 'object' && 'Object'; // Object as catch-all
var comparator = type && comparators[type];
@@ -161,6 +160,81 @@ var compareProperties = function(actual, expected, properties, message, options)
}
};
+/**
+ * Compare 2 image data with resemble.js library.
+ * When comparison fails, expected, actual and compared images are displayed.
+ * @param {ImageData} imageData1 the expected image data
+ * @param {ImageData} imageData2 the actual image data
+ * @param {number} tolerance
+ * @param {string} diffDetail text displayed when comparison fails
+ */
+var compareImageData = function(imageData1, imageData2, tolerance, diffDetail) {
+ /**
+ * Build an image element from a given image data.
+ * @param {ImageData} imageData
+ * @return {HTMLImageElement}
+ */
+ function image(imageData) {
+ var canvas = document.createElement('canvas');
+ canvas.width = imageData.width;
+ canvas.height = imageData.height;
+ canvas.getContext('2d').putImageData(imageData, 0, 0);
+ var image = new Image();
+ image.src = canvas.toDataURL();
+ canvas.remove();
+ return image;
+ }
+
+ tolerance = (tolerance || 1e-4) * 100;
+
+ var id = QUnit.config.current.testId,
+ index = QUnit.config.current.assertions.length + 1,
+ result;
+ // Compare image-data using resemble.js:
+ resemble.compare(
+ imageData1,
+ imageData2,
+ {
+ output: {
+ errorColor: { red: 255, green: 51, blue: 0 },
+ errorType: 'flat',
+ transparency: 1
+ },
+ ignore: ['antialiasing']
+ },
+ // When working with imageData, this call is synchronous:
+ function (error, data) {
+ if (error) {
+ console.error(error);
+ } else {
+ result = data;
+ }
+ }
+ )
+ // Compare with tolerance in percentage...
+ var fixed = tolerance < 1 ? ((1 / tolerance) + '').length - 1 : 0,
+ identical = result ? 100 - result.misMatchPercentage : 0,
+ ok = Math.abs(100 - identical) <= tolerance,
+ text = identical.toFixed(fixed) + '% identical',
+ detail = text;
+ if (!ok && diffDetail) {
+ detail += diffDetail;
+ }
+ QUnit.push(ok, text, (100).toFixed(fixed) + '% identical');
+ if (!ok && result && !isNodeContext) {
+ // Get the right entry for this unit test and assertion, and
+ // replace the results with images
+ var entry = document.getElementById('qunit-test-output-' + id)
+ .querySelector('li:nth-child(' + (index) + ')'),
+ bounds = result.diffBounds;
+ entry.querySelector('.test-expected td').appendChild(image(imageData1));
+ entry.querySelector('.test-actual td').appendChild(image(imageData2));
+ entry.querySelector('.test-diff td').innerHTML = '' + detail
+ + '
'
+ + '';
+ }
+};
+
var comparePixels = function(actual, expected, message, options) {
function rasterize(item, group, resolution) {
var raster = null;
@@ -178,11 +252,6 @@ var comparePixels = function(actual, expected, message, options) {
return raster;
}
- function getImageTag(raster) {
- return '';
- }
-
if (!expected) {
return QUnit.strictEqual(actual, expected, message, options);
} else if (!actual) {
@@ -197,12 +266,12 @@ var comparePixels = function(actual, expected, message, options) {
// bounds of both items before rasterizing.
var resolution = options.resolution || 72,
actualBounds = actual.strokeBounds,
- expecedBounds = expected.strokeBounds,
+ expectedBounds = expected.strokeBounds,
bounds = actualBounds.isEmpty()
- ? expecedBounds
- : expecedBounds.isEmpty()
+ ? expectedBounds
+ : expectedBounds.isEmpty()
? actualBounds
- : actualBounds.unite(expecedBounds);
+ : actualBounds.unite(expectedBounds);
if (bounds.isEmpty()) {
QUnit.equal('empty', 'empty', message);
return;
@@ -220,53 +289,20 @@ var comparePixels = function(actual, expected, message, options) {
expectedRaster = rasterize(expected, group, resolution);
if (!actualRaster || !expectedRaster) {
QUnit.push(false, null, null, 'Unable to compare rasterized items: ' +
- (!actualRaster ? 'actual' : 'expected') + ' item is null',
- QUnit.stack(2));
+ (!actualRaster ? 'actual' : 'expected') + ' item is null',
+ QUnit.stack(2));
} else {
- // Use resemble.js to compare the two rasterized items.
- var id = QUnit.config.current.testId,
- index = QUnit.config.current.assertions.length + 1,
- result;
- if (!resemble._setup) {
- resemble._setup = true;
- resemble.outputSettings({
- errorColor: { red: 255, green: 51, blue: 0 },
- errorType: 'flat',
- transparency: 1
- });
- }
- resemble(actualRaster.getImageData())
- .compareTo(expectedRaster.getImageData())
- .ignoreAntialiasing()
- // When working with imageData, this call is synchronous:
- .onComplete(function(data) { result = data; });
- // Compare with tolerance in percentage...
- var tolerance = (options.tolerance || 1e-4) * 100,
- fixed = tolerance < 1 ? ((1 / tolerance) + '').length - 1 : 0,
- identical = result ? 100 - result.misMatchPercentage : 0,
- ok = Math.abs(100 - identical) <= tolerance,
- text = identical.toFixed(fixed) + '% identical',
- detail = text;
- if (!ok &&
- actual instanceof PathItem && expected instanceof PathItem) {
- detail += '\nExpected:\n' + expected.pathData +
- '\nActual:\n' + actual.pathData;
- }
- QUnit.push(ok, text, (100).toFixed(fixed) + '% identical', message);
- if (!ok && result && !isNode) {
- // Get the right entry for this unit test and assertion, and
- // replace the results with images
- var entry = document.getElementById('qunit-test-output-' + id)
- .querySelector('li:nth-child(' + (index) + ')'),
- bounds = result.diffBounds;
- entry.querySelector('.test-expected td').innerHTML =
- getImageTag(expectedRaster);
- entry.querySelector('.test-actual td').innerHTML =
- getImageTag(actualRaster);
- entry.querySelector('.test-diff td').innerHTML = '' + detail
- + '
'
- + '';
- }
+ // Compare the two rasterized items.
+ var detail = actual instanceof PathItem && expected instanceof PathItem
+ ? '\nExpected:\n' + expected.pathData +
+ '\nActual:\n' + actual.pathData
+ : '';
+ compareImageData(
+ actualRaster.getImageData(),
+ expectedRaster.getImageData(),
+ options.tolerance,
+ detail
+ );
}
};
@@ -304,6 +340,41 @@ var compareItem = function(actual, expected, message, options, properties) {
}
};
+/**
+ * Run each callback in a separated canvas context and compare both outputs.
+ * This can be used to do selection drawing tests as it is not possible with
+ * comparePixels() method which relies on the item.rasterize() method which
+ * ignores selection.
+ * @param {number} width the width of the canvas
+ * @param {number} height the height of the canvas
+ * @param {function} expectedCallback the function producing the expected result
+ * @param {function} actualCallback the function producing the actual result
+ * @param {number} tolerance between 0 and 1
+ */
+var compareCanvas = function(width, height, expected, actual, tolerance) {
+ function getImageData(width, height, callback) {
+ var canvas = document.createElement('canvas');
+ canvas.width = width;
+ canvas.height = height;
+ var project = new Project(canvas);
+ var view = project.view;
+ callback();
+ view.update();
+ var imageData = view.context.getImageData(0, 0, width, height);
+ project.remove();
+ canvas.remove();
+ return imageData;
+ }
+
+ compareImageData(
+ getImageData(width, height, expected),
+ getImageData(width, height, actual),
+ tolerance
+ );
+
+ currentProject.activate();
+};
+
// A list of comparator functions, based on `expected` type. See equals() for
// an explanation of how the type is determined.
var comparators = {
@@ -385,7 +456,7 @@ var comparators = {
equals(actual.components, expected.components,
message + ' (#components)', options);
} else {
- QUnit.strictEqual(actual, expected, message);
+ QUnit.push(expected.equals(actual), actual, expected, message);
}
},
@@ -597,8 +668,8 @@ var MouseEventPolyfill = function(type, params) {
);
return mouseEvent;
};
-MouseEventPolyfill.prototype = typeof NativeClasses !== 'undefined'
- && NativeClasses.Event.prototype || Event.prototype;
+
+MouseEventPolyfill.prototype = nativeClasses.Event.prototype;
var triggerMouseEvent = function(type, point, target) {
// Depending on event type, events have to be triggered on different
@@ -606,21 +677,16 @@ var triggerMouseEvent = function(type, point, target) {
// and `docEvents` in View.js). And we cannot rely on the fact that event
// will bubble from canvas to document, since the canvas used in tests is
// not inserted in DOM.
- target = target || (type === 'mousedown' ? view._element : document);
-
+ target = target || (type === 'mousedown' ? view.element : document);
// If `gulp load` was run, there is a name collision between paper Event /
// MouseEvent and native javascript classes. In this case, we need to use
- // native classes stored in global NativeClasses object instead.
- var constructor = typeof NativeClasses !== 'undefined'
- && NativeClasses.MouseEvent || MouseEvent;
-
+ // native classes stored in the nativeClasses object instead.
// MouseEvent class does not exist in PhantomJS, so in that case, we need to
- // use a polyfill method.
- if (typeof constructor !== 'function') {
- constructor = MouseEventPolyfill;
- }
-
- var event = new constructor(type, {
+ // use a polyfill method, see: https://stackoverflow.com/questions/42929639
+ var MouseEvent = typeof nativeClasses.MouseEvent === 'function'
+ ? nativeClasses.MouseEvent
+ : MouseEventPolyfill;
+ var event = new MouseEvent(type, {
bubbles: true,
cancelable: true,
composed: true,
diff --git a/test/load.js b/test/load.js
index ed1cf72e..0769f330 100644
--- a/test/load.js
+++ b/test/load.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Color.js b/test/tests/Color.js
index 32f0cf9d..363cdcc8 100644
--- a/test/tests/Color.js
+++ b/test/tests/Color.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -81,6 +81,9 @@ test('Creating Colors', function() {
equals(new Color('rgba(255, 0, 0, 0.5)'), new Color(1, 0, 0, 0.5),
'Color from rgba() string');
+ equals(new Color('rgba( 255, 0, 0, 0.5 )'), new Color(1, 0, 0, 0.5),
+ 'Color from rgba() string 2nd test');
+
equals(new Color('hsl(180deg, 20%, 40%)'),
new Color({ hue: 180, saturation: 0.2, lightness: 0.4 }),
'Color from hsl() string');
@@ -299,3 +302,11 @@ test('Gradients with applyMatrix', function() {
comparePixels(path, shape);
});
+
+test('Modifying group.strokeColor for multiple children', function() {
+ var item = new Group(new Path(), new Path());
+ item.strokeColor = 'red';
+ var strokeColor = item.strokeColor;
+ item.strokeColor.hue = 50;
+ equals(function() { return item.strokeColor !== undefined; }, true);
+});
diff --git a/test/tests/CompoundPath.js b/test/tests/CompoundPath.js
index adc0224d..2bad91e4 100644
--- a/test/tests/CompoundPath.js
+++ b/test/tests/CompoundPath.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Curve.js b/test/tests/Curve.js
index 6a4b6c4a..82ea945f 100644
--- a/test/tests/Curve.js
+++ b/test/tests/Curve.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/CurveLocation.js b/test/tests/CurveLocation.js
index fa3b06c2..816a7337 100644
--- a/test/tests/CurveLocation.js
+++ b/test/tests/CurveLocation.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Emitter.js b/test/tests/Emitter.js
index 9e55136b..2bbfdc98 100644
--- a/test/tests/Emitter.js
+++ b/test/tests/Emitter.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Group.js b/test/tests/Group.js
index 3f542204..e1e47153 100644
--- a/test/tests/Group.js
+++ b/test/tests/Group.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -134,4 +134,58 @@ test('group.addChildren()', function() {
group.addChildren(children);
equals(group.children.length, 2,
'adding the same item twice should only add it once.');
-})
+});
+
+test('group.setSelectedColor() with selected bound and position', function() {
+ // Working: Set selected color first then add child.
+ var group1 = new Group();
+ group1.bounds.selected = true;
+ group1.position.selected = true;
+ group1.selectedColor = 'black';
+ group1.addChild(new Path.Circle([50, 50], 40));
+ // Failing: Add child first then set selected color.
+ var group2 = new Group();
+ group2.bounds.selected = true;
+ group2.position.selected = true;
+ group2.addChild(new Path.Circle([50, 50], 40));
+ group2.selectedColor = 'black';
+ comparePixels(group1, group2);
+});
+
+test('Group#isEmpty(recursively)', function() {
+ var group = new Group();
+ equals(true, group.isEmpty());
+ equals(true, group.isEmpty(true));
+ var group = new Group(new Group());
+ equals(false, group.isEmpty());
+ equals(true, group.isEmpty(true));
+ var group = new Group(new Path());
+ equals(false, group.isEmpty());
+ equals(true, group.isEmpty(true));
+ var group = new Group(new PointText());
+ equals(false, group.isEmpty());
+ equals(true, group.isEmpty(true));
+});
+
+test(
+ 'group.internalBounds with clip item without clip.applyMatrix = false',
+ function() {
+ var point = new Point(100, 100);
+ var translation = new Point(100, 100);
+ var item = new Path.Circle({
+ center: point,
+ radius: 50,
+ fillColor: 'orange'
+ });
+ var clip = new Path.Rectangle({
+ from: point.subtract(translation),
+ to: point.add(translation)
+ });
+ clip.applyMatrix = false;
+ clip.translate(translation);
+ var group = new Group(clip, item);
+ group.clipped = true;
+ var expected = new Rectangle(point, point.add(translation.multiply(2)));
+ equals(group.internalBounds, expected);
+ }
+);
diff --git a/test/tests/HitResult.js b/test/tests/HitResult.js
index 5ca489f7..e9926815 100644
--- a/test/tests/HitResult.js
+++ b/test/tests/HitResult.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Interactions.js b/test/tests/Interactions.js
index f606fb78..299d564b 100644
--- a/test/tests/Interactions.js
+++ b/test/tests/Interactions.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Item.js b/test/tests/Item.js
index fa226b93..0f751996 100644
--- a/test/tests/Item.js
+++ b/test/tests/Item.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -945,3 +945,33 @@ test('Children global matrices are cleared after parent transformation', functio
group.translate(100, 0);
equals(item.localToGlobal(item.getPointAt(0)), new Point(100, 100));
});
+
+test('Item#rasterize() with empty bounds', function() {
+ new Path.Line([0, 0], [100, 0]).rasterize();
+ view.update();
+ expect(0);
+});
+
+test('Item#draw() with CompoundPath as clip item', function() {
+ function createdClippedGroup(invertedOrder) {
+ var compound = new CompoundPath({
+ children: [
+ new Path.Circle(new Point(50, 50), 50),
+ new Path.Circle(new Point(100, 50), 50)
+ ],
+ fillRule: 'evenodd'
+ });
+
+ var rectangle = new Shape.Rectangle(new Point(0, 0), new Point(150, 50));
+
+ var group = new Group();
+ group.children = invertedOrder
+ ? [compound, rectangle]
+ : [rectangle, compound];
+ group.fillColor = 'black';
+ group.clipped = true;
+ return group;
+ };
+
+ comparePixels(createdClippedGroup(true), createdClippedGroup(false));
+});
diff --git a/test/tests/Item_Bounds.js b/test/tests/Item_Bounds.js
index f0b8ae03..3e9417d9 100644
--- a/test/tests/Item_Bounds.js
+++ b/test/tests/Item_Bounds.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -722,7 +722,7 @@ test('path.strokeBounds with applyMatrix disabled', function() {
testHitResult();
});
-test('TEST', function() {
+test('path.strokeBounds with applyMatrix enabled', function() {
var path = new Path.Rectangle({
applyMatrix: false,
point: [10, 10],
diff --git a/test/tests/Item_Cloning.js b/test/tests/Item_Cloning.js
index 762701d0..723a2a20 100644
--- a/test/tests/Item_Cloning.js
+++ b/test/tests/Item_Cloning.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Item_Getting.js b/test/tests/Item_Getting.js
index 120d0500..d561572f 100644
--- a/test/tests/Item_Getting.js
+++ b/test/tests/Item_Getting.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Item_Order.js b/test/tests/Item_Order.js
index b99814ef..2d0adb2b 100644
--- a/test/tests/Item_Order.js
+++ b/test/tests/Item_Order.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/JSON.js b/test/tests/JSON.js
index 1c2fe5af..656d63d2 100644
--- a/test/tests/JSON.js
+++ b/test/tests/JSON.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -256,3 +256,10 @@ test('Path#importJSON()', function() {
equals(function() { return layer.firstChild === path; }, true);
equals(function() { return path.parent === layer; }, true);
});
+
+test('Item#importJSON() does not override Item#insert()', function() {
+ var path = new Path();
+ equals(typeof path.insert, 'function');
+ path.importJSON(path.exportJSON());
+ equals(typeof path.insert, 'function');
+});
diff --git a/test/tests/Layer.js b/test/tests/Layer.js
index c4d2a188..947f0ab4 100644
--- a/test/tests/Layer.js
+++ b/test/tests/Layer.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -139,3 +139,9 @@ test('#remove() with named layers', function(){
equals(removeCount, 2,
'project.layers[name].remove(); should be called twice');
});
+
+test('#bounds with nested empty items', function() {
+ var item = new Path.Rectangle(new Point(10,10), new Size(10));
+ new Group(new Group());
+ equals(item.bounds, project.activeLayer.bounds);
+});
diff --git a/test/tests/Matrix.js b/test/tests/Matrix.js
index 6046eaf8..ec499e4a 100644
--- a/test/tests/Matrix.js
+++ b/test/tests/Matrix.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Numerical.js b/test/tests/Numerical.js
index 01a5cb08..4bf3040f 100644
--- a/test/tests/Numerical.js
+++ b/test/tests/Numerical.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/PaperScript.js b/test/tests/PaperScript.js
new file mode 100644
index 00000000..1f2510c9
--- /dev/null
+++ b/test/tests/PaperScript.js
@@ -0,0 +1,48 @@
+/*
+ * Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
+ * http://paperjs.org/
+ *
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
+ *
+ * Distributed under the MIT license. See LICENSE file for details.
+ *
+ * All rights reserved.
+ */
+
+QUnit.module('PaperScript');
+
+function executeCode(code, expected) {
+ try {
+ equals(PaperScript.execute(code, paper), expected, code);
+ } catch (err) {
+ ok(false, err + '');
+ }
+}
+
+test('PaperScript with prefix decrement operators', function() {
+ executeCode(
+ 'var j = 0; for (var i = 10; i > 0; i--) { j++ }; module.exports = j',
+ 10
+ );
+ executeCode(
+ 'var x = 1; var y = 4 * --x; y; module.exports = x + " " + y',
+ '0 0'
+ );
+});
+
+test('PaperScript with suffix increment operators', function() {
+ executeCode(
+ 'var j = 0; for (var i = 0; i < 10; ++i) { j++ }; module.exports = j',
+ 10
+ );
+ // #691
+ executeCode(
+ 'var x = 1; x = x++; module.exports = x',
+ 1
+ );
+ executeCode(
+ 'var x = 1; var y = 4 * x++; y; module.exports = x + " " + y',
+ '2 4'
+ );
+});
diff --git a/test/tests/Path.js b/test/tests/Path.js
index d985fe7b..47678d73 100644
--- a/test/tests/Path.js
+++ b/test/tests/Path.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -645,3 +645,11 @@ test('Path#arcTo(through, to) is on through point side (#1477)', function() {
path.arcTo(p2, p3);
equals(true, path.segments[1].point.x > p1.x);
});
+
+test('Path#arcTo(to, radius, rotation, clockwise, large) when from and to are equal (#1613)', function(){
+ var point = new Point(10,10);
+ var path = new Path();
+ path.moveTo(point);
+ path.arcTo(point, new Size(10), 0, true, true);
+ expect(0);
+});
diff --git a/test/tests/PathItem.js b/test/tests/PathItem.js
index 2ac17864..e92c4a1e 100644
--- a/test/tests/PathItem.js
+++ b/test/tests/PathItem.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/PathItem_Contains.js b/test/tests/PathItem_Contains.js
index 30367955..4a07f48e 100644
--- a/test/tests/PathItem_Contains.js
+++ b/test/tests/PathItem_Contains.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -394,4 +394,10 @@ test('Path#contains() with Path#interiorPoint: #854, #1064', function() {
}
});
-
+test('IPathtem#contains() with non-invertible matrices (#1651)', function() {
+ var path = new Path({
+ matrix: new Matrix(0, 0, 0, 0, 0, 0)
+ });
+ equals(path.contains(path.position), false,
+ 'A path with a non-invertible matrix cannot contain its position');
+});
diff --git a/test/tests/Path_Boolean.js b/test/tests/Path_Boolean.js
index ed9061f8..c965ee89 100644
--- a/test/tests/Path_Boolean.js
+++ b/test/tests/Path_Boolean.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -219,7 +219,6 @@ test('#784', function() {
'M265.13434,453.46566l-0.03434,0.03434c0,0 -49.1,-14.5 -36.6,-36.6c7.48073,-13.22593 39.10093,-1.6319 63.28843,9.81157l16.18604,-16.18604c-8.05354,-21.53223 -15.90287,-47.40397 -10.27447,-54.42553c9.77623,-12.51358 31.40373,30.40618 32.36674,32.33326l0.03326,-0.03326c0,0.1 65,49.8 65,65c0,15.2 -33.8,65 -65,65c-30.62393,0 -63.75273,-62.62185 -64.96566,-64.93434z');
});
-
test('#784#issuecomment-144653463', function() {
var path1 = new Path({
segments: [
@@ -1202,4 +1201,4 @@ test('#1513', function () {
var path2 = PathItem.create('M200,100c55.22847,0 100,44.77153 100,100h-200c0,-55.22847 44.77153,-100 100,-100z');
var result = 'M100,100h200v100c0,-55.22847 -44.77153,-100 -100,-100c-55.22847,0 -100,44.77153 -100,100z';
compareBoolean(path1.subtract(path2), result);
-});
\ No newline at end of file
+});
diff --git a/test/tests/Path_Constructors.js b/test/tests/Path_Constructors.js
index 220f0ca4..e4eaa33f 100644
--- a/test/tests/Path_Constructors.js
+++ b/test/tests/Path_Constructors.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Path_Intersections.js b/test/tests/Path_Intersections.js
index 3d079706..6e69ec65 100644
--- a/test/tests/Path_Intersections.js
+++ b/test/tests/Path_Intersections.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Point.js b/test/tests/Point.js
index 41a5d1e6..46a415d6 100644
--- a/test/tests/Point.js
+++ b/test/tests/Point.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Project.js b/test/tests/Project.js
index ca970d01..31da0956 100644
--- a/test/tests/Project.js
+++ b/test/tests/Project.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Raster.js b/test/tests/Raster.js
index 883dff1a..32f56fbf 100644
--- a/test/tests/Raster.js
+++ b/test/tests/Raster.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -206,3 +206,31 @@ test('Raster#setSmoothing setting does not impact canvas context', function(asse
done();
};
});
+
+test('new Raster(size[, position])', function() {
+ // Size only.
+ var raster = new Raster(new Size(100, 100));
+ equals(raster.position, new Point(0, 0));
+ equals(raster.bounds, new Rectangle(-50, -50, 100, 100));
+
+ var raster = new Raster({size:new Size(100, 100)});
+ equals(raster.position, new Point(0, 0));
+ equals(raster.bounds, new Rectangle(-50, -50, 100, 100));
+
+ var raster = new Raster({width:100, height:100});
+ equals(raster.position, new Point(0, 0));
+ equals(raster.bounds, new Rectangle(-50, -50, 100, 100));
+
+ // Size and position.
+ var raster = new Raster(new Size(100, 100), new Point(100, 100));
+ equals(raster.position, new Point(100, 100));
+ equals(raster.bounds, new Rectangle(50, 50, 100, 100));
+
+ var raster = new Raster({size:new Size(100, 100), position:new Point(100, 100)});
+ equals(raster.position, new Point(100, 100));
+ equals(raster.bounds, new Rectangle(50, 50, 100, 100));
+
+ var raster = new Raster({width:100, height:100, position:new Point(100, 100)});
+ equals(raster.position, new Point(100, 100));
+ equals(raster.bounds, new Rectangle(50, 50, 100, 100));
+});
diff --git a/test/tests/Rectangle.js b/test/tests/Rectangle.js
index af17a14d..70de44ca 100644
--- a/test/tests/Rectangle.js
+++ b/test/tests/Rectangle.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Segment.js b/test/tests/Segment.js
index 3a2107af..29bb0434 100644
--- a/test/tests/Segment.js
+++ b/test/tests/Segment.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Shape.js b/test/tests/Shape.js
index cc5b59fd..3380e92f 100644
--- a/test/tests/Shape.js
+++ b/test/tests/Shape.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Size.js b/test/tests/Size.js
index df21a771..14f3ac61 100644
--- a/test/tests/Size.js
+++ b/test/tests/Size.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/Style.js b/test/tests/Style.js
index b0d84183..f930592b 100644
--- a/test/tests/Style.js
+++ b/test/tests/Style.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/SvgExport.js b/test/tests/SvgExport.js
index a68f6cd3..a9b2ca62 100644
--- a/test/tests/SvgExport.js
+++ b/test/tests/SvgExport.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -113,7 +113,13 @@ test('Export SVG path at precision 0', function() {
equals(path.exportSVG({ precision: 0 }).getAttribute('d'), 'M0,2l1,1');
});
-if (!isNode) {
+test('Export SVG viewbox attribute with top left at origin', function() {
+ var path = new Path.Rectangle(new Point(10, 10), new Size(80));
+ var rectangle = new Rectangle(new Point(0, 0), new Size(100));
+ equals(project.exportSVG({ bounds: rectangle }).getAttribute('viewBox'), '0,0,100,100');
+});
+
+if (!isNodeContext) {
// JSDom does not have SVG rendering, so we can't test there.
test('Export transformed shapes', function(assert) {
var rect = new Shape.Rectangle({
@@ -149,6 +155,17 @@ if (!isNode) {
compareSVG(assert.async(), svg, project.activeLayer);
});
+ test('Export not invertible item.matrix', function(assert) {
+ var rect = new Shape.Rectangle({
+ point: [100, 100],
+ size: [100, 100],
+ fillColor: 'red',
+ matrix: [1, 1, 1, 1, 1, 1]
+ });
+ var svg = project.exportSVG({ bounds: 'content', asString: true });
+ compareSVG(assert.async(), svg, project.activeLayer);
+ });
+
test('Export gradients', function(assert) {
var bounds = new Rectangle(new Size(300, 600));
var stops = [new Color(1, 1, 0, 0), 'red', 'black'];
@@ -212,4 +229,19 @@ if (!isNode) {
tolerance: 1e-2
});
});
+
+ test('Export symbol with stroke', function(assert) {
+ var item = new Path.Circle({
+ center: [0, 0],
+ radius: 50,
+ strokeColor: 'blue',
+ strokeWidth: 10
+ });
+
+ var symbol = new Symbol(item);
+ symbol.place([50, 50]);
+
+ var svg = project.exportSVG({ bounds: 'content', asString: true });
+ compareSVG(assert.async(), svg, project.activeLayer);
+ });
}
diff --git a/test/tests/SvgImport.js b/test/tests/SvgImport.js
index a7e256bf..a7dc2a48 100644
--- a/test/tests/SvgImport.js
+++ b/test/tests/SvgImport.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -143,6 +143,21 @@ test('Import SVG without insertion', function() {
}, true);
});
+test('Import SVG switch', function(assert) {
+ var done = assert.async();
+ var svg = '';
+ paper.project.importSVG(svg, {
+ onLoad: function(item) {
+ equals(item.className, 'Group');
+ equals(item.children.length, 1);
+ equals(item.firstChild.className, 'Group');
+ equals(item.firstChild.children.length, 1);
+ equals(item.firstChild.firstChild, new Path([new Point(0, 0), new Point(10, 10)]));
+ done();
+ }
+ });
+});
+
function importSVG(assert, url, message, options) {
var done = assert.async();
project.importSVG(url, {
@@ -166,7 +181,7 @@ function importSVG(assert, url, message, options) {
});
}
-if (!isNode) {
+if (!isNodeContext) {
// JSDom does not have SVG rendering, so we can't test there.
var svgFiles = {
'butterfly': { tolerance: 1e-2 },
@@ -176,16 +191,18 @@ if (!isNode) {
'symbol': {},
'symbols': {},
'blendModes': {},
- 'gradients-1': {}
+ 'gradients-1': {},
+ 'gradients-2': !isPhantomContext && {},
+ 'gradients-3': {},
+ 'gradients-4': {}
};
- // TODO: Investigate why Phantom struggles with this file:
- if (!isPhantom)
- svgFiles['gradients-2'] = {};
Base.each(svgFiles, function(options, name) {
- name += '.svg';
- test('Import ' + name, function(assert) {
- importSVG(assert, 'assets/' + name, null, options);
- });
+ if (options) {
+ name += '.svg';
+ test('Import ' + name, function(assert) {
+ importSVG(assert, 'assets/' + name, null, options);
+ });
+ }
});
test('Import inexistent file', function(assert) {
diff --git a/test/tests/SymbolItem.js b/test/tests/SymbolItem.js
index 23957210..9e3ba191 100644
--- a/test/tests/SymbolItem.js
+++ b/test/tests/SymbolItem.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/TextItem.js b/test/tests/TextItem.js
index 4223f249..d544dcc2 100644
--- a/test/tests/TextItem.js
+++ b/test/tests/TextItem.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
diff --git a/test/tests/load.js b/test/tests/load.js
index 17e34a9a..a2546737 100644
--- a/test/tests/load.js
+++ b/test/tests/load.js
@@ -2,8 +2,8 @@
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
- * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
- * http://scratchdisk.com/ & http://jonathanpuckey.com/
+ * Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+ * http://scratchdisk.com/ & https://puckey.studio/
*
* Distributed under the MIT license. See LICENSE file for details.
*
@@ -63,7 +63,9 @@
/*#*/ include('Numerical.js');
+/*#*/ include('PaperScript.js');
+
// There is no need to test interactions in node context.
-if (!isNode) {
+if (!isNodeContext) {
/*#*/ include('Interactions.js');
}
diff --git a/travis/deploy-prebuilt.sh b/travis/deploy-prebuilt.sh
index 491eabc8..4e786d91 100755
--- a/travis/deploy-prebuilt.sh
+++ b/travis/deploy-prebuilt.sh
@@ -3,8 +3,8 @@
# Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
# http://paperjs.org/
#
-# Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
-# http://scratchdisk.com/ & http://jonathanpuckey.com/
+# Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+# http://scratchdisk.com/ & https://puckey.studio/
#
# Distributed under the MIT license. See LICENSE file for details.
#
diff --git a/travis/install-assets.sh b/travis/install-assets.sh
index 9ca3d767..8c1b9b8e 100755
--- a/travis/install-assets.sh
+++ b/travis/install-assets.sh
@@ -3,8 +3,8 @@
# Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
# http://paperjs.org/
#
-# Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
-# http://scratchdisk.com/ & http://jonathanpuckey.com/
+# Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+# http://scratchdisk.com/ & https://puckey.studio/
#
# Distributed under the MIT license. See LICENSE file for details.
#
diff --git a/travis/setup-git.sh b/travis/setup-git.sh
index fbc225bf..52021b5f 100755
--- a/travis/setup-git.sh
+++ b/travis/setup-git.sh
@@ -3,8 +3,8 @@
# Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
# http://paperjs.org/
#
-# Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
-# http://scratchdisk.com/ & http://jonathanpuckey.com/
+# Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
+# http://scratchdisk.com/ & https://puckey.studio/
#
# Distributed under the MIT license. See LICENSE file for details.
#