diff --git a/AUTHORS.md b/AUTHORS.md index 547c42e0..a5f025ab 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,15 +1,18 @@ ## Authors - Jürg Lehni -- Jonathan Puckey +- Jonathan Puckey ## Contributors - Harikrishnan Gopalakrishnan -- Jan Bösenberg +- Jan Bösenberg - Jt Whissel - Andrew Roles - Jacob Lites - Justin Ridgewell - Andrew Wagenheim - Scott Kieronski +- DD Liu +- Samuel Asensi +- Takahiro Nishino diff --git a/CHANGELOG.md b/CHANGELOG.md index af4ca06c..68cf659d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,205 @@ # Change Log +## `0.12.7` + +### Fixed + +- PaperScript: Actually make `options.paperFeatures.moduleExports` work + independently from `options.paperFeatures.operatorOverloading`. + +## `0.12.6` + +### Added + +- PaperScript: Add option `options.paperFeatures.moduleExports` to control + module exports conversion. + +## `0.12.5` + +### Added + +- PaperScript: Add option `options.paperFeatures.operatorOverloading` to control + operator overloading. + +### Fixed + +- Fix `new Raster(HTMLCanvasElement)` constructor (#1745). +- Handle `CurveLocation` on paths with only one segment. +- Fix recently introduced error in `CompoundPath.compare()` (#1769). +- Clamp opacity values to [0, 1] (#1814). +- Support closed `Path` items with blend mode and no segments (#1763). +- Fix error in `getCrossingSegments()` (#1773). +- SVG Import: Support SVG strings with leading line-breaks (#1813). +- Docs: Improve documentation for `Raster#drawImage(CanvasImageSource)` (#1784). + +### Changed + +- Use `'paper-'` prefix in generated view ids. + +## `0.12.4` + +### Added + +- Allow paper core import in TypeScript (#1713). +- Boolean: Improve performance from `O(n^2)` to nearly `O(n)` by the use of the + sweep and prune algorithm (#1737). +- Docs: Add support for nullable values. + +### Fixed + +- Fix `PathItem#getCrossing()` to not return overlaps (#1409). +- Fix regression in `Curve.getIntersections()` (#1638). +- Fix edge cases in `CurveLocation.isCrossing()` (#1419, #1263). +- Fix `SymbolItem#hitTestAll()` to return only one match per symbol item + (#1680). +- Fix handling of negative `Shape` sizes (#1733). +- Fix parsing of RGB `Color` strings with percentages (#1736). +- Fix `Shape` bounds when passing position in constructor (#1686). +- Prevent nested group matrix from reset when transforming parent (#1711). +- Boolean: Fix edge cases in overlap detection (#1262). +- Boolean: Add check for paths with only one segment (#1351). +- Boolean: Correctly handle open filled paths (#1647). +- Boolean: Avoid winding number edge cases (#1619). +- Docs: Fix some documentation return types (#1679). + +## `0.12.3` + +### Added + +- Add documentation for `Item#internalBounds`. + +### 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). + +## `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 + +This is the first release in quite a while, and it was made possible thanks to +two new people on the team: + +A warm welcome to [@sasensi](https://github.com/sasensi) and +[@sapics](https://github.com/sapics), the two new and very active maintainers / +contributors! :tada: + +Their efforts mean that many issues are finally getting proper attention and +solid fixes, as we are paving the way for the upcoming release of `1.0.0`. Here +the fixes and additions from the past two weeks: + +### Fixed + +- Prevent `paper` object from polluting the global scope (#1544). +- Make sure `Path#arcTo()` always passes through the provide through point + (#1477). +- Draw shadows on `Raster` images (#1437). +- Fix boolean operation edge case (#1506, #1513, #1515). +- Handle closed paths with only one segment in `Path#flatten()` (#1338). +- Remove memory leak on gradient colors (#1499). +- Support alpha channel in CSS colors (#1468, #1539, #1565). +- Improve color CSS string parsing and documentation. +- Improve caching of item positions (#1503). +- Always draw selected position in global coordinates system (#1545). +- Prevent empty `Symbol` items from causing issues with transformations (#1561). +- Better detect when a cached global matrix is not valid anymore (#1448). +- Correctly draw selected position when item is in a group with matrix not + applied (#1535). +- Improve handling of huge amounts of segments in paths (#1493). +- Do not trigger error messages about passive event listeners on Chrome (#1501). +- Fix errors with event listeners on mobile (#1533). +- Prevent first mouse drag event from being emitted twice (#1553). +- Support optional arguments in translate and rotate statements in SVG Import + (#1487). +- Make sure SVG import always applies imported attributes (#1416). +- Correctly handle `Raster` images positions in SVG import (#1328). +- Improve documentation for `Shape#toPath()` (#1374). +- Improve documentation of hit test coordinate system (#1430). +- Add documentation for `Item#locked` (#1436). +- Support Webpack bundling in Node.js server (#1482). +- Travis CI: Get unit tests to run correctly again. +- Travis CI: Remove Node 4 and add Node 9. + +### Added + +- `Curve#getTimesWithTangent()` and `Path#getOffsetsWithTangent()` as a way to + get the curve-times / offsets where the path is tangential to a given vector. +- `Raster#smoothing` to control if pixels should be blurred or repeated when a + raster is scaled up (#1521). +- Allow `PaperScript`to export from executed code, supporting `export default`, + named exports, as well as `module.exports`. + ## `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). @@ -15,38 +212,42 @@ ## `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 @@ -59,12 +260,14 @@ [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). @@ -98,6 +301,7 @@ ## `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). @@ -122,6 +326,7 @@ `#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 @@ -140,6 +345,7 @@ (#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. @@ -180,17 +386,20 @@ (#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. @@ -228,6 +437,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. @@ -244,7 +454,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` @@ -304,6 +514,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 @@ -368,6 +579,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() @@ -446,10 +658,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] { @@ -464,6 +677,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)` @@ -471,7 +685,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..84e905d8 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 - 2020, Jürg Lehni & Jonathan Puckey +http://juerglehni.com/ & https://puckey.studio/ All rights reserved. The MIT License (MIT) diff --git a/README.md b/README.md index ca80c52c..3d104586 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,45 @@ -# Paper.js - The Swiss Army Knife of Vector Graphics Scripting [![Build Status](https://travis-ci.org/paperjs/paper.js.svg?branch=develop)](https://travis-ci.org/paperjs/paper.js) [![NPM](https://img.shields.io/npm/v/paper.svg)](https://www.npmjs.com/package/paper) ![Bower](https://img.shields.io/bower/v/paper.svg) +# Scratch's fork of Paper.js [![Build Status](https://circleci.com/gh/LLK/paper.js.svg?style=shield)](https://app.circleci.com/pipelines/github/LLK/paper.js?branch=develop) [![NPM](https://img.shields.io/npm/v/@scratch/paper.svg)](https://www.npmjs.com/package/@scratch/paper) + +This is a fork of Paper.js for use in Scratch. Please do not contact the Paper.js authors to support this fork. + +_Original README.md below_ + +# Paper.js - The Swiss Army Knife of Vector Graphics Scripting If you want to work with Paper.js, simply download the latest "stable" version from [http://paperjs.org/download/](http://paperjs.org/download/) - Website: -- Discussion forum: +- Questions: +- Discussion forum: - Mainline source code: -- Twitter: [@paperjs](http://twitter.com/paperjs) +- Twitter: [@paperjs](https://twitter.com/paperjs) - Latest releases: -- Pre-built development versions: [`prebuilt/module`](https://github.com/paperjs/paper.js/tree/prebuilt/module) -and [`prebuilt/dist`](https://github.com/paperjs/paper.js/tree/prebuilt/dist) branches. +- Pre-built development versions: + [`prebuilt/module`](https://github.com/paperjs/paper.js/tree/prebuilt/module) + and [`prebuilt/dist`](https://github.com/paperjs/paper.js/tree/prebuilt/dist) + branches. ## Installing Paper.js The recommended way to install and maintain Paper.js as a dependency in your project is through the [Node.js Package Manager (NPM)](https://www.npmjs.com/) -for browsers, Node.js or Electron, as well as through Bower for browsers. +for browsers, Node.js or Electron. -If NPM or Bower is already installed, simply type one of these -commands in your project folder: +If NPM is already installed, simply type one of these commands in your project +folder: ```sh npm install paper -# Or: -bower install paper ``` Upon execution, you will find a `paper` folder inside the project's -`node_modules` / `bower_components` folder. +`node_modules` folder. For more information on how to install Node.js and NPM, read the chapter [Installing Node.js and NPM](#installing-nodejs-and-npm). -### Which Version to Use? +### Which Version to Use The various distributions come with two different pre-build versions of Paper.js, in minified and normal variants: @@ -51,9 +58,9 @@ generally not recommended to install Node.js through OS-supplied package managers, as the its development cycles move fast and these versions are often out-of-date. -On macOS, [Homebrew](http://brew.sh/) is a good option if one version of +On macOS, [Homebrew](https://brew.sh/) is a good option if one version of Node.js that is kept up to date with `brew upgrade` is enough: - + [NVM](https://github.com/creationix/nvm) can be used instead to install and maintain multiple versions of Node.js on the same platform, as often required by @@ -63,10 +70,10 @@ different projects: Homebrew is recommended on macOS also if you intend to install Paper.js with rendering to the Canvas on Node.js, as described in the next paragraph. -For Linux, see to locate 32-bit and 64-bit Node.js +For Linux, see to locate 32-bit and 64-bit Node.js binaries as well as sources, or use NVM, as described in the paragraph above. -### Installing Paper.js for Node.js +### Installing Paper.js Using NPM Paper.js comes in three different versions on NPM: `paper`, `paper-jsdom` and `paper-jsdom-canvas`. Depending on your use case, you need to required a @@ -81,12 +88,19 @@ different one: SVG importing and exporting through [jsdom](https://github.com/tmpvar/jsdom). In order to install `paper-jsdom-canvas`, you need the [Cairo Graphics -library](http://cairographics.org/) installed in your system: +library](https://cairographics.org/) installed in your system: -##### Installing Cairo and Pango on macOS: +### Installing Native Dependencies -The easiest way to install Cairo is through [Homebrew](http://brew.sh/), by -issuing the command: +Paper.js relies on [Node-Canvas](https://github.com/Automattic/node-canvas) for +rendering, which in turn relies on the native libraries +[Cairo](https://cairographics.org/) and [Pango](https://www.pango.org/). + +#### Installing Native Dependencies on macOS + +Paper.js relies on Node-Canvas for rendering, which in turn relies on Cairo and +Pango. The easiest way to install Cairo is through +[Homebrew](https://brew.sh/), by issuing the command: brew install cairo pango @@ -110,7 +124,7 @@ After adding this line, your commands should work in the expected way: npm install paper npm update -##### Installing Cairo, Pango and all other dependencies on Debian/Ubuntu Linux: +#### Installing Native Dependencies on Debian/Ubuntu Linux sudo apt-get install pkg-config libcairo2-dev libpango1.0-dev libssl-dev libjpeg62-dev libgif-dev @@ -119,24 +133,23 @@ build from c++ sources: sudo apt-get install build-essential -##### After Cairo has been installed: +#### Installing Native Dependencies for Electron + +In order to build Node-Canvas for use of `paper-jsdom-canvas` in Electron, which +is likely to use a different version of V8 than the Node binary installed in +your system, you need to manually specify the location of Electron’s headers. +Follow these steps to do so: + +[Electron — Using Native Node +Modules](https://electron.atom.io/docs/tutorial/using-native-node-modules/) + +#### After Native Dependencies have been installed You should now be able to install the Paper.js module with jsdom and Canvas rendering from NPM: npm install paper-jsdom-canvas -### Installing Paper.js with Node-Canvas for Electron - -[Node-Canvas](https://github.com/Automattic/node-canvas) is a native dependency. -In order to build it for use of `paper-jsdom-canvas` in Electron, which is -likely to use a different version of V8 than the Node binary installed in your -system, you need to manually specify the location of Electron’s headers. Follow -these steps to do so: - -[Electron — Using Native Node -Modules](https://electron.atom.io/docs/tutorial/using-native-node-modules/) - ## Development The main Paper.js source tree is hosted on @@ -160,9 +173,9 @@ run: ### Setting Up For Building -As of 2016, Paper.js uses [Gulp.js](http://gulpjs.com/) for building, and has a -couple of dependencies as Bower and NPM modules. Read the chapter [Installing -Node.js, NPM and Bower](#installing-nodejs-npm-and-bower) if you still need to +As of 2016, Paper.js uses [Gulp.js](https://gulpjs.com/) for building, and has a +couple of dependencies as NPM modules. Read the chapter [Installing +Node.js and NPM](#installing-nodejs-and-npm) if you still need to install these. In order to be able to build Paper.js, after checking out the repository, paper @@ -248,7 +261,7 @@ Your docs will then be located at `dist/docs`. ### Testing Paper.js was developed and tested from day 1 using proper unit testing through -jQuery's [Qunit](http://docs.jquery.com/Qunit). To run the tests after any +jQuery's [Qunit](https://qunitjs.com/). To run the tests after any change to the library's source, simply open `index.html` inside the `test` folder in your web browser. There should be a green bar at the top, meaning all tests have passed. If the bar is red, some tests have not passed. These will be @@ -274,24 +287,30 @@ And to test both the PhantomJS and Node.js environments together, simply run: gulp test -### Contributing +### Contributing [![Open Source Helpers](https://www.codetriage.com/paperjs/paper.js/badges/users.svg)](https://www.codetriage.com/paperjs/paper.js) The main Paper.js source tree is hosted on GitHub, thus you should create a fork of the repository in which you perform development. See -. +. -We prefer that you send a [pull request on GitHub] -(http://help.github.com/pull-requests/) which will then be merged into the -official main line repository. You need to sign the Paper.js CLA to be able to -contribute (see below). +We prefer that you send a +[pull request on GitHub](https://help.github.com/articles/about-pull-requests/) +which will then be merged into the official main line repository. +You need to sign the Paper.js CLA to be able to contribute (see below). Also, in your first contribution, add yourself to the end of `AUTHORS.md` (which of course is optional). +In addition to contributing code you can also triage issues which may include +reproducing bug reports or asking for vital information, such as version numbers +or reproduction instructions. If you would like to start triaging issues, one +easy way to get started is to +[subscribe to paper.js on CodeTriage](https://www.codetriage.com/paperjs/paper.js). + **Get the source (for contributing):** If you want to contribute to the project you will have to [make a -fork](http://help.github.com/forking/). Then do this: +fork](https://help.github.com/articles/fork-a-repo/). Then do this: git clone --recursive git@github.com:yourusername/paper.js.git cd paper.js @@ -304,11 +323,11 @@ To then fetch changes from upstream, run #### Creating and Submitting a Patch As mentioned above, we prefer that you send a -[pull request](http://help.github.com/pull-requests/) on GitHub: +[pull request](https://help.github.com/articles/about-pull-requests/) on GitHub: 1. Create a fork of the upstream repository by visiting . If you feel insecure, here's a - great guide: + great guide: 2. Clone of your repository: `git clone https://yourusername@github.com/yourusername/paper.js.git` @@ -326,7 +345,7 @@ As mentioned above, we prefer that you send a repository's site at GitHub (i.e. https://github.com/yourusername/paper.js) and press the "Pull Request" button. Make sure you are creating the pull request to the `develop` branch, not the `master` branch. Here's a good guide - on pull requests: + on pull requests: ##### Use one topic branch per feature: @@ -335,7 +354,7 @@ together into your `develop` branch (or develop everything in your `develop` branch and then cherry-pick-and-merge into the different topic branches). Git provides for an extremely flexible workflow, which in many ways causes more confusion than it helps you when new to collaborative software development. The -guides provided by GitHub at are a really good +guides provided by GitHub at are a really good starting point and reference. If you are fixing an issue, a convenient way to name the branch is to use the issue number as a prefix, like this: `git checkout -tb issue-937-feature-add-text-styling`. @@ -343,7 +362,7 @@ name the branch is to use the issue number as a prefix, like this: `git checkout #### Contributor License Agreement Before we can accept any contributions to Paper.js, you need to sign this -[CLA](http://en.wikipedia.org/wiki/Contributor_License_Agreement): +[CLA](https://en.wikipedia.org/wiki/Contributor_License_Agreement): [Contributor License Agreement](https://spreadsheets.google.com/a/paperjs.org/spreadsheet/embeddedform?formkey=dENxd0JBVDY2REo3THVuRmh4YjdWRlE6MQ) @@ -352,10 +371,11 @@ Before we can accept any contributions to Paper.js, you need to sign this > defend the project should there be a legal dispute regarding the software at > some future time. -For a list of authors and contributors, please see [AUTHORS] -(https://github.com/paperjs/paper.js/blob/master/AUTHORS.md). +For a list of authors and contributors, please see +[AUTHORS](https://github.com/paperjs/paper.js/blob/master/AUTHORS.md). ## License -Distributed under the MIT license. See [LICENSE] -(https://github.com/paperjs/paper.js/blob/master/LICENSE.txt) for details. +Distributed under the MIT license. See +[LICENSE](https://github.com/paperjs/paper.js/blob/master/LICENSE.txt) +fo details. diff --git a/bower.json b/bower.json index c1ae758a..87612109 100644 --- a/bower.json +++ b/bower.json @@ -9,8 +9,8 @@ }, "bugs": "https://github.com/paperjs/paper.js/issues", "authors": [ - "Jürg Lehni (http://scratchdisk.com)", - "Jonathan Puckey (http://studiomoniker.com)" + "Jürg Lehni (http://juerglehni.com)", + "Jonathan Puckey (http://puckey.studio)" ], "main": "dist/paper-full.js", "ignore": [ diff --git a/dist/docs/assets/js/paper.js b/dist/docs/assets/js/paper.js index 0c71eac5..a6dfbea6 100644 --- a/dist/docs/assets/js/paper.js +++ b/dist/docs/assets/js/paper.js @@ -1,29 +1,29 @@ /*! - * Paper.js v0.11.5-develop - The Swiss Army Knife of Vector Graphics Scripting. + * Paper.js v0.12.7 - 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 - 2020, Jürg Lehni & Jonathan Puckey + * http://juerglehni.com/ & https://puckey.studio/ * * Distributed under the MIT license. See LICENSE file for details. * * All rights reserved. * - * Date: Sun Oct 8 17:48:20 2017 +0200 + * Date: Mon Oct 30 15:37:23 2023 -0400 * *** * * Straps.js - Class inheritance library with support for bean-style accessors * - * Copyright (c) 2006 - 2016 Juerg Lehni - * http://scratchdisk.com/ + * Copyright (c) 2006 - 2020 Jürg Lehni + * http://juerglehni.com/ * * Distributed under the MIT license. * *** * * 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. @@ -33,7 +33,7 @@ var paper = function(self, undefined) { self = self || require('./node/self.js'); -var window = self.window, +var window = self.window ? self.window : self, document = self.document; var Base = new function() { @@ -378,26 +378,52 @@ statics: { readNamed: function(list, name, start, options, amount) { var value = this.getNamed(list, name), - hasObject = value !== undefined; - if (hasObject) { + hasValue = value !== undefined; + if (hasValue) { var filtered = list.__filtered; if (!filtered) { - filtered = list.__filtered = Base.create(list[0]); - filtered.__unfiltered = list[0]; + var source = this.getSource(list); + filtered = list.__filtered = Base.create(source); + filtered.__unfiltered = source; } filtered[name] = undefined; } - var l = hasObject ? [value] : list, - res = this.read(l, start, options, amount); - return res; + return this.read(hasValue ? [value] : list, start, options, amount); + }, + + readSupported: function(list, dest) { + var source = this.getSource(list), + that = this, + read = false; + if (source) { + Object.keys(source).forEach(function(key) { + if (key in dest) { + var value = that.readNamed(list, key); + if (value !== undefined) { + dest[key] = value; + } + read = true; + } + }); + } + return read; + }, + + getSource: function(list) { + var source = list.__source; + if (source === undefined) { + var arg = list.length === 1 && list[0]; + source = list.__source = arg && Base.isPlainObject(arg) + ? arg : null; + } + return source; }, getNamed: function(list, name) { - var arg = list[0]; - if (list._hasObject === undefined) - list._hasObject = list.length === 1 && Base.isPlainObject(arg); - if (list._hasObject) - return name ? arg[name] : list.__filtered || arg; + var source = this.getSource(list); + if (source) { + return name ? source[name] : list.__filtered || source; + } }, hasNamed: function(list, name) { @@ -515,8 +541,7 @@ statics: { if (create) { res = create(type, args, isFirst || _isRoot); } else { - res = Base.create(type.prototype); - type.apply(res, args); + res = new type(args); } } } else if (Base.isPlainObject(json)) { @@ -547,8 +572,12 @@ statics: { 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; + if (useTarget) { + args = args.concat([{ insert: true }]); + } + } } (useTarget ? obj.set : ctor).apply(obj, args); if (useTarget) @@ -557,6 +586,20 @@ statics: { }); }, + push: function(list, items) { + var itemsLength = items.length; + if (itemsLength < 4096) { + list.push.apply(list, items); + } else { + var startLength = list.length; + list.length += itemsLength; + for (var i = 0; i < itemsLength; i++) { + list[startLength + i] = items[i]; + } + } + return list; + }, + splice: function(list, items, index, remove) { var amount = items && items.length, append = index === undefined; @@ -566,12 +609,12 @@ statics: { for (var i = 0; i < amount; i++) items[i]._index = index + i; if (append) { - list.push.apply(list, items); + Base.push(list, items); return []; } else { var args = [index, remove]; if (items) - args.push.apply(args, items); + Base.push(args, items); var removed = list.splice.apply(list, args); for (var i = 0, l = removed.length; i < l; i++) removed[i]._index = undefined; @@ -643,9 +686,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); }); }, @@ -758,14 +801,14 @@ var PaperScope = Base.extend({ if (platform) agent[platform] = true; 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) { if (!agent.chrome) { var v = n === 'opera' ? v2 : /^(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; } @@ -778,7 +821,7 @@ var PaperScope = Base.extend({ } }, - version: "0.11.5-develop", + version: "0.12.7", getView: function() { var project = this.project; @@ -790,8 +833,9 @@ var PaperScope = Base.extend({ }, execute: function(code, options) { - paper.PaperScript.execute(code, this, options); - View.updateFocus(); + var exports = paper.PaperScript.execute(code, this, options); + View.updateFocus(); + return exports; }, install: function(scope) { @@ -898,6 +942,164 @@ var PaperScopeItem = Base.extend(Emitter, { } }); +var CollisionDetection = { + findItemBoundsCollisions: function(items1, items2, tolerance) { + function getBounds(items) { + var bounds = new Array(items.length); + for (var i = 0; i < items.length; i++) { + var rect = items[i].getBounds(); + bounds[i] = [rect.left, rect.top, rect.right, rect.bottom]; + } + return bounds; + } + + var bounds1 = getBounds(items1), + bounds2 = !items2 || items2 === items1 + ? bounds1 + : getBounds(items2); + return this.findBoundsCollisions(bounds1, bounds2, tolerance || 0); + }, + + findCurveBoundsCollisions: function(curves1, curves2, tolerance, bothAxis) { + function getBounds(curves) { + var min = Math.min, + max = Math.max, + bounds = new Array(curves.length); + for (var i = 0; i < curves.length; i++) { + var v = curves[i]; + bounds[i] = [ + min(v[0], v[2], v[4], v[6]), + min(v[1], v[3], v[5], v[7]), + max(v[0], v[2], v[4], v[6]), + max(v[1], v[3], v[5], v[7]) + ]; + } + return bounds; + } + + var bounds1 = getBounds(curves1), + bounds2 = !curves2 || curves2 === curves1 + ? bounds1 + : getBounds(curves2); + if (bothAxis) { + var hor = this.findBoundsCollisions( + bounds1, bounds2, tolerance || 0, false, true), + ver = this.findBoundsCollisions( + bounds1, bounds2, tolerance || 0, true, true), + list = []; + for (var i = 0, l = hor.length; i < l; i++) { + list[i] = { hor: hor[i], ver: ver[i] }; + } + return list; + } + return this.findBoundsCollisions(bounds1, bounds2, tolerance || 0); + }, + + findBoundsCollisions: function(boundsA, boundsB, tolerance, + sweepVertical, onlySweepAxisCollisions) { + var self = !boundsB || boundsA === boundsB, + allBounds = self ? boundsA : boundsA.concat(boundsB), + lengthA = boundsA.length, + lengthAll = allBounds.length; + + function binarySearch(indices, coord, value) { + var lo = 0, + hi = indices.length; + while (lo < hi) { + var mid = (hi + lo) >>> 1; + if (allBounds[indices[mid]][coord] < value) { + lo = mid + 1; + } else { + hi = mid; + } + } + return lo - 1; + } + + var pri0 = sweepVertical ? 1 : 0, + pri1 = pri0 + 2, + sec0 = sweepVertical ? 0 : 1, + sec1 = sec0 + 2; + var allIndicesByPri0 = new Array(lengthAll); + for (var i = 0; i < lengthAll; i++) { + allIndicesByPri0[i] = i; + } + allIndicesByPri0.sort(function(i1, i2) { + return allBounds[i1][pri0] - allBounds[i2][pri0]; + }); + var activeIndicesByPri1 = [], + allCollisions = new Array(lengthA); + for (var i = 0; i < lengthAll; i++) { + var curIndex = allIndicesByPri0[i], + curBounds = allBounds[curIndex], + origIndex = self ? curIndex : curIndex - lengthA, + isCurrentA = curIndex < lengthA, + isCurrentB = self || !isCurrentA, + curCollisions = isCurrentA ? [] : null; + if (activeIndicesByPri1.length) { + var pruneCount = binarySearch(activeIndicesByPri1, pri1, + curBounds[pri0] - tolerance) + 1; + activeIndicesByPri1.splice(0, pruneCount); + if (self && onlySweepAxisCollisions) { + curCollisions = curCollisions.concat(activeIndicesByPri1); + for (var j = 0; j < activeIndicesByPri1.length; j++) { + var activeIndex = activeIndicesByPri1[j]; + allCollisions[activeIndex].push(origIndex); + } + } else { + var curSec1 = curBounds[sec1], + curSec0 = curBounds[sec0]; + for (var j = 0; j < activeIndicesByPri1.length; j++) { + var activeIndex = activeIndicesByPri1[j], + activeBounds = allBounds[activeIndex], + isActiveA = activeIndex < lengthA, + isActiveB = self || activeIndex >= lengthA; + + if ( + onlySweepAxisCollisions || + ( + isCurrentA && isActiveB || + isCurrentB && isActiveA + ) && ( + curSec1 >= activeBounds[sec0] - tolerance && + curSec0 <= activeBounds[sec1] + tolerance + ) + ) { + if (isCurrentA && isActiveB) { + curCollisions.push( + self ? activeIndex : activeIndex - lengthA); + } + if (isCurrentB && isActiveA) { + allCollisions[activeIndex].push(origIndex); + } + } + } + } + } + if (isCurrentA) { + if (boundsA === boundsB) { + curCollisions.push(curIndex); + } + allCollisions[curIndex] = curCollisions; + } + if (activeIndicesByPri1.length) { + var curPri1 = curBounds[pri1], + index = binarySearch(activeIndicesByPri1, pri1, curPri1); + activeIndicesByPri1.splice(index + 1, 0, curIndex); + } else { + activeIndicesByPri1.push(curIndex); + } + } + for (var i = 0; i < allCollisions.length; i++) { + var collisions = allCollisions[i]; + if (collisions) { + collisions.sort(function(i1, i2) { return i1 - i2; }); + } + } + return allCollisions; + } +}; + var Formatter = Base.extend({ initialize: function(precision) { this.precision = Base.pick(precision, 5); @@ -1025,6 +1227,10 @@ var Numerical = new function() { return val >= -EPSILON && val <= EPSILON; }, + isMachineZero: function(val) { + return val >= -MACHINE_EPSILON && val <= MACHINE_EPSILON; + }, + clamp: clamp, integrate: function(f, a, b, n) { @@ -1319,11 +1525,12 @@ var Point = Base.extend({ }, getDistance: function() { - var point = Point.read(arguments), + var args = arguments, + point = Point.read(args), x = point.x - this.x, y = point.y - this.y, d = x * x + y * y, - squared = Base.read(arguments); + squared = Base.read(args); return squared ? d : Math.sqrt(d); }, @@ -1390,8 +1597,9 @@ var Point = Base.extend({ }, isClose: function() { - var point = Point.read(arguments), - tolerance = Base.read(arguments); + var args = arguments, + point = Point.read(args), + tolerance = Base.read(args); return this.getDistance(point) <= tolerance; }, @@ -1442,8 +1650,9 @@ var Point = Base.extend({ statics: { min: function() { - var point1 = Point.read(arguments), - point2 = Point.read(arguments); + var args = arguments, + point1 = Point.read(args), + point2 = Point.read(args); return new Point( Math.min(point1.x, point2.x), Math.min(point1.y, point2.y) @@ -1451,8 +1660,9 @@ var Point = Base.extend({ }, max: function() { - var point1 = Point.read(arguments), - point2 = Point.read(arguments); + var args = arguments, + point1 = Point.read(args), + point2 = Point.read(args); return new Point( Math.max(point1.x, point2.x), Math.max(point1.y, point2.y) @@ -1699,7 +1909,8 @@ var Rectangle = Base.extend({ beans: true, initialize: function Rectangle(arg0, arg1, arg2, arg3) { - var type = typeof arg0, + var args = arguments, + type = typeof arg0, read; if (type === 'number') { this._set(arg0, arg1, arg2, arg3); @@ -1707,7 +1918,7 @@ var Rectangle = Base.extend({ } else if (type === 'undefined' || arg0 === null) { this._set(0, 0, 0, 0); read = arg0 === null ? 1 : 0; - } else if (arguments.length === 1) { + } else if (args.length === 1) { if (Array.isArray(arg0)) { this._set.apply(this, arg0); read = 1; @@ -1717,20 +1928,20 @@ var Rectangle = Base.extend({ read = 1; } else if (arg0.from === undefined && arg0.to === undefined) { this._set(0, 0, 0, 0); - Base.filter(this, arg0); - read = 1; + if (Base.readSupported(args, this)) { + read = 1; + } } } if (read === undefined) { - var frm = Point.readNamed(arguments, 'from'), - next = Base.peek(arguments), + var frm = Point.readNamed(args, 'from'), + next = Base.peek(args), x = frm.x, y = frm.y, width, height; - if (next && next.x !== undefined - || Base.hasNamed(arguments, 'to')) { - var to = Point.readNamed(arguments, 'to'); + if (next && next.x !== undefined || Base.hasNamed(args, 'to')) { + var to = Point.readNamed(args, 'to'); width = to.x - x; height = to.y - y; if (width < 0) { @@ -1742,16 +1953,16 @@ var Rectangle = Base.extend({ height = -height; } } else { - var size = Size.read(arguments); + var size = Size.read(args); width = size.width; height = size.height; } this._set(x, y, width, height); - read = arguments.__index; - var filtered = arguments.__filtered; - if (filtered) - this.__filtered = filtered; + read = args.__index; } + var filtered = args.__filtered; + if (filtered) + this.__filtered = filtered; if (this.__read) this.__read = read; return this; @@ -2109,10 +2320,11 @@ var Matrix = Base.extend({ _class: 'Matrix', initialize: function Matrix(arg, _dontNotify) { - var count = arguments.length, + var args = arguments, + count = args.length, ok = true; if (count >= 6) { - this._set.apply(this, arguments); + this._set.apply(this, args); } else if (count === 1 || count === 2) { if (arg instanceof Matrix) { this._set(arg._a, arg._b, arg._c, arg._d, arg._tx, arg._ty, @@ -2158,7 +2370,7 @@ var Matrix = Base.extend({ if (owner._applyMatrix) { owner.transform(null, true); } else { - owner._changed(9); + owner._changed(25); } } }, @@ -2193,8 +2405,7 @@ var Matrix = Base.extend({ apply: function(recursively, _setApplyMatrix) { var owner = this._owner; if (owner) { - owner.transform(null, true, Base.pick(recursively, true), - _setApplyMatrix); + owner.transform(null, Base.pick(recursively, true), _setApplyMatrix); return this.isIdentity(); } return false; @@ -2211,8 +2422,9 @@ var Matrix = Base.extend({ }, scale: function() { - var scale = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }); + var args = arguments, + scale = Point.read(args), + center = Point.read(args, 0, { readNull: true }); if (center) this.translate(center); this._a *= scale.x; @@ -2249,8 +2461,9 @@ var Matrix = Base.extend({ }, shear: function() { - var shear = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }); + var args = arguments, + shear = Point.read(args), + center = Point.read(args, 0, { readNull: true }); if (center) this.translate(center); var a = this._a, @@ -2266,8 +2479,9 @@ var Matrix = Base.extend({ }, skew: function() { - var skew = Point.read(arguments), - center = Point.read(arguments, 0, { readNull: true }), + var args = arguments, + skew = Point.read(args), + center = Point.read(args, 0, { readNull: true }), toRadians = Math.PI / 180, shear = new Point(Math.tan(skew.x * toRadians), Math.tan(skew.y * toRadians)); @@ -2507,11 +2721,11 @@ var Matrix = Base.extend({ }, getScaling: function() { - return (this.decompose() || {}).scaling; + return this.decompose().scaling; }, getRotation: function() { - return (this.decompose() || {}).rotation; + return this.decompose().rotation; }, applyToContext: function(ctx) { @@ -2608,7 +2822,7 @@ var Line = Base.extend({ v2y -= p2y; } var cross = v1x * v2y - v1y * v2x; - if (!Numerical.isZero(cross)) { + if (!Numerical.isMachineZero(cross)) { var dx = p1x - p2x, dy = p1y - p2y, u1 = (v2x * dy - v2y * dx) / cross, @@ -2636,7 +2850,7 @@ var Line = Base.extend({ var v2x = x - px, v2y = y - py, ccw = v2x * vy - v2y * vx; - if (!isInfinite && Numerical.isZero(ccw)) { + if (!isInfinite && Numerical.isMachineZero(ccw)) { ccw = (v2x * vx + v2x * vx) / (vx * vx + vy * vy); if (ccw >= 0 && ccw <= 1) ccw = 0; @@ -2649,9 +2863,13 @@ var Line = Base.extend({ vx -= px; vy -= py; } - return vx === 0 ? vy > 0 ? x - px : px - x - : vy === 0 ? vx < 0 ? y - py : py - y - : ((x-px) * vy - (y-py) * vx) / Math.sqrt(vx * vx + vy * vy); + return vx === 0 ? (vy > 0 ? x - px : px - x) + : vy === 0 ? (vx < 0 ? y - py : py - y) + : ((x - px) * vy - (y - py) * vx) / ( + vy > vx + ? vy * Math.sqrt(1 + (vx * vx) / (vy * vy)) + : vx * Math.sqrt(1 + (vy * vy) / (vx * vx)) + ); }, getDistance: function(px, py, vx, vy, x, y, asVector) { @@ -3046,11 +3264,13 @@ new function() { cacheParent = this._parent || symbol, project = this._project; if (flags & 8) { - this._bounds = this._position = this._decomposed = - this._globalMatrix = undefined; + this._bounds = this._position = this._decomposed = undefined; + } + if (flags & 16) { + this._globalMatrix = undefined; } if (cacheParent - && (flags & 40)) { + && (flags & 72)) { Item._clearBoundsCache(cacheParent); } if (flags & 2) { @@ -3086,7 +3306,7 @@ new function() { children[name] = this; } this._name = name || undefined; - this._changed(128); + this._changed(256); }, getStyle: function() { @@ -3101,8 +3321,8 @@ new function() { var part = Base.capitalize(name), key = '_' + name, flags = { - locked: 128, - visible: 137 + locked: 256, + visible: 265 }; this['get' + part] = function() { return this[key]; @@ -3110,7 +3330,7 @@ new function() { this['set' + part] = function(value) { if (value != this[key]) { this[key] = value; - this._changed(flags[name] || 129); + this._changed(flags[name] || 257); } }; }, @@ -3127,7 +3347,7 @@ new function() { var project = this._project; if (project) { project._updateSelection(this); - this._changed(129); + this._changed(257); } } }, @@ -3188,9 +3408,9 @@ new function() { this.setFillColor(null); this.setStrokeColor(null); } - this._changed(129); + this._changed(257); if (this._parent) - this._parent._changed(1024); + this._parent._changed(2048); } }, @@ -3205,14 +3425,9 @@ new function() { }, getPosition: function(_dontLink) { - var position = this._position, - ctor = _dontLink ? Point : LinkedPoint; - if (!position) { - var pivot = this._pivot; - position = this._position = pivot - ? this._matrix._transformPoint(pivot) - : this.getBounds().getCenter(true); - } + var ctor = _dontLink ? Point : LinkedPoint; + var position = this._position || + (this._position = this._getPositionFromBounds()); return new ctor(position.x, position.y, this, 'setPosition'); }, @@ -3220,6 +3435,12 @@ new function() { this.translate(Point.read(arguments).subtract(this.getPosition(true))); }, + _getPositionFromBounds: function(bounds) { + return this._pivot + ? this._matrix._transformPoint(this._pivot) + : (bounds || this.getBounds()).getCenter(true); + }, + getPivot: function() { var pivot = this._pivot; return pivot @@ -3234,7 +3455,8 @@ new function() { }, Base.each({ getStrokeBounds: { stroke: true }, getHandleBounds: { handle: true }, - getInternalBounds: { internal: true } + getInternalBounds: { internal: true }, + getDrawnBounds: { stroke: true, drawnTextBounds: true }, }, function(options, key) { this[key] = function(matrix) { @@ -3291,6 +3513,7 @@ new function() { return [ options.stroke ? 1 : 0, options.handle ? 1 : 0, + options.drawnTextBounds? 1 : 0, internal ? 1 : 0 ].join(''); }, @@ -3379,7 +3602,7 @@ new function() { options = options || {}; for (var i = 0, l = items.length; i < l; i++) { var item = items[i]; - if (item._visible && !item.isEmpty()) { + if (item._visible && !item.isEmpty(true)) { var bounds = item._getCachedBounds( matrix && matrix.appended(item._matrix), options, true), rect = bounds.rect; @@ -3465,16 +3688,27 @@ new function() { }, getGlobalMatrix: function(_dontClone) { - var matrix = this._globalMatrix, - updateVersion = this._project._updateVersion; - if (matrix && matrix._updateVersion !== updateVersion) - matrix = null; + var matrix = this._globalMatrix; + if (matrix) { + var parent = this._parent; + var parents = []; + while (parent) { + if (!parent._globalMatrix) { + matrix = null; + for (var i = 0, l = parents.length; i < l; i++) { + parents[i]._globalMatrix = null; + } + break; + } + parents.push(parent); + parent = parent._parent; + } + } if (!matrix) { matrix = this._globalMatrix = this._matrix.clone(); var parent = this._parent; if (parent) matrix.prepend(parent.getGlobalMatrix(true)); - matrix._updateVersion = updateVersion; } return _dontClone ? matrix : matrix.clone(); }, @@ -3649,8 +3883,8 @@ new function() { this.setName(name); }, - rasterize: function(resolution, insert) { - var bounds = this.getStrokeBounds(), + rasterize: function(resolution, insert, boundRect) { + var bounds = boundRect ? boundRect : this.getStrokeBounds(), scale = (resolution || this.getView().getResolution()) / 72, topLeft = bounds.getTopLeft().floor(), bottomRight = bounds.getBottomRight().ceil(), @@ -3660,6 +3894,7 @@ new function() { var canvas = CanvasProvider.getCanvas(size.multiply(scale)), ctx = canvas.getContext('2d'), matrix = new Matrix().scale(scale).translate(topLeft.negate()); + ctx.imageSmoothingEnabled = false; ctx.save(); matrix.applyToContext(ctx); this.draw(ctx, new Base({ matrices: [matrix] })); @@ -3674,8 +3909,11 @@ new function() { }, contains: function() { - 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) { @@ -3711,16 +3949,18 @@ new function() { }, new function() { function hitTest() { + var args = arguments; return this._hitTest( - Point.read(arguments), - HitResult.getOptions(arguments)); + Point.read(args), + HitResult.getOptions(args)); } function hitTestAll() { - var point = Point.read(arguments), - options = HitResult.getOptions(arguments), + var args = arguments, + point = Point.read(args), + options = HitResult.getOptions(args), all = []; - this._hitTest(point, Base.set({ all: all }, options)); + this._hitTest(point, new Base({ all: all }, options)); return all; } @@ -4099,6 +4339,8 @@ new function() { var owner = this._getOwner(), project = this._project, index = this._index; + if (this._style) + this._style._dispose(); if (owner) { if (this._name) this._removeNamed(); @@ -4155,9 +4397,18 @@ new function() { } }, - isEmpty: function() { + isEmpty: function(recursively) { var children = this._children; - return !children || !children.length; + var numChildren = children ? children.length : 0; + if (recursively) { + for (var i = 0; i < numChildren; i++) { + if (!children[i].isEmpty(recursively)) { + return false; + } + } + return true; + } + return !numChildren; }, isEditable: function() { @@ -4256,8 +4507,9 @@ new function() { }, Base.each(['rotate', 'scale', 'shear', 'skew'], function(key) { var rotate = key === 'rotate'; this[key] = function() { - var value = (rotate ? Base : Point).read(arguments), - center = Point.read(arguments, 0, { readNull: true }); + var args = arguments, + value = (rotate ? Base : Point).read(args), + center = Point.read(args, 0, { readNull: true }); return this.transform(new Matrix()[key](value, center || this.getPosition(true))); }; @@ -4267,16 +4519,19 @@ new function() { return this.transform(mx.translate.apply(mx, arguments)); }, - transform: function(matrix, _applyMatrix, _applyRecursively, - _setApplyMatrix) { + transform: function(matrix, _applyRecursively, _setApplyMatrix) { var _matrix = this._matrix, - transform = matrix && !matrix.isIdentity(), - applyMatrix = (_applyMatrix || this._applyMatrix) - && ((!_matrix.isIdentity() || transform) - || _applyMatrix && _applyRecursively && this._children); - if (!transform && !applyMatrix) + transformMatrix = matrix && !matrix.isIdentity(), + applyMatrix = ( + _setApplyMatrix && this._canApplyMatrix || + this._applyMatrix && ( + transformMatrix || !_matrix.isIdentity() || + _applyRecursively && this._children + ) + ); + if (!transformMatrix && !applyMatrix) return this; - if (transform) { + if (transformMatrix) { if (!matrix.isInvertible() && _matrix.isInvertible()) _matrix._backup = _matrix.getValues(); _matrix.prepend(matrix, true); @@ -4288,8 +4543,9 @@ new function() { if (strokeColor) strokeColor.transform(matrix); } - if (applyMatrix && (applyMatrix = this._transformContent(_matrix, - _applyRecursively, _setApplyMatrix))) { + + if (applyMatrix && (applyMatrix = this._transformContent( + _matrix, _applyRecursively, _setApplyMatrix))) { var pivot = this._pivot; if (pivot) _matrix._transformPoint(pivot, pivot, true); @@ -4299,10 +4555,10 @@ new function() { } var bounds = this._bounds, position = this._position; - if (transform || applyMatrix) { - this._changed(9); + if (transformMatrix || applyMatrix) { + this._changed(25); } - var decomp = transform && bounds && matrix.decompose(); + var decomp = transformMatrix && bounds && matrix.decompose(); if (decomp && decomp.skewing.isZero() && decomp.rotation % 90 === 0) { for (var key in bounds) { var cache = bounds[key]; @@ -4315,11 +4571,11 @@ new function() { } this._bounds = bounds; var cached = bounds[this._getBoundsCacheKey( - this._boundsOptions || {})]; + this._boundsOptions || {})]; if (cached) { - this._position = cached.rect.getCenter(true); + this._position = this._getPositionFromBounds(cached.rect); } - } else if (transform && position && this._pivot) { + } else if (transformMatrix && position && this._pivot) { this._position = matrix._transformPoint(position, position); } return this; @@ -4328,9 +4584,9 @@ new function() { _transformContent: function(matrix, applyRecursively, setApplyMatrix) { var children = this._children; if (children) { - for (var i = 0, l = children.length; i < l; i++) - children[i].transform(matrix, true, applyRecursively, - setApplyMatrix); + for (var i = 0, l = children.length; i < l; i++) { + children[i].transform(matrix, applyRecursively, setApplyMatrix); + } return true; } }, @@ -4368,14 +4624,14 @@ new function() { } }), { - _setStyles: function(ctx, param, viewMatrix) { + _setStyles: function(ctx, param, viewMatrix, strokeMatrix) { var style = this._style, matrix = this._matrix; if (style.hasFill()) { - ctx.fillStyle = style.getFillColor().toCanvasStyle(ctx, matrix); + ctx.fillStyle = style.getFillColor().toCanvasStyle(ctx, matrix, strokeMatrix); } if (style.hasStroke()) { - ctx.strokeStyle = style.getStrokeColor().toCanvasStyle(ctx, matrix); + ctx.strokeStyle = style.getStrokeColor().toCanvasStyle(ctx, matrix, strokeMatrix); ctx.lineWidth = style.getStrokeWidth(); var strokeJoin = style.getStrokeJoin(), strokeCap = style.getStrokeCap(), @@ -4429,12 +4685,11 @@ new function() { matrices.push(globalMatrix); if (param.updateMatrix) { - globalMatrix._updateVersion = updateVersion; this._globalMatrix = globalMatrix; } var blendMode = this._blendMode, - opacity = this._opacity, + opacity = Numerical.clamp(this._opacity, 0, 1), normalBlend = blendMode === 'normal', nativeBlend = BlendMode.nativeModes[blendMode], direct = normalBlend && opacity === 1 @@ -4446,8 +4701,10 @@ new function() { mainCtx, itemOffset, prevOffset; if (!direct) { var bounds = this.getStrokeBounds(viewMatrix); - if (!bounds.width || !bounds.height) + if (!bounds.width || !bounds.height) { + matrices.pop(); return; + } prevOffset = param.offset; itemOffset = param.offset = bounds.getTopLeft().floor(); mainCtx = ctx; @@ -4485,8 +4742,9 @@ new function() { this._draw(ctx, param, viewMatrix, strokeMatrix); ctx.restore(); matrices.pop(); - if (param.clip && !param.dontFinish) - ctx.clip(); + if (param.clip && !param.dontFinish) { + ctx.clip(this.getFillRule()); + } if (!direct) { BlendMode.process(blendMode, ctx, mainCtx, opacity, itemOffset.subtract(prevOffset).multiply(pixelRatio)); @@ -4525,10 +4783,13 @@ new function() { half = size / 2; ctx.strokeStyle = ctx.fillStyle = color ? color.toCanvasStyle(ctx) : '#009dec'; + ctx.lineWidth=2.5; if (itemSelected) this._drawSelected(ctx, mx, selectionItems); if (positionSelected) { - var point = this.getPosition(true), + var pos = this.getPosition(true), + parent = this._parent, + point = parent ? parent.localToGlobal(pos) : pos, x = point.x, y = point.y; ctx.beginPath(); @@ -4585,7 +4846,43 @@ new function() { } return this; } -})); +}), { + tween: function(from, to, options) { + if (!options) { + 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; + }, + + tweenTo: function(to, options) { + return this.tween(null, to, options); + }, + + tweenFrom: function(from, options) { + return this.tween(from, null, options); + } +}); var Group = Item.extend({ _class: 'Group', @@ -4604,7 +4901,7 @@ var Group = Item.extend({ _changed: function _changed(flags) { _changed.base.call(this, flags); - if (flags & 1026) { + if (flags & 2050) { this._clipItem = undefined; } }, @@ -4638,8 +4935,7 @@ var Group = Item.extend({ _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); }, @@ -4745,7 +5041,7 @@ var Shape = Item.extend({ width = size.width, height = size.height; if (type === 'rectangle') { - this._radius.set(Size.min(this._radius, size.divide(2))); + this._radius.set(Size.min(this._radius, size.divide(2).abs())); } else if (type === 'circle') { width = height = (width + height) / 2; this._radius = width / 2; @@ -4880,7 +5176,7 @@ var Shape = Item.extend({ ctx.closePath(); } if (!dontPaint && (hasFill || hasStroke)) { - this._setStyles(ctx, param, viewMatrix); + this._setStyles(ctx, param, viewMatrix, strokeMatrix); if (hasFill) { ctx.fill(style.getFillRule()); ctx.shadowColor = 'rgba(0,0,0,0)'; @@ -4983,34 +5279,38 @@ new function() { statics: new function() { function createShape(type, point, size, radius, args) { - var item = new Shape(Base.getNamed(args), point); + var item = Base.create(Shape.prototype); item._type = type; item._size = size; item._radius = radius; + item._initialize(Base.getNamed(args), point); return item; } return { Circle: function() { - var center = Point.readNamed(arguments, 'center'), - radius = Base.readNamed(arguments, 'radius'); + var args = arguments, + center = Point.readNamed(args, 'center'), + radius = Base.readNamed(args, 'radius'); return createShape('circle', center, new Size(radius * 2), radius, - arguments); + args); }, Rectangle: function() { - var rect = Rectangle.readNamed(arguments, 'rectangle'), - radius = Size.min(Size.readNamed(arguments, 'radius'), + var args = arguments, + rect = Rectangle.readNamed(args, 'rectangle'), + radius = Size.min(Size.readNamed(args, 'radius'), rect.getSize(true).divide(2)); return createShape('rectangle', rect.getCenter(true), - rect.getSize(true), radius, arguments); + rect.getSize(true), radius, args); }, Ellipse: function() { - var ellipse = Shape._readEllipse(arguments), + var args = arguments, + ellipse = Shape._readEllipse(args), radius = ellipse.radius; return createShape('ellipse', ellipse.center, radius.multiply(2), - radius, arguments); + radius, args); }, _readEllipse: function(args) { @@ -5039,16 +5339,33 @@ var Raster = Item.extend({ source: null }, _prioritize: ['crossOrigin'], + _smoothing: false, + beans: true, - initialize: function Raster(object, position) { - if (!this._initialize(object, - position !== undefined && Point.read(arguments, 1))) { - var image = typeof object === 'string' - ? document.getElementById(object) : object; + initialize: function Raster(source, position) { + 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.getContext || object.naturalHeight != null) { + image = object; + } else if (object) { + var size = Size.read(arguments); + if (!size.isZero()) { + image = CanvasProvider.getCanvas(size); + } + } + } if (image) { this.setImage(image); } else { - this.setSource(object); + this.setSource(source); } } if (!this._size) { @@ -5181,7 +5498,7 @@ var Raster = Item.extend({ image ? image.naturalWidth || image.width : 0, image ? image.naturalHeight || image.height : 0); this._context = null; - this._changed(521); + this._changed(1033); }, getCanvas: function() { @@ -5200,12 +5517,12 @@ var Raster = Item.extend({ setCanvas: '#setImage', - getContext: function(modify) { + getContext: function(_change) { if (!this._context) this._context = this.getCanvas().getContext('2d'); - if (modify) { + if (_change) { this._image = null; - this._changed(513); + this._changed(1025); } return this._context; }, @@ -5224,7 +5541,8 @@ var Raster = Item.extend({ crossOrigin = this._crossOrigin; if (crossOrigin) image.crossOrigin = crossOrigin; - image.src = src; + if (src) + image.src = src; this.setImage(image); }, @@ -5240,6 +5558,15 @@ var Raster = Item.extend({ image.crossOrigin = crossOrigin; }, + getSmoothing: function() { + return this._smoothing; + }, + + setSmoothing: function(smoothing) { + this._smoothing = smoothing; + this._changed(257); + }, + getElement: function() { return this._canvas || this._loaded && this._image; } @@ -5249,8 +5576,16 @@ var Raster = Item.extend({ getSubCanvas: function() { var rect = Rectangle.read(arguments), ctx = CanvasProvider.getContext(rect.getSize()); - ctx.drawImage(this.getCanvas(), rect.x, rect.y, - rect.width, rect.height, 0, 0, rect.width, rect.height); + var clippedStartX = Math.max(0, rect.x); + var clippedStartY = Math.max(0, rect.y); + var clippedEndX = Math.min(this.getCanvas().width, rect.x + rect.width); + var clippedEndY = Math.min(this.getCanvas().height, rect.y + rect.height); + ctx.drawImage(this.getCanvas(), + clippedStartX, clippedStartY, + clippedEndX - clippedStartX, clippedEndY - clippedStartY, + clippedStartX - rect.x, clippedStartY - rect.y, + clippedEndX - clippedStartX, clippedEndY - clippedStartY + ); return ctx.canvas; }, @@ -5342,8 +5677,9 @@ var Raster = Item.extend({ }, setPixel: function() { - var point = Point.read(arguments), - color = Color.read(arguments), + var args = arguments, + point = Point.read(args), + color = Color.read(args), components = color._convert('rgb'), alpha = color._alpha, ctx = this.getContext(true), @@ -5356,6 +5692,11 @@ var Raster = Item.extend({ ctx.putImageData(imageData, point.x, point.y); }, + clear: function() { + var size = this._size; + this.getContext(true).clearRect(0, 0, size.width + 1, size.height + 1); + }, + createImageData: function() { var size = Size.read(arguments); return this.getContext().createImageData(size.width, size.height); @@ -5393,10 +5734,17 @@ var Raster = Item.extend({ } }, - _draw: function(ctx) { + _draw: function(ctx, param, viewMatrix) { var element = this.getElement(); - if (element) { - ctx.globalAlpha = this._opacity; + if (element && element.width > 0 && element.height > 0) { + ctx.globalAlpha = Numerical.clamp(this._opacity, 0, 1); + + this._setStyles(ctx, param, viewMatrix); + + DomElement.setPrefixed( + ctx, 'imageSmoothingEnabled', this._smoothing + ); + ctx.drawImage(element, -this._size.width / 2, -this._size.height / 2); } @@ -5453,7 +5801,8 @@ var SymbolItem = Item.extend({ }, _hitTestSelf: function(point, options, viewMatrix) { - var res = this._definition._item._hitTest(point, options, viewMatrix); + var opts = options.extend({ all: false }); + var res = this._definition._item._hitTest(point, opts, viewMatrix); if (res) res.item = this; return res; @@ -5538,7 +5887,7 @@ var HitResult = Base.extend({ statics: { getOptions: function(args) { var options = args && Base.read(args); - return Base.set({ + return new Base({ type: null, tolerance: paper.settings.hitTolerance, fill: !options, @@ -5617,7 +5966,7 @@ var Segment = Base.extend({ && (curve = curves[index])) curve._changed(); } - path._changed(25); + path._changed(41); }, getPoint: function() { @@ -5670,7 +6019,7 @@ var Segment = Base.extend({ this._selection = selection = selection || 0; if (path && selection !== oldSelection) { path._updateSelection(this, oldSelection, selection); - path._changed(129); + path._changed(257); } }, @@ -6598,6 +6947,13 @@ statics: { getParameterAt: '#getTimeAt', + getTimesWithTangent: function () { + var tangent = Point.read(arguments); + return tangent.isZero() + ? [] + : Curve.getTimesWithTangent(this.getValues(), tangent); + }, + getOffsetAtTime: function(t) { return this.getPartLength(0, t); }, @@ -6958,8 +7314,9 @@ new function() { flip ? c1 : c2, flip ? t : u); } else { v1 = Curve.getPart(v1, tMinClip, tMaxClip); + var uDiff = uMax - uMin; if (tMaxClip - tMinClip > 0.8) { - if (tMaxNew - tMinNew > uMax - uMin) { + if (tMaxNew - tMinNew > uDiff) { var parts = Curve.subdivide(v1, 0.5), t = (tMinNew + tMaxNew) / 2; calls = addCurveIntersections( @@ -6979,7 +7336,7 @@ new function() { recursion, calls, u, uMax, tMinNew, tMaxNew); } } else { - if (uMax - uMin >= fatLineEpsilon) { + if (uDiff === 0 || uDiff >= fatLineEpsilon) { calls = addCurveIntersections( v2, v1, c2, c1, locations, include, !flip, recursion, calls, uMin, uMax, tMinNew, tMaxNew); @@ -7147,7 +7504,7 @@ new function() { return locations; } - function getLoopIntersection(v1, c1, locations, include) { + function getSelfIntersection(v1, c1, locations, include) { var info = Curve.classify(v1); if (info.type === 'loop') { var roots = info.roots; @@ -7160,39 +7517,46 @@ new function() { function getIntersections(curves1, curves2, include, matrix1, matrix2, _returnFirst) { - var self = !curves2; + var epsilon = 1e-7, + self = !curves2; if (self) curves2 = curves1; var length1 = curves1.length, length2 = curves2.length, - values2 = [], - arrays = [], - locations, - current; - for (var i = 0; i < length2; i++) - values2[i] = curves2[i].getValues(matrix2); + values1 = new Array(length1), + values2 = self ? values1 : new Array(length2), + locations = []; + for (var i = 0; i < length1; i++) { - var curve1 = curves1[i], - values1 = self ? values2[i] : curve1.getValues(matrix1), - path1 = curve1.getPath(); - if (path1 !== current) { - current = path1; - locations = []; - arrays.push(locations); - } - if (self) { - getLoopIntersection(values1, curve1, locations, include); - } - for (var j = self ? i + 1 : 0; j < length2; j++) { - if (_returnFirst && locations.length) - return locations; - getCurveIntersections(values1, values2[j], curve1, curves2[j], - locations, include); + values1[i] = curves1[i].getValues(matrix1); + } + if (!self) { + for (var i = 0; i < length2; i++) { + values2[i] = curves2[i].getValues(matrix2); } } - locations = []; - for (var i = 0, l = arrays.length; i < l; i++) { - locations.push.apply(locations, arrays[i]); + var boundsCollisions = CollisionDetection.findCurveBoundsCollisions( + values1, values2, epsilon); + for (var index1 = 0; index1 < length1; index1++) { + var curve1 = curves1[index1], + v1 = values1[index1]; + if (self) { + getSelfIntersection(v1, curve1, locations, include); + } + var collisions1 = boundsCollisions[index1]; + if (collisions1) { + for (var j = 0; j < collisions1.length; j++) { + if (_returnFirst && locations.length) + return locations; + var index2 = collisions1[j]; + if (!self || index2 > index1) { + var curve2 = curves2[index2], + v2 = values2[index2]; + getCurveIntersections( + v1, v2, curve1, curve2, locations, include); + } + } + } } return locations; } @@ -7267,18 +7631,58 @@ new function() { return pairs; } + function getTimesWithTangent(v, tangent) { + var x0 = v[0], y0 = v[1], + x1 = v[2], y1 = v[3], + x2 = v[4], y2 = v[5], + x3 = v[6], y3 = v[7], + normalized = tangent.normalize(), + tx = normalized.x, + ty = normalized.y, + ax = 3 * x3 - 9 * x2 + 9 * x1 - 3 * x0, + ay = 3 * y3 - 9 * y2 + 9 * y1 - 3 * y0, + bx = 6 * x2 - 12 * x1 + 6 * x0, + by = 6 * y2 - 12 * y1 + 6 * y0, + cx = 3 * x1 - 3 * x0, + cy = 3 * y1 - 3 * y0, + den = 2 * ax * ty - 2 * ay * tx, + times = []; + if (Math.abs(den) < Numerical.CURVETIME_EPSILON) { + var num = ax * cy - ay * cx, + den = ax * by - ay * bx; + if (den != 0) { + var t = -num / den; + if (t >= 0 && t <= 1) times.push(t); + } + } else { + var delta = (bx * bx - 4 * ax * cx) * ty * ty + + (-2 * bx * by + 4 * ay * cx + 4 * ax * cy) * tx * ty + + (by * by - 4 * ay * cy) * tx * tx, + k = bx * ty - by * tx; + if (delta >= 0 && den != 0) { + var d = Math.sqrt(delta), + t0 = -(k + d) / den, + t1 = (-k + d) / den; + if (t0 >= 0 && t0 <= 1) times.push(t0); + if (t1 >= 0 && t1 <= 1) times.push(t1); + } + } + return times; + } + return { getIntersections: function(curve) { var v1 = this.getValues(), v2 = curve && curve !== this && curve.getValues(); return v2 ? getCurveIntersections(v1, v2, this, curve, []) - : getLoopIntersection(v1, this, []); + : getSelfIntersection(v1, this, []); }, statics: { getOverlaps: getOverlaps, getIntersections: getIntersections, - getCurveLineIntersections: getCurveLineIntersections + getCurveLineIntersections: getCurveLineIntersections, + getTimesWithTangent: getTimesWithTangent } }; }); @@ -7302,10 +7706,13 @@ var CurveLocation = Base.extend({ this._intersection = this._next = this._previous = null; }, - _setCurve: function(curve) { - var path = curve._path; + _setPath: function(path) { this._path = path; this._version = path ? path._version : 0; + }, + + _setCurve: function(curve) { + this._setPath(curve._path); this._curve = curve; this._segment = null; this._segment1 = curve._segment1; @@ -7313,7 +7720,14 @@ var CurveLocation = Base.extend({ }, _setSegment: function(segment) { - this._setCurve(segment.getCurve()); + var curve = segment.getCurve(); + if (curve) { + this._setCurve(curve); + } else { + this._setPath(segment._path); + this._segment1 = segment; + this._segment2 = null; + } this._segment = segment; this._time = segment === this._segment1 ? 0 : 1; this._point = segment._point.clone(); @@ -7500,9 +7914,9 @@ var CurveLocation = Base.extend({ if (t1Inside && t2Inside) return !this.isTouching(); var c2 = this.getCurve(), - c1 = t1 < tMin ? c2.getPrevious() : c2, + c1 = c2 && t1 < tMin ? c2.getPrevious() : c2, c4 = inter.getCurve(), - c3 = t2 < tMin ? c4.getPrevious() : c4; + c3 = c4 && t2 < tMin ? c4.getPrevious() : c4; if (t1 > tMax) c2 = c2.getNext(); if (t2 > tMax) @@ -7516,10 +7930,10 @@ var CurveLocation = Base.extend({ var v = curve.getValues(), roots = Curve.classify(v).roots || Curve.getPeaks(v), count = roots.length, - t = end && count > 1 ? roots[count - 1] - : count > 0 ? roots[0] - : 0.5; - offsets.push(Curve.getLength(v, end ? t : 0, end ? 1 : t) / 2); + offset = Curve.getLength(v, + end && count ? roots[count - 1] : 0, + !end && count ? roots[0] : 1); + offsets.push(count ? offset : offset / 32); } function isInRange(angle, min, max) { @@ -7815,7 +8229,7 @@ var PathItem = Item.extend({ getCrossings: function(path) { return this.getIntersections(path, function(inter) { - return inter.hasOverlap() || inter.isCrossing(); + return inter.isCrossing(); }); }, @@ -7878,16 +8292,20 @@ var PathItem = Item.extend({ matched = [], count = 0; ok = true; + var boundsOverlaps = CollisionDetection.findItemBoundsCollisions(paths1, paths2, Numerical.GEOMETRIC_EPSILON); for (var i1 = length1 - 1; i1 >= 0 && ok; i1--) { var path1 = paths1[i1]; ok = false; - for (var i2 = length2 - 1; i2 >= 0 && !ok; i2--) { - if (path1.compare(paths2[i2])) { - if (!matched[i2]) { - matched[i2] = true; - count++; + var pathBoundsOverlaps = boundsOverlaps[i1]; + if (pathBoundsOverlaps) { + for (var i2 = pathBoundsOverlaps.length - 1; i2 >= 0 && !ok; i2--) { + if (path1.compare(paths2[pathBoundsOverlaps[i2]])) { + if (!matched[pathBoundsOverlaps[i2]]) { + matched[pathBoundsOverlaps[i2]] = true; + count++; + } + ok = true; } - ok = true; } } } @@ -7909,13 +8327,14 @@ var Path = PathItem.extend({ this._closed = false; this._segments = []; this._version = 0; - var segments = Array.isArray(arg) + var args = arguments, + segments = Array.isArray(arg) ? typeof arg[0] === 'object' ? arg - : arguments + : args : arg && (arg.size === undefined && (arg.x !== undefined || arg.point !== undefined)) - ? arguments + ? args : null; if (segments && segments.length > 0) { this.setSegments(segments); @@ -7944,13 +8363,13 @@ var Path = PathItem.extend({ _changed.base.call(this, flags); if (flags & 8) { this._length = this._area = undefined; - if (flags & 16) { + if (flags & 32) { this._version++; } else if (this._curves) { for (var i = 0, l = this._curves.length; i < l; i++) this._curves[i]._changed(); } - } else if (flags & 32) { + } else if (flags & 64) { this._bounds = undefined; } }, @@ -8025,7 +8444,7 @@ var Path = PathItem.extend({ this._curves[length - 1] = new Curve(this, this._segments[length - 1], this._segments[0]); } - this._changed(25); + this._changed(41); } } }, { @@ -8115,7 +8534,7 @@ var Path = PathItem.extend({ this._updateSelection(segment, 0, segment._selection); } if (append) { - segments.push.apply(segments, segs); + Base.push(segments, segs); } else { segments.splice.apply(segments, [index, 0].concat(segs)); for (var i = index + amount, l = segments.length; i < l; i++) @@ -8135,7 +8554,7 @@ var Path = PathItem.extend({ curves.splice(i, 0, new Curve(this, null, null)); this._adjustCurves(start, end); } - this._changed(25); + this._changed(41); return segs; }, @@ -8167,15 +8586,17 @@ var Path = PathItem.extend({ }, add: function(segment1 ) { - return arguments.length > 1 && typeof segment1 !== 'number' - ? this._add(Segment.readList(arguments)) - : this._add([ Segment.read(arguments) ])[0]; + var args = arguments; + return args.length > 1 && typeof segment1 !== 'number' + ? this._add(Segment.readList(args)) + : this._add([ Segment.read(args) ])[0]; }, insert: function(index, segment1 ) { - return arguments.length > 2 && typeof segment1 !== 'number' - ? this._add(Segment.readList(arguments, 1), index) - : this._add([ Segment.read(arguments, 1) ], index)[0]; + var args = arguments; + return args.length > 2 && typeof segment1 !== 'number' + ? this._add(Segment.readList(args, 1), index) + : this._add([ Segment.read(args, 1) ], index)[0]; }, addSegment: function() { @@ -8227,7 +8648,7 @@ var Path = PathItem.extend({ removed._curves = curves.slice(1); this._adjustCurves(index, index); } - this._changed(25); + this._changed(41); return removed; }, @@ -8721,8 +9142,8 @@ var Path = PathItem.extend({ strokePadding = tolerancePadding, join, cap, miterLimit, area, loc, res, - hitStroke = options.stroke && style.hasStroke(), - hitFill = options.fill && style.hasFill(), + hitStroke = options.stroke && (style.hasStroke() || options.hitUnstrokedPaths), + hitFill = options.fill && (style.hasFill() || options.hitUnfilledPaths), hitCurves = options.curves, strokeRadius = hitStroke ? style.getStrokeWidth() / 2 @@ -8883,12 +9304,36 @@ var Path = PathItem.extend({ return offset; } return null; - } + }, + getOffsetsWithTangent: function() { + var tangent = Point.read(arguments); + if (tangent.isZero()) { + return []; + } + + var offsets = []; + var curveStart = 0; + var curves = this.getCurves(); + for (var i = 0, l = curves.length; i < l; i++) { + var curve = curves[i]; + var curveTimes = curve.getTimesWithTangent(tangent); + for (var j = 0, m = curveTimes.length; j < m; j++) { + var offset = curveStart + curve.getOffsetAtTime(curveTimes[j]); + if (offsets.indexOf(offset) < 0) { + offsets.push(offset); + } + } + curveStart += curve.length; + } + return offsets; + } }), new function() { - function drawHandles(ctx, segments, matrix, size) { + function drawHandles(ctx, segments, matrix, size, isFullySelected) { + if (size <= 0) return; + var half = size / 2, coords = new Array(6), pX, pY; @@ -8900,10 +9345,12 @@ new function() { ctx.beginPath(); ctx.moveTo(pX, pY); ctx.lineTo(hX, hY); + ctx.moveTo(hX - half, hY); + ctx.lineTo(hX, hY + half); + ctx.lineTo(hX + half, hY); + ctx.lineTo(hX, hY - half); + ctx.closePath(); ctx.stroke(); - ctx.beginPath(); - ctx.arc(hX, hY, half, 0, Math.PI * 2, true); - ctx.fill(); } } @@ -8913,17 +9360,19 @@ new function() { segment._transformCoordinates(matrix, coords); pX = coords[0]; pY = coords[1]; - if (selection & 2) + if (selection & 2 && !isFullySelected) drawHandle(2); - if (selection & 4) + if (selection & 4 && !isFullySelected) drawHandle(4); - ctx.fillRect(pX - half, pY - half, size, size); + ctx.beginPath(); + ctx.arc(pX, pY, half, 0, Math.PI * 2, true); + ctx.stroke(); + var fillStyle = ctx.fillStyle; if (!(selection & 1)) { - var fillStyle = ctx.fillStyle; - ctx.fillStyle = '#ffffff'; - ctx.fillRect(pX - half + 1, pY - half + 1, size - 2, size - 2); - ctx.fillStyle = fillStyle; + ctx.fillStyle = 'rgba(255, 255, 255, 0.5)'; } + ctx.fill(); + ctx.fillStyle = fillStyle; } } @@ -9009,7 +9458,7 @@ new function() { } if (!dontPaint && (hasFill || hasStroke)) { - this._setStyles(ctx, param, viewMatrix); + this._setStyles(ctx, param, viewMatrix, strokeMatrix); if (hasFill) { ctx.fill(style.getFillRule()); ctx.shadowColor = 'rgba(0,0,0,0)'; @@ -9044,7 +9493,8 @@ new function() { ctx.beginPath(); drawSegments(ctx, this, matrix); ctx.stroke(); - drawHandles(ctx, this._segments, matrix, paper.settings.handleSize); + drawHandles(ctx, this._segments, matrix, paper.settings.handleSize, + this.isFullySelected()); } }; }, @@ -9074,17 +9524,19 @@ new function() { }, cubicCurveTo: function() { - var handle1 = Point.read(arguments), - handle2 = Point.read(arguments), - to = Point.read(arguments), + var args = arguments, + handle1 = Point.read(args), + handle2 = Point.read(args), + to = Point.read(args), current = getCurrentSegment(this); current.setHandleOut(handle1.subtract(current._point)); this._add([ new Segment(to, handle2.subtract(to)) ]); }, quadraticCurveTo: function() { - var handle = Point.read(arguments), - to = Point.read(arguments), + var args = arguments, + handle = Point.read(args), + to = Point.read(args), current = getCurrentSegment(this)._point; this.cubicCurveTo( handle.add(current.subtract(handle).multiply(1 / 3)), @@ -9094,9 +9546,10 @@ new function() { }, curveTo: function() { - var through = Point.read(arguments), - to = Point.read(arguments), - t = Base.pick(Base.read(arguments), 0.5), + var args = arguments, + through = Point.read(args), + to = Point.read(args), + t = Base.pick(Base.read(args), 0.5), t1 = 1 - t, current = getCurrentSegment(this)._point, handle = through.subtract(current.multiply(t1 * t1)) @@ -9108,30 +9561,31 @@ new function() { }, arcTo: function() { - var abs = Math.abs, + var args = arguments, + abs = Math.abs, sqrt = Math.sqrt, current = getCurrentSegment(this), from = current._point, - to = Point.read(arguments), + to = Point.read(args), through, - peek = Base.peek(arguments), + peek = Base.peek(args), clockwise = Base.pick(peek, true), center, extent, vector, matrix; if (typeof clockwise === 'boolean') { var middle = from.add(to).divide(2), through = middle.add(middle.subtract(from).rotate( clockwise ? -90 : 90)); - } else if (Base.remain(arguments) <= 2) { + } else if (Base.remain(args) <= 2) { through = to; - to = Point.read(arguments); - } else { - var radius = Size.read(arguments), + to = Point.read(args); + } else if (!from.equals(to)) { + var radius = Size.read(args), isZero = Numerical.isZero; if (isZero(radius.width) || isZero(radius.height)) return this.lineTo(to); - var rotation = Base.read(arguments), - clockwise = !!Base.read(arguments), - large = !!Base.read(arguments), + var rotation = Base.read(args), + clockwise = !!Base.read(args), + large = !!Base.read(args), middle = from.add(to).divide(2), pt = from.subtract(middle).rotate(-rotation), x = pt.x, @@ -9184,46 +9638,48 @@ new function() { } vector = from.subtract(center); extent = vector.getDirectedAngle(to.subtract(center)); - var centerSide = line.getSide(center); + var centerSide = line.getSide(center, true); if (centerSide === 0) { extent = throughSide * abs(extent); } else if (throughSide === centerSide) { extent += extent < 0 ? 360 : -360; } } - var epsilon = 1e-7, - ext = abs(extent), - 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++) { - 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 = 1e-7, + ext = abs(extent), + 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++) { + 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) { + current.setHandleOut(out); } else { - pt = center.add(vector); + 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) { - current.setHandleOut(out); - } else { - 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); + this._add(segments); } - this._add(segments); }, lineBy: function() { @@ -9233,37 +9689,41 @@ new function() { }, curveBy: function() { - var through = Point.read(arguments), - to = Point.read(arguments), - parameter = Base.read(arguments), + var args = arguments, + through = Point.read(args), + to = Point.read(args), + parameter = Base.read(args), current = getCurrentSegment(this)._point; this.curveTo(current.add(through), current.add(to), parameter); }, cubicCurveBy: function() { - var handle1 = Point.read(arguments), - handle2 = Point.read(arguments), - to = Point.read(arguments), + var args = arguments, + handle1 = Point.read(args), + handle2 = Point.read(args), + to = Point.read(args), current = getCurrentSegment(this)._point; this.cubicCurveTo(current.add(handle1), current.add(handle2), current.add(to)); }, quadraticCurveBy: function() { - var handle = Point.read(arguments), - to = Point.read(arguments), + var args = arguments, + handle = Point.read(args), + to = Point.read(args), current = getCurrentSegment(this)._point; this.quadraticCurveTo(current.add(handle), current.add(to)); }, arcBy: function() { - var current = getCurrentSegment(this)._point, - point = current.add(Point.read(arguments)), - clockwise = Base.pick(Base.peek(arguments), true); + var args = arguments, + current = getCurrentSegment(this)._point, + point = current.add(Point.read(args)), + clockwise = Base.pick(Base.peek(args), true); if (typeof clockwise === 'boolean') { this.arcTo(point, clockwise); } else { - this.arcTo(point, current.add(Point.read(arguments))); + this.arcTo(point, current.add(Point.read(args))); } }, @@ -9361,13 +9821,16 @@ statics: { } var length = segments.length - (closed ? 0 : 1); - for (var i = 1; i < length; i++) - addJoin(segments[i], join); - if (closed) { - addJoin(segments[0], join); - } else if (length > 0) { - addCap(segments[0], cap); - addCap(segments[segments.length - 1], cap); + if (length > 0) { + for (var i = 1; i < length; i++) { + addJoin(segments[i], join); + } + if (closed) { + addJoin(segments[0], join); + } else { + addCap(segments[0], cap); + addCap(segments[segments.length - 1], cap); + } } return bounds; }, @@ -9397,8 +9860,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(); } @@ -9513,21 +9977,24 @@ Path.inject({ statics: new function() { return { Line: function() { + var args = arguments; return createPath([ - new Segment(Point.readNamed(arguments, 'from')), - new Segment(Point.readNamed(arguments, 'to')) - ], false, arguments); + new Segment(Point.readNamed(args, 'from')), + new Segment(Point.readNamed(args, 'to')) + ], false, args); }, Circle: function() { - var center = Point.readNamed(arguments, 'center'), - radius = Base.readNamed(arguments, 'radius'); - return createEllipse(center, new Size(radius), arguments); + var args = arguments, + center = Point.readNamed(args, 'center'), + radius = Base.readNamed(args, 'radius'); + return createEllipse(center, new Size(radius), args); }, Rectangle: function() { - var rect = Rectangle.readNamed(arguments, 'rectangle'), - radius = Size.readNamed(arguments, 'radius', 0, + var args = arguments, + rect = Rectangle.readNamed(args, 'rectangle'), + radius = Size.readNamed(args, 'radius', 0, { readNull: true }), bl = rect.getBottomLeft(true), tl = rect.getTopLeft(true), @@ -9558,23 +10025,25 @@ Path.inject({ statics: new function() { new Segment(br.subtract(rx, 0), [hx, 0]) ]; } - return createPath(segments, true, arguments); + return createPath(segments, true, args); }, RoundRectangle: '#Rectangle', Ellipse: function() { - var ellipse = Shape._readEllipse(arguments); - return createEllipse(ellipse.center, ellipse.radius, arguments); + var args = arguments, + ellipse = Shape._readEllipse(args); + return createEllipse(ellipse.center, ellipse.radius, args); }, Oval: '#Ellipse', Arc: function() { - var from = Point.readNamed(arguments, 'from'), - through = Point.readNamed(arguments, 'through'), - to = Point.readNamed(arguments, 'to'), - props = Base.getNamed(arguments), + var args = arguments, + from = Point.readNamed(args, 'from'), + through = Point.readNamed(args, 'through'), + to = Point.readNamed(args, 'to'), + props = Base.getNamed(args), path = new Path(props && props.insert == false && Item.NO_INSERT); path.moveTo(from); @@ -9583,9 +10052,10 @@ Path.inject({ statics: new function() { }, RegularPolygon: function() { - var center = Point.readNamed(arguments, 'center'), - sides = Base.readNamed(arguments, 'sides'), - radius = Base.readNamed(arguments, 'radius'), + var args = arguments, + center = Point.readNamed(args, 'center'), + sides = Base.readNamed(args, 'sides'), + radius = Base.readNamed(args, 'radius'), step = 360 / sides, three = sides % 3 === 0, vector = new Point(0, three ? -radius : radius), @@ -9594,21 +10064,22 @@ Path.inject({ statics: new function() { for (var i = 0; i < sides; i++) segments[i] = new Segment(center.add( vector.rotate((i + offset) * step))); - return createPath(segments, true, arguments); + return createPath(segments, true, args); }, Star: function() { - var center = Point.readNamed(arguments, 'center'), - points = Base.readNamed(arguments, 'points') * 2, - radius1 = Base.readNamed(arguments, 'radius1'), - radius2 = Base.readNamed(arguments, 'radius2'), + var args = arguments, + center = Point.readNamed(args, 'center'), + points = Base.readNamed(args, 'points') * 2, + radius1 = Base.readNamed(args, 'radius1'), + radius2 = Base.readNamed(args, 'radius2'), step = 360 / points, vector = new Point(0, -1), segments = new Array(points); for (var i = 0; i < points; i++) segments[i] = new Segment(center.add(vector.rotate(step * i) .multiply(i % 2 ? radius2 : radius1))); - return createPath(segments, true, arguments); + return createPath(segments, true, args); } }; }}); @@ -9697,8 +10168,9 @@ var CompoundPath = PathItem.extend({ getCurves: function() { var children = this._children, curves = []; - for (var i = 0, l = children.length; i < l; i++) - curves.push.apply(curves, children[i].getCurves()); + for (var i = 0, l = children.length; i < l; i++) { + Base.push(curves, children[i].getCurves()); + } return curves; }, @@ -9742,7 +10214,7 @@ var CompoundPath = PathItem.extend({ _hitTestChildren: function _hitTestChildren(point, options, viewMatrix) { return _hitTestChildren.base.call(this, point, - options.class === Path || options.type === 'path' ? options + options.class === Path || options.type === 'path' || options.hitUnfilledPaths ? options : Base.set({}, options, { fill: false }), viewMatrix); }, @@ -9758,7 +10230,7 @@ var CompoundPath = PathItem.extend({ children[i].draw(ctx, param, strokeMatrix); if (!param.clip) { - this._setStyles(ctx, param, viewMatrix); + this._setStyles(ctx, param, viewMatrix, strokeMatrix); var style = this._style; if (style.hasFill()) { ctx.fill(style.getFillRule()); @@ -9841,13 +10313,30 @@ PathItem.inject(new function() { exclude: { '1': true, '-1': true } }; + function getPaths(path) { + return path._children || [path]; + } + function preparePath(path, resolve) { - var res = path.clone(false).reduce({ simplify: true }) - .transform(null, true, true); - return resolve - ? res.resolveCrossings().reorient( - res.getFillRule() === 'nonzero', true) - : res; + var res = path + .clone(false) + .reduce({ simplify: true }) + .transform(null, true, true); + if (resolve) { + var paths = getPaths(res); + for (var i = 0, l = paths.length; i < l; i++) { + var path = paths[i]; + if (!path._closed && !path.isEmpty()) { + path.closePath(1e-12); + path.getFirstSegment().setHandleIn(0, 0); + path.getLastSegment().setHandleOut(0, 0); + } + } + res = res + .resolveCrossings() + .reorient(res.getFillRule() === 'nonzero', true); + } + return res; } function createResult(paths, simplify, path1, path2, options) { @@ -9862,6 +10351,10 @@ PathItem.inject(new function() { return result; } + function filterIntersection(inter) { + return inter.hasOverlap() || inter.isCrossing(); + } + function traceBoolean(path1, path2, operation, options) { if (options && (options.trace == false || options.stroke) && /^(subtract|intersect)$/.test(operation)) @@ -9873,36 +10366,63 @@ PathItem.inject(new function() { if (_path2 && (operator.subtract || operator.exclude) ^ (_path2.isClockwise() ^ _path1.isClockwise())) _path2.reverse(); - var crossings = divideLocations( - CurveLocation.expand(_path1.getCrossings(_path2))), - paths1 = _path1._children || [_path1], - paths2 = _path2 && (_path2._children || [_path2]), + var crossings = divideLocations(CurveLocation.expand( + _path1.getIntersections(_path2, filterIntersection))), + paths1 = getPaths(_path1), + paths2 = _path2 && getPaths(_path2), segments = [], curves = [], paths; - function collect(paths) { + function collectPaths(paths) { for (var i = 0, l = paths.length; i < l; i++) { var path = paths[i]; - segments.push.apply(segments, path._segments); - curves.push.apply(curves, path.getCurves()); + Base.push(segments, path._segments); + Base.push(curves, path.getCurves()); path._overlapsOnly = true; } } + function getCurves(indices) { + var list = []; + for (var i = 0, l = indices && indices.length; i < l; i++) { + list.push(curves[indices[i]]); + } + return list; + } + if (crossings.length) { - collect(paths1); + collectPaths(paths1); if (paths2) - collect(paths2); + collectPaths(paths2); + + var curvesValues = new Array(curves.length); + for (var i = 0, l = curves.length; i < l; i++) { + curvesValues[i] = curves[i].getValues(); + } + var curveCollisions = CollisionDetection.findCurveBoundsCollisions( + curvesValues, curvesValues, 0, true); + var curveCollisionsMap = {}; + for (var i = 0; i < curves.length; i++) { + var curve = curves[i], + id = curve._path._id, + map = curveCollisionsMap[id] = curveCollisionsMap[id] || {}; + map[curve.getIndex()] = { + hor: getCurves(curveCollisions[i].hor), + ver: getCurves(curveCollisions[i].ver) + }; + } + for (var i = 0, l = crossings.length; i < l; i++) { - propagateWinding(crossings[i]._segment, _path1, _path2, curves, - operator); + propagateWinding(crossings[i]._segment, _path1, _path2, + curveCollisionsMap, operator); } for (var i = 0, l = segments.length; i < l; i++) { var segment = segments[i], inter = segment._intersection; if (!segment._winding) { - propagateWinding(segment, _path1, _path2, curves, operator); + propagateWinding(segment, _path1, _path2, + curveCollisionsMap, operator); } if (!(inter && inter._overlap)) segment._path._overlapsOnly = false; @@ -9915,14 +10435,13 @@ PathItem.inject(new function() { return !!operator[w]; }); } - return createResult(paths, true, path1, path2, options); } function splitBoolean(path1, path2, operation) { var _path1 = preparePath(path1), _path2 = preparePath(path2), - crossings = _path1.getCrossings(_path2), + crossings = _path1.getIntersections(_path2, filterIntersection), subtract = operation === 'subtract', divide = operation === 'divide', added = {}, @@ -9985,22 +10504,30 @@ PathItem.inject(new function() { return abs(b.getArea()) - abs(a.getArea()); }), first = sorted[0]; + var collisions = CollisionDetection.findItemBoundsCollisions(sorted, + null, Numerical.GEOMETRIC_EPSILON); if (clockwise == null) clockwise = first.isClockwise(); for (var i = 0; i < length; i++) { var path1 = sorted[i], entry1 = lookup[path1._id], - point = path1.getInteriorPoint(), - containerWinding = 0; - for (var j = i - 1; j >= 0; j--) { - var path2 = sorted[j]; - if (path2.contains(point)) { - var entry2 = lookup[path2._id]; - containerWinding = entry2.winding; - entry1.winding += containerWinding; - entry1.container = entry2.exclude ? entry2.container - : path2; - break; + containerWinding = 0, + indices = collisions[i]; + if (indices) { + var point = null; + for (var j = indices.length - 1; j >= 0; j--) { + if (indices[j] < i) { + point = point || path1.getInteriorPoint(); + var path2 = sorted[indices[j]]; + if (path2.contains(point)) { + var entry2 = lookup[path2._id]; + containerWinding = entry2.winding; + entry1.winding += containerWinding; + entry1.container = entry2.exclude + ? entry2.container : path2; + break; + } + } } } if (isInside(entry1.winding) === isInside(containerWinding)) { @@ -10008,8 +10535,8 @@ PathItem.inject(new function() { paths[entry1.index] = null; } else { var container = entry1.container; - path1.setClockwise(container ? !container.isClockwise() - : clockwise); + path1.setClockwise( + container ? !container.isClockwise() : clockwise); } } } @@ -10097,6 +10624,9 @@ PathItem.inject(new function() { } function getWinding(point, curves, dir, closed, dontFlip) { + var curvesList = Array.isArray(curves) + ? curves + : curves[dir ? 'hor' : 'ver']; var ia = dir ? 1 : 0, io = ia ^ 1, pv = [point.x, point.y], @@ -10172,7 +10702,7 @@ PathItem.inject(new function() { onPath = true; } } - quality = 0; + quality /= 4; } vPrev = v; return !dontFlip && a > paL && a < paR @@ -10201,12 +10731,12 @@ PathItem.inject(new function() { } } - for (var i = 0, l = curves.length; i < l; i++) { - var curve = curves[i], + for (var i = 0, l = curvesList.length; i < l; i++) { + var curve = curvesList[i], path = curve._path, v = curve.getValues(), res; - if (!i || curves[i - 1]._path !== path) { + if (!i || curvesList[i - 1]._path !== path) { vPrev = null; if (!path._closed) { vClose = Curve.getValues( @@ -10235,7 +10765,7 @@ PathItem.inject(new function() { if (res = handleCurve(v)) return res; - if (i + 1 === l || curves[i + 1]._path !== path) { + if (i + 1 === l || curvesList[i + 1]._path !== path) { if (vClose && (res = handleCurve(vClose))) return res; if (onPath && !pathWindingL && !pathWindingR) { @@ -10263,21 +10793,24 @@ PathItem.inject(new function() { }; } - function propagateWinding(segment, path1, path2, curves, operator) { + function propagateWinding(segment, path1, path2, curveCollisionsMap, + operator) { var chain = [], start = segment, totalLength = 0, winding; do { - var curve = segment.getCurve(), - length = curve.getLength(); - chain.push({ segment: segment, curve: curve, length: length }); - totalLength += length; + var curve = segment.getCurve(); + if (curve) { + var length = curve.getLength(); + chain.push({ segment: segment, curve: curve, length: length }); + totalLength += length; + } segment = segment.getNext(); } while (segment && !segment._intersection && segment !== start); var offsets = [0.5, 0.25, 0.75], winding = { winding: 0, quality: -1 }, - tMin = 1e-8, + tMin = 1e-3, tMax = 1 - tMin; for (var i = 0; i < offsets.length && winding.quality < 0.5; i++) { var length = totalLength * offsets[i]; @@ -10292,13 +10825,22 @@ PathItem.inject(new function() { t = Numerical.clamp(curve.getTimeAt(length), tMin, tMax), pt = curve.getPointAtTime(t), dir = abs(curve.getTangentAtTime(t).y) < Math.SQRT1_2; - var wind = !(operator.subtract && path2 && ( - operand === path1 && - path2._getWinding(pt, dir, true).winding || - operand === path2 && - !path1._getWinding(pt, dir, true).winding)) - ? getWinding(pt, curves, dir, true) - : { winding: 0, quality: 1 }; + var wind = null; + if (operator.subtract && path2) { + var otherPath = operand === path1 ? path2 : path1, + pathWinding = otherPath._getWinding(pt, dir, true); + if (operand === path1 && pathWinding.winding || + operand === path2 && !pathWinding.winding) { + if (pathWinding.quality < 1) { + continue; + } else { + wind = { winding: 0, quality: 1 }; + } + } + } + wind = wind || getWinding( + pt, curveCollisionsMap[path._id][curve.getIndex()], + dir, true); if (wind.quality > winding.quality) winding = wind; break; @@ -10370,8 +10912,8 @@ PathItem.inject(new function() { if (inter) { collect(inter); - while (inter && inter._prev) - inter = inter._prev; + while (inter && inter._previous) + inter = inter._previous; collect(inter, start); } return crossings; @@ -10572,7 +11114,7 @@ PathItem.inject(new function() { if (clearCurves) clearCurveHandles(clearCurves); paths = tracePaths(Base.each(paths, function(path) { - this.push.apply(this, path._segments); + Base.push(this, path._segments); }, [])); } var length = paths.length, @@ -10701,7 +11243,7 @@ var PathFlattener = Base.extend({ segment1 = segment2; } if (path._closed) - addCurve(segment2, segments[0]); + addCurve(segment2 || segment1, segments[0]); this.curves = curves; this.parts = parts; this.length = length; @@ -10927,7 +11469,7 @@ var PathFitter = Base.extend({ pt2 = this.evaluate(1, curve2, u), diff = pt.subtract(point), df = pt1.dot(pt1) + diff.dot(pt2); - return Numerical.isZero(df) ? u : u - diff.dot(pt1) / df; + return Numerical.isMachineZero(df) ? u : u - diff.dot(pt1) / df; }, evaluate: function(degree, curve, t) { @@ -11003,7 +11545,7 @@ var TextItem = Item.extend({ setContent: function(content) { this._content = '' + content; this._lines = this._content.split(/\r\n|\n|\r/mg); - this._changed(265); + this._changed(521); }, isEmpty: function() { @@ -11060,6 +11602,11 @@ var PointText = TextItem.extend({ }, _getBounds: function(matrix, options) { + var rect = options.drawnTextBounds ? this._getDrawnTextSize() : this._getMeasuredTextSize(); + return matrix ? matrix._transformBounds(rect, rect) : rect; + }, + + _getMeasuredTextSize: function() { var style = this._style, lines = this._lines, numLines = lines.length, @@ -11069,10 +11616,67 @@ var PointText = TextItem.extend({ x = 0; if (justification !== 'left') x -= width / (justification === 'center' ? 2: 1); - var rect = new Rectangle(x, + return new Rectangle(x, numLines ? - 0.75 * leading : 0, width, numLines * leading); - return matrix ? matrix._transformBounds(rect, rect) : rect; + }, + + _getDrawnTextSize: function() { + var style = this._style; + var lines = this._lines; + var numLines = lines.length; + var leading = style.getLeading(); + var justification = style.getJustification(); + + var svg = SvgElement.create('svg', { + version: '1.1', + xmlns: SvgElement.svg + }); + var node = SvgElement.create('text'); + node.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve'); + svg.appendChild(node); + for (var i = 0; i < numLines; i++) { + var tspanNode = SvgElement.create('tspan', { + x: '0', + dy: i === 0 ? '0' : leading + 'px' + }); + tspanNode.textContent = this._lines[i]; + node.appendChild(tspanNode); + } + + var element = document.createElement('span'); + element.style.visibility = ('hidden'); + element.style.whiteSpace = 'pre'; + element.style.fontSize = this.fontSize + 'px'; + element.style.fontFamily = this.font; + element.style.lineHeight = this.leading / this.fontSize; + + var bbox; + try { + element.appendChild(svg); + document.body.appendChild(element); + bbox = svg.getBBox(); + } finally { + document.body.removeChild(element); + } + + var halfStrokeWidth = this.strokeWidth / 2; + var width = bbox.width + (halfStrokeWidth * 2); + var height = bbox.height + (halfStrokeWidth * 2); + var x = bbox.x - halfStrokeWidth; + var y = bbox.y - halfStrokeWidth; + + if (justification !== 'left') { + var eltWidth = this.getView().getTextWidth(style.getFontStyle(), lines); + x -= eltWidth / (justification === 'center' ? 2: 1); + } + + return new Rectangle(x, y, width + 1, Math.max(height, numLines * leading)); + }, + + _hitTestSelf: function(point, options) { + if (options.fill && (this.hasFill() || options.hitUnfilledPaths) && this._contains(point)) + return new HitResult('fill', this); } }); @@ -11086,47 +11690,74 @@ var Color = Base.extend(new function() { }; var componentParsers = {}, - colorCache = {}, + namedColors = { + transparent: [0, 0, 0, 0] + }, colorCtx; function fromCSS(string) { - var match = string.match(/^#(\w{1,2})(\w{1,2})(\w{1,2})$/), + var match = string.match( + /^#([\da-f]{2})([\da-f]{2})([\da-f]{2})([\da-f]{2})?$/i + ) || string.match( + /^#([\da-f])([\da-f])([\da-f])([\da-f])?$/i + ), + type = 'rgb', components; if (match) { - components = [0, 0, 0]; - for (var i = 0; i < 3; i++) { + var amount = match[4] ? 4 : 3; + components = new Array(amount); + for (var i = 0; i < amount; i++) { var value = match[i + 1]; components[i] = parseInt(value.length == 1 ? value + value : value, 16) / 255; } - } else if (match = string.match(/^rgba?\((.*)\)$/)) { - components = match[1].split(','); - for (var i = 0, l = components.length; i < l; i++) { - var value = +components[i]; - components[i] = i < 3 ? value / 255 : value; - } - } else if (window) { - var cached = colorCache[string]; - if (!cached) { - if (!colorCtx) { - colorCtx = CanvasProvider.getContext(1, 1); - colorCtx.globalCompositeOperation = 'copy'; + } else if (match = string.match(/^(rgb|hsl)a?\((.*)\)$/)) { + type = match[1]; + 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]; + var value = parseFloat(component); + if (isHSL) { + if (i === 0) { + var unit = component.match(/([a-z]*)$/)[1]; + value *= ({ + turn: 360, + rad: 180 / Math.PI, + grad: 0.9 + }[unit] || 1); + } else if (i < 3) { + value /= 100; + } + } else if (i < 3) { + value /= /%$/.test(component) ? 100 : 255; } - colorCtx.fillStyle = 'rgba(0,0,0,0)'; - colorCtx.fillStyle = string; - colorCtx.fillRect(0, 0, 1, 1); - var data = colorCtx.getImageData(0, 0, 1, 1).data; - cached = colorCache[string] = [ - data[0] / 255, - data[1] / 255, - data[2] / 255 - ]; + components[i] = value; } - components = cached.slice(); } else { - components = [0, 0, 0]; + var color = namedColors[string]; + if (!color) { + if (window) { + if (!colorCtx) { + colorCtx = CanvasProvider.getContext(1, 1); + colorCtx.globalCompositeOperation = 'copy'; + } + colorCtx.fillStyle = 'rgba(0,0,0,0)'; + colorCtx.fillStyle = string; + colorCtx.fillRect(0, 0, 1, 1); + var data = colorCtx.getImageData(0, 0, 1, 1).data; + color = namedColors[string] = [ + data[0] / 255, + data[1] / 255, + data[2] / 255 + ]; + } else { + color = [0, 0, 0]; + } + } + components = color.slice(); } - return components; + return [type, components]; } var hsbIndices = [ @@ -11234,30 +11865,32 @@ var Color = Base.extend(new function() { Base.each(properties, function(name, index) { var part = Base.capitalize(name), hasOverlap = /^(hue|saturation)$/.test(name), - parser = componentParsers[type][index] = name === 'gradient' - ? function(value) { - var current = this._components[0]; - value = Gradient.read(Array.isArray(value) ? value - : arguments, 0, { readNull: true }); - if (current !== value) { - if (current) - current._removeOwner(this); - if (value) - value._addOwner(this); + parser = componentParsers[type][index] = type === 'gradient' + ? name === 'gradient' + ? function(value) { + var current = this._components[0]; + value = Gradient.read( + Array.isArray(value) + ? value + : arguments, 0, { readNull: true } + ); + if (current !== value) { + if (current) + current._removeOwner(this); + if (value) + value._addOwner(this); + } + return value; } - return value; - } - : type === 'gradient' - ? function() { + : function() { return Point.read(arguments, 0, { readNull: name === 'highlight', clone: true }); } - : function(value) { - return value == null || isNaN(value) ? 0 : value; - }; - + : function(value) { + return value == null || isNaN(value) ? 0 : +value; + }; this['get' + part] = function() { return this._type === type || hasOverlap && /^hs[bl]$/.test(this._type) @@ -11327,8 +11960,9 @@ var Color = Base.extend(new function() { if (values.length > length) values = Base.slice(values, 0, length); } else if (argType === 'string') { - type = 'rgb'; - components = fromCSS(arg); + var converted = fromCSS(arg); + type = converted[0]; + components = converted[1]; if (components.length === 4) { alpha = components[3]; components.length--; @@ -11412,8 +12046,13 @@ var Color = Base.extend(new function() { _changed: function() { this._canvasStyle = null; - if (this._owner) - this._owner._changed(65); + if (this._owner) { + if (this._setter) { + this._owner[this._setter](this); + } else { + this._owner._changed(129); + } + } }, _convert: function(type) { @@ -11509,8 +12148,9 @@ var Color = Base.extend(new function() { + components.join(',') + ')'; }, - toCanvasStyle: function(ctx, matrix) { - if (this._canvasStyle) + toCanvasStyle: function(ctx, matrix, strokeMatrix) { + var strokeMayChange = this._type === 'gradient' && strokeMatrix; + if (this._canvasStyle && !strokeMayChange) return this._canvasStyle; if (this._type !== 'gradient') return this._canvasStyle = this.toCSS(); @@ -11528,6 +12168,12 @@ var Color = Base.extend(new function() { if (highlight) highlight = inverse._transformPoint(highlight); } + if (strokeMatrix) { + origin = strokeMatrix._transformPoint(origin); + destination = strokeMatrix._transformPoint(destination); + if (highlight) + highlight = strokeMatrix._transformPoint(highlight); + } if (gradient._radial) { var radius = destination.getDistance(origin); if (highlight) { @@ -11549,7 +12195,8 @@ var Color = Base.extend(new function() { offset == null ? i / (l - 1) : offset, stop._color.toCanvasStyle()); } - return this._canvasStyle = canvasGradient; + if (!strokeMayChange) this._canvasStyle = canvasGradient; + return canvasGradient; }, transform: function(matrix) { @@ -11569,6 +12216,19 @@ var Color = Base.extend(new function() { random: function() { var random = Math.random; return new Color(random(), random(), random()); + }, + + _setOwner: function(color, owner, setter) { + if (color) { + if (color._owner && owner && color._owner !== owner) { + color = color.clone(); + } + if (!color._owner ^ !owner) { + color._owner = owner || null; + color._setter = setter || null; + } + } + return color; } } }); @@ -11744,7 +12404,7 @@ var GradientStop = Base.extend({ _changed: function() { if (this._owner) - this._owner._changed(65); + this._owner._changed(129); }, getOffset: function() { @@ -11764,10 +12424,9 @@ var GradientStop = Base.extend({ }, setColor: function() { - var color = Color.read(arguments, 0, { clone: true }); - if (color) - color._owner = this; - this._color = color; + Color._setOwner(this._color, null); + this._color = Color._setOwner(Color.read(arguments, 0), this, + 'setColor'); this._changed(); }, @@ -11807,11 +12466,11 @@ var Style = Base.extend(new function() { fillColor: new Color() }), flags = { - strokeWidth: 97, - strokeCap: 97, - strokeJoin: 97, - strokeScaling: 105, - miterLimit: 97, + strokeWidth: 193, + strokeCap: 193, + strokeJoin: 193, + strokeScaling: 201, + miterLimit: 193, fontFamily: 9, fontWeight: 9, fontSize: 9, @@ -11849,26 +12508,30 @@ var Style = Base.extend(new function() { fields[set] = function(value) { var owner = this._owner, - children = owner && owner._children; - if (children && children.length > 0 - && !(owner instanceof CompoundPath)) { + children = owner && owner._children, + applyToChildren = 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) { + } + if ((key === 'selectedColor' || !applyToChildren) + && key in this._defaults) { var old = this._values[key]; if (old !== value) { if (isColor) { - if (old && old._owner !== undefined) - old._owner = undefined; + if (old) { + Color._setOwner(old, null); + old._canvasStyle = null; + } if (value && value.constructor === Color) { - if (value._owner) - value = value.clone(); - value._owner = owner; + value = Color._setOwner(value, owner, + applyToChildren && set); } } this._values[key] = value; if (owner) - owner._changed(flag || 65); + owner._changed(flag || 129); } } }; @@ -11876,24 +12539,10 @@ 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 (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)) { - this._values[key] = value = ctor.read([value], 0, - { readNull: true, clone: true }); - if (value && isColor) - value._owner = owner; - } - } - } else if (children) { + if (applyToChildren && !_dontMerge) { for (var i = 0, l = children.length; i < l; i++) { var childValue = children[i]._style[get](); if (!i) { @@ -11902,6 +12551,23 @@ 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]; + if (value && value.clone) { + value = value.clone(); + } + } else { + var ctor = isColor ? Color : isPoint ? Point : null; + if (ctor && !(value && value.constructor === ctor)) { + this._values[key] = value = ctor.read([value], 0, + { readNull: true, clone: true }); + } + } + } + if (value && isColor) { + value = Color._setOwner(value, owner, applyToChildren && set); } return value; }; @@ -11963,6 +12629,16 @@ var Style = Base.extend(new function() { || false; }, + _dispose: function() { + var color; + color = this.getFillColor(); + if (color) color._canvasStyle = null; + color = this.getStrokeColor(); + if (color) color._canvasStyle = null; + color = this.getShadowColor(); + if (color) color._canvasStyle = null; + }, + hasFill: function() { var color = this.getFillColor(); return !!color && color.alpha > 0; @@ -12101,8 +12777,14 @@ var DomEvent = { for (var type in events) { var func = events[type], parts = type.split(/[\s,]+/g); - for (var i = 0, l = parts.length; i < l; i++) - el.addEventListener(parts[i], func, false); + for (var i = 0, l = parts.length; i < l; i++) { + var name = parts[i]; + var options = ( + el === document + && (name === 'touchstart' || name === 'touchmove') + ) ? { passive: false } : false; + el.addEventListener(name, func, options); + } } } }, @@ -12193,7 +12875,7 @@ var View = Base.extend(Emitter, { if (window && element) { this._id = element.getAttribute('id'); if (this._id == null) - element.setAttribute('id', this._id = 'view-' + View._id++); + element.setAttribute('id', this._id = 'paper-view-' + View._id++); DomEvent.add(element, this._viewEvents); var none = 'none'; DomElement.setPrefixed(element.style, { @@ -12379,7 +13061,7 @@ var View = Base.extend(Emitter, { }, _changed: function() { - this._project._changed(2049); + this._project._changed(4097); this._bounds = this._decomposed = undefined; }, @@ -12465,8 +13147,9 @@ var View = Base.extend(Emitter, { }, Base.each(['rotate', 'scale', 'shear', 'skew'], function(key) { var rotate = key === 'rotate'; this[key] = function() { - var value = (rotate ? Base : Point).read(arguments), - center = Point.read(arguments, 0, { readNull: true }); + var args = arguments, + value = (rotate ? Base : Point).read(args), + center = Point.read(args, 0, { readNull: true }); return this.transform(new Matrix()[key](value, center || this.getCenter(true))); }; @@ -12490,9 +13173,8 @@ var View = Base.extend(Emitter, { }, getZoom: function() { - var decomposed = this._decompose(), - scaling = decomposed && decomposed.scaling; - return scaling ? (scaling.x + scaling.y) / 2 : 0; + var scaling = this._decompose().scaling; + return (scaling.x + scaling.y) / 2; }, setZoom: function(zoom) { @@ -12501,8 +13183,7 @@ var View = Base.extend(Emitter, { }, getRotation: function() { - var decomposed = this._decompose(); - return decomposed && decomposed.rotation; + return this._decompose().rotation; }, setRotation: function(rotation) { @@ -12513,11 +13194,8 @@ var View = Base.extend(Emitter, { }, getScaling: function() { - var decomposed = this._decompose(), - scaling = decomposed && decomposed.scaling; - return scaling - ? new LinkedPoint(scaling.x, scaling.y, this, 'setScaling') - : undefined; + var scaling = this._decompose().scaling; + return new LinkedPoint(scaling.x, scaling.y, this, 'setScaling'); }, setScaling: function() { @@ -12747,8 +13425,8 @@ new function() { point, prevPoint) || hitItem && hitItem !== dragItem && !hitItem.isDescendant(dragItem) - && emitMouseEvent(hitItem, null, type, event, point, prevPoint, - dragItem) + && emitMouseEvent(hitItem, null, type === 'mousedrag' ? + 'mousemove' : type, event, point, prevPoint, dragItem) || emitMouseEvent(view, dragItem || hitItem || view, type, event, point, prevPoint)); } @@ -12858,8 +13536,12 @@ new function() { || called; } - if (called && !mouse.move || mouse.down && responds('mouseup')) + if ( + event.cancelable !== false + && (called && !mouse.move || mouse.down && responds('mouseup')) + ) { event.preventDefault(); + } }, _handleKeyEvent: function(type, event, key, character) { @@ -12894,7 +13576,14 @@ new function() { }, statics: { - updateFocus: updateFocus + updateFocus: updateFocus, + + _resetState: function() { + dragging = mouseDown = called = wasInView = false; + prevFocus = tempFocus = overView = downPoint = lastPoint = + downItem = overItem = dragItem = clickItem = clickTime = + dblClick = null; + } } }; }); @@ -12946,6 +13635,10 @@ var CanvasView = View.extend({ } }, + getContext: function() { + return this._context; + }, + getPixelSize: function getPixelSize(size) { var agent = paper.agent, pixels; @@ -13362,7 +14055,7 @@ var Tool = PaperScopeItem.extend({ var pt = point, toolPoint = move ? tool._point : (tool._downPoint || pt); if (move) { - if (tool._moveCount && pt.equals(toolPoint)) { + if (tool._moveCount >= 0 && pt.equals(toolPoint)) { return false; } if (toolPoint && (minDistance != null || maxDistance != null)) { @@ -13409,6 +14102,245 @@ var Tool = PaperScopeItem.extend({ }); +var Tween = Base.extend(Emitter, { + _class: 'Tween', + + statics: { + easings: { + linear: function(t) { + return t; + }, + + easeInQuad: function(t) { + return t * t; + }, + + easeOutQuad: function(t) { + return t * (2 - t); + }, + + easeInOutQuad: function(t) { + return t < 0.5 + ? 2 * t * t + : -1 + 2 * (2 - t) * t; + }, + + easeInCubic: function(t) { + return t * t * t; + }, + + easeOutCubic: function(t) { + return --t * t * t + 1; + }, + + easeInOutCubic: function(t) { + return t < 0.5 + ? 4 * t * t * t + : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; + }, + + easeInQuart: function(t) { + return t * t * t * t; + }, + + easeOutQuart: function(t) { + return 1 - (--t) * t * t * t; + }, + + easeInOutQuart: function(t) { + return t < 0.5 + ? 8 * t * t * t * t + : 1 - 8 * (--t) * t * t * t; + }, + + easeInQuint: function(t) { + return t * t * t * t * t; + }, + + easeOutQuint: function(t) { + return 1 + --t * t * t * t * t; + }, + + easeInOutQuint: function(t) { + return t < 0.5 + ? 16 * t * t * t * t * t + : 1 + 16 * (--t) * t * t * t * t; + } + } + }, + + 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(); + } + }, + + then: function(then) { + this._then = then; + return this; + }, + + start: function() { + this._startTime = null; + this.running = true; + return this; + }, + + stop: function() { + this.running = false; + return this; + }, + + update: function(progress) { + if (this.running) { + if (progress > 1) { + 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]), + 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) { + this._then(this.object); + } + if (this.responds('update')) { + this.emit('update', new Base({ + progress: progress, + factor: factor + })); + } + } + return this; + }, + + _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]); + this._setProperty(path, resolved); + value = this._getProperty(path); + value = value && value.clone ? value.clone() : value; + this._setProperty(path, current); + } else { + 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 && + 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 + .replace(/\.([^.]*)/g, '/$1') + .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; + } + } +}); + var Http = { request: function(options) { var xhr = new self.XMLHttpRequest(); @@ -13841,11 +14773,16 @@ new function() { var attrs = new Base(), trans = matrix.getTranslation(); if (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()) { var decomposed = matrix.decompose(); @@ -13986,7 +14923,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) @@ -14003,7 +14940,7 @@ new function() { return SvgElement.create('use', attrs, formatter); } - function exportGradient(color) { + function exportGradient(color, item) { var gradientNode = getDefinition(color, 'color'); if (!gradientNode) { var gradient = color.getGradient(), @@ -14030,6 +14967,11 @@ new function() { y2: destination.y }; } + if (item instanceof paper.PointText) { + attrs.gradientTransform = getTransform( + item._matrix.clone().invert(), false, formatter).transform; + } + attrs.gradientUnits = 'userSpaceOnUse'; gradientNode = SvgElement.create((radial ? 'radial' : 'linear') + 'Gradient', attrs, formatter); @@ -14055,9 +14997,18 @@ new function() { } function exportText(item) { - var node = SvgElement.create('text', getTransform(item._matrix, true), + var node = SvgElement.create('text', getTransform(item._matrix, false), formatter); - node.textContent = item._content; + node.setAttribute('font-size', item.fontSize); + node.setAttribute('xml:space', 'preserve'); + for (var i = 0; i < item._lines.length; i++) { + var tspanNode = SvgElement.create('tspan', { + x: '0', + dy: i === 0 ? '0' : item.getLeading() + 'px' + }, formatter); + tspanNode.textContent = item._lines[i] ? item._lines[i] : ' '; + node.appendChild(tspanNode); + } return node; } @@ -14084,9 +15035,13 @@ new function() { var get = entry.get, type = entry.type, value = item[get](); + + if (value === undefined) return; + if (entry.exportFilter ? entry.exportFilter(item, value) - : !parent || !Base.equals(parent[get](), value)) { + : !parent || !Base.equals(parent[get](), value) || + item instanceof paper.PointText) { if (type === 'color' && value != null) { var alpha = value.getAlpha(); if (alpha < 1) @@ -14196,7 +15151,7 @@ new function() { rect = bounds === 'view' ? new Rectangle([0, 0], view.getViewSize()) : bounds === 'content' - ? Item._getBounds(children, matrix, { stroke: true }) + ? Item._getBounds(children, matrix, { stroke: true, drawnTextBounds: true }) .rect : Rectangle.read([bounds], 0, { readNull: true }), attrs = { @@ -14207,7 +15162,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), @@ -14229,8 +15184,9 @@ new function() { var definitions = {}, rootSize; - function getValue(node, name, isString, allowNull, allowPercent) { - var value = SvgElement.get(node, name), + function getValue(node, name, isString, allowNull, allowPercent, + defaultValue) { + var value = SvgElement.get(node, name) || defaultValue, res = value == null ? allowNull ? null @@ -14244,9 +15200,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); } @@ -14348,13 +15304,16 @@ new function() { scaleToBounds = getValue(node, 'gradientUnits', true) !== 'userSpaceOnUse'; 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); @@ -14385,9 +15344,8 @@ new function() { raster.on('load', function() { var size = getSize(node); this.setSize(size); - var center = this._matrix._transformPoint( - getPoint(node).add(size.divide(2))); - this.translate(center); + var center = getPoint(node).add(size.divide(2)); + this._matrix.append(new Matrix().translate(center)); }); return raster; }, @@ -14437,11 +15395,47 @@ new function() { }, text: function(node) { - var text = new PointText(getPoint(node).add( - getPoint(node, 'dx', 'dy'))); - text.setContent(node.textContent.trim() || ''); - return text; - } + + var fontSize = parseFloat(node.getAttribute("font-size")); + var alignmentBaseline = node.getAttribute("alignment-baseline"); + if (node.childElementCount === 0) { + var text = new PointText(); + text.setContent(node.textContent.trim() || ''); + text.translate(0, text._style.getLeading()); + if (!isNaN(fontSize)) text.setFontSize(fontSize); + return text; + } else { + var lines = []; + var spacing = 1.2; + for (var i = 0; i < node.childNodes.length; i++) { + var child = node.childNodes[i]; + if (!child.getAttribute) continue; + lines.push(child.textContent); + var dyString = child.getAttribute('dy'); + if (dyString) { + var dy = parseFloat(dyString); + if (!isNaN(dy)) { + if (dyString.endsWith('em')) { + spacing = dy; + } else if (dyString.endsWith('px') && !isNaN(fontSize)) { + spacing = dy / fontSize; + } + } + } + } + var text = new PointText(); + if (!isNaN(fontSize)) text.setFontSize(fontSize); + text.setLeading(text.fontSize * spacing); + if (alignmentBaseline === 'text-before-edge') { + text.setContent(' '); + text.translate(0, text.bounds.height); + } + text.setContent(lines.join('\n')); + return text; + } + }, + + switch: importGroup }; function applyTransform(item, value, name, node) { @@ -14463,10 +15457,10 @@ new function() { new Matrix(v[0], v[1], v[2], v[3], v[4], v[5])); break; case 'rotate': - matrix.rotate(v[0], v[1], v[2]); + matrix.rotate(v[0], v[1] || 0, v[2] || 0); break; case 'translate': - matrix.translate(v[0], v[1]); + matrix.translate(v[0], v[1] || 0); break; case 'scale': matrix.scale(v); @@ -14510,8 +15504,6 @@ new function() { }, {}), { id: function(item, value) { definitions[value] = item; - if (item.setName) - item.setName(value); }, 'clip-path': function(item, value) { @@ -14584,13 +15576,17 @@ new function() { if (matrix) group.transform(matrix); } + }, + + 'fill-rule': function(item, value) { + if (value === 'evenodd' || value === 'nonzero') item.fillRule = value; } }); function getAttribute(node, name, styles) { var attr = node.attributes[name], value = attr && attr.value; - if (!value) { + if (!value && node.style) { var style = Base.camelize(name); value = node.style[style]; if (!value && styles.node[style] !== styles.parent[style]) @@ -14602,19 +15598,17 @@ new function() { } function applyAttributes(item, node, isRoot) { - if (node.style) { - var parent = node.parentNode, - styles = { - node: DomElement.getStyles(node) || {}, - parent: !isRoot && !/^defs$/i.test(parent.tagName) - && DomElement.getStyles(parent) || {} - }; - Base.each(attributes, function(apply, name) { - var value = getAttribute(node, name, styles); - item = value !== undefined - && apply(item, value, name, node, styles) || item; - }); - } + var parent = node.parentNode, + styles = { + node: DomElement.getStyles(node) || {}, + parent: !isRoot && !/^defs$/i.test(parent.tagName) + && DomElement.getStyles(parent) || {} + }; + Base.each(attributes, function(apply, name) { + var value = getAttribute(node, name, styles); + item = value !== undefined + && apply(item, value, name, node, styles) || item; + }); return item; } @@ -14700,8 +15694,12 @@ new function() { function onLoad(svg) { try { - var node = typeof svg === 'object' ? svg : new self.DOMParser() - .parseFromString(svg, 'image/svg+xml'); + var node = typeof svg === 'object' + ? svg + : new self.DOMParser().parseFromString( + svg, + 'image/svg+xml' + ); if (!node.nodeName) { node = null; throw new Error('Unsupported SVG source: ' + source); @@ -14728,7 +15726,7 @@ new function() { } } - if (typeof source === 'string' && !/^.*= 30 || agent.webkit && version >= 537.76 @@ -16321,7 +17370,16 @@ Base.exports.PaperScript = function() { sourcesContent: [source] }; } - walkAST(parse(code, { ranges: true, preserveParens: true })); + if ( + paperFeatures.operatorOverloading !== false || + paperFeatures.moduleExports !== false + ) { + walkAST(parse(code, { + ranges: true, + preserveParens: true, + sourceType: 'module' + }), null, paperFeatures); + } if (map) { if (offsetCode) { code = new Array(offset + 1).join('\n') + code; @@ -16363,17 +17421,20 @@ Base.exports.PaperScript = function() { } } } - expose({ __$__: __$__, $__: $__, paper: scope, view: view, tool: tool }, + expose({ __$__: __$__, $__: $__, paper: scope, tool: tool }, true); expose(scope); - handlers = Base.each(handlers, function(key) { + code = 'var module = { exports: {} }; ' + code; + var exports = Base.each(handlers, function(key) { if (new RegExp('\\s+' + key + '\\b').test(code)) { params.push(key); - this.push(key + ': ' + key); + this.push('module.exports.' + key + ' = ' + key + ';'); } - }, []).join(', '); - if (handlers) - code += '\nreturn { ' + handlers + ' };'; + }, []).join('\n'); + if (exports) { + code += '\n' + exports; + } + code += '\nreturn module.exports;'; var agent = paper.agent; if (document && (agent.chrome || agent.firefox && agent.versionNumber < 40)) { @@ -16382,33 +17443,36 @@ Base.exports.PaperScript = function() { if (agent.firefox) code = '\n' + code; script.appendChild(document.createTextNode( - 'paper._execute = function(' + params + ') {' + code + '\n}' + 'document.__paperscript__ = function(' + params + ') {' + + code + + '\n}' )); head.appendChild(script); - func = paper._execute; - delete paper._execute; + func = document.__paperscript__; + delete document.__paperscript__; head.removeChild(script); } else { func = Function(params, code); } - var res = func.apply(scope, args) || {}; + var exports = func && func.apply(scope, args); + var obj = exports || {}; Base.each(toolHandlers, function(key) { - var value = res[key]; + var value = obj[key]; if (value) tool[key] = value; }); if (view) { - if (res.onResize) - view.setOnResize(res.onResize); + if (obj.onResize) + view.setOnResize(obj.onResize); view.emit('resize', { size: view.size, delta: new Point() }); - if (res.onFrame) - view.setOnFrame(res.onFrame); + if (obj.onFrame) + view.setOnFrame(obj.onFrame); view.requestUpdate(); } - return compiled; + return exports; } function loadScript(script) { @@ -16463,12 +17527,14 @@ Base.exports.PaperScript = function() { compile: compile, execute: execute, load: load, - parse: parse + parse: parse, + calculateBinary: __$__, + calculateUnary: $__ }; }.call(this); -paper = new (PaperScope.inject(Base.exports, { +var paper = new (PaperScope.inject(Base.exports, { Base: Base, Numerical: Numerical, Key: Key, diff --git a/dist/docs/classes/Color.html b/dist/docs/classes/Color.html index 2ade8800..4137454a 100644 --- a/dist/docs/classes/Color.html +++ b/dist/docs/classes/Color.html @@ -340,6 +340,65 @@ var path = new Path.Rectangle({ +
+ + +
+ +
- -
+
@@ -437,7 +496,7 @@ path.fillColor = gradientColor;
Run
- -
+
@@ -907,7 +966,7 @@ console.log(color.type); // 'rgb'

    Type:

  • - Array of Numbers + Array of Numbers
@@ -930,6 +989,11 @@ console.log(color.type); // 'rgb' +
    +

    Default:

    +
  • 1
  • +
+

    Type:

  • @@ -946,7 +1010,7 @@ console.log(color.type); // 'rgb'
    Run
    - -
    +
    @@ -998,14 +1062,14 @@ circle.strokeColor.alpha = 0.5;
    Run
    - -
    +
    @@ -1042,7 +1106,7 @@ circle.fillColor.red = 1;
    Run
    - -
    +
    @@ -1088,7 +1152,7 @@ circle.fillColor.green = 1;
    Run
    - -
    +
    @@ -1164,12 +1228,12 @@ circle.fillColor.blue = 1;
    Run
    - -
    +
    @@ -1181,7 +1245,7 @@ circle.fillColor.hue += 30;
    Run
    - -
    +
    @@ -1337,7 +1401,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -1378,16 +1442,38 @@ function onMouseMove(event) {

    Methods

    -
    +
    - -
    +
    @@ -813,6 +882,11 @@ circle2.opacity = 0.5; +
      +

      Default:

      +
    • false
    • +
    +

      Type:

    • @@ -842,14 +916,14 @@ circle2.opacity = 0.5;
      Run
    - -
    +
    @@ -866,10 +940,15 @@ path.selected = true; // Select the path @@ -1001,7 +1080,7 @@ circle.position += new Point(100, 50);
    Run
    - -
    +
    @@ -1033,6 +1112,11 @@ circle.position.x += 100; +
      +

      Default:

      +
    • null
    • +
    +

      Type:

    • @@ -1120,6 +1204,33 @@ circle.position.x += 100; + + + + + + +
      + + @@ -1271,6 +1382,11 @@ circle.position.x += 100; +
        +

        Default:

        +
      • true
      • +
      +

        Type:

      • @@ -1282,16 +1398,6 @@ circle.position.x += 100;
      - - - - -
      - -
      @@ -1481,7 +1587,7 @@ console.log(group.children[0] == path); // true
      Run
      - -
      +
      @@ -1506,7 +1612,7 @@ group.children[0].fillColor = 'red';
      Run
      - -
      +
      @@ -1533,7 +1639,7 @@ group.children['example'].fillColor = 'orange';
      Run
      - -
      +
      @@ -1711,7 +1817,7 @@ group.firstChild.fillColor = 'green'; @@ -1724,7 +1830,7 @@ group.firstChild.fillColor = 'green';
      Run
      - -
      +
      @@ -1772,7 +1878,7 @@ circle.strokeColor = new Color(1, 0, 0);
      Run
      - -
      +
      @@ -1831,7 +1937,7 @@ circle.strokeWidth = 10;
      Run
      - -
      +
      @@ -1899,7 +2005,7 @@ line2.strokeCap = 'butt';
      Run
      - -
      +
      @@ -2007,7 +2113,7 @@ path3.strokeJoin = 'bevel';

        Type:

      • - Array + Array of Numbers
      @@ -2020,7 +2126,7 @@ path3.strokeJoin = 'bevel';
      Run
      - -
      +
      @@ -2088,7 +2194,7 @@ path.dashArray = [10, 4]; @@ -2101,7 +2207,7 @@ path.dashArray = [10, 4];
      Run
      - -
      +
      @@ -2174,7 +2280,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -2187,7 +2293,7 @@ circle.fillColor = new Color(1, 0, 0);
      Run
      - -
      +
      @@ -2288,7 +2394,7 @@ var circle = new Path.Circle({ @@ -2316,7 +2422,7 @@ var circle = new Path.Circle({

        Type:

      • - Function + Functionnull
        @@ -2341,7 +2447,7 @@ var circle = new Path.Circle({
        Run
        - -
        +
        @@ -2376,7 +2482,7 @@ path.onFrame = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2396,7 +2502,7 @@ path.onFrame = function(event) {
        Run
        - -
        +
        @@ -2422,7 +2528,7 @@ path.onMouseDown = function(event) {
        Run
        - -
        +
        @@ -2464,7 +2570,7 @@ for (var i = 0; i < 30; i++) {

          Type:

        • - Function + Functionnull
        @@ -2484,7 +2590,7 @@ for (var i = 0; i < 30; i++) {
        Run
        - -
        +
        @@ -2521,7 +2627,7 @@ path.onMouseDrag = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2541,7 +2647,7 @@ path.onMouseDrag = function(event) {
        Run
        - -
        +
        @@ -2579,7 +2685,7 @@ path.onMouseUp = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2599,7 +2705,7 @@ path.onMouseUp = function(event) {
        Run
        - -
        +
        @@ -2625,7 +2731,7 @@ path.onClick = function(event) {
        Run
        - -
        +
        @@ -2667,7 +2773,7 @@ for (var i = 0; i < 30; i++) {

          Type:

        • - Function + Functionnull
        @@ -2687,7 +2793,7 @@ for (var i = 0; i < 30; i++) {
        Run
        - -
        +
        @@ -2713,7 +2819,7 @@ path.onDoubleClick = function(event) {
        Run
        - -
        +
        @@ -2755,7 +2861,7 @@ for (var i = 0; i < 30; i++) {

          Type:

        • - Function + Functionnull
        @@ -2775,7 +2881,7 @@ for (var i = 0; i < 30; i++) {
        Run
        - -
        +
        @@ -2813,7 +2919,7 @@ path.onMouseMove = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2833,7 +2939,7 @@ path.onMouseMove = function(event) {
        Run
        - -
        +
        @@ -2863,7 +2969,7 @@ path.onMouseLeave = function(event) {
        Run
        - -
        +
        @@ -2909,7 +3015,7 @@ function onMouseDown(event) {

          Type:

        • - Function + Functionnull
        @@ -2929,7 +3035,7 @@ function onMouseDown(event) {
        Run
        - -
        +
        @@ -3001,7 +3107,7 @@ path.onMouseLeave = function(event) {
        Run
        - -
        +
        @@ -3070,7 +3176,7 @@ circle.set({
        Run
        - -
        +
        @@ -3165,7 +3271,7 @@ for (var i = 0; i < 20; i++) {
      @@ -3213,7 +3326,7 @@ for (var i = 0; i < 20; i++) {
      Run
      - -
      +
      @@ -3263,6 +3376,16 @@ raster.scale(5);
    +
      +

      Returns:

      + +
    • +Boolean +
    • + + +
    + @@ -3274,7 +3397,7 @@ raster.scale(5);
    Run
    - -
    +
    @@ -3412,6 +3535,8 @@ function onMouseDown(event) {
  • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
  • options.guides: Boolean — hit-test items that have Item#guide set to true
  • options.selected: Boolean — only hit selected items
  • +
  • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
  • +
  • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
    @@ -3420,7 +3545,7 @@ function onMouseDown(event) {
  • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
  • @@ -3469,7 +3594,7 @@ function onMouseDown(event) {
  • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
  • @@ -3788,6 +3913,16 @@ function onMouseDown(event) {
+
    +

    Returns:

    + +
  • +Item +
  • + + +
+ @@ -3831,7 +3966,7 @@ function onMouseDown(event) {

Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -4244,150 +4379,6 @@ Array of Item objects - - - - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    @@ -4559,8 +4550,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -4686,19 +4677,31 @@ Array of Item objects
    @@ -5292,7 +5295,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -5363,7 +5366,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -5387,7 +5390,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -5455,7 +5458,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -5491,7 +5494,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -5588,7 +5591,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -5905,7 +5908,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -5938,7 +5941,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -5971,7 +5974,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -6042,7 +6045,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -6112,7 +6115,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -6142,7 +6145,7 @@ path.on({
    Run
    - -
    +
    @@ -6393,7 +6396,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6440,7 +6443,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -6484,7 +6487,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -6528,7 +6531,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6572,7 +6575,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + - -
    +
    @@ -7305,7 +7713,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -7401,7 +7809,7 @@ copy.flatten(4);
    Run
    - -
    +
    @@ -7432,7 +7840,7 @@ copy.smooth({ type: 'continuous' });
    Run
    - -
    +
    @@ -7469,7 +7877,7 @@ copy.smooth({ type: 'catmull-rom', factor: 0.5 });
    Run
    - -
    +
    @@ -7552,7 +7960,7 @@ paths[4].smooth({ type: 'continuous', from: -1, to: 1 });
    Run
    - -
    +
    @@ -7781,7 +8189,7 @@ function onMouseUp(event) {
    Run
    - -
    +
    @@ -7813,7 +8221,7 @@ circle.fillColor = 'red';
    Run
    - -
    +
    @@ -7890,7 +8298,7 @@ function onMouseUp(event) {
    Run
    - -
    +
    @@ -7917,7 +8325,7 @@ path2.arcTo(new Point(280, 25), false);
    Run
    - -
    +
    @@ -7994,7 +8402,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -8200,7 +8608,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -8226,7 +8634,7 @@ path.lineBy(0, 50);
    Run
    - -
    +
    @@ -8471,8 +8879,8 @@ path.smooth(); +Paper.js v0.12.7
    +Copyright © 2011—2023 Jürg Lehni & Jonathan Puckey. All Rights Reserved.

    diff --git a/dist/docs/classes/Curve.html b/dist/docs/classes/Curve.html index dede5098..646ca52c 100644 --- a/dist/docs/classes/Curve.html +++ b/dist/docs/classes/Curve.html @@ -460,7 +460,7 @@

      Type:

    • - Array of Numbers + Array of Numbers
    @@ -727,7 +727,7 @@
    • info.type: String — the type of Bézier curve, possible values are: ‘line’, ‘quadratic’, ‘serpentine’, ‘cusp’, ‘loop’, ‘arch’
    • -
    • info.roots: Array of Numbers — the curve-time parameters of the associated points of inflection for serpentine curves, loops, cusps, etc
    • +
    • info.roots: Array of Numbers — the curve-time parameters of the associated points of inflection for serpentine curves, loops, cusps, etc
    @@ -1481,6 +1481,47 @@ + + + + + +
    + +
    @@ -2273,8 +2314,8 @@ +Paper.js v0.12.7
    +Copyright © 2011—2023 Jürg Lehni & Jonathan Puckey. All Rights Reserved.

    diff --git a/dist/docs/classes/CurveLocation.html b/dist/docs/classes/CurveLocation.html index d592b595..eb3fc245 100644 --- a/dist/docs/classes/CurveLocation.html +++ b/dist/docs/classes/CurveLocation.html @@ -162,7 +162,7 @@ @@ -190,7 +190,7 @@

      Type:

    • - Index + Number
    @@ -452,7 +452,7 @@
  • curve.getNearestLocation(point)
  • -
  • Path#getNearestLocation(point)
  • +
  • pathItem.getNearestLocation(point)
  • @@ -663,8 +663,8 @@ +Paper.js v0.12.7
    +Copyright © 2011—2023 Jürg Lehni & Jonathan Puckey. All Rights Reserved.

    diff --git a/dist/docs/classes/Event.html b/dist/docs/classes/Event.html index 7cf469ce..57603a28 100644 --- a/dist/docs/classes/Event.html +++ b/dist/docs/classes/Event.html @@ -167,8 +167,8 @@ +Paper.js v0.12.7
    +Copyright © 2011—2023 Jürg Lehni & Jonathan Puckey. All Rights Reserved.

    diff --git a/dist/docs/classes/Gradient.html b/dist/docs/classes/Gradient.html index 921208d9..cd10fc86 100644 --- a/dist/docs/classes/Gradient.html +++ b/dist/docs/classes/Gradient.html @@ -231,8 +231,8 @@ path.fillColor = { +Paper.js v0.12.7
    +Copyright © 2011—2023 Jürg Lehni & Jonathan Puckey. All Rights Reserved.

    diff --git a/dist/docs/classes/GradientStop.html b/dist/docs/classes/GradientStop.html index 54e5d8d0..48eff73c 100644 --- a/dist/docs/classes/GradientStop.html +++ b/dist/docs/classes/GradientStop.html @@ -264,8 +264,8 @@ function onFrame(event) { +Paper.js v0.12.7
    +Copyright © 2011—2023 Jürg Lehni & Jonathan Puckey. All Rights Reserved.

    diff --git a/dist/docs/classes/Group.html b/dist/docs/classes/Group.html index 707bc276..be8eec7b 100644 --- a/dist/docs/classes/Group.html +++ b/dist/docs/classes/Group.html @@ -488,6 +488,75 @@ path2.style = myStyle; +
    + + +
    + +
    - -
    +
    @@ -553,7 +622,7 @@ path.visible = false;

      Values:

    • 'normal', 'multiply', 'screen', 'overlay', 'soft-light', 'hard- - light', 'color-dodge', 'color-burn', 'darken', 'lighten', 'difference', 'exclusion', 'hue', 'saturation', 'luminosity', 'color', 'add', 'subtract', 'average', 'pin-light', 'negation', 'source- over', 'source-in', 'source-out', 'source-atop', 'destination-over', 'destination-in', 'destination-out', 'destination-atop', 'lighter', 'darker', 'copy', 'xor'
    • + light', 'color-dodge', 'color-burn', 'darken', 'lighten', 'difference', 'exclusion', 'hue', 'saturation', 'luminosity', 'color', 'add', 'subtract', 'average', 'pin-light', 'negation', 'source-over', 'source-in', 'source-out', 'source-atop', 'destination-over', 'destination-in', 'destination-out', 'destination-atop', 'lighter', 'darker', 'copy', 'xor'
    @@ -578,7 +647,7 @@ path.visible = false;
    Run
    - -
    +
    @@ -641,7 +710,7 @@ circle2.blendMode = 'multiply';
    Run
    - -
    +
    @@ -681,6 +750,11 @@ circle2.opacity = 0.5; +
      +

      Default:

      +
    • false
    • +
    +

      Type:

    • @@ -710,14 +784,14 @@ circle2.opacity = 0.5;
      Run
      - -
      +
      @@ -734,10 +808,15 @@ path.selected = true; // Select the path @@ -869,7 +948,7 @@ circle.position += new Point(100, 50);
      Run
      - -
      +
      @@ -901,6 +980,11 @@ circle.position.x += 100; +
        +

        Default:

        +
      • null
      • +
      +

        Type:

      • @@ -988,6 +1072,33 @@ circle.position.x += 100; + + + + + + +
        + + @@ -1139,6 +1250,11 @@ circle.position.x += 100; +
          +

          Default:

          +
        • true
        • +
        +

          Type:

        • @@ -1150,16 +1266,6 @@ circle.position.x += 100;
        - - - - -
        - -
        @@ -1349,7 +1455,7 @@ console.log(group.children[0] == path); // true
        Run
        - -
        +
        @@ -1374,7 +1480,7 @@ group.children[0].fillColor = 'red';
        Run
        - -
        +
        @@ -1401,7 +1507,7 @@ group.children['example'].fillColor = 'orange';
        Run
        - -
        +
        @@ -1579,7 +1685,7 @@ group.firstChild.fillColor = 'green'; @@ -1592,7 +1698,7 @@ group.firstChild.fillColor = 'green';
        Run
        - -
        +
        @@ -1640,7 +1746,7 @@ circle.strokeColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -1699,7 +1805,7 @@ circle.strokeWidth = 10;
        Run
        - -
        +
        @@ -1767,7 +1873,7 @@ line2.strokeCap = 'butt';
        Run
        - -
        +
        @@ -1875,7 +1981,7 @@ path3.strokeJoin = 'bevel';

          Type:

        • - Array + Array of Numbers
        @@ -1888,7 +1994,7 @@ path3.strokeJoin = 'bevel';
        Run
        - -
        +
        @@ -1956,7 +2062,7 @@ path.dashArray = [10, 4]; @@ -1969,7 +2075,7 @@ path.dashArray = [10, 4];
        Run
        - -
        +
        @@ -2042,7 +2148,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -2055,7 +2161,7 @@ circle.fillColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -2156,7 +2262,7 @@ var circle = new Path.Circle({ @@ -2184,7 +2290,7 @@ var circle = new Path.Circle({

          Type:

        • - Function + Functionnull
          @@ -2209,7 +2315,7 @@ var circle = new Path.Circle({
          Run
          - -
          +
          @@ -2244,7 +2350,7 @@ path.onFrame = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2264,7 +2370,7 @@ path.onFrame = function(event) {
          Run
          - -
          +
          @@ -2290,7 +2396,7 @@ path.onMouseDown = function(event) {
          Run
          - -
          +
          @@ -2332,7 +2438,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2352,7 +2458,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2389,7 +2495,7 @@ path.onMouseDrag = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2409,7 +2515,7 @@ path.onMouseDrag = function(event) {
          Run
          - -
          +
          @@ -2447,7 +2553,7 @@ path.onMouseUp = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2467,7 +2573,7 @@ path.onMouseUp = function(event) {
          Run
          - -
          +
          @@ -2493,7 +2599,7 @@ path.onClick = function(event) {
          Run
          - -
          +
          @@ -2535,7 +2641,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2555,7 +2661,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2581,7 +2687,7 @@ path.onDoubleClick = function(event) {
          Run
          - -
          +
          @@ -2623,7 +2729,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2643,7 +2749,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2681,7 +2787,7 @@ path.onMouseMove = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2701,7 +2807,7 @@ path.onMouseMove = function(event) {
          Run
          - -
          +
          @@ -2731,7 +2837,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -2777,7 +2883,7 @@ function onMouseDown(event) {

            Type:

          • - Function + Functionnull
          @@ -2797,7 +2903,7 @@ function onMouseDown(event) {
          Run
          - -
          +
          @@ -2869,7 +2975,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -2938,7 +3044,7 @@ circle.set({
          Run
          - -
          +
          @@ -3033,7 +3139,7 @@ for (var i = 0; i < 20; i++) {
        @@ -3081,7 +3194,7 @@ for (var i = 0; i < 20; i++) {
        Run
        - -
        +
        @@ -3131,6 +3244,16 @@ raster.scale(5);
      +
        +

        Returns:

        + +
      • +Boolean +
      • + + +
      + @@ -3142,7 +3265,7 @@ raster.scale(5);
      Run
      - -
      +
      @@ -3280,6 +3403,8 @@ function onMouseDown(event) {
    • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
    • options.guides: Boolean — hit-test items that have Item#guide set to true
    • options.selected: Boolean — only hit selected items
    • +
    • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
    • +
    • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
      @@ -3288,7 +3413,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3337,7 +3462,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3656,6 +3781,16 @@ function onMouseDown(event) {
    +
      +

      Returns:

      + +
    • +Item +
    • + + +
    + @@ -3699,7 +3834,7 @@ function onMouseDown(event) {

    Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -4112,150 +4247,6 @@ Array of Item objects - - - - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    @@ -4427,8 +4418,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -4554,19 +4545,31 @@ Array of Item objects
    @@ -5160,7 +5163,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -5231,7 +5234,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -5255,7 +5258,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -5323,7 +5326,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -5359,7 +5362,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -5456,7 +5459,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -5773,7 +5776,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -5806,7 +5809,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -5839,7 +5842,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -5910,7 +5913,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -5980,7 +5983,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -6010,7 +6013,7 @@ path.on({
    Run
    - -
    +
    @@ -6261,7 +6264,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6308,7 +6311,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -6352,7 +6355,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -6396,7 +6399,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6440,7 +6443,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + - -
    +
    @@ -398,7 +467,7 @@ circle2.blendMode = 'multiply';
    Run
    - -
    +
    @@ -438,6 +507,11 @@ circle2.opacity = 0.5; +
      +

      Default:

      +
    • false
    • +
    +

      Type:

    • @@ -467,14 +541,14 @@ circle2.opacity = 0.5;
      Run
      - -
      +
      @@ -491,10 +565,15 @@ path.selected = true; // Select the path @@ -626,7 +705,7 @@ circle.position += new Point(100, 50);
      Run
      - -
      +
      @@ -658,6 +737,11 @@ circle.position.x += 100; +
        +

        Default:

        +
      • null
      • +
      +

        Type:

      • @@ -745,6 +829,33 @@ circle.position.x += 100; + + + + + + +
        + + @@ -896,6 +1007,11 @@ circle.position.x += 100; +
          +

          Default:

          +
        • true
        • +
        +

          Type:

        • @@ -1096,7 +1212,7 @@ console.log(group.children[0] == path); // true
          Run
        - -
        +
        @@ -1121,7 +1237,7 @@ group.children[0].fillColor = 'red';
        Run
        - -
        +
        @@ -1148,7 +1264,7 @@ group.children['example'].fillColor = 'orange';
        Run
        - -
        +
        @@ -1326,7 +1442,7 @@ group.firstChild.fillColor = 'green'; @@ -1339,7 +1455,7 @@ group.firstChild.fillColor = 'green';
        Run
        - -
        +
        @@ -1387,7 +1503,7 @@ circle.strokeColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -1446,7 +1562,7 @@ circle.strokeWidth = 10;
        Run
        - -
        +
        @@ -1514,7 +1630,7 @@ line2.strokeCap = 'butt';
        Run
        - -
        +
        @@ -1622,7 +1738,7 @@ path3.strokeJoin = 'bevel';

          Type:

        • - Array + Array of Numbers
        @@ -1635,7 +1751,7 @@ path3.strokeJoin = 'bevel';
        Run
        - -
        +
        @@ -1703,7 +1819,7 @@ path.dashArray = [10, 4]; @@ -1716,7 +1832,7 @@ path.dashArray = [10, 4];
        Run
        - -
        +
        @@ -1789,7 +1905,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -1802,7 +1918,7 @@ circle.fillColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -1903,7 +2019,7 @@ var circle = new Path.Circle({ @@ -1931,7 +2047,7 @@ var circle = new Path.Circle({

          Type:

        • - Function + Functionnull
          @@ -1956,7 +2072,7 @@ var circle = new Path.Circle({
          Run
          - -
          +
          @@ -1991,7 +2107,7 @@ path.onFrame = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2011,7 +2127,7 @@ path.onFrame = function(event) {
          Run
          - -
          +
          @@ -2037,7 +2153,7 @@ path.onMouseDown = function(event) {
          Run
          - -
          +
          @@ -2079,7 +2195,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2099,7 +2215,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2136,7 +2252,7 @@ path.onMouseDrag = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2156,7 +2272,7 @@ path.onMouseDrag = function(event) {
          Run
          - -
          +
          @@ -2194,7 +2310,7 @@ path.onMouseUp = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2214,7 +2330,7 @@ path.onMouseUp = function(event) {
          Run
          - -
          +
          @@ -2240,7 +2356,7 @@ path.onClick = function(event) {
          Run
          - -
          +
          @@ -2282,7 +2398,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2302,7 +2418,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2328,7 +2444,7 @@ path.onDoubleClick = function(event) {
          Run
          - -
          +
          @@ -2370,7 +2486,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2390,7 +2506,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2428,7 +2544,7 @@ path.onMouseMove = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2448,7 +2564,7 @@ path.onMouseMove = function(event) {
          Run
          - -
          +
          @@ -2478,7 +2594,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -2524,7 +2640,7 @@ function onMouseDown(event) {

            Type:

          • - Function + Functionnull
          @@ -2544,7 +2660,7 @@ function onMouseDown(event) {
          Run
          - -
          +
          @@ -2620,7 +2736,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -2689,7 +2805,7 @@ circle.set({
          Run
          - -
          +
          @@ -2784,7 +2900,7 @@ for (var i = 0; i < 20; i++) {
        @@ -2832,7 +2955,7 @@ for (var i = 0; i < 20; i++) {
        Run
        - -
        +
        @@ -2882,6 +3005,16 @@ raster.scale(5);
      +
        +

        Returns:

        + +
      • +Boolean +
      • + + +
      + @@ -2893,7 +3026,7 @@ raster.scale(5);
      Run
      - -
      +
      @@ -3031,6 +3164,8 @@ function onMouseDown(event) {
    • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
    • options.guides: Boolean — hit-test items that have Item#guide set to true
    • options.selected: Boolean — only hit selected items
    • +
    • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
    • +
    • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
      @@ -3039,7 +3174,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3088,7 +3223,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3407,6 +3542,16 @@ function onMouseDown(event) {
    +
      +

      Returns:

      + +
    • +Item +
    • + + +
    + @@ -3450,7 +3595,7 @@ function onMouseDown(event) {

    Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -4034,8 +4179,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -4161,19 +4306,31 @@ Array of Item objects
    @@ -4767,7 +4924,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -4838,7 +4995,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -4862,7 +5019,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -4930,7 +5087,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -4966,7 +5123,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -5063,7 +5220,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -5380,7 +5537,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -5413,7 +5570,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -5446,7 +5603,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -5517,7 +5674,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -5587,7 +5744,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -5617,7 +5774,7 @@ path.on({
    Run
    - -
    +
    @@ -5868,7 +6025,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -5915,7 +6072,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -5959,7 +6116,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -6003,7 +6160,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6047,7 +6204,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + - -
    +
    @@ -557,7 +626,7 @@ circle2.blendMode = 'multiply';
    Run
    - -
    +
    @@ -597,6 +666,11 @@ circle2.opacity = 0.5; +
      +

      Default:

      +
    • false
    • +
    +

      Type:

    • @@ -626,14 +700,14 @@ circle2.opacity = 0.5;
      Run
      - -
      +
      @@ -650,10 +724,15 @@ path.selected = true; // Select the path @@ -785,7 +864,7 @@ circle.position += new Point(100, 50);
      Run
      - -
      +
      @@ -817,6 +896,11 @@ circle.position.x += 100; +
        +

        Default:

        +
      • null
      • +
      +

        Type:

      • @@ -904,6 +988,33 @@ circle.position.x += 100; + + + + + + +
        + + @@ -1055,6 +1166,11 @@ circle.position.x += 100; +
          +

          Default:

          +
        • true
        • +
        +

          Type:

        • @@ -1066,16 +1182,6 @@ circle.position.x += 100;
        - - - - -
        - -
        @@ -1265,7 +1371,7 @@ console.log(group.children[0] == path); // true
        Run
        - -
        +
        @@ -1290,7 +1396,7 @@ group.children[0].fillColor = 'red';
        Run
        - -
        +
        @@ -1317,7 +1423,7 @@ group.children['example'].fillColor = 'orange';
        Run
        - -
        +
        @@ -1495,7 +1601,7 @@ group.firstChild.fillColor = 'green'; @@ -1508,7 +1614,7 @@ group.firstChild.fillColor = 'green';
        Run
        - -
        +
        @@ -1556,7 +1662,7 @@ circle.strokeColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -1615,7 +1721,7 @@ circle.strokeWidth = 10;
        Run
        - -
        +
        @@ -1683,7 +1789,7 @@ line2.strokeCap = 'butt';
        Run
        - -
        +
        @@ -1791,7 +1897,7 @@ path3.strokeJoin = 'bevel';

          Type:

        • - Array + Array of Numbers
        @@ -1804,7 +1910,7 @@ path3.strokeJoin = 'bevel';
        Run
        - -
        +
        @@ -1872,7 +1978,7 @@ path.dashArray = [10, 4]; @@ -1885,7 +1991,7 @@ path.dashArray = [10, 4];
        Run
        - -
        +
        @@ -1958,7 +2064,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -1971,7 +2077,7 @@ circle.fillColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -2072,7 +2178,7 @@ var circle = new Path.Circle({ @@ -2100,7 +2206,7 @@ var circle = new Path.Circle({

          Type:

        • - Function + Functionnull
          @@ -2125,7 +2231,7 @@ var circle = new Path.Circle({
          Run
          - -
          +
          @@ -2160,7 +2266,7 @@ path.onFrame = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2180,7 +2286,7 @@ path.onFrame = function(event) {
          Run
          - -
          +
          @@ -2206,7 +2312,7 @@ path.onMouseDown = function(event) {
          Run
          - -
          +
          @@ -2248,7 +2354,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2268,7 +2374,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2305,7 +2411,7 @@ path.onMouseDrag = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2325,7 +2431,7 @@ path.onMouseDrag = function(event) {
          Run
          - -
          +
          @@ -2363,7 +2469,7 @@ path.onMouseUp = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2383,7 +2489,7 @@ path.onMouseUp = function(event) {
          Run
          - -
          +
          @@ -2409,7 +2515,7 @@ path.onClick = function(event) {
          Run
          - -
          +
          @@ -2451,7 +2557,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2471,7 +2577,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2497,7 +2603,7 @@ path.onDoubleClick = function(event) {
          Run
          - -
          +
          @@ -2539,7 +2645,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2559,7 +2665,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2597,7 +2703,7 @@ path.onMouseMove = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2617,7 +2723,7 @@ path.onMouseMove = function(event) {
          Run
          - -
          +
          @@ -2647,7 +2753,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -2693,7 +2799,7 @@ function onMouseDown(event) {

            Type:

          • - Function + Functionnull
          @@ -2713,7 +2819,7 @@ function onMouseDown(event) {
          Run
          - -
          +
          @@ -2785,7 +2891,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -2854,7 +2960,7 @@ circle.set({
          Run
          - -
          +
          @@ -2949,7 +3055,7 @@ for (var i = 0; i < 20; i++) {
        @@ -2997,7 +3110,7 @@ for (var i = 0; i < 20; i++) {
        Run
        - -
        +
        @@ -3047,6 +3160,16 @@ raster.scale(5);
      +
        +

        Returns:

        + +
      • +Boolean +
      • + + +
      + @@ -3058,7 +3181,7 @@ raster.scale(5);
      Run
      - -
      +
      @@ -3196,6 +3319,8 @@ function onMouseDown(event) {
    • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
    • options.guides: Boolean — hit-test items that have Item#guide set to true
    • options.selected: Boolean — only hit selected items
    • +
    • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
    • +
    • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
      @@ -3204,7 +3329,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3253,7 +3378,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3572,6 +3697,16 @@ function onMouseDown(event) {
    +
      +

      Returns:

      + +
    • +Item +
    • + + +
    + @@ -3615,7 +3750,7 @@ function onMouseDown(event) {

    Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -4028,150 +4163,6 @@ Array of Item objects - - - - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    @@ -4343,8 +4334,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -4470,19 +4461,31 @@ Array of Item objects
    @@ -5076,7 +5079,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -5147,7 +5150,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -5171,7 +5174,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -5239,7 +5242,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -5275,7 +5278,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -5372,7 +5375,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -5689,7 +5692,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -5722,7 +5725,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -5755,7 +5758,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -5826,7 +5829,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -5896,7 +5899,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -5926,7 +5929,7 @@ path.on({
    Run
    - -
    +
    @@ -6177,7 +6180,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6224,7 +6227,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -6268,7 +6271,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -6312,7 +6315,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6356,7 +6359,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + @@ -6454,8 +6852,8 @@ function onFrame(event) { +Paper.js v0.12.7
    +Copyright © 2011—2023 Jürg Lehni & Jonathan Puckey. All Rights Reserved.

    diff --git a/dist/docs/classes/Line.html b/dist/docs/classes/Line.html deleted file mode 100644 index cd42cc45..00000000 --- a/dist/docs/classes/Line.html +++ /dev/null @@ -1,392 +0,0 @@ - - - - -Line - - - - - - - - -
    -
    -

    Line

    - -

    The Line object represents..

    - -
    - - -
    -

    Constructors

    - - -
    - - -
    - -
    - - - - - - -
    -

    Properties

    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    - - - - - - -
    -

    Methods

    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - - -
    - - - - - - -
    - - -
    - \ No newline at end of file diff --git a/dist/docs/classes/Matrix.html b/dist/docs/classes/Matrix.html index cba60b0c..7c33ac1c 100644 --- a/dist/docs/classes/Matrix.html +++ b/dist/docs/classes/Matrix.html @@ -150,7 +150,7 @@
  • values: -Array of Numbers +Array of Numbers — the matrix values to initialize this matrix with
  • @@ -400,7 +400,7 @@ Array of Numbers

      Type:

    • - Array of Numbers + Array of Numbers
    @@ -520,16 +520,38 @@ Array of Numbers

    Methods

    -
    +
    +
    + + +
    + + @@ -4166,6 +4321,11 @@ circle.position.x += 100; +
      +

      Default:

      +
    • true
    • +
    +

      Type:

    • @@ -4177,16 +4337,6 @@ circle.position.x += 100;
    -
    -
    - - -
    - -
    @@ -4376,7 +4526,7 @@ console.log(group.children[0] == path); // true
    Run
    - -
    +
    @@ -4401,7 +4551,7 @@ group.children[0].fillColor = 'red';
    Run
    - -
    +
    @@ -4428,7 +4578,7 @@ group.children['example'].fillColor = 'orange';
    Run
    - -
    +
    @@ -4606,7 +4756,7 @@ group.firstChild.fillColor = 'green'; @@ -4619,7 +4769,7 @@ group.firstChild.fillColor = 'green';
    Run
    - -
    +
    @@ -4667,7 +4817,7 @@ circle.strokeColor = new Color(1, 0, 0);
    Run
    - -
    +
    @@ -4726,7 +4876,7 @@ circle.strokeWidth = 10;
    Run
    - -
    +
    @@ -4794,7 +4944,7 @@ line2.strokeCap = 'butt';
    Run
    - -
    +
    @@ -4902,7 +5052,7 @@ path3.strokeJoin = 'bevel';

      Type:

    • - Array + Array of Numbers
    @@ -4915,7 +5065,7 @@ path3.strokeJoin = 'bevel';
    Run
    - -
    +
    @@ -4983,7 +5133,7 @@ path.dashArray = [10, 4]; @@ -4996,7 +5146,7 @@ path.dashArray = [10, 4];
    Run
    - -
    +
    @@ -5069,7 +5219,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -5082,7 +5232,7 @@ circle.fillColor = new Color(1, 0, 0);
    Run
    - -
    +
    @@ -5183,7 +5333,7 @@ var circle = new Path.Circle({ @@ -5211,7 +5361,7 @@ var circle = new Path.Circle({

      Type:

    • - Function + Functionnull
      @@ -5236,7 +5386,7 @@ var circle = new Path.Circle({
      Run
      - -
      +
      @@ -5271,7 +5421,7 @@ path.onFrame = function(event) {

        Type:

      • - Function + Functionnull
      @@ -5291,7 +5441,7 @@ path.onFrame = function(event) {
      Run
      - -
      +
      @@ -5317,7 +5467,7 @@ path.onMouseDown = function(event) {
      Run
      - -
      +
      @@ -5359,7 +5509,7 @@ for (var i = 0; i < 30; i++) {

        Type:

      • - Function + Functionnull
      @@ -5379,7 +5529,7 @@ for (var i = 0; i < 30; i++) {
      Run
      - -
      +
      @@ -5416,7 +5566,7 @@ path.onMouseDrag = function(event) {

        Type:

      • - Function + Functionnull
      @@ -5436,7 +5586,7 @@ path.onMouseDrag = function(event) {
      Run
      - -
      +
      @@ -5474,7 +5624,7 @@ path.onMouseUp = function(event) {

        Type:

      • - Function + Functionnull
      @@ -5494,7 +5644,7 @@ path.onMouseUp = function(event) {
      Run
      - -
      +
      @@ -5520,7 +5670,7 @@ path.onClick = function(event) {
      Run
      - -
      +
      @@ -5562,7 +5712,7 @@ for (var i = 0; i < 30; i++) {

        Type:

      • - Function + Functionnull
      @@ -5582,7 +5732,7 @@ for (var i = 0; i < 30; i++) {
      Run
      - -
      +
      @@ -5608,7 +5758,7 @@ path.onDoubleClick = function(event) {
      Run
      - -
      +
      @@ -5650,7 +5800,7 @@ for (var i = 0; i < 30; i++) {

        Type:

      • - Function + Functionnull
      @@ -5670,7 +5820,7 @@ for (var i = 0; i < 30; i++) {
      Run
      - -
      +
      @@ -5708,7 +5858,7 @@ path.onMouseMove = function(event) {

        Type:

      • - Function + Functionnull
      @@ -5728,7 +5878,7 @@ path.onMouseMove = function(event) {
      Run
      - -
      +
      @@ -5758,7 +5908,7 @@ path.onMouseLeave = function(event) {
      Run
      - -
      +
      @@ -5804,7 +5954,7 @@ function onMouseDown(event) {

        Type:

      • - Function + Functionnull
      @@ -5824,7 +5974,7 @@ function onMouseDown(event) {
      Run
      - -
      +
      @@ -5896,7 +6046,7 @@ path.onMouseLeave = function(event) {
      Run
      - -
      +
      @@ -5965,7 +6115,7 @@ circle.set({
      Run
      - -
      +
      @@ -6060,7 +6210,7 @@ for (var i = 0; i < 20; i++) {
    @@ -6108,7 +6265,7 @@ for (var i = 0; i < 20; i++) {
    Run
    - -
    +
    @@ -6158,6 +6315,16 @@ raster.scale(5); +
      +

      Returns:

      + +
    • +Boolean +
    • + + +
    + @@ -6169,7 +6336,7 @@ raster.scale(5);
    Run
    - -
    +
    @@ -6307,6 +6474,8 @@ function onMouseDown(event) {
  • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
  • options.guides: Boolean — hit-test items that have Item#guide set to true
  • options.selected: Boolean — only hit selected items
  • +
  • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
  • +
  • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
    • @@ -6315,7 +6484,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -6364,7 +6533,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -6683,6 +6852,16 @@ function onMouseDown(event) {
    +
      +

      Returns:

      + +
    • +Item +
    • + + +
    + @@ -6726,7 +6905,7 @@ function onMouseDown(event) {

    Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -7139,150 +7318,6 @@ Array of Item objects - - - - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    @@ -7413,8 +7448,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -7540,19 +7575,31 @@ Array of Item objects
    @@ -8146,7 +8193,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -8217,7 +8264,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -8241,7 +8288,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -8309,7 +8356,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -8345,7 +8392,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -8442,7 +8489,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -8759,7 +8806,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -8792,7 +8839,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -8825,7 +8872,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -8896,7 +8943,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -8966,7 +9013,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -8996,7 +9043,7 @@ path.on({
    Run
    - -
    +
    @@ -9247,7 +9294,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -9294,7 +9341,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -9338,7 +9385,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -9382,7 +9429,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -9426,7 +9473,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + - -
    +
    @@ -10159,7 +10611,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -10255,7 +10707,7 @@ copy.flatten(4);
    Run
    - -
    +
    @@ -10286,7 +10738,7 @@ copy.smooth({ type: 'continuous' });
    Run
    - -
    +
    @@ -10323,7 +10775,7 @@ copy.smooth({ type: 'catmull-rom', factor: 0.5 });
    Run
    - -
    +
    @@ -10406,7 +10858,7 @@ paths[4].smooth({ type: 'continuous', from: -1, to: 1 });
    Run
    - -
    +
    @@ -10635,7 +11087,7 @@ function onMouseUp(event) {
    Run
    - -
    +
    @@ -10667,7 +11119,7 @@ circle.fillColor = 'red';
    Run
    - -
    +
    @@ -10744,7 +11196,7 @@ function onMouseUp(event) {
    Run
    - -
    +
    @@ -10771,7 +11223,7 @@ path2.arcTo(new Point(280, 25), false);
    Run
    - -
    +
    @@ -10848,7 +11300,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -11054,7 +11506,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -11080,7 +11532,7 @@ path.lineBy(0, 50);
    Run
    - -
    +
    @@ -11325,8 +11777,8 @@ path.smooth(); +Paper.js v0.12.7
    +Copyright © 2011—2023 Jürg Lehni & Jonathan Puckey. All Rights Reserved.

    diff --git a/dist/docs/classes/PathItem.html b/dist/docs/classes/PathItem.html index 7e6c5654..b6b6679e 100644 --- a/dist/docs/classes/PathItem.html +++ b/dist/docs/classes/PathItem.html @@ -80,9 +80,9 @@ @@ -343,7 +343,7 @@ - -
    +
    @@ -2406,7 +2485,7 @@ circle2.blendMode = 'multiply';
    Run
    - -
    +
    @@ -2446,6 +2525,11 @@ circle2.opacity = 0.5; +
      +

      Default:

      +
    • false
    • +
    +

      Type:

    • @@ -2475,14 +2559,14 @@ circle2.opacity = 0.5;
      Run
      - -
      +
      @@ -2499,10 +2583,15 @@ path.selected = true; // Select the path @@ -2634,7 +2723,7 @@ circle.position += new Point(100, 50);
      Run
      - -
      +
      @@ -2666,6 +2755,11 @@ circle.position.x += 100; +
        +

        Default:

        +
      • null
      • +
      +

        Type:

      • @@ -2753,6 +2847,33 @@ circle.position.x += 100; + + + + + + +
        + + @@ -2904,6 +3025,11 @@ circle.position.x += 100; +
          +

          Default:

          +
        • true
        • +
        +

          Type:

        • @@ -2915,16 +3041,6 @@ circle.position.x += 100;
        - - - - -
        - -
        @@ -3114,7 +3230,7 @@ console.log(group.children[0] == path); // true
        Run
        - -
        +
        @@ -3139,7 +3255,7 @@ group.children[0].fillColor = 'red';
        Run
        - -
        +
        @@ -3166,7 +3282,7 @@ group.children['example'].fillColor = 'orange';
        Run
        - -
        +
        @@ -3344,7 +3460,7 @@ group.firstChild.fillColor = 'green'; @@ -3357,7 +3473,7 @@ group.firstChild.fillColor = 'green';
        Run
        - -
        +
        @@ -3405,7 +3521,7 @@ circle.strokeColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -3464,7 +3580,7 @@ circle.strokeWidth = 10;
        Run
        - -
        +
        @@ -3532,7 +3648,7 @@ line2.strokeCap = 'butt';
        Run
        - -
        +
        @@ -3640,7 +3756,7 @@ path3.strokeJoin = 'bevel';

          Type:

        • - Array + Array of Numbers
        @@ -3653,7 +3769,7 @@ path3.strokeJoin = 'bevel';
        Run
        - -
        +
        @@ -3721,7 +3837,7 @@ path.dashArray = [10, 4]; @@ -3734,7 +3850,7 @@ path.dashArray = [10, 4];
        Run
        - -
        +
        @@ -3807,7 +3923,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -3820,7 +3936,7 @@ circle.fillColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -3921,7 +4037,7 @@ var circle = new Path.Circle({ @@ -3949,7 +4065,7 @@ var circle = new Path.Circle({

          Type:

        • - Function + Functionnull
          @@ -3974,7 +4090,7 @@ var circle = new Path.Circle({
          Run
          - -
          +
          @@ -4009,7 +4125,7 @@ path.onFrame = function(event) {

            Type:

          • - Function + Functionnull
          @@ -4029,7 +4145,7 @@ path.onFrame = function(event) {
          Run
          - -
          +
          @@ -4055,7 +4171,7 @@ path.onMouseDown = function(event) {
          Run
          - -
          +
          @@ -4097,7 +4213,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -4117,7 +4233,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -4154,7 +4270,7 @@ path.onMouseDrag = function(event) {

            Type:

          • - Function + Functionnull
          @@ -4174,7 +4290,7 @@ path.onMouseDrag = function(event) {
          Run
          - -
          +
          @@ -4212,7 +4328,7 @@ path.onMouseUp = function(event) {

            Type:

          • - Function + Functionnull
          @@ -4232,7 +4348,7 @@ path.onMouseUp = function(event) {
          Run
          - -
          +
          @@ -4258,7 +4374,7 @@ path.onClick = function(event) {
          Run
          - -
          +
          @@ -4300,7 +4416,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -4320,7 +4436,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -4346,7 +4462,7 @@ path.onDoubleClick = function(event) {
          Run
          - -
          +
          @@ -4388,7 +4504,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -4408,7 +4524,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -4446,7 +4562,7 @@ path.onMouseMove = function(event) {

            Type:

          • - Function + Functionnull
          @@ -4466,7 +4582,7 @@ path.onMouseMove = function(event) {
          Run
          - -
          +
          @@ -4496,7 +4612,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -4542,7 +4658,7 @@ function onMouseDown(event) {

            Type:

          • - Function + Functionnull
          @@ -4562,7 +4678,7 @@ function onMouseDown(event) {
          Run
          - -
          +
          @@ -4634,7 +4750,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -4703,7 +4819,7 @@ circle.set({
          Run
          - -
          +
          @@ -4798,7 +4914,7 @@ for (var i = 0; i < 20; i++) {
        @@ -4846,7 +4969,7 @@ for (var i = 0; i < 20; i++) {
        Run
        - -
        +
        @@ -4896,6 +5019,16 @@ raster.scale(5);
      +
        +

        Returns:

        + +
      • +Boolean +
      • + + +
      + @@ -4907,7 +5040,7 @@ raster.scale(5);
      Run
      - -
      +
      @@ -5045,6 +5178,8 @@ function onMouseDown(event) {
    • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
    • options.guides: Boolean — hit-test items that have Item#guide set to true
    • options.selected: Boolean — only hit selected items
    • +
    • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
    • +
    • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
      @@ -5053,7 +5188,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -5102,7 +5237,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -5421,6 +5556,16 @@ function onMouseDown(event) {
    +
      +

      Returns:

      + +
    • +Item +
    • + + +
    + @@ -5464,7 +5609,7 @@ function onMouseDown(event) {

    Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -5877,150 +6022,6 @@ Array of Item objects - - - - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    @@ -6192,8 +6193,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -6319,19 +6320,31 @@ Array of Item objects
    @@ -6925,7 +6938,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -6996,7 +7009,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -7020,7 +7033,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -7088,7 +7101,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -7124,7 +7137,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -7221,7 +7234,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -7538,7 +7551,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -7571,7 +7584,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -7604,7 +7617,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -7675,7 +7688,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -7745,7 +7758,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -7775,7 +7788,7 @@ path.on({
    Run
    - -
    +
    @@ -8026,7 +8039,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -8073,7 +8086,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -8117,7 +8130,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -8161,7 +8174,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -8205,7 +8218,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + - -
    +
    @@ -657,10 +731,15 @@ path.selected = true; // Select the path @@ -792,7 +871,7 @@ circle.position += new Point(100, 50);
    Run
    - -
    +
    @@ -824,6 +903,11 @@ circle.position.x += 100; +
      +

      Default:

      +
    • null
    • +
    +

      Type:

    • @@ -911,6 +995,33 @@ circle.position.x += 100; + + + + + + +
      + + @@ -1062,6 +1173,11 @@ circle.position.x += 100; +
        +

        Default:

        +
      • true
      • +
      +

        Type:

      • @@ -1073,16 +1189,6 @@ circle.position.x += 100;
      - - - - -
      - -
      @@ -1272,7 +1378,7 @@ console.log(group.children[0] == path); // true
      Run
      - -
      +
      @@ -1297,7 +1403,7 @@ group.children[0].fillColor = 'red';
      Run
      - -
      +
      @@ -1324,7 +1430,7 @@ group.children['example'].fillColor = 'orange';
      Run
      - -
      +
      @@ -1502,7 +1608,7 @@ group.firstChild.fillColor = 'green'; @@ -1515,7 +1621,7 @@ group.firstChild.fillColor = 'green';
      Run
      - -
      +
      @@ -1563,7 +1669,7 @@ circle.strokeColor = new Color(1, 0, 0);
      Run
      - -
      +
      @@ -1622,7 +1728,7 @@ circle.strokeWidth = 10;
      Run
      - -
      +
      @@ -1690,7 +1796,7 @@ line2.strokeCap = 'butt';
      Run
      - -
      +
      @@ -1798,7 +1904,7 @@ path3.strokeJoin = 'bevel';

        Type:

      • - Array + Array of Numbers
      @@ -1811,7 +1917,7 @@ path3.strokeJoin = 'bevel';
      Run
      - -
      +
      @@ -1879,7 +1985,7 @@ path.dashArray = [10, 4]; @@ -1892,7 +1998,7 @@ path.dashArray = [10, 4];
      Run
      - -
      +
      @@ -1965,7 +2071,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -1978,7 +2084,7 @@ circle.fillColor = new Color(1, 0, 0);
      Run
      - -
      +
      @@ -2079,7 +2185,7 @@ var circle = new Path.Circle({ @@ -2107,7 +2213,7 @@ var circle = new Path.Circle({

        Type:

      • - Function + Functionnull
        @@ -2132,7 +2238,7 @@ var circle = new Path.Circle({
        Run
        - -
        +
        @@ -2167,7 +2273,7 @@ path.onFrame = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2187,7 +2293,7 @@ path.onFrame = function(event) {
        Run
        - -
        +
        @@ -2213,7 +2319,7 @@ path.onMouseDown = function(event) {
        Run
        - -
        +
        @@ -2255,7 +2361,7 @@ for (var i = 0; i < 30; i++) {

          Type:

        • - Function + Functionnull
        @@ -2275,7 +2381,7 @@ for (var i = 0; i < 30; i++) {
        Run
        - -
        +
        @@ -2312,7 +2418,7 @@ path.onMouseDrag = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2332,7 +2438,7 @@ path.onMouseDrag = function(event) {
        Run
        - -
        +
        @@ -2370,7 +2476,7 @@ path.onMouseUp = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2390,7 +2496,7 @@ path.onMouseUp = function(event) {
        Run
        - -
        +
        @@ -2416,7 +2522,7 @@ path.onClick = function(event) {
        Run
        - -
        +
        @@ -2458,7 +2564,7 @@ for (var i = 0; i < 30; i++) {

          Type:

        • - Function + Functionnull
        @@ -2478,7 +2584,7 @@ for (var i = 0; i < 30; i++) {
        Run
        - -
        +
        @@ -2504,7 +2610,7 @@ path.onDoubleClick = function(event) {
        Run
        - -
        +
        @@ -2546,7 +2652,7 @@ for (var i = 0; i < 30; i++) {

          Type:

        • - Function + Functionnull
        @@ -2566,7 +2672,7 @@ for (var i = 0; i < 30; i++) {
        Run
        - -
        +
        @@ -2604,7 +2710,7 @@ path.onMouseMove = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2624,7 +2730,7 @@ path.onMouseMove = function(event) {
        Run
        - -
        +
        @@ -2654,7 +2760,7 @@ path.onMouseLeave = function(event) {
        Run
        - -
        +
        @@ -2700,7 +2806,7 @@ function onMouseDown(event) {

          Type:

        • - Function + Functionnull
        @@ -2720,7 +2826,7 @@ function onMouseDown(event) {
        Run
        - -
        +
        @@ -2792,7 +2898,7 @@ path.onMouseLeave = function(event) {
        Run
        - -
        +
        @@ -2861,7 +2967,7 @@ circle.set({
        Run
        - -
        +
        @@ -2956,7 +3062,7 @@ for (var i = 0; i < 20; i++) {
      @@ -3004,7 +3117,7 @@ for (var i = 0; i < 20; i++) {
      Run
      - -
      +
      @@ -3054,6 +3167,16 @@ raster.scale(5);
    +
      +

      Returns:

      + +
    • +Boolean +
    • + + +
    + @@ -3065,7 +3188,7 @@ raster.scale(5);
    Run
    - -
    +
    @@ -3203,6 +3326,8 @@ function onMouseDown(event) {
  • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
  • options.guides: Boolean — hit-test items that have Item#guide set to true
  • options.selected: Boolean — only hit selected items
  • +
  • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
  • +
  • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
    • @@ -3211,7 +3336,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3260,7 +3385,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3579,6 +3704,16 @@ function onMouseDown(event) {
    +
      +

      Returns:

      + +
    • +Item +
    • + + +
    + @@ -3622,7 +3757,7 @@ function onMouseDown(event) {

    Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -4035,150 +4170,6 @@ Array of Item objects - - - - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    @@ -4350,8 +4341,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -4477,19 +4468,31 @@ Array of Item objects
    @@ -5083,7 +5086,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -5154,7 +5157,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -5178,7 +5181,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -5246,7 +5249,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -5282,7 +5285,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -5379,7 +5382,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -5696,7 +5699,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -5729,7 +5732,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -5762,7 +5765,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -5833,7 +5836,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -5903,7 +5906,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -5933,7 +5936,7 @@ path.on({
    Run
    - -
    +
    @@ -6184,7 +6187,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6231,7 +6234,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -6275,7 +6278,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -6319,7 +6322,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6363,7 +6366,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + @@ -6440,7 +6838,7 @@ text.content = 'Hello world';
    Run
    - -
    +
    @@ -6552,37 +6950,6 @@ function onMouseMove(event) { - - - - - - -
    - - @@ -6664,8 +7031,8 @@ function onMouseMove(event) { +Paper.js v0.12.7
    +Copyright © 2011—2023 Jürg Lehni & Jonathan Puckey. All Rights Reserved.

    diff --git a/dist/docs/classes/Project.html b/dist/docs/classes/Project.html index 0baa0618..c3b706d2 100644 --- a/dist/docs/classes/Project.html +++ b/dist/docs/classes/Project.html @@ -42,8 +42,8 @@
  • element: -HTMLCanvasElementString -— the HTML canvas element that should be used as the element for the view, or an ID string by which to find the element. +HTMLCanvasElementStringSize +— the HTML canvas element that should be used as the element for the view, or an ID string by which to find the element, or the size of the canvas to be created for usage in a web worker.
  • @@ -379,7 +379,7 @@ var path2 = new Path.Circle(new Point(175, 50), 20);

    Returns:

  • - — Boolean +Boolean
  • @@ -494,9 +494,9 @@ var path2 = new Path.Circle(new Point(175, 50), 20);
    -
    +
    +
    + + +
    + +
    @@ -315,7 +389,7 @@ raster.rotate(10);

      Type:

    • - HTMLCanvasELement + HTMLCanvasElement
    @@ -327,9 +401,9 @@ raster.rotate(10);
    -
    +
    - -
    +
    @@ -397,13 +471,13 @@ raster.position = view.center;
    Run
    - -
    +
    @@ -440,7 +514,7 @@ var raster = new Raster({
    Run
    - -
    +
    + + + + + + + + + +
    + + +
    + + +
    + +
    @@ -1122,7 +1264,7 @@ raster.on('load', function() {
    Run
    - -
    +
    @@ -1174,7 +1316,7 @@ group.children['example'].fillColor = 'red';
    Run
    - -
    +
    @@ -1197,7 +1339,7 @@ circle.style = {
    Run
    - -
    +
    @@ -1224,7 +1366,7 @@ path2.style = path.style;
    Run
    - -
    +
    + + + + + + + + + +
    + + @@ -1318,7 +1529,7 @@ path.visible = false;

      Values:

    • 'normal', 'multiply', 'screen', 'overlay', 'soft-light', 'hard- - light', 'color-dodge', 'color-burn', 'darken', 'lighten', 'difference', 'exclusion', 'hue', 'saturation', 'luminosity', 'color', 'add', 'subtract', 'average', 'pin-light', 'negation', 'source- over', 'source-in', 'source-out', 'source-atop', 'destination-over', 'destination-in', 'destination-out', 'destination-atop', 'lighter', 'darker', 'copy', 'xor'
    • + light', 'color-dodge', 'color-burn', 'darken', 'lighten', 'difference', 'exclusion', 'hue', 'saturation', 'luminosity', 'color', 'add', 'subtract', 'average', 'pin-light', 'negation', 'source-over', 'source-in', 'source-out', 'source-atop', 'destination-over', 'destination-in', 'destination-out', 'destination-atop', 'lighter', 'darker', 'copy', 'xor'
    @@ -1343,7 +1554,7 @@ path.visible = false;
    Run
    - -
    +
    @@ -1406,7 +1617,7 @@ circle2.blendMode = 'multiply';
    Run
    - -
    +
    @@ -1446,6 +1657,11 @@ circle2.opacity = 0.5; +
      +

      Default:

      +
    • false
    • +
    +

      Type:

    • @@ -1475,14 +1691,14 @@ circle2.opacity = 0.5;
      Run
      - -
      +
      @@ -1499,10 +1715,15 @@ path.selected = true; // Select the path @@ -1634,7 +1855,7 @@ circle.position += new Point(100, 50);
      Run
      - -
      +
      @@ -1666,6 +1887,11 @@ circle.position.x += 100; +
        +

        Default:

        +
      • null
      • +
      +

        Type:

      • @@ -1753,6 +1979,33 @@ circle.position.x += 100; + + + + + + +
        + + @@ -1904,6 +2157,11 @@ circle.position.x += 100; +
          +

          Default:

          +
        • true
        • +
        +

          Type:

        • @@ -1915,16 +2173,6 @@ circle.position.x += 100;
        - - - - -
        - -
        @@ -2114,7 +2362,7 @@ console.log(group.children[0] == path); // true
        Run
        - -
        +
        @@ -2139,7 +2387,7 @@ group.children[0].fillColor = 'red';
        Run
        - -
        +
        @@ -2166,7 +2414,7 @@ group.children['example'].fillColor = 'orange';
        Run
        - -
        +
        @@ -2344,7 +2592,7 @@ group.firstChild.fillColor = 'green'; @@ -2357,7 +2605,7 @@ group.firstChild.fillColor = 'green';
        Run
        - -
        +
        @@ -2405,7 +2653,7 @@ circle.strokeColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -2464,7 +2712,7 @@ circle.strokeWidth = 10;
        Run
        - -
        +
        @@ -2532,7 +2780,7 @@ line2.strokeCap = 'butt';
        Run
        - -
        +
        @@ -2640,7 +2888,7 @@ path3.strokeJoin = 'bevel';

          Type:

        • - Array + Array of Numbers
        @@ -2653,7 +2901,7 @@ path3.strokeJoin = 'bevel';
        Run
        - -
        +
        @@ -2721,7 +2969,7 @@ path.dashArray = [10, 4]; @@ -2734,7 +2982,7 @@ path.dashArray = [10, 4];
        Run
        - -
        +
        @@ -2807,7 +3055,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -2820,7 +3068,7 @@ circle.fillColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -2921,7 +3169,7 @@ var circle = new Path.Circle({ @@ -2949,7 +3197,7 @@ var circle = new Path.Circle({

          Type:

        • - Function + Functionnull
          @@ -2974,7 +3222,7 @@ var circle = new Path.Circle({
          Run
          - -
          +
          @@ -3009,7 +3257,7 @@ path.onFrame = function(event) {

            Type:

          • - Function + Functionnull
          @@ -3029,7 +3277,7 @@ path.onFrame = function(event) {
          Run
          - -
          +
          @@ -3055,7 +3303,7 @@ path.onMouseDown = function(event) {
          Run
          - -
          +
          @@ -3097,7 +3345,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -3117,7 +3365,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -3154,7 +3402,7 @@ path.onMouseDrag = function(event) {

            Type:

          • - Function + Functionnull
          @@ -3174,7 +3422,7 @@ path.onMouseDrag = function(event) {
          Run
          - -
          +
          @@ -3212,7 +3460,7 @@ path.onMouseUp = function(event) {

            Type:

          • - Function + Functionnull
          @@ -3232,7 +3480,7 @@ path.onMouseUp = function(event) {
          Run
          - -
          +
          @@ -3258,7 +3506,7 @@ path.onClick = function(event) {
          Run
          - -
          +
          @@ -3300,7 +3548,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -3320,7 +3568,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -3346,7 +3594,7 @@ path.onDoubleClick = function(event) {
          Run
          - -
          +
          @@ -3388,7 +3636,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -3408,7 +3656,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -3446,7 +3694,7 @@ path.onMouseMove = function(event) {

            Type:

          • - Function + Functionnull
          @@ -3466,7 +3714,7 @@ path.onMouseMove = function(event) {
          Run
          - -
          +
          @@ -3496,7 +3744,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -3542,7 +3790,7 @@ function onMouseDown(event) {

            Type:

          • - Function + Functionnull
          @@ -3562,7 +3810,7 @@ function onMouseDown(event) {
          Run
          - -
          +
          @@ -3634,7 +3882,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -3703,7 +3951,7 @@ circle.set({
          Run
          - -
          +
          @@ -3798,7 +4046,7 @@ for (var i = 0; i < 20; i++) {
        @@ -3846,7 +4101,7 @@ for (var i = 0; i < 20; i++) {
        Run
        - -
        +
        @@ -3896,6 +4151,16 @@ raster.scale(5);
      +
        +

        Returns:

        + +
      • +Boolean +
      • + + +
      + @@ -3907,7 +4172,7 @@ raster.scale(5);
      Run
      - -
      +
      @@ -4045,6 +4310,8 @@ function onMouseDown(event) {
    • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
    • options.guides: Boolean — hit-test items that have Item#guide set to true
    • options.selected: Boolean — only hit selected items
    • +
    • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
    • +
    • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
      @@ -4053,7 +4320,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -4102,7 +4369,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -4421,6 +4688,16 @@ function onMouseDown(event) {
    +
      +

      Returns:

      + +
    • +Item +
    • + + +
    + @@ -4464,7 +4741,7 @@ function onMouseDown(event) {

    Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -4877,150 +5154,6 @@ Array of Item objects - - - - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    @@ -5192,8 +5325,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -5319,19 +5452,31 @@ Array of Item objects
    @@ -5925,7 +6070,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -5996,7 +6141,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -6020,7 +6165,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -6088,7 +6233,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -6124,7 +6269,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -6221,7 +6366,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -6538,7 +6683,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -6571,7 +6716,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -6604,7 +6749,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -6675,7 +6820,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -6745,7 +6890,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -6775,7 +6920,7 @@ path.on({
    Run
    - -
    +
    @@ -7026,7 +7171,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -7073,7 +7218,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -7117,7 +7262,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -7161,7 +7306,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -7205,7 +7350,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + - -
    +
    @@ -1233,10 +1307,15 @@ path.selected = true; // Select the path @@ -1368,7 +1447,7 @@ circle.position += new Point(100, 50);
    Run
    - -
    +
    @@ -1400,6 +1479,11 @@ circle.position.x += 100; +
      +

      Default:

      +
    • null
    • +
    +

      Type:

    • @@ -1487,6 +1571,33 @@ circle.position.x += 100; + + + + + + +
      + + @@ -1638,6 +1749,11 @@ circle.position.x += 100; +
        +

        Default:

        +
      • true
      • +
      +

        Type:

      • @@ -1649,16 +1765,6 @@ circle.position.x += 100;
      - - - - -
      - -
      @@ -1848,7 +1954,7 @@ console.log(group.children[0] == path); // true
      Run
      - -
      +
      @@ -1873,7 +1979,7 @@ group.children[0].fillColor = 'red';
      Run
      - -
      +
      @@ -1900,7 +2006,7 @@ group.children['example'].fillColor = 'orange';
      Run
      - -
      +
      @@ -2078,7 +2184,7 @@ group.firstChild.fillColor = 'green'; @@ -2091,7 +2197,7 @@ group.firstChild.fillColor = 'green';
      Run
      - -
      +
      @@ -2139,7 +2245,7 @@ circle.strokeColor = new Color(1, 0, 0);
      Run
      - -
      +
      @@ -2198,7 +2304,7 @@ circle.strokeWidth = 10;
      Run
      - -
      +
      @@ -2266,7 +2372,7 @@ line2.strokeCap = 'butt';
      Run
      - -
      +
      @@ -2374,7 +2480,7 @@ path3.strokeJoin = 'bevel';

        Type:

      • - Array + Array of Numbers
      @@ -2387,7 +2493,7 @@ path3.strokeJoin = 'bevel';
      Run
      - -
      +
      @@ -2455,7 +2561,7 @@ path.dashArray = [10, 4]; @@ -2468,7 +2574,7 @@ path.dashArray = [10, 4];
      Run
      - -
      +
      @@ -2541,7 +2647,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -2554,7 +2660,7 @@ circle.fillColor = new Color(1, 0, 0);
      Run
      - -
      +
      @@ -2655,7 +2761,7 @@ var circle = new Path.Circle({ @@ -2683,7 +2789,7 @@ var circle = new Path.Circle({

        Type:

      • - Function + Functionnull
        @@ -2708,7 +2814,7 @@ var circle = new Path.Circle({
        Run
        - -
        +
        @@ -2743,7 +2849,7 @@ path.onFrame = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2763,7 +2869,7 @@ path.onFrame = function(event) {
        Run
        - -
        +
        @@ -2789,7 +2895,7 @@ path.onMouseDown = function(event) {
        Run
        - -
        +
        @@ -2831,7 +2937,7 @@ for (var i = 0; i < 30; i++) {

          Type:

        • - Function + Functionnull
        @@ -2851,7 +2957,7 @@ for (var i = 0; i < 30; i++) {
        Run
        - -
        +
        @@ -2888,7 +2994,7 @@ path.onMouseDrag = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2908,7 +3014,7 @@ path.onMouseDrag = function(event) {
        Run
        - -
        +
        @@ -2946,7 +3052,7 @@ path.onMouseUp = function(event) {

          Type:

        • - Function + Functionnull
        @@ -2966,7 +3072,7 @@ path.onMouseUp = function(event) {
        Run
        - -
        +
        @@ -2992,7 +3098,7 @@ path.onClick = function(event) {
        Run
        - -
        +
        @@ -3034,7 +3140,7 @@ for (var i = 0; i < 30; i++) {

          Type:

        • - Function + Functionnull
        @@ -3054,7 +3160,7 @@ for (var i = 0; i < 30; i++) {
        Run
        - -
        +
        @@ -3080,7 +3186,7 @@ path.onDoubleClick = function(event) {
        Run
        - -
        +
        @@ -3122,7 +3228,7 @@ for (var i = 0; i < 30; i++) {

          Type:

        • - Function + Functionnull
        @@ -3142,7 +3248,7 @@ for (var i = 0; i < 30; i++) {
        Run
        - -
        +
        @@ -3180,7 +3286,7 @@ path.onMouseMove = function(event) {

          Type:

        • - Function + Functionnull
        @@ -3200,7 +3306,7 @@ path.onMouseMove = function(event) {
        Run
        - -
        +
        @@ -3230,7 +3336,7 @@ path.onMouseLeave = function(event) {
        Run
        - -
        +
        @@ -3276,7 +3382,7 @@ function onMouseDown(event) {

          Type:

        • - Function + Functionnull
        @@ -3296,7 +3402,7 @@ function onMouseDown(event) {
        Run
        - -
        +
        @@ -3368,7 +3474,7 @@ path.onMouseLeave = function(event) {
        Run
        - -
        +
        @@ -3437,7 +3543,7 @@ circle.set({
        Run
        - -
        +
        @@ -3532,7 +3638,7 @@ for (var i = 0; i < 20; i++) {
      @@ -3580,7 +3693,7 @@ for (var i = 0; i < 20; i++) {
      Run
      - -
      +
      @@ -3630,6 +3743,16 @@ raster.scale(5);
    +
      +

      Returns:

      + +
    • +Boolean +
    • + + +
    + @@ -3641,7 +3764,7 @@ raster.scale(5);
    Run
    - -
    +
    @@ -3779,6 +3902,8 @@ function onMouseDown(event) {
  • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
  • options.guides: Boolean — hit-test items that have Item#guide set to true
  • options.selected: Boolean — only hit selected items
  • +
  • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
  • +
  • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
    • @@ -3787,7 +3912,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3836,7 +3961,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -4155,6 +4280,16 @@ function onMouseDown(event) {
    +
      +

      Returns:

      + +
    • +Item +
    • + + +
    + @@ -4198,7 +4333,7 @@ function onMouseDown(event) {

    Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -4611,150 +4746,6 @@ Array of Item objects - - - - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    @@ -4926,8 +4917,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -5053,19 +5044,31 @@ Array of Item objects
    @@ -5659,7 +5662,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -5730,7 +5733,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -5754,7 +5757,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -5822,7 +5825,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -5858,7 +5861,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -5955,7 +5958,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -6272,7 +6275,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -6305,7 +6308,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -6338,7 +6341,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -6409,7 +6412,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -6479,7 +6482,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -6509,7 +6512,7 @@ path.on({
    Run
    - -
    +
    @@ -6760,7 +6763,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6807,7 +6810,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -6851,7 +6854,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -6895,7 +6898,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6939,7 +6942,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + @@ -792,6 +871,11 @@ circle.position.x += 100; +
      +

      Default:

      +
    • null
    • +
    +

      Type:

    • @@ -879,6 +963,33 @@ circle.position.x += 100; +
    + + + + + +
    + + @@ -1030,6 +1141,11 @@ circle.position.x += 100; +
      +

      Default:

      +
    • true
    • +
    +

      Type:

    • @@ -1041,16 +1157,6 @@ circle.position.x += 100;
    - - - - -
    - -
    @@ -1240,7 +1346,7 @@ console.log(group.children[0] == path); // true
    Run
    - -
    +
    @@ -1265,7 +1371,7 @@ group.children[0].fillColor = 'red';
    Run
    - -
    +
    @@ -1292,7 +1398,7 @@ group.children['example'].fillColor = 'orange';
    Run
    - -
    +
    @@ -1470,7 +1576,7 @@ group.firstChild.fillColor = 'green'; @@ -1483,7 +1589,7 @@ group.firstChild.fillColor = 'green';
    Run
    - -
    +
    @@ -1531,7 +1637,7 @@ circle.strokeColor = new Color(1, 0, 0);
    Run
    - -
    +
    @@ -1590,7 +1696,7 @@ circle.strokeWidth = 10;
    Run
    - -
    +
    @@ -1658,7 +1764,7 @@ line2.strokeCap = 'butt';
    Run
    - -
    +
    @@ -1766,7 +1872,7 @@ path3.strokeJoin = 'bevel';

      Type:

    • - Array + Array of Numbers
    @@ -1779,7 +1885,7 @@ path3.strokeJoin = 'bevel';
    Run
    - -
    +
    @@ -1847,7 +1953,7 @@ path.dashArray = [10, 4]; @@ -1860,7 +1966,7 @@ path.dashArray = [10, 4];
    Run
    - -
    +
    @@ -1933,7 +2039,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -1946,7 +2052,7 @@ circle.fillColor = new Color(1, 0, 0);
    Run
    - -
    +
    @@ -2047,7 +2153,7 @@ var circle = new Path.Circle({ @@ -2075,7 +2181,7 @@ var circle = new Path.Circle({

      Type:

    • - Function + Functionnull
      @@ -2100,7 +2206,7 @@ var circle = new Path.Circle({
      Run
      - -
      +
      @@ -2135,7 +2241,7 @@ path.onFrame = function(event) {

        Type:

      • - Function + Functionnull
      @@ -2155,7 +2261,7 @@ path.onFrame = function(event) {
      Run
      - -
      +
      @@ -2181,7 +2287,7 @@ path.onMouseDown = function(event) {
      Run
      - -
      +
      @@ -2223,7 +2329,7 @@ for (var i = 0; i < 30; i++) {

        Type:

      • - Function + Functionnull
      @@ -2243,7 +2349,7 @@ for (var i = 0; i < 30; i++) {
      Run
      - -
      +
      @@ -2280,7 +2386,7 @@ path.onMouseDrag = function(event) {

        Type:

      • - Function + Functionnull
      @@ -2300,7 +2406,7 @@ path.onMouseDrag = function(event) {
      Run
      - -
      +
      @@ -2338,7 +2444,7 @@ path.onMouseUp = function(event) {

        Type:

      • - Function + Functionnull
      @@ -2358,7 +2464,7 @@ path.onMouseUp = function(event) {
      Run
      - -
      +
      @@ -2384,7 +2490,7 @@ path.onClick = function(event) {
      Run
      - -
      +
      @@ -2426,7 +2532,7 @@ for (var i = 0; i < 30; i++) {

        Type:

      • - Function + Functionnull
      @@ -2446,7 +2552,7 @@ for (var i = 0; i < 30; i++) {
      Run
      - -
      +
      @@ -2472,7 +2578,7 @@ path.onDoubleClick = function(event) {
      Run
      - -
      +
      @@ -2514,7 +2620,7 @@ for (var i = 0; i < 30; i++) {

        Type:

      • - Function + Functionnull
      @@ -2534,7 +2640,7 @@ for (var i = 0; i < 30; i++) {
      Run
      - -
      +
      @@ -2572,7 +2678,7 @@ path.onMouseMove = function(event) {

        Type:

      • - Function + Functionnull
      @@ -2592,7 +2698,7 @@ path.onMouseMove = function(event) {
      Run
      - -
      +
      @@ -2622,7 +2728,7 @@ path.onMouseLeave = function(event) {
      Run
      - -
      +
      @@ -2668,7 +2774,7 @@ function onMouseDown(event) {

        Type:

      • - Function + Functionnull
      @@ -2688,7 +2794,7 @@ function onMouseDown(event) {
      Run
      - -
      +
      @@ -2760,7 +2866,7 @@ path.onMouseLeave = function(event) {
      Run
      - -
      +
      @@ -2829,7 +2935,7 @@ circle.set({
      Run
      - -
      +
      @@ -2924,7 +3030,7 @@ for (var i = 0; i < 20; i++) {
    @@ -2972,7 +3085,7 @@ for (var i = 0; i < 20; i++) {
    Run
    - -
    +
    @@ -3022,6 +3135,16 @@ raster.scale(5); +
      +

      Returns:

      + +
    • +Boolean +
    • + + +
    + @@ -3033,7 +3156,7 @@ raster.scale(5);
    Run
    - -
    +
    @@ -3171,6 +3294,8 @@ function onMouseDown(event) {
  • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
  • options.guides: Boolean — hit-test items that have Item#guide set to true
  • options.selected: Boolean — only hit selected items
  • +
  • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
  • +
  • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
    • @@ -3179,7 +3304,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3228,7 +3353,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3547,6 +3672,16 @@ function onMouseDown(event) {
    +
      +

      Returns:

      + +
    • +Item +
    • + + +
    + @@ -3590,7 +3725,7 @@ function onMouseDown(event) {

    Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -4003,150 +4138,6 @@ Array of Item objects - - - - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    @@ -4318,8 +4309,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -4445,19 +4436,31 @@ Array of Item objects
    @@ -5051,7 +5054,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -5122,7 +5125,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -5146,7 +5149,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -5214,7 +5217,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -5250,7 +5253,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -5347,7 +5350,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -5664,7 +5667,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -5697,7 +5700,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -5730,7 +5733,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -5801,7 +5804,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -5871,7 +5874,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -5901,7 +5904,7 @@ path.on({
    Run
    - -
    +
    @@ -6152,7 +6155,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6199,7 +6202,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -6243,7 +6246,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -6287,7 +6290,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6331,7 +6334,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + - -
    +
    @@ -646,7 +715,7 @@ circle2.blendMode = 'multiply';
    Run
    - -
    +
    @@ -686,6 +755,11 @@ circle2.opacity = 0.5; +
      +

      Default:

      +
    • false
    • +
    +

      Type:

    • @@ -715,14 +789,14 @@ circle2.opacity = 0.5;
      Run
      - -
      +
      @@ -739,10 +813,15 @@ path.selected = true; // Select the path @@ -874,7 +953,7 @@ circle.position += new Point(100, 50);
      Run
      - -
      +
      @@ -906,6 +985,11 @@ circle.position.x += 100; +
        +

        Default:

        +
      • null
      • +
      +

        Type:

      • @@ -993,6 +1077,33 @@ circle.position.x += 100; + + + + + + +
        + + @@ -1144,6 +1255,11 @@ circle.position.x += 100; +
          +

          Default:

          +
        • true
        • +
        +

          Type:

        • @@ -1155,16 +1271,6 @@ circle.position.x += 100;
        - - - - -
        - -
        @@ -1354,7 +1460,7 @@ console.log(group.children[0] == path); // true
        Run
        - -
        +
        @@ -1379,7 +1485,7 @@ group.children[0].fillColor = 'red';
        Run
        - -
        +
        @@ -1406,7 +1512,7 @@ group.children['example'].fillColor = 'orange';
        Run
        - -
        +
        @@ -1584,7 +1690,7 @@ group.firstChild.fillColor = 'green'; @@ -1597,7 +1703,7 @@ group.firstChild.fillColor = 'green';
        Run
        - -
        +
        @@ -1645,7 +1751,7 @@ circle.strokeColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -1704,7 +1810,7 @@ circle.strokeWidth = 10;
        Run
        - -
        +
        @@ -1772,7 +1878,7 @@ line2.strokeCap = 'butt';
        Run
        - -
        +
        @@ -1880,7 +1986,7 @@ path3.strokeJoin = 'bevel';

          Type:

        • - Array + Array of Numbers
        @@ -1893,7 +1999,7 @@ path3.strokeJoin = 'bevel';
        Run
        - -
        +
        @@ -1961,7 +2067,7 @@ path.dashArray = [10, 4]; @@ -1974,7 +2080,7 @@ path.dashArray = [10, 4];
        Run
        - -
        +
        @@ -2047,7 +2153,7 @@ circle.fillColor = new Color(1, 0, 0); @@ -2060,7 +2166,7 @@ circle.fillColor = new Color(1, 0, 0);
        Run
        - -
        +
        @@ -2161,7 +2267,7 @@ var circle = new Path.Circle({ @@ -2189,7 +2295,7 @@ var circle = new Path.Circle({

          Type:

        • - Function + Functionnull
          @@ -2214,7 +2320,7 @@ var circle = new Path.Circle({
          Run
          - -
          +
          @@ -2249,7 +2355,7 @@ path.onFrame = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2269,7 +2375,7 @@ path.onFrame = function(event) {
          Run
          - -
          +
          @@ -2295,7 +2401,7 @@ path.onMouseDown = function(event) {
          Run
          - -
          +
          @@ -2337,7 +2443,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2357,7 +2463,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2394,7 +2500,7 @@ path.onMouseDrag = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2414,7 +2520,7 @@ path.onMouseDrag = function(event) {
          Run
          - -
          +
          @@ -2452,7 +2558,7 @@ path.onMouseUp = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2472,7 +2578,7 @@ path.onMouseUp = function(event) {
          Run
          - -
          +
          @@ -2498,7 +2604,7 @@ path.onClick = function(event) {
          Run
          - -
          +
          @@ -2540,7 +2646,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2560,7 +2666,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2586,7 +2692,7 @@ path.onDoubleClick = function(event) {
          Run
          - -
          +
          @@ -2628,7 +2734,7 @@ for (var i = 0; i < 30; i++) {

            Type:

          • - Function + Functionnull
          @@ -2648,7 +2754,7 @@ for (var i = 0; i < 30; i++) {
          Run
          - -
          +
          @@ -2686,7 +2792,7 @@ path.onMouseMove = function(event) {

            Type:

          • - Function + Functionnull
          @@ -2706,7 +2812,7 @@ path.onMouseMove = function(event) {
          Run
          - -
          +
          @@ -2736,7 +2842,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -2782,7 +2888,7 @@ function onMouseDown(event) {

            Type:

          • - Function + Functionnull
          @@ -2802,7 +2908,7 @@ function onMouseDown(event) {
          Run
          - -
          +
          @@ -2874,7 +2980,7 @@ path.onMouseLeave = function(event) {
          Run
          - -
          +
          @@ -2943,7 +3049,7 @@ circle.set({
          Run
          - -
          +
          @@ -3038,7 +3144,7 @@ for (var i = 0; i < 20; i++) {
        @@ -3086,7 +3199,7 @@ for (var i = 0; i < 20; i++) {
        Run
        - -
        +
        @@ -3136,6 +3249,16 @@ raster.scale(5);
      +
        +

        Returns:

        + +
      • +Boolean +
      • + + +
      + @@ -3147,7 +3270,7 @@ raster.scale(5);
      Run
      - -
      +
      @@ -3285,6 +3408,8 @@ function onMouseDown(event) {
    • options.bounds: Boolean — hit-test the corners and side-centers of the bounding rectangle of items (item.bounds)
    • options.guides: Boolean — hit-test items that have Item#guide set to true
    • options.selected: Boolean — only hit selected items
    • +
    • options.hitUnfilledPaths: Boolean — Allow hitting null or alpha 0 fills for paths
    • +
    • options.hitUnstrokedPaths: Boolean — Allow hitting null or alpha 0 strokes for paths
      @@ -3293,7 +3418,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3342,7 +3467,7 @@ function onMouseDown(event) {
    • point: Point -— the point where the hit-test should be performed +— the point where the hit-test should be performed (in global coordinates system).
    • @@ -3661,6 +3786,16 @@ function onMouseDown(event) {
    +
      +

      Returns:

      + +
    • +Item +
    • + + +
    + @@ -3704,7 +3839,7 @@ function onMouseDown(event) {

    Returns:

  • -SVGElement — the item converted to an SVG node +SVGElementString — the item converted to an SVG node or a String depending on option.asString value
  • @@ -4117,150 +4252,6 @@ Array of Item objects - - - - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    @@ -4432,8 +4423,8 @@ Array of Item objects
  • item: - - +Item +— the item that will replace this item
  • @@ -4559,19 +4550,31 @@ Array of Item objects
    @@ -5165,7 +5168,7 @@ path.rotate(30);
    Run
    - -
    +
    @@ -5236,7 +5239,7 @@ function onFrame(event) {
    Run
    - -
    +
    @@ -5260,7 +5263,7 @@ circle.scale(1.5);
    Run
    - -
    +
    @@ -5328,7 +5331,7 @@ circle.scale(1.5, circle.bounds.bottomLeft);
    Run
    - -
    +
    @@ -5364,7 +5367,7 @@ circle.scale(3, 1);
  • shear: Point -— the horziontal and vertical shear factors as a point +— the horizontal and vertical shear factors as a point
  • @@ -5461,7 +5464,7 @@ circle.scale(3, 1);
  • skew: Point -— the horziontal and vertical skew angles in degrees +— the horizontal and vertical skew angles in degrees
  • @@ -5778,7 +5781,7 @@ circle.scale(3, 1);
    Run
    - -
    +
    @@ -5811,7 +5814,7 @@ circlePath.fitBounds(path.bounds);
    Run
    - -
    +
    @@ -5844,7 +5847,7 @@ circlePath.fitBounds(path.bounds, true);
    Run
    - -
    +
    @@ -5915,7 +5918,7 @@ path.fitBounds(view.bounds);
    Run
    - -
    +
    @@ -5985,7 +5988,7 @@ path.on('mouseleave', function() {
    Run
    - -
    +
    @@ -6015,7 +6018,7 @@ path.on({
    Run
    - -
    +
    @@ -6266,7 +6269,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6313,7 +6316,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    @@ -6357,7 +6360,7 @@ function onMouseMove(event) {
    Run
    - -
    +
    @@ -6401,7 +6404,7 @@ function onMouseDown(event) {
    Run
    - -
    +
    @@ -6445,7 +6448,7 @@ function onMouseDrag(event) {
    Run
    - -
    +
    + + + + + + + + +

    Tweening Functions

    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + +