mirror of
https://github.com/liabru/matter-js.git
synced 2025-03-14 00:38:41 -04:00
Merge branch 'master' into patch-3
This commit is contained in:
commit
0414cc553a
109 changed files with 41039 additions and 14541 deletions
11
.eslintrc
11
.eslintrc
|
@ -29,7 +29,6 @@
|
|||
"process": false,
|
||||
"HTMLElement": false,
|
||||
"require": false,
|
||||
"PIXI": false,
|
||||
"$": false,
|
||||
"Image": false,
|
||||
"navigator": false,
|
||||
|
@ -59,13 +58,17 @@
|
|||
"Vector": false,
|
||||
"Vertices": false,
|
||||
"Render": false,
|
||||
"RenderPixi": false,
|
||||
"Events": false,
|
||||
"Query": false,
|
||||
"Runner": false,
|
||||
"Svg": false,
|
||||
"Metrics": false,
|
||||
"Example": false
|
||||
"Example": false,
|
||||
"__MATTER_VERSION__": false,
|
||||
"__MATTER_IS_DEV__": false,
|
||||
"jest": false,
|
||||
"test": false,
|
||||
"expect": false,
|
||||
"describe": false
|
||||
},
|
||||
"extends": "eslint:recommended"
|
||||
}
|
||||
|
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,14 +1,16 @@
|
|||
.idea
|
||||
node_modules
|
||||
npm-debug.log
|
||||
doc
|
||||
docs
|
||||
matter-doc-theme
|
||||
build/matter-dev.js
|
||||
build/matter-dev.min.js
|
||||
demo/js/lib/matter-dev.js
|
||||
demo/js/Examples.js
|
||||
demo/js/Examples.min.js
|
||||
examples/build
|
||||
test/browser/diffs
|
||||
test/browser/refs
|
||||
test/node/diffs
|
||||
test/node/refs
|
||||
__snapshots__
|
||||
__compare__
|
14
.travis.yml
14
.travis.yml
|
@ -2,10 +2,10 @@ language: node_js
|
|||
sudo: false
|
||||
node_js:
|
||||
- "node"
|
||||
before_install:
|
||||
- npm install -g gulp
|
||||
- mkdir travis-phantomjs
|
||||
- wget https://s3.amazonaws.com/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2 -O $PWD/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2
|
||||
- tar -xvf $PWD/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2 -C $PWD/travis-phantomjs
|
||||
- export PATH=$PWD/travis-phantomjs:$PATH
|
||||
install: npm install
|
||||
install:
|
||||
- npm ci
|
||||
script:
|
||||
- npm run lint
|
||||
- npm run test
|
||||
- npm run build
|
||||
- npm run build-demo
|
137
CHANGELOG.md
137
CHANGELOG.md
|
@ -1,3 +1,140 @@
|
|||
## <small>0.17.1 (2021-04-14)</small>
|
||||
|
||||
* deprecate Engine.run alias replaced by Runner.run ([5817046](https://github.com/liabru/matter-js/commit/5817046))
|
||||
|
||||
|
||||
|
||||
## 0.17.0 (2021-04-11)
|
||||
|
||||
* add Common.setDecomp and Common.getDecomp ([313c150](https://github.com/liabru/matter-js/commit/313c150))
|
||||
* add demo build config and refactor demo ([653a647](https://github.com/liabru/matter-js/commit/653a647))
|
||||
* add docs for all Matter.Render options ([ec3eecc](https://github.com/liabru/matter-js/commit/ec3eecc))
|
||||
* add title to all examples ([f4d72ba](https://github.com/liabru/matter-js/commit/f4d72ba))
|
||||
* added Common.deprecated ([ffa3193](https://github.com/liabru/matter-js/commit/ffa3193))
|
||||
* added Common.warnOnce ([6957dbf](https://github.com/liabru/matter-js/commit/6957dbf))
|
||||
* added Date.now fallback to Common.now, closes #739 ([c06c107](https://github.com/liabru/matter-js/commit/c06c107)), closes [#739](https://github.com/liabru/matter-js/issues/739)
|
||||
* added debug stats and performance monitoring to Matter.Render ([119881b](https://github.com/liabru/matter-js/commit/119881b))
|
||||
* added doc watch script ([164456b](https://github.com/liabru/matter-js/commit/164456b))
|
||||
* added docs for additional engine timing and render properties ([8017bdb](https://github.com/liabru/matter-js/commit/8017bdb))
|
||||
* added Example.stats ([9915007](https://github.com/liabru/matter-js/commit/9915007))
|
||||
* added lastDelta and lastElapsed to engine.timing ([6dc703f](https://github.com/liabru/matter-js/commit/6dc703f))
|
||||
* build demo ([0816454](https://github.com/liabru/matter-js/commit/0816454))
|
||||
* change all examples to use Composite.add instead of the alias World.add ([a3f298f](https://github.com/liabru/matter-js/commit/a3f298f))
|
||||
* changed engine.broadphase to engine.grid ([b74e400](https://github.com/liabru/matter-js/commit/b74e400))
|
||||
* changed Example.views to use render events ([3ac3498](https://github.com/liabru/matter-js/commit/3ac3498))
|
||||
* changed world.gravity to engine.gravity ([6abb3b7](https://github.com/liabru/matter-js/commit/6abb3b7))
|
||||
* deprecated Composites.car and added to car example ([cd9c5d4](https://github.com/liabru/matter-js/commit/cd9c5d4))
|
||||
* deprecated Composites.newtonsCradle and added to newtonsCradle example ([9ad980b](https://github.com/liabru/matter-js/commit/9ad980b))
|
||||
* deprecated Composites.softBody and added to softBody and cloth examples ([818f354](https://github.com/liabru/matter-js/commit/818f354))
|
||||
* improve Render.debug ([1753bf0](https://github.com/liabru/matter-js/commit/1753bf0))
|
||||
* migrate Matter.World to the equivalent Matter.Composite ([5dbec9b](https://github.com/liabru/matter-js/commit/5dbec9b))
|
||||
* remove deprecated backwards compatibility engine events from Matter.Runner ([76bf80e](https://github.com/liabru/matter-js/commit/76bf80e))
|
||||
* remove deprecated backwards compatibility render integration from Matter.Engine ([1aa8ed0](https://github.com/liabru/matter-js/commit/1aa8ed0))
|
||||
* remove deprecated backwards compatibility render integration from Matter.Runner ([6805f85](https://github.com/liabru/matter-js/commit/6805f85))
|
||||
* remove deprecated Matter.Metrics ([63a9e98](https://github.com/liabru/matter-js/commit/63a9e98))
|
||||
* remove deprecated Matter.RenderPixi ([08a515b](https://github.com/liabru/matter-js/commit/08a515b))
|
||||
* remove unused render shadow function ([e49834d](https://github.com/liabru/matter-js/commit/e49834d))
|
||||
* run all examples in browser tests ([5734bfd](https://github.com/liabru/matter-js/commit/5734bfd))
|
||||
* set render showDebug option on examples stress and stress2 ([f2ef3aa](https://github.com/liabru/matter-js/commit/f2ef3aa))
|
||||
* update matter-tools ([f8d366a](https://github.com/liabru/matter-js/commit/f8d366a))
|
||||
|
||||
|
||||
|
||||
## <small>0.16.1 (2021-01-31)</small>
|
||||
|
||||
* add log capture and reporting in tests ([7bfd3c2](https://github.com/liabru/matter-js/commit/7bfd3c2))
|
||||
* add matter-wrap as dev dependency ([ef7c4c6](https://github.com/liabru/matter-js/commit/ef7c4c6))
|
||||
* catch missing plugin require in examples ([1ba1255](https://github.com/liabru/matter-js/commit/1ba1255))
|
||||
* change example matter-wrap require precedence ([aa1e4e7](https://github.com/liabru/matter-js/commit/aa1e4e7))
|
||||
* change perf threshold in test ([7b00354](https://github.com/liabru/matter-js/commit/7b00354))
|
||||
* change test worker decomp require ([5e746b0](https://github.com/liabru/matter-js/commit/5e746b0))
|
||||
* disable jest cache ([8ee0ebb](https://github.com/liabru/matter-js/commit/8ee0ebb))
|
||||
* enable useful dev server features ([839f7d9](https://github.com/liabru/matter-js/commit/839f7d9))
|
||||
* fix decomp require and improve warning message ([e87f64a](https://github.com/liabru/matter-js/commit/e87f64a))
|
||||
* fix dev server externals ([1f2f9fe](https://github.com/liabru/matter-js/commit/1f2f9fe))
|
||||
* fix named require in test ([92080ff](https://github.com/liabru/matter-js/commit/92080ff))
|
||||
* improve CI speed ([1af64eb](https://github.com/liabru/matter-js/commit/1af64eb))
|
||||
* improve docs for Bodies.fromVertices ([2ade78f](https://github.com/liabru/matter-js/commit/2ade78f))
|
||||
* improve stack examples with exact contact ([522f4e8](https://github.com/liabru/matter-js/commit/522f4e8))
|
||||
* improve test report log ([b5326f8](https://github.com/liabru/matter-js/commit/b5326f8))
|
||||
|
||||
|
||||
|
||||
## 0.16.0 (2021-01-17)
|
||||
|
||||
* added removeDuplicatePoints option from poly-decomp 0.3.0 to Bodies.fromVertices ([#639](https://github.com/liabru/matter-js/issues/639), [947cb97](https://github.com/liabru/matter-js/commit/947cb97), [a9694e6](https://github.com/liabru/matter-js/commit/a9694e6))
|
||||
* added support for > and >= operators in plugin version ranges ([0792716](https://github.com/liabru/matter-js/commit/0792716))
|
||||
* added support for example versioning in tests ([31d0ace](https://github.com/liabru/matter-js/commit/31d0ace))
|
||||
* added version targets for examples ([142b7de](https://github.com/liabru/matter-js/commit/142b7de))
|
||||
* added warning check on browser tests ([12377cc](https://github.com/liabru/matter-js/commit/12377cc))
|
||||
* changed svg and terrain example to use fetch ([5551cd5](https://github.com/liabru/matter-js/commit/5551cd5))
|
||||
* changed deprecated comments to avoid confusion ([1e73cab](https://github.com/liabru/matter-js/commit/1e73cab))
|
||||
* fixed poly-decomp external require ([882e07c](https://github.com/liabru/matter-js/commit/882e07c))
|
||||
* removed bower.json ([f71d4c0](https://github.com/liabru/matter-js/commit/f71d4c0))
|
||||
* removed unused dev dependency run-sequence ([be592fd](https://github.com/liabru/matter-js/commit/be592fd))
|
||||
* updated dev dependencies ([151eb30](https://github.com/liabru/matter-js/commit/151eb30))
|
||||
* updated matter-tools ([5c66458](https://github.com/liabru/matter-js/commit/5c66458))
|
||||
* updated matter-tools ([33e8fe8](https://github.com/liabru/matter-js/commit/33e8fe8))
|
||||
* updated demo matter-tools ([a694ae5](https://github.com/liabru/matter-js/commit/a694ae5))
|
||||
* updated demo pathseg ([9c5325b](https://github.com/liabru/matter-js/commit/9c5325b))
|
||||
* updated readme ([3089b41](https://github.com/liabru/matter-js/commit/3089b41))
|
||||
|
||||
|
||||
|
||||
## 0.15.0 (2020-12-24)
|
||||
|
||||
* add window global, stub require and handle bad values in test tools ([497ac80](https://github.com/liabru/matter-js/commit/497ac80))
|
||||
* added Body.setCentre, closes #684, closes #461, closes #679 ([2ec247b](https://github.com/liabru/matter-js/commit/2ec247b)), closes [#684](https://github.com/liabru/matter-js/issues/684) [#461](https://github.com/liabru/matter-js/issues/461) [#679](https://github.com/liabru/matter-js/issues/679)
|
||||
* added browser tests ([ceb7cd5](https://github.com/liabru/matter-js/commit/ceb7cd5))
|
||||
* Added build comparison tools and tests ([b7c938a](https://github.com/liabru/matter-js/commit/b7c938a))
|
||||
* added check for window in Common.now ([9ef9d02](https://github.com/liabru/matter-js/commit/9ef9d02))
|
||||
* added comparison output file option to test tools ([45aae25](https://github.com/liabru/matter-js/commit/45aae25))
|
||||
* Added config and test files to lint ([21e4ea6](https://github.com/liabru/matter-js/commit/21e4ea6))
|
||||
* added Constraint.pointAWorld and Constraint.pointBWorld ([3c32969](https://github.com/liabru/matter-js/commit/3c32969))
|
||||
* added examples to dev server bundle and commit built examples ([fe80478](https://github.com/liabru/matter-js/commit/fe80478))
|
||||
* added module export to examples ([f9ea799](https://github.com/liabru/matter-js/commit/f9ea799))
|
||||
* added overlap metric to test tools ([3fd674d](https://github.com/liabru/matter-js/commit/3fd674d))
|
||||
* added release scripts ([341c247](https://github.com/liabru/matter-js/commit/341c247))
|
||||
* added tag push to release task ([060283b](https://github.com/liabru/matter-js/commit/060283b))
|
||||
* added timing to engine snapshot ([e0cdbb8](https://github.com/liabru/matter-js/commit/e0cdbb8))
|
||||
* Added watch content base to dev server ([f471d4e](https://github.com/liabru/matter-js/commit/f471d4e))
|
||||
* added webpack build script ([046013e](https://github.com/liabru/matter-js/commit/046013e))
|
||||
* changed alpha build configuration ([182c84a](https://github.com/liabru/matter-js/commit/182c84a))
|
||||
* changed demo to auto populate examples with sourceLink and init ([5b0d34b](https://github.com/liabru/matter-js/commit/5b0d34b))
|
||||
* changed demo to serve without sub-directory ([823bbc0](https://github.com/liabru/matter-js/commit/823bbc0))
|
||||
* changed docs build config ([864452d](https://github.com/liabru/matter-js/commit/864452d))
|
||||
* changed example tests to use jest ([104d319](https://github.com/liabru/matter-js/commit/104d319))
|
||||
* fix decomp import in Bodies.fromVertices ([94e9614](https://github.com/liabru/matter-js/commit/94e9614))
|
||||
* fix decomp require ([0af1645](https://github.com/liabru/matter-js/commit/0af1645))
|
||||
* fix issues with render pixel ratio, closes #686, closes #687 ([d577477](https://github.com/liabru/matter-js/commit/d577477)), closes [#686](https://github.com/liabru/matter-js/issues/686) [#687](https://github.com/liabru/matter-js/issues/687)
|
||||
* fix lint ([5a0079d](https://github.com/liabru/matter-js/commit/5a0079d))
|
||||
* fix lint issues ([9ca21c1](https://github.com/liabru/matter-js/commit/9ca21c1))
|
||||
* fix path to build in test worker ([fcdb4fa](https://github.com/liabru/matter-js/commit/fcdb4fa))
|
||||
* fix preversion script ([c368c14](https://github.com/liabru/matter-js/commit/c368c14))
|
||||
* fix terrain example module export ([4a967ec](https://github.com/liabru/matter-js/commit/4a967ec))
|
||||
* Fix typo in docs ([c486635](https://github.com/liabru/matter-js/commit/c486635))
|
||||
* fixed plugins in compare ([82bb415](https://github.com/liabru/matter-js/commit/82bb415))
|
||||
* implemented threaded comparison testing ([285d70d](https://github.com/liabru/matter-js/commit/285d70d))
|
||||
* Optimized Body's hidden class ([b3220cf](https://github.com/liabru/matter-js/commit/b3220cf))
|
||||
* Optimized Events.trigger method when no event is emitted ([b17cb48](https://github.com/liabru/matter-js/commit/b17cb48))
|
||||
* remove gulp ([6a28090](https://github.com/liabru/matter-js/commit/6a28090))
|
||||
* remove old demo libs ([13c7eb5](https://github.com/liabru/matter-js/commit/13c7eb5))
|
||||
* removed unused gulp release tasks ([e5a7311](https://github.com/liabru/matter-js/commit/e5a7311))
|
||||
* removed yuidocjs dev dependency ([ee848d2](https://github.com/liabru/matter-js/commit/ee848d2))
|
||||
* Set loose build version on dev server ([1fcf292](https://github.com/liabru/matter-js/commit/1fcf292))
|
||||
* update build script ([90abab6](https://github.com/liabru/matter-js/commit/90abab6))
|
||||
* update default render theme ([d258411](https://github.com/liabru/matter-js/commit/d258411))
|
||||
* update demo and example render styles ([6dd5ec5](https://github.com/liabru/matter-js/commit/6dd5ec5))
|
||||
* update dependencies ([e1e058c](https://github.com/liabru/matter-js/commit/e1e058c)) ([5f5b8a1](https://github.com/liabru/matter-js/commit/5f5b8a1))
|
||||
* update examples build config and scripts ([69afb11](https://github.com/liabru/matter-js/commit/69afb11))
|
||||
* update package lock ([ac3da07](https://github.com/liabru/matter-js/commit/ac3da07))
|
||||
* updated build scripts ([6b698ea](https://github.com/liabru/matter-js/commit/6b698ea))
|
||||
* updated ci ([288b9cd](https://github.com/liabru/matter-js/commit/288b9cd))
|
||||
* updated docs ([50cf171](https://github.com/liabru/matter-js/commit/50cf171))
|
||||
* updated readme ([ea5c012](https://github.com/liabru/matter-js/commit/ea5c012)) ([61b1963](https://github.com/liabru/matter-js/commit/61b1963))
|
||||
|
||||
|
||||
|
||||
<a name="0.14.2"></a>
|
||||
## <small>0.14.2 (2018-06-11)</small>
|
||||
|
||||
|
|
|
@ -2,22 +2,51 @@
|
|||
|
||||
## License Agreement
|
||||
|
||||
When providing any contributions, you must agree and be legally entitled to provide them for use and distribution in the project under the same terms as the [license](https://github.com/liabru/matter-js/blob/master/LICENSE), otherwise they can not be accepted.
|
||||
|
||||
## Building
|
||||
|
||||
To build you must first install [node.js](http://nodejs.org/) and [gulp](http://gulpjs.com/), then run
|
||||
|
||||
npm install
|
||||
|
||||
This will install the required build dependencies, then run
|
||||
|
||||
gulp dev
|
||||
|
||||
which is a task that builds the `matter-dev.js` file, spawns a development server and opens `http://localhost:8000/demo/index.html` in your browser. Any changes you make to the source will automatically rebuild `matter-dev.js` and reload your browser.
|
||||
By providing any kind of contribution to this project, **you must agree and be legally entitled** to provide them for use and distribution as a part of this project **wholly under the same terms as in the original included [license](https://github.com/liabru/matter-js/blob/master/LICENSE)**.
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions by pull request are welcome! Please ensure they follow the same style and architecture as the rest of the code. You should run `gulp test` and ensure there are no reported errors. Please do not include any changes to the files in the `build` directory. All contributors must agree to the license agreement described at the beginning of this document.
|
||||
Contributions by pull request or issues are welcome. Please ensure they follow the same style and architecture as the rest of the code. Use `npm run lint` and see [Testing](#Testing) below before submitting. Please **do not include** any changes to the files in the `build` directory.
|
||||
|
||||
If you'd like to contribute but not sure what to work on, feel free to get in touch.
|
||||
Before contributing please read the license agreement described at the beginning of this document.
|
||||
|
||||
## Building
|
||||
|
||||
To build you must first install [node.js](http://nodejs.org), then run
|
||||
|
||||
npm install
|
||||
|
||||
which will install the required build dependencies, then run
|
||||
|
||||
npm start
|
||||
|
||||
which will run the development server and opens `http://localhost:8000/` in your browser. Any changes you make to the source will automatically rebuild and reload the page.
|
||||
|
||||
## Testing
|
||||
|
||||
All contributions should pass when running the commands
|
||||
|
||||
- `npm run lint`
|
||||
- `npm run test`
|
||||
- `npm run test-browser`
|
||||
|
||||
The output of `npm run test` also includes a [comparison report](https://github.com/liabru/matter-js/pull/794), which highlights changes in results, performance and accuracy against the last release build.
|
||||
|
||||
## Commands
|
||||
|
||||
The following development commands can be run at the terminal
|
||||
|
||||
- **npm start**
|
||||
runs development server and opens demo page
|
||||
- **npm run build**
|
||||
creates a release build
|
||||
- **npm run build-demo**
|
||||
builds the demo
|
||||
- **npm run lint**
|
||||
runs the linter
|
||||
- **npm run test**
|
||||
runs the tests and compares results
|
||||
- **npm run test-browser**
|
||||
runs the browser tests
|
||||
- **npm run doc**
|
||||
builds the documentation
|
||||
|
|
313
Gulpfile.js
313
Gulpfile.js
|
@ -1,313 +0,0 @@
|
|||
var gulp = require('gulp');
|
||||
var uglify = require('gulp-uglify');
|
||||
var rename = require('gulp-rename');
|
||||
var header = require('gulp-header');
|
||||
var eslint = require('gulp-eslint');
|
||||
var bump = require('gulp-bump');
|
||||
var changelog = require('gulp-conventional-changelog');
|
||||
var tag = require('gulp-tag-version');
|
||||
var release = require('gulp-github-release');
|
||||
var sequence = require('run-sequence');
|
||||
var gutil = require('gulp-util');
|
||||
var replace = require('gulp-replace');
|
||||
var webserver = require('gulp-webserver');
|
||||
var concat = require('gulp-concat');
|
||||
var preprocess = require('gulp-preprocess');
|
||||
var browserify = require('browserify');
|
||||
var derequire = require('gulp-derequire');
|
||||
var transform = require('vinyl-transform');
|
||||
var through2 = require('through2');
|
||||
var pkg = require('./package.json');
|
||||
var clone = require('gulp-clone');
|
||||
var livereload = require('connect-livereload');
|
||||
var es = require('event-stream');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var watchify = require('watchify');
|
||||
var extend = require('util')._extend;
|
||||
var exec = require('child_process').exec;
|
||||
var buildDirectory = 'build';
|
||||
var server;
|
||||
|
||||
gulp.task('default', ['build:dev']);
|
||||
|
||||
gulp.task('dev', function(callback) {
|
||||
sequence('watch', 'serve', callback);
|
||||
});
|
||||
|
||||
gulp.task('release', function(callback) {
|
||||
shell('git status --porcelain', function(err, stdout) {
|
||||
if (stdout && stdout.trim()) {
|
||||
throw new gutil.PluginError({
|
||||
plugin: 'release',
|
||||
message: 'cannot build release as there are uncomitted changes'
|
||||
});
|
||||
} else {
|
||||
sequence('test', 'bump', 'reload', 'build:release', 'doc', 'changelog', callback);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('release:push', function(callback) {
|
||||
shell('git status --porcelain', function(err, stdout) {
|
||||
if (stdout && stdout.trim()) {
|
||||
throw new gutil.PluginError({
|
||||
plugin: 'release',
|
||||
message: 'cannot push release as it has not yet been committed'
|
||||
});
|
||||
} else {
|
||||
sequence('tag', 'release:push:git', 'release:push:npm', callback);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('release:push:github', function(callback) {
|
||||
return gulp.src([
|
||||
'CHANGELOG.md',
|
||||
'LICENSE',
|
||||
buildDirectory + '/matter.min.js',
|
||||
buildDirectory + '/matter.js'
|
||||
]).pipe(release({
|
||||
owner: 'liabru',
|
||||
repo: pkg.name,
|
||||
tag: pkg.version,
|
||||
name: 'Matter.js ' + pkg.version
|
||||
}));
|
||||
});
|
||||
|
||||
gulp.task('release:push:git', function(callback) {
|
||||
shell('git push', callback);
|
||||
});
|
||||
|
||||
gulp.task('release:push:npm', function(callback) {
|
||||
shell('npm publish', callback);
|
||||
});
|
||||
|
||||
gulp.task('build:dev', function() {
|
||||
return build(extend(extend({}, pkg), { version: pkg.version + '-dev' }));
|
||||
});
|
||||
|
||||
gulp.task('build:edge', function() {
|
||||
return build(extend(extend({}, pkg), { version: pkg.version + '-alpha' }));
|
||||
});
|
||||
|
||||
gulp.task('build:release', function() {
|
||||
return build(extend(extend({}, pkg), { version: pkg.version }));
|
||||
});
|
||||
|
||||
gulp.task('build:examples', function() {
|
||||
var options = extend(extend({}, pkg), { version: pkg.version + '-dev' });
|
||||
options.name = options.name + '-examples';
|
||||
options.date = options.date || new Date().toISOString().slice(0, 10);
|
||||
options.author = '@liabru';
|
||||
|
||||
return gulp.src('examples/**/*.js')
|
||||
.pipe(concat('examples.js'))
|
||||
.pipe(header(banner, { context: options }))
|
||||
.pipe(gulp.dest('examples/build'));
|
||||
});
|
||||
|
||||
gulp.task('watch', function() {
|
||||
var b = browserify({
|
||||
entries: ['src/module/main.js'],
|
||||
standalone: 'Matter',
|
||||
plugin: [watchify]
|
||||
});
|
||||
|
||||
var bundle = function() {
|
||||
gutil.log('Updated bundle build/matter-dev.js');
|
||||
b.bundle()
|
||||
.on('error', function(err) {
|
||||
gutil.log('ERROR', err.message);
|
||||
this.emit('end');
|
||||
})
|
||||
.pipe(through2({ objectMode: true }, function(chunk, encoding, callback) {
|
||||
return callback(
|
||||
null,
|
||||
chunk.toString().replace(/@@VERSION@@/g, pkg.version + '-dev')
|
||||
);
|
||||
}))
|
||||
.pipe(fs.createWriteStream('build/matter-dev.js'));
|
||||
};
|
||||
|
||||
b.on('update', bundle);
|
||||
bundle();
|
||||
});
|
||||
|
||||
gulp.task('bump', function() {
|
||||
return gulp.src(['package.json', 'bower.json'])
|
||||
.pipe(bump({ type: process.argv[4] || 'minor' }))
|
||||
.pipe(gulp.dest('.'));
|
||||
});
|
||||
|
||||
gulp.task('reload', function(callback) {
|
||||
delete require.cache[require.resolve('./package.json')];
|
||||
pkg = require('./package.json');
|
||||
callback();
|
||||
});
|
||||
|
||||
gulp.task('tag', function() {
|
||||
return gulp.src('package.json')
|
||||
.pipe(tag({ prefix: '' }));
|
||||
});
|
||||
|
||||
gulp.task('changelog', function () {
|
||||
return gulp.src('CHANGELOG.md')
|
||||
.pipe(changelog())
|
||||
.pipe(gulp.dest('.'));
|
||||
});
|
||||
|
||||
gulp.task('serve', function() {
|
||||
serve(false);
|
||||
});
|
||||
|
||||
gulp.task('serve:test', function() {
|
||||
serve(true);
|
||||
});
|
||||
|
||||
gulp.task('serve:stop', function() {
|
||||
if (server) {
|
||||
try {
|
||||
server.emit('kill');
|
||||
} catch (e) {} // eslint-disable-line no-empty
|
||||
gutil.log('Web server stopped');
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task('test', function(callback) {
|
||||
// TODO: fix tests by switching to nightmare instead of phantom
|
||||
// sequence('serve:test', 'lint', 'build:dev', 'test:browser', 'test:node', 'serve:stop', callback);
|
||||
sequence('lint', callback);
|
||||
});
|
||||
|
||||
gulp.task('test:browser', function(callback) {
|
||||
shell('phantomjs test/browser/TestDemo.js', callback);
|
||||
});
|
||||
|
||||
gulp.task('test:node', function(callback) {
|
||||
shell('node test/node/TestDemo.js', callback);
|
||||
});
|
||||
|
||||
gulp.task('lint', function() {
|
||||
return gulp.src([
|
||||
'src/**/*.js',
|
||||
'demo/js/*.js',
|
||||
'examples/*.js',
|
||||
'test/browser/TestDemo.js',
|
||||
'test/node/TestDemo.js',
|
||||
'Gulpfile.js'
|
||||
])
|
||||
.pipe(eslint())
|
||||
.pipe(eslint.format())
|
||||
.pipe(eslint.failAfterError());
|
||||
});
|
||||
|
||||
gulp.task('doc', function(callback) {
|
||||
var options = {
|
||||
paths: ['src'],
|
||||
themedir: 'matter-doc-theme',
|
||||
outdir: 'doc/build',
|
||||
linkNatives: true,
|
||||
project: {
|
||||
name: pkg.name + ' ' + pkg.version + ' Physics Engine API Docs',
|
||||
description: pkg.description,
|
||||
version: pkg.version,
|
||||
url: pkg.homepage
|
||||
}
|
||||
};
|
||||
|
||||
var Y = require('yuidocjs');
|
||||
var json = new Y.YUIDoc(options).run();
|
||||
json.project = options.project;
|
||||
|
||||
var builder = new Y.DocBuilder(options, json);
|
||||
builder.compile(callback);
|
||||
});
|
||||
|
||||
var serve = function(isTest) {
|
||||
process.on('uncaughtException', function(err) {
|
||||
if (err.errno === 'EADDRINUSE') {
|
||||
gutil.log('Server already running (or port is otherwise in use)');
|
||||
}
|
||||
});
|
||||
|
||||
server = gulp.src('.')
|
||||
.pipe(webserver({
|
||||
host: '0.0.0.0',
|
||||
livereload: {
|
||||
enable: !isTest,
|
||||
filter: function(filename) {
|
||||
return filename.match(/build|demo/);
|
||||
}
|
||||
},
|
||||
middleware: livereload(),
|
||||
open: isTest ? false : 'http://localhost:8000/demo/index.html',
|
||||
directoryListing: true
|
||||
}));
|
||||
};
|
||||
|
||||
var build = function(options) {
|
||||
var isDev = options.version.indexOf('-dev') !== -1,
|
||||
filename = buildDirectory + (isDev ? '/matter-dev' : '/matter'),
|
||||
dest = filename + '.js',
|
||||
destMin = filename + '.min.js';
|
||||
|
||||
options.date = options.date || new Date().toISOString().slice(0, 10);
|
||||
options.author = '@liabru';
|
||||
|
||||
gutil.log('Building', filename, options.date);
|
||||
|
||||
var compiled = gulp.src(['src/module/main.js'])
|
||||
.pipe(through2.obj(function(file, enc, next){
|
||||
browserify(file.path, { standalone: 'Matter' })
|
||||
.bundle(function(err, res){
|
||||
file.contents = res;
|
||||
next(null, file);
|
||||
});
|
||||
}))
|
||||
.pipe(derequire())
|
||||
.pipe(replace('@@VERSION@@', options.version));
|
||||
|
||||
if (!isDev) {
|
||||
compiled.pipe(preprocess({ context: { DEBUG: false } }));
|
||||
}
|
||||
|
||||
var build = compiled.pipe(clone())
|
||||
.pipe(header(banner + '\n' + license + '\n\n', { context: options }))
|
||||
.pipe(rename(dest))
|
||||
.pipe(gulp.dest('.'));
|
||||
|
||||
var buildMin = compiled.pipe(clone())
|
||||
.pipe(uglify({ output: { max_line_len: 1000 } }))
|
||||
.pipe(header(banner, { context: options }))
|
||||
.pipe(rename(destMin))
|
||||
.pipe(gulp.dest('.'));
|
||||
|
||||
return es.merge(build, buildMin);
|
||||
};
|
||||
|
||||
var shell = function(command, callback) {
|
||||
var args = process.argv.slice(3).join(' '),
|
||||
proc = exec(command + ' ' + args, function(err, stdout, stderr) {
|
||||
callback(err, stdout, stderr, proc);
|
||||
});
|
||||
|
||||
proc.stdout.on('data', function(data) {
|
||||
process.stdout.write(data);
|
||||
});
|
||||
|
||||
proc.stderr.on('data', function(data) {
|
||||
process.stderr.write(data);
|
||||
});
|
||||
};
|
||||
|
||||
var license = fs.readFileSync('src/module/license.js');
|
||||
|
||||
var banner = [
|
||||
'/**',
|
||||
'* <%= context.name %> <%= context.version %> by <%= context.author %> <%= context.date %>',
|
||||
'* <%= context.homepage %>',
|
||||
'* License <%= context.license %>',
|
||||
'*/',
|
||||
''
|
||||
].join('\n');
|
135
README.md
135
README.md
|
@ -1,10 +1,10 @@
|
|||
<img alt="Matter.js" src="http://brm.io/matter-js/img/matter-js.svg" width="300">
|
||||
<img alt="Matter.js" src="https://brm.io/matter-js/img/matter-js.svg" width="300">
|
||||
|
||||
> *Matter.js* is a JavaScript 2D rigid body physics engine for the web
|
||||
|
||||
[brm.io/matter-js](http://brm.io/matter-js/)
|
||||
[brm.io/matter-js](https://brm.io/matter-js/)
|
||||
|
||||
[Demos](#demos) - [Gallery](#gallery) - [Features](#features) - [Plugins](#plugins) - [Install](#install) - [Usage](#usage) - [Examples](#examples) - [Docs](#documentation) - [Wiki](https://github.com/liabru/matter-js/wiki) - [References](#references) - [License](#license)
|
||||
[Demos](#demos) ・ [Gallery](#gallery) ・ [Features](#features) ・ [Plugins](#plugins) ・ [Install](#install) ・ [Usage](#usage) ・ [Examples](#examples) ・ [Docs](#documentation) ・ [Wiki](https://github.com/liabru/matter-js/wiki) ・ [References](#references) ・ [License](#license)
|
||||
|
||||
[](https://travis-ci.org/liabru/matter-js)
|
||||
|
||||
|
@ -14,51 +14,55 @@
|
|||
<tr>
|
||||
<td>
|
||||
<ul>
|
||||
<li><a href="http://brm.io/matter-js/demo/#mixed">Mixed Shapes</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#mixedSolid">Solid Shapes</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#svg">Concave SVG Paths</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#terrain">Concave Terrain</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#concave">Concave Bodies</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#compound">Compound Bodies</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#newtonsCradle">Newton's Cradle</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#wreckingBall">Wrecking Ball</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#slingshot">Slingshot Game</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#rounded">Rounded Corners</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#views">Views</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#timescale">Time Scaling</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#manipulation">Body Manipulation</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#compositeManipulation">Composite Manipulation</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#raycasting">Raycasting</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#sprites">Sprites</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#pyramid">Pyramid</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#car">Car</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#catapult">Catapult</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#gravity">Reverse Gravity</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#mixed">Mixed Shapes</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#mixedSolid">Solid Shapes</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#svg">Concave SVG Paths</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#terrain">Concave Terrain</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#concave">Concave Bodies</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#compound">Compound Bodies</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#newtonsCradle">Newton's Cradle</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#wreckingBall">Wrecking Ball</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#slingshot">Slingshot Game</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#rounded">Rounded Corners</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#views">Views</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#timescale">Time Scaling</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#manipulation">Body Manipulation</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#compositeManipulation">Composite Manipulation</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li><a href="http://brm.io/matter-js/demo/#bridge">Bridge</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#avalanche">Avalanche</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#softBody">Basic Soft Bodies</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#cloth">Cloth</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#events">Events</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#collisionFiltering">Collision Filtering</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#chains">Chains</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#ballPool">Ball Pool</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#stack">Stack</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#circleStack">Circle Stack</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#compoundStack">Compound Stack</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#restitution">Restitution</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#friction">Friction</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#airFriction">Air Friction</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#staticFriction">Static Friction</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#sleeping">Sleeping</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#broadphase">Grid Broadphase</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#beachBalls">Beach Balls</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#stress">Stress 1</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#stress2">Stress 2</a></li>
|
||||
<li><a href="http://brm.io/matter-js/demo/#sensors">Sensors</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#raycasting">Raycasting</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#sprites">Sprites</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#pyramid">Pyramid</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#car">Car</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#catapult">Catapult</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#gravity">Reverse Gravity</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#bridge">Bridge</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#avalanche">Avalanche</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#softBody">Basic Soft Bodies</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#cloth">Cloth</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#events">Events</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#collisionFiltering">Collision Filtering</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#chains">Chains</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#ballPool">Ball Pool</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li><a href="https://brm.io/matter-js/demo/#stack">Stack</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#circleStack">Circle Stack</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#compoundStack">Compound Stack</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#restitution">Restitution</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#friction">Friction</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#airFriction">Air Friction</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#staticFriction">Static Friction</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#sleeping">Sleeping</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#broadphase">Grid Broadphase</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#beachBalls">Beach Balls</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#stress">Stress 1</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#stress2">Stress 2</a></li>
|
||||
<li><a href="https://brm.io/matter-js/demo/#sensors">Sensors</a></li>
|
||||
</ul>
|
||||
<br>
|
||||
</td>
|
||||
|
@ -69,16 +73,18 @@
|
|||
|
||||
See how others are using matter.js physics
|
||||
|
||||
- [Les métamorphoses de Mr. Kalia](http://lab212.org/Les-metamorphoses-de-Mr-Kalia) by Lab212 for Google
|
||||
- [4ify](http://pauliescanlon.io/4ify-channel-4-rebrand-2/) by Supernatural for Channel 4
|
||||
- [Adobe Analytics Live Stream](http://adobefirehose.mediarain.com/) by Rain for Adobe
|
||||
- [Blood Sweat & Tools Interactive](http://bloodsweatandtools.discovery.ca/gamebench/) by Jam3 for Discovery
|
||||
- [Oracle OpenWorld Experiment](http://theappslab.com/2016/10/10/how-i-attended-oracle-openworld-2016/) by Ed Jones for Oracle
|
||||
- [Pablo The Flamingo](http://pablotheflamingo.com/) by Nathan Gordon
|
||||
- [Goblins and Grottos](http://store.steampowered.com/app/389190) by Psychic Software
|
||||
- [masQueLaCara](https://www.instagram.com/p/BCFqCs6JNsq/) by Zach Lieberman for Art Blocks Houston
|
||||
- [#GIFMYLIVE](http://bonhommeparis.com/en/projects/arte-gifmylive) by Bonhomme for Arte
|
||||
- [Hype](http://tumult.com/hype/pro/) by Tumult
|
||||
- [Patrick Heng](https://patrickheng.com/) by Patrick Heng
|
||||
- [USELESS](https://useless.london/) by Nice and Serious
|
||||
- [Secret 7](https://secret-7.com/) by Goodness
|
||||
- [New Company](https://www.new.company/) by New Company
|
||||
- [Game of The Year](https://gameoftheyear.withgoogle.com/) by Google
|
||||
- [Pablo The Flamingo](https://pablotheflamingo.com/) by Nathan Gordon
|
||||
- [Les métamorphoses de Mr. Kalia](https://lab212.org/oeuvres/2:art/18/Les-metamorphoses-de-Mr-Kalia) by Lab212
|
||||
- [Phaser](https://phaser.io/) by Photon Storm
|
||||
- [Sorry I Have No Filter](https://sorryihavenofilter.com/pages/about/) by Jessica Walsh
|
||||
- [Fuse](https://fuse.blog/) by Fuse
|
||||
- [Glyphfinder](https://www.glyphfinder.com/) by überdosis
|
||||
- [Isolation](https://isolation.is/postcards/my-week) by sabato studio
|
||||
- [more...](https://github.com/liabru/matter-js/wiki/Gallery)
|
||||
|
||||
### Features
|
||||
|
@ -111,15 +117,14 @@ See how others are using matter.js physics
|
|||
|
||||
### Install
|
||||
|
||||
Download the [edge build (master)](https://github.com/liabru/matter-js/blob/master/build/matter.js) or get a [stable release](https://github.com/liabru/matter-js/releases) and include the script in your web page:
|
||||
You can install using package managers [npm](https://www.npmjs.org/package/matter-js) and [Yarn](https://yarnpkg.com/) using:
|
||||
|
||||
npm install matter-js
|
||||
|
||||
Alternatively you can download a [stable release](https://github.com/liabru/matter-js/tags) or try the latest experimental [alpha build](https://github.com/liabru/matter-js/tree/master/build) (master) and include the script in your web page:
|
||||
|
||||
<script src="matter.js" type="text/javascript"></script>
|
||||
|
||||
You can also install using the package managers [Bower](http://bower.io/search/?q=matter-js) and [NPM](https://www.npmjs.org/package/matter-js).
|
||||
|
||||
bower install matter-js
|
||||
npm install matter-js
|
||||
|
||||
### Usage
|
||||
|
||||
Visit the [Getting started](https://github.com/liabru/matter-js/wiki/Getting-started) wiki page for a minimal usage example which should work in both browsers and Node.js.
|
||||
|
@ -132,7 +137,7 @@ See the list of [tutorials](https://github.com/liabru/matter-js/wiki/Tutorials).
|
|||
### Examples
|
||||
|
||||
See the [examples](https://github.com/liabru/matter-js/tree/master/examples) directory which contains the source for all [demos](#demos).
|
||||
There are even more examples on [codepen](http://codepen.io/collection/Fuagy/).
|
||||
There are even more examples on [codepen](https://codepen.io/collection/Fuagy/).
|
||||
|
||||
### Plugins
|
||||
|
||||
|
@ -145,17 +150,17 @@ The engine can be extended through plugins, see these resources:
|
|||
|
||||
### Documentation
|
||||
|
||||
See the [API Documentation](http://brm.io/matter-js/docs/) and the [wiki](https://github.com/liabru/matter-js/wiki)
|
||||
See the [API Documentation](https://brm.io/matter-js/docs/) and the [wiki](https://github.com/liabru/matter-js/wiki)
|
||||
|
||||
### Building and Contributing
|
||||
|
||||
To build you must first install [node.js](http://nodejs.org/) and [gulp](http://gulpjs.com/), then run
|
||||
To build you must first install [node.js](https://nodejs.org/), then run
|
||||
|
||||
npm install
|
||||
|
||||
This will install the required build dependencies, then run
|
||||
|
||||
gulp dev
|
||||
npm run dev
|
||||
|
||||
to spawn a development server. For information on contributing see [CONTRIBUTING.md](https://github.com/liabru/matter-js/blob/master/CONTRIBUTING.md).
|
||||
|
||||
|
@ -169,7 +174,7 @@ See the wiki page on [References](https://github.com/liabru/matter-js/wiki/Refer
|
|||
|
||||
### License
|
||||
|
||||
Matter.js is licensed under [The MIT License (MIT)](http://opensource.org/licenses/MIT)
|
||||
Matter.js is licensed under [The MIT License (MIT)](https://opensource.org/licenses/MIT)
|
||||
Copyright (c) 2014 Liam Brummitt
|
||||
|
||||
This license is also supplied with the release and source code.
|
||||
|
|
139
RELEASE.md
Normal file
139
RELEASE.md
Normal file
|
@ -0,0 +1,139 @@
|
|||
## ▲.● matter.js `0.17.0`
|
||||
|
||||
Release notes for `0.17.0`. See the release [readme](https://github.com/liabru/matter-js/blob/0.17.0/README.md) for further information.
|
||||
|
||||
### Highlights ✺
|
||||
|
||||
- Added performance and stats monitoring overlays to `Matter.Render`
|
||||
- See the [stats demo](https://brm.io/matter-js/demo/#stats) or enable [render.options.showPerformance](https://brm.io/matter-js/docs/classes/Render.html#property_options.showPerformance) and [render.options.showStats](https://brm.io/matter-js/docs/classes/Render.html#property_options.showStats)
|
||||
- Stats shown include
|
||||
- render frequency (e.g. `60 fps`)
|
||||
- engine delta time (e.g. `16.66ms`)
|
||||
- engine execution duration (e.g. `5.00ms`)
|
||||
- render execution duration (e.g.` 0.40ms`)
|
||||
- effective play speed (e.g. `1.00x` is real-time)
|
||||
- various other engine internal stats for debugging
|
||||
- Improved [documentation](https://brm.io/matter-js/docs/) pages
|
||||
- Added [Common.setDecomp](https://brm.io/matter-js/docs/classes/Common.html#method_setDecomp) and [Common.getDecomp](https://brm.io/matter-js/docs/classes/Common.html#method_getDecomp) to fix [bundler issues](https://github.com/liabru/matter-js/issues/981)
|
||||
- Added docs for all [Matter.Render options](https://brm.io/matter-js/docs/classes/Render.html#properties)
|
||||
- Migrated usage of `Matter.World` over to `Matter.Composite` (more info in [docs](https://brm.io/matter-js/docs/classes/World.html))
|
||||
- Migrated, deprecated and removed various old functionality (see the [changelog](https://github.com/liabru/matter-js/blob/0.17.0/CHANGELOG.md) for details)
|
||||
|
||||
### Changes ✲
|
||||
|
||||
See the release [compare page](https://github.com/liabru/matter-js/compare/0.16.1...0.17.0) and the [changelog](https://github.com/liabru/matter-js/blob/0.17.0/CHANGELOG.md) for a detailed list of changes.
|
||||
|
||||
### Comparison ⎄
|
||||
|
||||
Differences in behaviour, quality and performance against the previous release `0.16.1`. For more information see [comparison method](https://github.com/liabru/matter-js/pull/794).
|
||||
|
||||
```ocaml
|
||||
Output comparison of 37 examples against previous release matter-js@0.16.1
|
||||
|
||||
Similarity 100% Performance +0.00% Overlap +0.00%
|
||||
|
||||
airFriction · · avalanche · · ballPool · · bridge · · broadphase · · car · ·
|
||||
catapult · · chains · · circleStack · · cloth · · collisionFiltering · ·
|
||||
compound · · compoundStack · · constraints · · events · · friction · ·
|
||||
gyro · · manipulation · · mixed · · newtonsCradle · · pyramid · ·
|
||||
ragdoll · · restitution · · rounded · · sensors · · sleeping · ·
|
||||
slingshot · · softBody · · sprites · · stack · · staticFriction · ·
|
||||
stats · · stress · · stress2 · · timescale · · views · ·
|
||||
wreckingBall · ·
|
||||
where · no change ● extrinsics changed ◆ intrinsics changed
|
||||
|
||||
```
|
||||
|
||||
### Contributors ♥︎
|
||||
|
||||
Many thanks to the [contributors](https://github.com/liabru/matter-js/compare/0.16.1...0.17.0) of this release, [past contributors](https://github.com/liabru/matter-js/graphs/contributors) as well those involved in the [community](https://github.com/liabru/matter-js/issues) for your input and support.
|
||||
|
||||
---
|
||||
|
||||
## ▲.● matter.js `0.16.0`
|
||||
|
||||
Release notes for `0.16.0`. See the release [readme](https://github.com/liabru/matter-js/blob/0.16.0/README.md) for further information.
|
||||
|
||||
### Highlights ✺
|
||||
|
||||
- Changed external require method for `poly-decomp` ([882e07c](https://github.com/liabru/matter-js/commit/882e07c))
|
||||
- Improved `Bodies.fromVertices` decomposition quality using `removeDuplicatePoints` ([#639](https://github.com/liabru/matter-js/pull/639))
|
||||
- Added support for `>x.x.x` and `>=x.x.x` semver ranges in plugins ([0792716](https://github.com/liabru/matter-js/commit/0792716))
|
||||
- Changed demo example select background colour for Windows ([matter-tools #5](https://github.com/liabru/matter-tools/pull/5))
|
||||
- Updated demo to use latest [matter-tools](https://github.com/liabru/matter-tools) ([#33e8fe8](https://github.com/liabru/matter-js/commit/33e8fe8))
|
||||
- Updated SVG and terrain examples to use `fetch` ([5551cd5](https://github.com/liabru/matter-js/commit/5551cd5))
|
||||
|
||||
### Changes ✲
|
||||
|
||||
See the release [compare page](https://github.com/liabru/matter-js/compare/0.15.0...0.16.0) and the [changelog](https://github.com/liabru/matter-js/blob/0.16.0/CHANGELOG.md) for a detailed list of changes.
|
||||
|
||||
### Comparison ⎄
|
||||
|
||||
Differences in behaviour, quality and performance against the previous release `0.15.0`. For more information see [comparison method](https://github.com/liabru/matter-js/pull/794).
|
||||
|
||||
```ocaml
|
||||
Output comparison of 41 examples against matter-js@0.15.0 build on last run
|
||||
|
||||
Similarity 100% Performance +0.00% Overlap +0.00%
|
||||
|
||||
airFriction · · avalanche · · ballPool · · bridge · · broadphase · · car · ·
|
||||
catapult · · chains · · circleStack · · cloth · · collisionFiltering · ·
|
||||
compositeManipulation · · compound · · compoundStack · · concave · · constraints · ·
|
||||
doublePendulum · · events · · friction · · gravity · · gyro · ·
|
||||
manipulation · · mixed · · newtonsCradle · · pyramid · · ragdoll · ·
|
||||
raycasting · · restitution · · rounded · · sensors · · sleeping · ·
|
||||
slingshot · · softBody · · sprites · · stack · · staticFriction · ·
|
||||
stress · · stress2 · · timescale · · views · · wreckingBall · ·
|
||||
|
||||
where · no change ● extrinsics changed ◆ intrinsics changed
|
||||
|
||||
```
|
||||
|
||||
### Contributors ♥︎
|
||||
|
||||
Many thanks to the [contributors](https://github.com/liabru/matter-js/compare/0.15.0...0.16.0) of this release, [past contributors](https://github.com/liabru/matter-js/graphs/contributors) as well those involved in the [community](https://github.com/liabru/matter-js/issues) for your input and support.
|
||||
|
||||
---
|
||||
|
||||
## ▲.● matter.js `0.15.0`
|
||||
|
||||
Release notes for `0.15.0`. See the release [readme](https://github.com/liabru/matter-js/blob/0.15.0/README.md) for further information.
|
||||
|
||||
### Highlights ✺
|
||||
|
||||
- __Optimised performance up to ~30% boost vs. `0.14.2`__ ([#528](https://github.com/liabru/matter-js/pull/528)) ([#522](https://github.com/liabru/matter-js/pull/522)) ([#553](https://github.com/liabru/matter-js/pull/553))
|
||||
- Added `Body.setCentre` ([2ec247b](https://github.com/liabru/matter-js/commit/2ec247b))
|
||||
- Added `Constraint.pointAWorld` and `Constraint.pointBWorld` ([3c32969](https://github.com/liabru/matter-js/commit/3c32969))
|
||||
- Changed default colour scheme ([d258411](https://github.com/liabru/matter-js/commit/d258411)) ([6dd5ec5](https://github.com/liabru/matter-js/commit/6dd5ec5))
|
||||
- Fixed issues with decomp require ([0af1645](https://github.com/liabru/matter-js/commit/0af1645))
|
||||
- Fixed issues with render pixel ratio ([d577477](https://github.com/liabru/matter-js/commit/d577477))
|
||||
|
||||
### Changes ✲
|
||||
|
||||
See the release [compare page](https://github.com/liabru/matter-js/compare/0.14.2...0.15.0) and the [changelog](https://github.com/liabru/matter-js/blob/0.15.0/CHANGELOG.md) for a detailed list of all changes.
|
||||
|
||||
### Comparison ⎄
|
||||
|
||||
Differences in behaviour, quality and performance against the previous release `0.14.2`. For more information see [comparison method](https://github.com/liabru/matter-js/pull/794).
|
||||
|
||||
```ocaml
|
||||
Output comparison of 41 examples against matter-js@0.14.2 build on last run
|
||||
|
||||
Similarity 100% Performance +33.6% Overlap +0.00%
|
||||
|
||||
airFriction · · avalanche · · ballPool · · bridge · · broadphase · · car · ·
|
||||
catapult · · chains · · circleStack · · cloth · · collisionFiltering · ·
|
||||
compositeManipulation · · compound · · compoundStack · · concave · · constraints · ·
|
||||
doublePendulum · · events · · friction · · gravity · · gyro · ·
|
||||
manipulation · · mixed · · newtonsCradle · · pyramid · · ragdoll · ·
|
||||
raycasting · · restitution · · rounded · · sensors · · sleeping · ·
|
||||
slingshot · · softBody · · sprites · · stack · · staticFriction · ·
|
||||
stress · · stress2 · · timescale · · views · · wreckingBall · ·
|
||||
|
||||
where · no change ● extrinsics changed ◆ intrinsics changed
|
||||
|
||||
```
|
||||
|
||||
### Contributors ♥︎
|
||||
|
||||
Many thanks to the [contributors](https://github.com/liabru/matter-js/compare/0.14.2...0.15.0) of this release, [past contributors](https://github.com/liabru/matter-js/graphs/contributors) as well those involved in the [community](https://github.com/liabru/matter-js/issues) for your input and support.
|
27
bower.json
27
bower.json
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"name": "Matter",
|
||||
"version": "0.14.2",
|
||||
"homepage": "https://github.com/liabru/matter-js",
|
||||
"authors": [
|
||||
"Liam Brummitt <liam@brm.io> (http://brm.io/)"
|
||||
],
|
||||
"description": "a 2D rigid body physics engine for the web",
|
||||
"main": "build/matter.js",
|
||||
"keywords": [
|
||||
"javascript",
|
||||
"canvas",
|
||||
"html5",
|
||||
"physics",
|
||||
"physics engine",
|
||||
"game engine",
|
||||
"rigid body physics"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
13256
build/matter.js
13256
build/matter.js
File diff suppressed because it is too large
Load diff
96
build/matter.min.js
vendored
96
build/matter.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -9,70 +9,8 @@
|
|||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<title>Matter.js Demo</title>
|
||||
|
||||
<!-- libs -->
|
||||
<script type="text/javascript" src="/demo/lib/decomp.js"></script>
|
||||
<script type="text/javascript" src="/demo/lib/pathseg.js"></script>
|
||||
|
||||
<!-- Matter -->
|
||||
<script src="../build/matter-dev.js"></script>
|
||||
|
||||
<!-- MatterTools -->
|
||||
<script src="//code.jquery.com/jquery-3.1.1.js"></script>
|
||||
<script src="/demo/lib/matter-tools.gui.js"></script>
|
||||
<script src="/demo/lib/matter-tools.inspector.js"></script>
|
||||
<script src="/demo/lib/matter-tools.demo.js"></script>
|
||||
|
||||
<!-- Plugins -->
|
||||
<script src="/demo/lib/matter-wrap.js"></script>
|
||||
|
||||
<!-- Examples -->
|
||||
<script src="../examples/airFriction.js"></script>
|
||||
<script src="../examples/avalanche.js"></script>
|
||||
<script src="../examples/ballPool.js"></script>
|
||||
<script src="../examples/bridge.js"></script>
|
||||
<script src="../examples/broadphase.js"></script>
|
||||
<script src="../examples/car.js"></script>
|
||||
<script src="../examples/catapult.js"></script>
|
||||
<script src="../examples/chains.js"></script>
|
||||
<script src="../examples/circleStack.js"></script>
|
||||
<script src="../examples/cloth.js"></script>
|
||||
<script src="../examples/collisionFiltering.js"></script>
|
||||
<script src="../examples/compositeManipulation.js"></script>
|
||||
<script src="../examples/compound.js"></script>
|
||||
<script src="../examples/compoundStack.js"></script>
|
||||
<script src="../examples/concave.js"></script>
|
||||
<script src="../examples/constraints.js"></script>
|
||||
<script src="../examples/doublePendulum.js"></script>
|
||||
<script src="../examples/events.js"></script>
|
||||
<script src="../examples/friction.js"></script>
|
||||
<script src="../examples/gravity.js"></script>
|
||||
<script src="../examples/gyro.js"></script>
|
||||
<script src="../examples/manipulation.js"></script>
|
||||
<script src="../examples/mixed.js"></script>
|
||||
<script src="../examples/newtonsCradle.js"></script>
|
||||
<script src="../examples/ragdoll.js"></script>
|
||||
<script src="../examples/pyramid.js"></script>
|
||||
<script src="../examples/raycasting.js"></script>
|
||||
<script src="../examples/restitution.js"></script>
|
||||
<script src="../examples/rounded.js"></script>
|
||||
<script src="../examples/sensors.js"></script>
|
||||
<script src="../examples/sleeping.js"></script>
|
||||
<script src="../examples/slingshot.js"></script>
|
||||
<script src="../examples/softBody.js"></script>
|
||||
<script src="../examples/sprites.js"></script>
|
||||
<script src="../examples/stack.js"></script>
|
||||
<script src="../examples/staticFriction.js"></script>
|
||||
<script src="../examples/stress.js"></script>
|
||||
<script src="../examples/stress2.js"></script>
|
||||
<script src="../examples/svg.js"></script>
|
||||
<script src="../examples/terrain.js"></script>
|
||||
<script src="../examples/timescale.js"></script>
|
||||
<script src="../examples/views.js"></script>
|
||||
<script src="../examples/wreckingBall.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
|
@ -82,9 +20,41 @@
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.matter-btn-compare.matter-btn {
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.matter-js-compare-build.matter-demo {
|
||||
position: absolute;
|
||||
background: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.matter-js-compare-build.matter-demo .matter-header-outer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.matter-js-compare-build.matter-demo canvas {
|
||||
opacity: 0.5;
|
||||
background: transparent !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="/demo/js/Demo.js"></script>
|
||||
<script src="./js/matter-demo.main.5a504f.min.js"></script>
|
||||
<script src="./js/matter-demo.matter-tools.5e580e.min.js"></script>
|
||||
<script src="./js/matter-demo.matter-wrap.b3a896.min.js"></script>
|
||||
<script src="./js/matter-demo.pathseg.067c95.min.js"></script>
|
||||
<script src="./js/matter-demo.poly-decomp.59954b.min.js"></script>
|
||||
<script src="./js/matter-demo.e7da73.min.js"></script>
|
||||
</body>
|
||||
</html>
|
297
demo/js/Demo.js
297
demo/js/Demo.js
|
@ -1,297 +0,0 @@
|
|||
/**
|
||||
* The Matter.js demo page controller and example runner.
|
||||
*
|
||||
* NOTE: For the actual example code, refer to the source files in `/examples/`.
|
||||
*
|
||||
* @class Demo
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var sourceLinkRoot = 'https://github.com/liabru/matter-js/blob/master/examples';
|
||||
|
||||
var demo = MatterTools.Demo.create({
|
||||
toolbar: {
|
||||
title: 'matter-js',
|
||||
url: 'https://github.com/liabru/matter-js',
|
||||
reset: true,
|
||||
source: true,
|
||||
inspector: true,
|
||||
tools: true,
|
||||
fullscreen: true,
|
||||
exampleSelect: true
|
||||
},
|
||||
tools: {
|
||||
inspector: true,
|
||||
gui: true
|
||||
},
|
||||
inline: false,
|
||||
preventZoom: true,
|
||||
resetOnOrientation: true,
|
||||
routing: true,
|
||||
startExample: 'mixed',
|
||||
examples: [
|
||||
{
|
||||
name: 'Air Friction',
|
||||
id: 'airFriction',
|
||||
init: Example.airFriction,
|
||||
sourceLink: sourceLinkRoot + '/airFriction.js'
|
||||
},
|
||||
{
|
||||
name: 'Avalanche',
|
||||
id: 'avalanche',
|
||||
init: Example.avalanche,
|
||||
sourceLink: sourceLinkRoot + '/avalanche.js'
|
||||
},
|
||||
{
|
||||
name: 'Ball Pool',
|
||||
id: 'ballPool',
|
||||
init: Example.ballPool,
|
||||
sourceLink: sourceLinkRoot + '/ballPool.js'
|
||||
},
|
||||
{
|
||||
name: 'Bridge',
|
||||
id: 'bridge',
|
||||
init: Example.bridge,
|
||||
sourceLink: sourceLinkRoot + '/bridge.js'
|
||||
},
|
||||
{
|
||||
name: 'Broadphase',
|
||||
id: 'broadphase',
|
||||
init: Example.broadphase,
|
||||
sourceLink: sourceLinkRoot + '/broadphase.js'
|
||||
},
|
||||
{
|
||||
name: 'Car',
|
||||
id: 'car',
|
||||
init: Example.car,
|
||||
sourceLink: sourceLinkRoot + '/car.js'
|
||||
},
|
||||
{
|
||||
name: 'Catapult',
|
||||
id: 'catapult',
|
||||
init: Example.catapult,
|
||||
sourceLink: sourceLinkRoot + '/catapult.js'
|
||||
},
|
||||
{
|
||||
name: 'Chains',
|
||||
id: 'chains',
|
||||
init: Example.chains,
|
||||
sourceLink: sourceLinkRoot + '/chains.js'
|
||||
},
|
||||
{
|
||||
name: 'Circle Stack',
|
||||
id: 'circleStack',
|
||||
init: Example.circleStack,
|
||||
sourceLink: sourceLinkRoot + '/circleStack.js'
|
||||
},
|
||||
{
|
||||
name: 'Cloth',
|
||||
id: 'cloth',
|
||||
init: Example.cloth,
|
||||
sourceLink: sourceLinkRoot + '/cloth.js'
|
||||
},
|
||||
{
|
||||
name: 'Collision Filtering',
|
||||
id: 'collisionFiltering',
|
||||
init: Example.collisionFiltering,
|
||||
sourceLink: sourceLinkRoot + '/collisionFiltering.js'
|
||||
},
|
||||
{
|
||||
name: 'Composite Manipulation',
|
||||
id: 'compositeManipulation',
|
||||
init: Example.compositeManipulation,
|
||||
sourceLink: sourceLinkRoot + '/compositeManipulation.js'
|
||||
},
|
||||
{
|
||||
name: 'Compound Bodies',
|
||||
id: 'compound',
|
||||
init: Example.compound,
|
||||
sourceLink: sourceLinkRoot + '/compound.js'
|
||||
},
|
||||
{
|
||||
name: 'Compound Stack',
|
||||
id: 'compoundStack',
|
||||
init: Example.compoundStack,
|
||||
sourceLink: sourceLinkRoot + '/compoundStack.js'
|
||||
},
|
||||
{
|
||||
name: 'Concave',
|
||||
id: 'concave',
|
||||
init: Example.concave,
|
||||
sourceLink: sourceLinkRoot + '/concave.js'
|
||||
},
|
||||
{
|
||||
name: 'Constraints',
|
||||
id: 'constraints',
|
||||
init: Example.constraints,
|
||||
sourceLink: sourceLinkRoot + '/constraints.js'
|
||||
},
|
||||
{
|
||||
name: 'Double Pendulum',
|
||||
id: 'doublePendulum',
|
||||
init: Example.doublePendulum,
|
||||
sourceLink: sourceLinkRoot + '/doublePendulum.js'
|
||||
},
|
||||
{
|
||||
name: 'Events',
|
||||
id: 'events',
|
||||
init: Example.events,
|
||||
sourceLink: sourceLinkRoot + '/events.js'
|
||||
},
|
||||
{
|
||||
name: 'Friction',
|
||||
id: 'friction',
|
||||
init: Example.friction,
|
||||
sourceLink: sourceLinkRoot + '/friction.js'
|
||||
},
|
||||
{
|
||||
name: 'Reverse Gravity',
|
||||
id: 'gravity',
|
||||
init: Example.gravity,
|
||||
sourceLink: sourceLinkRoot + '/gravity.js'
|
||||
},
|
||||
{
|
||||
name: 'Gyroscope',
|
||||
id: 'gyro',
|
||||
init: Example.gyro,
|
||||
sourceLink: sourceLinkRoot + '/gyro.js'
|
||||
},
|
||||
{
|
||||
name: 'Manipulation',
|
||||
id: 'manipulation',
|
||||
init: Example.manipulation,
|
||||
sourceLink: sourceLinkRoot + '/manipulation.js'
|
||||
},
|
||||
{
|
||||
name: 'Mixed Shapes',
|
||||
id: 'mixed',
|
||||
init: Example.mixed,
|
||||
sourceLink: sourceLinkRoot + '/mixed.js'
|
||||
},
|
||||
{
|
||||
name: 'Newton\'s Cradle',
|
||||
id: 'newtonsCradle',
|
||||
init: Example.newtonsCradle,
|
||||
sourceLink: sourceLinkRoot + '/newtonsCradle.js'
|
||||
},
|
||||
{
|
||||
name: 'Ragdoll',
|
||||
id: 'ragdoll',
|
||||
init: Example.ragdoll,
|
||||
sourceLink: sourceLinkRoot + '/ragdoll.js'
|
||||
},
|
||||
{
|
||||
name: 'Pyramid',
|
||||
id: 'pyramid',
|
||||
init: Example.pyramid,
|
||||
sourceLink: sourceLinkRoot + '/pyramid.js'
|
||||
},
|
||||
{
|
||||
name: 'Raycasting',
|
||||
id: 'raycasting',
|
||||
init: Example.raycasting,
|
||||
sourceLink: sourceLinkRoot + '/raycasting.js'
|
||||
},
|
||||
{
|
||||
name: 'Restitution',
|
||||
id: 'restitution',
|
||||
init: Example.restitution,
|
||||
sourceLink: sourceLinkRoot + '/restitution.js'
|
||||
},
|
||||
{
|
||||
name: 'Rounded Corners (Chamfering)',
|
||||
id: 'rounded',
|
||||
init: Example.rounded,
|
||||
sourceLink: sourceLinkRoot + '/rounded.js'
|
||||
},
|
||||
{
|
||||
name: 'Sensors',
|
||||
id: 'sensors',
|
||||
init: Example.sensors,
|
||||
sourceLink: sourceLinkRoot + '/sensors.js'
|
||||
},
|
||||
{
|
||||
name: 'Sleeping',
|
||||
id: 'sleeping',
|
||||
init: Example.sleeping,
|
||||
sourceLink: sourceLinkRoot + '/sleeping.js'
|
||||
},
|
||||
{
|
||||
name: 'Slingshot',
|
||||
id: 'slingshot',
|
||||
init: Example.slingshot,
|
||||
sourceLink: sourceLinkRoot + '/slingshot.js'
|
||||
},
|
||||
{
|
||||
name: 'Soft Body',
|
||||
id: 'softBody',
|
||||
init: Example.softBody,
|
||||
sourceLink: sourceLinkRoot + '/softBody.js'
|
||||
},
|
||||
{
|
||||
name: 'Sprites',
|
||||
id: 'sprites',
|
||||
init: Example.sprites,
|
||||
sourceLink: sourceLinkRoot + '/sprites.js'
|
||||
},
|
||||
{
|
||||
name: 'Stack',
|
||||
id: 'stack',
|
||||
init: Example.stack,
|
||||
sourceLink: sourceLinkRoot + '/stack.js'
|
||||
},
|
||||
{
|
||||
name: 'Static Friction',
|
||||
id: 'staticFriction',
|
||||
init: Example.staticFriction,
|
||||
sourceLink: sourceLinkRoot + '/staticFriction.js'
|
||||
},
|
||||
{
|
||||
name: 'Stress',
|
||||
id: 'stress',
|
||||
init: Example.stress,
|
||||
sourceLink: sourceLinkRoot + '/stress.js'
|
||||
},
|
||||
{
|
||||
name: 'Stress 2',
|
||||
id: 'stress2',
|
||||
init: Example.stress2,
|
||||
sourceLink: sourceLinkRoot + '/stress2.js'
|
||||
},
|
||||
{
|
||||
name: 'Concave SVG Paths',
|
||||
id: 'svg',
|
||||
init: Example.svg,
|
||||
sourceLink: sourceLinkRoot + '/svg.js'
|
||||
},
|
||||
{
|
||||
name: 'Terrain',
|
||||
id: 'terrain',
|
||||
init: Example.terrain,
|
||||
sourceLink: sourceLinkRoot + '/terrain.js'
|
||||
},
|
||||
{
|
||||
name: 'Time Scaling',
|
||||
id: 'timescale',
|
||||
init: Example.timescale,
|
||||
sourceLink: sourceLinkRoot + '/timescale.js'
|
||||
},
|
||||
{
|
||||
name: 'Views',
|
||||
id: 'views',
|
||||
init: Example.views,
|
||||
sourceLink: sourceLinkRoot + '/views.js'
|
||||
},
|
||||
{
|
||||
name: 'Wrecking Ball',
|
||||
id: 'wreckingBall',
|
||||
init: Example.wreckingBall,
|
||||
sourceLink: sourceLinkRoot + '/wreckingBall.js'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
document.body.appendChild(demo.dom.root);
|
||||
|
||||
MatterTools.Demo.start(demo);
|
||||
})();
|
6
demo/js/matter-demo.e7da73.min.js
vendored
Normal file
6
demo/js/matter-demo.e7da73.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
demo/js/matter-demo.main.5a504f.min.js
vendored
Normal file
5
demo/js/matter-demo.main.5a504f.min.js
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
/*!
|
||||
* matter-demo bundle 0.17.1 by @liabru
|
||||
* http://brm.io/matter-js/
|
||||
* License MIT
|
||||
*/!function(e){function t(t){for(var n,l,a=t[0],f=t[1],i=t[2],c=0,s=[];c<a.length;c++)l=a[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(p&&p(t);s.length;)s.shift()();return u.push.apply(u,i||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var f=r[a];0!==o[f]&&(n=!1)}n&&(u.splice(t--,1),e=l(l.s=r[0]))}return e}var n={},o={1:0},u=[];function l(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.m=e,l.c=n,l.d=function(e,t,r){l.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,t){if(1&t&&(e=l(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(l.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)l.d(r,n,function(t){return e[t]}.bind(null,n));return r},l.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(t,"a",t),t},l.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},l.p="./js";var a=this.webpackJsonpMatterDemo=this.webpackJsonpMatterDemo||[],f=a.push.bind(a);a.push=t,a=a.slice();for(var i=0;i<a.length;i++)t(a[i]);var p=f;r()}([]);
|
117
demo/js/matter-demo.matter-tools.5e580e.min.js
vendored
Normal file
117
demo/js/matter-demo.matter-tools.5e580e.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12
demo/js/matter-demo.matter-wrap.b3a896.min.js
vendored
Normal file
12
demo/js/matter-demo.matter-wrap.b3a896.min.js
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*!
|
||||
* matter-demo bundle 0.17.1 by @liabru
|
||||
* http://brm.io/matter-js/
|
||||
* License MIT
|
||||
*/
|
||||
(this.webpackJsonpMatterDemo=this.webpackJsonpMatterDemo||[]).push([[3],{OPlj:function(n,r,t){
|
||||
/*!
|
||||
* matter-wrap 0.2.0 by Liam Brummitt 2017-07-04
|
||||
* https://github.com/liabru/matter-wrap
|
||||
* License MIT
|
||||
*/
|
||||
var o;o=function(n){return function(n){var r={};function t(o){if(r[o])return r[o].exports;var e=r[o]={i:o,l:!1,exports:{}};return n[o].call(e.exports,e,e.exports,t),e.l=!0,e.exports}return t.m=n,t.c=r,t.i=function(n){return n},t.d=function(n,r,o){t.o(n,r)||Object.defineProperty(n,r,{configurable:!1,enumerable:!0,get:o})},t.n=function(n){var r=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(r,"a",r),r},t.o=function(n,r){return Object.prototype.hasOwnProperty.call(n,r)},t.p="/libs",t(t.s=1)}([function(r,t){r.exports=n},function(n,r,t){"use strict";var o=t(0),e={name:"matter-wrap",version:"0.1.3",for:"matter-js@^0.12.0",install:function(n){n.after("Engine.update",(function(){e.Engine.update(this)}))},Engine:{update:function(n){for(var r=n.world,t=o.Composite.allBodies(r),i=o.Composite.allComposites(r),a=0;a<t.length;a+=1){var u=t[a];u.plugin.wrap&&e.Body.wrap(u,u.plugin.wrap)}for(a=0;a<i.length;a+=1){var s=i[a];s.plugin.wrap&&e.Composite.wrap(s,s.plugin.wrap)}}},Bounds:{wrap:function(n,r){var t=null,o=null;if(void 0!==r.min.x&&void 0!==r.max.x&&(n.min.x>r.max.x?t=r.min.x-n.max.x:n.max.x<r.min.x&&(t=r.max.x-n.min.x)),void 0!==r.min.y&&void 0!==r.max.y&&(n.min.y>r.max.y?o=r.min.y-n.max.y:n.max.y<r.min.y&&(o=r.max.y-n.min.y)),null!==t||null!==o)return{x:t||0,y:o||0}}},Body:{wrap:function(n,r){var t=e.Bounds.wrap(n.bounds,r);return t&&o.Body.translate(n,t),t}},Composite:{bounds:function(n){for(var r=o.Composite.allBodies(n),t=[],e=0;e<r.length;e+=1){var i=r[e];t.push(i.bounds.min,i.bounds.max)}return o.Bounds.create(t)},wrap:function(n,r){var t=e.Bounds.wrap(e.Composite.bounds(n),r);return t&&o.Composite.translate(n,t),t}}};o.Plugin.register(e),n.exports=e}])},n.exports=o(t("lniP"))}}]);
|
6
demo/js/matter-demo.pathseg.067c95.min.js
vendored
Normal file
6
demo/js/matter-demo.pathseg.067c95.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
demo/js/matter-demo.poly-decomp.59954b.min.js
vendored
Normal file
6
demo/js/matter-demo.poly-decomp.59954b.min.js
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
/*!
|
||||
* matter-demo bundle 0.17.1 by @liabru
|
||||
* http://brm.io/matter-js/
|
||||
* License MIT
|
||||
*/
|
||||
(this.webpackJsonpMatterDemo=this.webpackJsonpMatterDemo||[]).push([[5],{Dded:function(n,r){function t(n,r,t){t=t||0;var e,u,f,o,i,h,a,l=[0,0];return e=n[1][1]-n[0][1],u=n[0][0]-n[1][0],f=e*n[0][0]+u*n[0][1],o=r[1][1]-r[0][1],i=r[0][0]-r[1][0],h=o*r[0][0]+i*r[0][1],x(a=e*i-o*u,0,t)||(l[0]=(i*f-u*h)/a,l[1]=(e*h-o*f)/a),l}function e(n,r,t,e){var u=r[0]-n[0],f=r[1]-n[1],o=e[0]-t[0],i=e[1]-t[1];if(o*f-i*u==0)return!1;var h=(u*(t[1]-n[1])+f*(n[0]-t[0]))/(o*f-i*u),a=(o*(n[1]-t[1])+i*(t[0]-n[0]))/(i*u-o*f);return h>=0&&h<=1&&a>=0&&a<=1}function u(n,r,t){return(r[0]-n[0])*(t[1]-n[1])-(t[0]-n[0])*(r[1]-n[1])}function f(n,r,t){return u(n,r,t)>0}function o(n,r,t){return u(n,r,t)>=0}function i(n,r,t){return u(n,r,t)<0}function h(n,r,t){return u(n,r,t)<=0}n.exports={decomp:function(n){var r=k(n);return r.length>0?D(n,r):[n]},quickDecomp:function n(r,t,e,u,a,l,c){l=l||100,c=c||0,a=a||25,t=void 0!==t?t:[],e=e||[],u=u||[];var m=[0,0],A=[0,0],M=[0,0],d=0,k=0,D=0,x=0,w=0,y=0,C=0,E=[],L=[],N=r,U=r;if(U.length<3)return t;if(++c>l)return console.warn("quickDecomp: max level ("+l+") reached."),t;for(var V=0;V<r.length;++V)if(p(N,V)){e.push(N[V]),d=k=Number.MAX_VALUE;for(var X=0;X<r.length;++X)f(s(N,V-1),s(N,V),s(N,X))&&h(s(N,V-1),s(N,V),s(N,X-1))&&(M=q(s(N,V-1),s(N,V),s(N,X),s(N,X-1)),i(s(N,V+1),s(N,V),M)&&(D=g(N[V],M))<k&&(k=D,A=M,y=X)),f(s(N,V+1),s(N,V),s(N,X+1))&&h(s(N,V+1),s(N,V),s(N,X))&&(M=q(s(N,V+1),s(N,V),s(N,X),s(N,X+1)),f(s(N,V-1),s(N,V),M)&&(D=g(N[V],M))<d&&(d=D,m=M,w=X));if(y===(w+1)%r.length)M[0]=(A[0]+m[0])/2,M[1]=(A[1]+m[1])/2,u.push(M),V<w?(v(E,N,V,w+1),E.push(M),L.push(M),0!==y&&v(L,N,y,N.length),v(L,N,0,V+1)):(0!==V&&v(E,N,V,N.length),v(E,N,0,w+1),E.push(M),L.push(M),v(L,N,y,V+1));else{if(y>w&&(w+=r.length),x=Number.MAX_VALUE,w<y)return t;for(X=y;X<=w;++X)o(s(N,V-1),s(N,V),s(N,X))&&h(s(N,V+1),s(N,V),s(N,X))&&(D=g(s(N,V),s(N,X)))<x&&b(N,V,X)&&(x=D,C=X%r.length);V<C?(v(E,N,V,C+1),0!==C&&v(L,N,C,U.length),v(L,N,0,V+1)):(0!==V&&v(E,N,V,U.length),v(E,N,0,C+1),v(L,N,C,V+1))}return E.length<L.length?(n(E,t,e,u,a,l,c),n(L,t,e,u,a,l,c)):(n(L,t,e,u,a,l,c),n(E,t,e,u,a,l,c)),t}return t.push(r),t},isSimple:function(n){var r,t=n;for(r=0;r<t.length-1;r++)for(var u=0;u<r-1;u++)if(e(t[r],t[r+1],t[u],t[u+1]))return!1;for(r=1;r<t.length-2;r++)if(e(t[0],t[t.length-1],t[r],t[r+1]))return!1;return!0},removeCollinearPoints:function(n,r){for(var t=0,e=n.length-1;n.length>3&&e>=0;--e)c(s(n,e-1),s(n,e),s(n,e+1),r)&&(n.splice(e%n.length,1),t++);return t},removeDuplicatePoints:function(n,r){for(var t=n.length-1;t>=1;--t)for(var e=n[t],u=t-1;u>=0;--u)w(e,n[u],r)&&n.splice(t,1)},makeCCW:function(n){for(var r=0,t=n,e=1;e<n.length;++e)(t[e][1]<t[r][1]||t[e][1]===t[r][1]&&t[e][0]>t[r][0])&&(r=e);return!f(s(n,r-1),s(n,r),s(n,r+1))&&(function(n){for(var r=[],t=n.length,e=0;e!==t;e++)r.push(n.pop());for(e=0;e!==t;e++)n[e]=r[e]}(n),!0)}};var a=[],l=[];function c(n,r,t,e){if(e){var f=a,o=l;f[0]=r[0]-n[0],f[1]=r[1]-n[1],o[0]=t[0]-r[0],o[1]=t[1]-r[1];var i=f[0]*o[0]+f[1]*o[1],h=Math.sqrt(f[0]*f[0]+f[1]*f[1]),c=Math.sqrt(o[0]*o[0]+o[1]*o[1]);return Math.acos(i/(h*c))<e}return 0===u(n,r,t)}function g(n,r){var t=r[0]-n[0],e=r[1]-n[1];return t*t+e*e}function s(n,r){var t=n.length;return n[r<0?r%t+t:r%t]}function v(n,r,t,e){for(var u=t;u<e;u++)n.push(r[u])}function p(n,r){return i(s(n,r-1),s(n,r),s(n,r+1))}var m=[],A=[];function M(n,r,e){var u,f,i=m,a=A;if(o(s(n,r+1),s(n,r),s(n,e))&&h(s(n,r-1),s(n,r),s(n,e)))return!1;f=g(s(n,r),s(n,e));for(var l=0;l!==n.length;++l)if((l+1)%n.length!==r&&l!==r&&o(s(n,r),s(n,e),s(n,l+1))&&h(s(n,r),s(n,e),s(n,l))&&(i[0]=s(n,r),i[1]=s(n,e),a[0]=s(n,l),a[1]=s(n,l+1),u=t(i,a),g(s(n,r),u)<f))return!1;return!0}function b(n,r,t){for(var u=0;u!==n.length;++u)if(u!==r&&u!==t&&(u+1)%n.length!==r&&(u+1)%n.length!==t&&e(s(n,r),s(n,t),s(n,u),s(n,u+1)))return!1;return!0}function d(n,r,t,e){var u=e||[];if(function(n){n.length=0}(u),r<t)for(var f=r;f<=t;f++)u.push(n[f]);else{for(f=0;f<=t;f++)u.push(n[f]);for(f=r;f<n.length;f++)u.push(n[f])}return u}function k(n){for(var r=[],t=[],e=[],u=[],f=Number.MAX_VALUE,o=0;o<n.length;++o)if(p(n,o))for(var i=0;i<n.length;++i)if(M(n,o,i)){t=k(d(n,o,i,u)),e=k(d(n,i,o,u));for(var h=0;h<e.length;h++)t.push(e[h]);t.length<f&&(r=t,f=t.length,r.push([s(n,o),s(n,i)]))}return r}function D(n,r){if(0===r.length)return[n];if(r instanceof Array&&r.length&&r[0]instanceof Array&&2===r[0].length&&r[0][0]instanceof Array){for(var t=[n],e=0;e<r.length;e++)for(var u=r[e],f=0;f<t.length;f++){var o=D(t[f],u);if(o){t.splice(f,1),t.push(o[0],o[1]);break}}return t}u=r,e=n.indexOf(u[0]),f=n.indexOf(u[1]);return-1!==e&&-1!==f&&[d(n,e,f),d(n,f,e)]}function q(n,r,t,e,u){u=u||0;var f=r[1]-n[1],o=n[0]-r[0],i=f*n[0]+o*n[1],h=e[1]-t[1],a=t[0]-e[0],l=h*t[0]+a*t[1],c=f*a-h*o;return x(c,0,u)?[0,0]:[(a*i-o*l)/c,(f*l-h*i)/c]}function x(n,r,t){return t=t||0,Math.abs(n-r)<=t}function w(n,r,t){return x(n[0],r[0],t)&&x(n[1],r[1],t)}}}]);
|
|
@ -1,604 +0,0 @@
|
|||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.decomp=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
|
||||
module.exports = {
|
||||
decomp: polygonDecomp,
|
||||
quickDecomp: polygonQuickDecomp,
|
||||
isSimple: polygonIsSimple,
|
||||
removeCollinearPoints: polygonRemoveCollinearPoints,
|
||||
makeCCW: polygonMakeCCW
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute the intersection between two lines.
|
||||
* @static
|
||||
* @method lineInt
|
||||
* @param {Array} l1 Line vector 1
|
||||
* @param {Array} l2 Line vector 2
|
||||
* @param {Number} precision Precision to use when checking if the lines are parallel
|
||||
* @return {Array} The intersection point.
|
||||
*/
|
||||
function lineInt(l1,l2,precision){
|
||||
precision = precision || 0;
|
||||
var i = [0,0]; // point
|
||||
var a1, b1, c1, a2, b2, c2, det; // scalars
|
||||
a1 = l1[1][1] - l1[0][1];
|
||||
b1 = l1[0][0] - l1[1][0];
|
||||
c1 = a1 * l1[0][0] + b1 * l1[0][1];
|
||||
a2 = l2[1][1] - l2[0][1];
|
||||
b2 = l2[0][0] - l2[1][0];
|
||||
c2 = a2 * l2[0][0] + b2 * l2[0][1];
|
||||
det = a1 * b2 - a2*b1;
|
||||
if (!scalar_eq(det, 0, precision)) { // lines are not parallel
|
||||
i[0] = (b2 * c1 - b1 * c2) / det;
|
||||
i[1] = (a1 * c2 - a2 * c1) / det;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if two line segments intersects.
|
||||
* @method segmentsIntersect
|
||||
* @param {Array} p1 The start vertex of the first line segment.
|
||||
* @param {Array} p2 The end vertex of the first line segment.
|
||||
* @param {Array} q1 The start vertex of the second line segment.
|
||||
* @param {Array} q2 The end vertex of the second line segment.
|
||||
* @return {Boolean} True if the two line segments intersect
|
||||
*/
|
||||
function lineSegmentsIntersect(p1, p2, q1, q2){
|
||||
var dx = p2[0] - p1[0];
|
||||
var dy = p2[1] - p1[1];
|
||||
var da = q2[0] - q1[0];
|
||||
var db = q2[1] - q1[1];
|
||||
|
||||
// segments are parallel
|
||||
if((da*dy - db*dx) === 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
var s = (dx * (q1[1] - p1[1]) + dy * (p1[0] - q1[0])) / (da * dy - db * dx);
|
||||
var t = (da * (p1[1] - q1[1]) + db * (q1[0] - p1[0])) / (db * dx - da * dy);
|
||||
|
||||
return (s>=0 && s<=1 && t>=0 && t<=1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the area of a triangle spanned by the three given points. Note that the area will be negative if the points are not given in counter-clockwise order.
|
||||
* @static
|
||||
* @method area
|
||||
* @param {Array} a
|
||||
* @param {Array} b
|
||||
* @param {Array} c
|
||||
* @return {Number}
|
||||
*/
|
||||
function triangleArea(a,b,c){
|
||||
return (((b[0] - a[0])*(c[1] - a[1]))-((c[0] - a[0])*(b[1] - a[1])));
|
||||
}
|
||||
|
||||
function isLeft(a,b,c){
|
||||
return triangleArea(a,b,c) > 0;
|
||||
}
|
||||
|
||||
function isLeftOn(a,b,c) {
|
||||
return triangleArea(a, b, c) >= 0;
|
||||
}
|
||||
|
||||
function isRight(a,b,c) {
|
||||
return triangleArea(a, b, c) < 0;
|
||||
}
|
||||
|
||||
function isRightOn(a,b,c) {
|
||||
return triangleArea(a, b, c) <= 0;
|
||||
}
|
||||
|
||||
var tmpPoint1 = [],
|
||||
tmpPoint2 = [];
|
||||
|
||||
/**
|
||||
* Check if three points are collinear
|
||||
* @method collinear
|
||||
* @param {Array} a
|
||||
* @param {Array} b
|
||||
* @param {Array} c
|
||||
* @param {Number} [thresholdAngle=0] Threshold angle to use when comparing the vectors. The function will return true if the angle between the resulting vectors is less than this value. Use zero for max precision.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function collinear(a,b,c,thresholdAngle) {
|
||||
if(!thresholdAngle){
|
||||
return triangleArea(a, b, c) === 0;
|
||||
} else {
|
||||
var ab = tmpPoint1,
|
||||
bc = tmpPoint2;
|
||||
|
||||
ab[0] = b[0]-a[0];
|
||||
ab[1] = b[1]-a[1];
|
||||
bc[0] = c[0]-b[0];
|
||||
bc[1] = c[1]-b[1];
|
||||
|
||||
var dot = ab[0]*bc[0] + ab[1]*bc[1],
|
||||
magA = Math.sqrt(ab[0]*ab[0] + ab[1]*ab[1]),
|
||||
magB = Math.sqrt(bc[0]*bc[0] + bc[1]*bc[1]),
|
||||
angle = Math.acos(dot/(magA*magB));
|
||||
return angle < thresholdAngle;
|
||||
}
|
||||
}
|
||||
|
||||
function sqdist(a,b){
|
||||
var dx = b[0] - a[0];
|
||||
var dy = b[1] - a[1];
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a vertex at position i. It does not matter if i is out of bounds, this function will just cycle.
|
||||
* @method at
|
||||
* @param {Number} i
|
||||
* @return {Array}
|
||||
*/
|
||||
function polygonAt(polygon, i){
|
||||
var s = polygon.length;
|
||||
return polygon[i < 0 ? i % s + s : i % s];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the polygon data
|
||||
* @method clear
|
||||
* @return {Array}
|
||||
*/
|
||||
function polygonClear(polygon){
|
||||
polygon.length = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append points "from" to "to"-1 from an other polygon "poly" onto this one.
|
||||
* @method append
|
||||
* @param {Polygon} poly The polygon to get points from.
|
||||
* @param {Number} from The vertex index in "poly".
|
||||
* @param {Number} to The end vertex index in "poly". Note that this vertex is NOT included when appending.
|
||||
* @return {Array}
|
||||
*/
|
||||
function polygonAppend(polygon, poly, from, to){
|
||||
for(var i=from; i<to; i++){
|
||||
polygon.push(poly[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the polygon vertices are ordered counter-clockwise.
|
||||
* @method makeCCW
|
||||
*/
|
||||
function polygonMakeCCW(polygon){
|
||||
var br = 0,
|
||||
v = polygon;
|
||||
|
||||
// find bottom right point
|
||||
for (var i = 1; i < polygon.length; ++i) {
|
||||
if (v[i][1] < v[br][1] || (v[i][1] === v[br][1] && v[i][0] > v[br][0])) {
|
||||
br = i;
|
||||
}
|
||||
}
|
||||
|
||||
// reverse poly if clockwise
|
||||
if (!isLeft(polygonAt(polygon, br - 1), polygonAt(polygon, br), polygonAt(polygon, br + 1))) {
|
||||
polygonReverse(polygon);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the vertices in the polygon
|
||||
* @method reverse
|
||||
*/
|
||||
function polygonReverse(polygon){
|
||||
var tmp = [];
|
||||
var N = polygon.length;
|
||||
for(var i=0; i!==N; i++){
|
||||
tmp.push(polygon.pop());
|
||||
}
|
||||
for(var i=0; i!==N; i++){
|
||||
polygon[i] = tmp[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a point in the polygon is a reflex point
|
||||
* @method isReflex
|
||||
* @param {Number} i
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function polygonIsReflex(polygon, i){
|
||||
return isRight(polygonAt(polygon, i - 1), polygonAt(polygon, i), polygonAt(polygon, i + 1));
|
||||
}
|
||||
|
||||
var tmpLine1=[],
|
||||
tmpLine2=[];
|
||||
|
||||
/**
|
||||
* Check if two vertices in the polygon can see each other
|
||||
* @method canSee
|
||||
* @param {Number} a Vertex index 1
|
||||
* @param {Number} b Vertex index 2
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function polygonCanSee(polygon, a,b) {
|
||||
var p, dist, l1=tmpLine1, l2=tmpLine2;
|
||||
|
||||
if (isLeftOn(polygonAt(polygon, a + 1), polygonAt(polygon, a), polygonAt(polygon, b)) && isRightOn(polygonAt(polygon, a - 1), polygonAt(polygon, a), polygonAt(polygon, b))) {
|
||||
return false;
|
||||
}
|
||||
dist = sqdist(polygonAt(polygon, a), polygonAt(polygon, b));
|
||||
for (var i = 0; i !== polygon.length; ++i) { // for each edge
|
||||
if ((i + 1) % polygon.length === a || i === a){ // ignore incident edges
|
||||
continue;
|
||||
}
|
||||
if (isLeftOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i + 1)) && isRightOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i))) { // if diag intersects an edge
|
||||
l1[0] = polygonAt(polygon, a);
|
||||
l1[1] = polygonAt(polygon, b);
|
||||
l2[0] = polygonAt(polygon, i);
|
||||
l2[1] = polygonAt(polygon, i + 1);
|
||||
p = lineInt(l1,l2);
|
||||
if (sqdist(polygonAt(polygon, a), p) < dist) { // if edge is blocking visibility to b
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the polygon from vertex i to vertex j.
|
||||
* @method copy
|
||||
* @param {Number} i
|
||||
* @param {Number} j
|
||||
* @param {Polygon} [targetPoly] Optional target polygon to save in.
|
||||
* @return {Polygon} The resulting copy.
|
||||
*/
|
||||
function polygonCopy(polygon, i,j,targetPoly){
|
||||
var p = targetPoly || [];
|
||||
polygonClear(p);
|
||||
if (i < j) {
|
||||
// Insert all vertices from i to j
|
||||
for(var k=i; k<=j; k++){
|
||||
p.push(polygon[k]);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Insert vertices 0 to j
|
||||
for(var k=0; k<=j; k++){
|
||||
p.push(polygon[k]);
|
||||
}
|
||||
|
||||
// Insert vertices i to end
|
||||
for(var k=i; k<polygon.length; k++){
|
||||
p.push(polygon[k]);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decomposes the polygon into convex pieces. Returns a list of edges [[p1,p2],[p2,p3],...] that cuts the polygon.
|
||||
* Note that this algorithm has complexity O(N^4) and will be very slow for polygons with many vertices.
|
||||
* @method getCutEdges
|
||||
* @return {Array}
|
||||
*/
|
||||
function polygonGetCutEdges(polygon) {
|
||||
var min=[], tmp1=[], tmp2=[], tmpPoly = [];
|
||||
var nDiags = Number.MAX_VALUE;
|
||||
|
||||
for (var i = 0; i < polygon.length; ++i) {
|
||||
if (polygonIsReflex(polygon, i)) {
|
||||
for (var j = 0; j < polygon.length; ++j) {
|
||||
if (polygonCanSee(polygon, i, j)) {
|
||||
tmp1 = polygonGetCutEdges(polygonCopy(polygon, i, j, tmpPoly));
|
||||
tmp2 = polygonGetCutEdges(polygonCopy(polygon, j, i, tmpPoly));
|
||||
|
||||
for(var k=0; k<tmp2.length; k++){
|
||||
tmp1.push(tmp2[k]);
|
||||
}
|
||||
|
||||
if (tmp1.length < nDiags) {
|
||||
min = tmp1;
|
||||
nDiags = tmp1.length;
|
||||
min.push([polygonAt(polygon, i), polygonAt(polygon, j)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decomposes the polygon into one or more convex sub-Polygons.
|
||||
* @method decomp
|
||||
* @return {Array} An array or Polygon objects.
|
||||
*/
|
||||
function polygonDecomp(polygon){
|
||||
var edges = polygonGetCutEdges(polygon);
|
||||
if(edges.length > 0){
|
||||
return polygonSlice(polygon, edges);
|
||||
} else {
|
||||
return [polygon];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Slices the polygon given one or more cut edges. If given one, this function will return two polygons (false on failure). If many, an array of polygons.
|
||||
* @method slice
|
||||
* @param {Array} cutEdges A list of edges, as returned by .getCutEdges()
|
||||
* @return {Array}
|
||||
*/
|
||||
function polygonSlice(polygon, cutEdges){
|
||||
if(cutEdges.length === 0){
|
||||
return [polygon];
|
||||
}
|
||||
if(cutEdges instanceof Array && cutEdges.length && cutEdges[0] instanceof Array && cutEdges[0].length===2 && cutEdges[0][0] instanceof Array){
|
||||
|
||||
var polys = [polygon];
|
||||
|
||||
for(var i=0; i<cutEdges.length; i++){
|
||||
var cutEdge = cutEdges[i];
|
||||
// Cut all polys
|
||||
for(var j=0; j<polys.length; j++){
|
||||
var poly = polys[j];
|
||||
var result = polygonSlice(poly, cutEdge);
|
||||
if(result){
|
||||
// Found poly! Cut and quit
|
||||
polys.splice(j,1);
|
||||
polys.push(result[0],result[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return polys;
|
||||
} else {
|
||||
|
||||
// Was given one edge
|
||||
var cutEdge = cutEdges;
|
||||
var i = polygon.indexOf(cutEdge[0]);
|
||||
var j = polygon.indexOf(cutEdge[1]);
|
||||
|
||||
if(i !== -1 && j !== -1){
|
||||
return [polygonCopy(polygon, i,j),
|
||||
polygonCopy(polygon, j,i)];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the line segments of this polygon do not intersect each other.
|
||||
* @method isSimple
|
||||
* @param {Array} path An array of vertices e.g. [[0,0],[0,1],...]
|
||||
* @return {Boolean}
|
||||
* @todo Should it check all segments with all others?
|
||||
*/
|
||||
function polygonIsSimple(polygon){
|
||||
var path = polygon, i;
|
||||
// Check
|
||||
for(i=0; i<path.length-1; i++){
|
||||
for(var j=0; j<i-1; j++){
|
||||
if(lineSegmentsIntersect(path[i], path[i+1], path[j], path[j+1] )){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the segment between the last and the first point to all others
|
||||
for(i=1; i<path.length-2; i++){
|
||||
if(lineSegmentsIntersect(path[0], path[path.length-1], path[i], path[i+1] )){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getIntersectionPoint(p1, p2, q1, q2, delta){
|
||||
delta = delta || 0;
|
||||
var a1 = p2[1] - p1[1];
|
||||
var b1 = p1[0] - p2[0];
|
||||
var c1 = (a1 * p1[0]) + (b1 * p1[1]);
|
||||
var a2 = q2[1] - q1[1];
|
||||
var b2 = q1[0] - q2[0];
|
||||
var c2 = (a2 * q1[0]) + (b2 * q1[1]);
|
||||
var det = (a1 * b2) - (a2 * b1);
|
||||
|
||||
if(!scalar_eq(det,0,delta)){
|
||||
return [((b2 * c1) - (b1 * c2)) / det, ((a1 * c2) - (a2 * c1)) / det];
|
||||
} else {
|
||||
return [0,0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quickly decompose the Polygon into convex sub-polygons.
|
||||
* @method quickDecomp
|
||||
* @param {Array} result
|
||||
* @param {Array} [reflexVertices]
|
||||
* @param {Array} [steinerPoints]
|
||||
* @param {Number} [delta]
|
||||
* @param {Number} [maxlevel]
|
||||
* @param {Number} [level]
|
||||
* @return {Array}
|
||||
*/
|
||||
function polygonQuickDecomp(polygon, result,reflexVertices,steinerPoints,delta,maxlevel,level){
|
||||
maxlevel = maxlevel || 100;
|
||||
level = level || 0;
|
||||
delta = delta || 25;
|
||||
result = typeof(result)!=="undefined" ? result : [];
|
||||
reflexVertices = reflexVertices || [];
|
||||
steinerPoints = steinerPoints || [];
|
||||
|
||||
var upperInt=[0,0], lowerInt=[0,0], p=[0,0]; // Points
|
||||
var upperDist=0, lowerDist=0, d=0, closestDist=0; // scalars
|
||||
var upperIndex=0, lowerIndex=0, closestIndex=0; // Integers
|
||||
var lowerPoly=[], upperPoly=[]; // polygons
|
||||
var poly = polygon,
|
||||
v = polygon;
|
||||
|
||||
if(v.length < 3){
|
||||
return result;
|
||||
}
|
||||
|
||||
level++;
|
||||
if(level > maxlevel){
|
||||
console.warn("quickDecomp: max level ("+maxlevel+") reached.");
|
||||
return result;
|
||||
}
|
||||
|
||||
for (var i = 0; i < polygon.length; ++i) {
|
||||
if (polygonIsReflex(poly, i)) {
|
||||
reflexVertices.push(poly[i]);
|
||||
upperDist = lowerDist = Number.MAX_VALUE;
|
||||
|
||||
|
||||
for (var j = 0; j < polygon.length; ++j) {
|
||||
if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j - 1))) { // if line intersects with an edge
|
||||
p = getIntersectionPoint(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j - 1)); // find the point of intersection
|
||||
if (isRight(polygonAt(poly, i + 1), polygonAt(poly, i), p)) { // make sure it's inside the poly
|
||||
d = sqdist(poly[i], p);
|
||||
if (d < lowerDist) { // keep only the closest intersection
|
||||
lowerDist = d;
|
||||
lowerInt = p;
|
||||
lowerIndex = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isLeft(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j + 1)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) {
|
||||
p = getIntersectionPoint(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j + 1));
|
||||
if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), p)) {
|
||||
d = sqdist(poly[i], p);
|
||||
if (d < upperDist) {
|
||||
upperDist = d;
|
||||
upperInt = p;
|
||||
upperIndex = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if there are no vertices to connect to, choose a point in the middle
|
||||
if (lowerIndex === (upperIndex + 1) % polygon.length) {
|
||||
//console.log("Case 1: Vertex("+i+"), lowerIndex("+lowerIndex+"), upperIndex("+upperIndex+"), poly.size("+polygon.length+")");
|
||||
p[0] = (lowerInt[0] + upperInt[0]) / 2;
|
||||
p[1] = (lowerInt[1] + upperInt[1]) / 2;
|
||||
steinerPoints.push(p);
|
||||
|
||||
if (i < upperIndex) {
|
||||
//lowerPoly.insert(lowerPoly.end(), poly.begin() + i, poly.begin() + upperIndex + 1);
|
||||
polygonAppend(lowerPoly, poly, i, upperIndex+1);
|
||||
lowerPoly.push(p);
|
||||
upperPoly.push(p);
|
||||
if (lowerIndex !== 0){
|
||||
//upperPoly.insert(upperPoly.end(), poly.begin() + lowerIndex, poly.end());
|
||||
polygonAppend(upperPoly, poly,lowerIndex,poly.length);
|
||||
}
|
||||
//upperPoly.insert(upperPoly.end(), poly.begin(), poly.begin() + i + 1);
|
||||
polygonAppend(upperPoly, poly,0,i+1);
|
||||
} else {
|
||||
if (i !== 0){
|
||||
//lowerPoly.insert(lowerPoly.end(), poly.begin() + i, poly.end());
|
||||
polygonAppend(lowerPoly, poly,i,poly.length);
|
||||
}
|
||||
//lowerPoly.insert(lowerPoly.end(), poly.begin(), poly.begin() + upperIndex + 1);
|
||||
polygonAppend(lowerPoly, poly,0,upperIndex+1);
|
||||
lowerPoly.push(p);
|
||||
upperPoly.push(p);
|
||||
//upperPoly.insert(upperPoly.end(), poly.begin() + lowerIndex, poly.begin() + i + 1);
|
||||
polygonAppend(upperPoly, poly,lowerIndex,i+1);
|
||||
}
|
||||
} else {
|
||||
// connect to the closest point within the triangle
|
||||
//console.log("Case 2: Vertex("+i+"), closestIndex("+closestIndex+"), poly.size("+polygon.length+")\n");
|
||||
|
||||
if (lowerIndex > upperIndex) {
|
||||
upperIndex += polygon.length;
|
||||
}
|
||||
closestDist = Number.MAX_VALUE;
|
||||
|
||||
if(upperIndex < lowerIndex){
|
||||
return result;
|
||||
}
|
||||
|
||||
for (var j = lowerIndex; j <= upperIndex; ++j) {
|
||||
if (isLeftOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) {
|
||||
d = sqdist(polygonAt(poly, i), polygonAt(poly, j));
|
||||
if (d < closestDist) {
|
||||
closestDist = d;
|
||||
closestIndex = j % polygon.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i < closestIndex) {
|
||||
polygonAppend(lowerPoly, poly,i,closestIndex+1);
|
||||
if (closestIndex !== 0){
|
||||
polygonAppend(upperPoly, poly,closestIndex,v.length);
|
||||
}
|
||||
polygonAppend(upperPoly, poly,0,i+1);
|
||||
} else {
|
||||
if (i !== 0){
|
||||
polygonAppend(lowerPoly, poly,i,v.length);
|
||||
}
|
||||
polygonAppend(lowerPoly, poly,0,closestIndex+1);
|
||||
polygonAppend(upperPoly, poly,closestIndex,i+1);
|
||||
}
|
||||
}
|
||||
|
||||
// solve smallest poly first
|
||||
if (lowerPoly.length < upperPoly.length) {
|
||||
polygonQuickDecomp(lowerPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level);
|
||||
polygonQuickDecomp(upperPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level);
|
||||
} else {
|
||||
polygonQuickDecomp(upperPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level);
|
||||
polygonQuickDecomp(lowerPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result.push(polygon);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove collinear points in the polygon.
|
||||
* @method removeCollinearPoints
|
||||
* @param {Number} [precision] The threshold angle to use when determining whether two edges are collinear. Use zero for finest precision.
|
||||
* @return {Number} The number of points removed
|
||||
*/
|
||||
function polygonRemoveCollinearPoints(polygon, precision){
|
||||
var num = 0;
|
||||
for(var i=polygon.length-1; polygon.length>3 && i>=0; --i){
|
||||
if(collinear(polygonAt(polygon, i-1),polygonAt(polygon, i),polygonAt(polygon, i+1),precision)){
|
||||
// Remove the middle point
|
||||
polygon.splice(i%polygon.length,1);
|
||||
num++;
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two scalars are equal
|
||||
* @static
|
||||
* @method eq
|
||||
* @param {Number} a
|
||||
* @param {Number} b
|
||||
* @param {Number} [precision]
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function scalar_eq(a,b,precision){
|
||||
precision = precision || 0;
|
||||
return Math.abs(a-b) < precision;
|
||||
}
|
||||
|
||||
},{}]},{},[1])
|
||||
(1)
|
||||
});
|
4
demo/lib/jquery-1.11.0.min.js
vendored
4
demo/lib/jquery-1.11.0.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,275 +0,0 @@
|
|||
/*!
|
||||
* matter-wrap 0.2.0 by Liam Brummitt 2017-07-04
|
||||
* https://github.com/liabru/matter-wrap
|
||||
* License MIT
|
||||
*/
|
||||
(function webpackUniversalModuleDefinition(root, factory) {
|
||||
if(typeof exports === 'object' && typeof module === 'object')
|
||||
module.exports = factory(require("matter-js"));
|
||||
else if(typeof define === 'function' && define.amd)
|
||||
define(["matter-js"], factory);
|
||||
else if(typeof exports === 'object')
|
||||
exports["MatterWrap"] = factory(require("matter-js"));
|
||||
else
|
||||
root["MatterWrap"] = factory(root["Matter"]);
|
||||
})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {
|
||||
return /******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId])
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
|
||||
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
|
||||
/******/ // identity function for calling harmony imports with the correct context
|
||||
/******/ __webpack_require__.i = function(value) { return value; };
|
||||
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, {
|
||||
/******/ configurable: false,
|
||||
/******/ enumerable: true,
|
||||
/******/ get: getter
|
||||
/******/ });
|
||||
/******/ }
|
||||
/******/ };
|
||||
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "/libs";
|
||||
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = 1);
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ([
|
||||
/* 0 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
module.exports = __WEBPACK_EXTERNAL_MODULE_0__;
|
||||
|
||||
/***/ }),
|
||||
/* 1 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
var Matter = __webpack_require__(0);
|
||||
|
||||
/**
|
||||
* A coordinate wrapping plugin for matter.js.
|
||||
* See the readme for usage and examples.
|
||||
* @module MatterWrap
|
||||
*/
|
||||
var MatterWrap = {
|
||||
// plugin meta
|
||||
name: 'matter-wrap', // PLUGIN_NAME
|
||||
version: '0.1.3', // PLUGIN_VERSION
|
||||
for: 'matter-js@^0.12.0',
|
||||
|
||||
// installs the plugin where `base` is `Matter`
|
||||
// you should not need to call this directly.
|
||||
install: function install(base) {
|
||||
base.after('Engine.update', function () {
|
||||
MatterWrap.Engine.update(this);
|
||||
});
|
||||
},
|
||||
|
||||
Engine: {
|
||||
/**
|
||||
* Updates the engine by wrapping bodies and composites inside `engine.world`.
|
||||
* This is called automatically by the plugin.
|
||||
* @function MatterWrap.Engine.update
|
||||
* @param {Matter.Engine} engine The engine to update.
|
||||
* @returns {void} No return value.
|
||||
*/
|
||||
update: function update(engine) {
|
||||
var world = engine.world,
|
||||
bodies = Matter.Composite.allBodies(world),
|
||||
composites = Matter.Composite.allComposites(world);
|
||||
|
||||
for (var i = 0; i < bodies.length; i += 1) {
|
||||
var body = bodies[i];
|
||||
|
||||
if (body.plugin.wrap) {
|
||||
MatterWrap.Body.wrap(body, body.plugin.wrap);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < composites.length; i += 1) {
|
||||
var composite = composites[i];
|
||||
|
||||
if (composite.plugin.wrap) {
|
||||
MatterWrap.Composite.wrap(composite, composite.plugin.wrap);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Bounds: {
|
||||
/**
|
||||
* Returns a translation vector that wraps the `objectBounds` inside the `bounds`.
|
||||
* @function MatterWrap.Bounds.wrap
|
||||
* @param {Matter.Bounds} objectBounds The bounds of the object to wrap inside the bounds.
|
||||
* @param {Matter.Bounds} bounds The bounds to wrap the body inside.
|
||||
* @returns {?Matter.Vector} A translation vector (only if wrapping is required).
|
||||
*/
|
||||
wrap: function wrap(objectBounds, bounds) {
|
||||
var x = null,
|
||||
y = null;
|
||||
|
||||
if (typeof bounds.min.x !== 'undefined' && typeof bounds.max.x !== 'undefined') {
|
||||
if (objectBounds.min.x > bounds.max.x) {
|
||||
x = bounds.min.x - objectBounds.max.x;
|
||||
} else if (objectBounds.max.x < bounds.min.x) {
|
||||
x = bounds.max.x - objectBounds.min.x;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof bounds.min.y !== 'undefined' && typeof bounds.max.y !== 'undefined') {
|
||||
if (objectBounds.min.y > bounds.max.y) {
|
||||
y = bounds.min.y - objectBounds.max.y;
|
||||
} else if (objectBounds.max.y < bounds.min.y) {
|
||||
y = bounds.max.y - objectBounds.min.y;
|
||||
}
|
||||
}
|
||||
|
||||
if (x !== null || y !== null) {
|
||||
return {
|
||||
x: x || 0,
|
||||
y: y || 0
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Body: {
|
||||
/**
|
||||
* Wraps the `body` position such that it always stays within the given bounds.
|
||||
* Upon crossing a boundary the body will appear on the opposite side of the bounds,
|
||||
* while maintaining its velocity.
|
||||
* This is called automatically by the plugin.
|
||||
* @function MatterWrap.Body.wrap
|
||||
* @param {Matter.Body} body The body to wrap.
|
||||
* @param {Matter.Bounds} bounds The bounds to wrap the body inside.
|
||||
* @returns {?Matter.Vector} The translation vector that was applied (only if wrapping was required).
|
||||
*/
|
||||
wrap: function wrap(body, bounds) {
|
||||
var translation = MatterWrap.Bounds.wrap(body.bounds, bounds);
|
||||
|
||||
if (translation) {
|
||||
Matter.Body.translate(body, translation);
|
||||
}
|
||||
|
||||
return translation;
|
||||
}
|
||||
},
|
||||
|
||||
Composite: {
|
||||
/**
|
||||
* Returns the union of the bounds of all of the composite's bodies
|
||||
* (not accounting for constraints).
|
||||
* @function MatterWrap.Composite.bounds
|
||||
* @param {Matter.Composite} composite The composite.
|
||||
* @returns {Matter.Bounds} The composite bounds.
|
||||
*/
|
||||
bounds: function bounds(composite) {
|
||||
var bodies = Matter.Composite.allBodies(composite),
|
||||
vertices = [];
|
||||
|
||||
for (var i = 0; i < bodies.length; i += 1) {
|
||||
var body = bodies[i];
|
||||
vertices.push(body.bounds.min, body.bounds.max);
|
||||
}
|
||||
|
||||
return Matter.Bounds.create(vertices);
|
||||
},
|
||||
|
||||
/**
|
||||
* Wraps the `composite` position such that it always stays within the given bounds.
|
||||
* Upon crossing a boundary the composite will appear on the opposite side of the bounds,
|
||||
* while maintaining its velocity.
|
||||
* This is called automatically by the plugin.
|
||||
* @function MatterWrap.Composite.wrap
|
||||
* @param {Matter.Composite} composite The composite to wrap.
|
||||
* @param {Matter.Bounds} bounds The bounds to wrap the composite inside.
|
||||
* @returns {?Matter.Vector} The translation vector that was applied (only if wrapping was required).
|
||||
*/
|
||||
wrap: function wrap(composite, bounds) {
|
||||
var translation = MatterWrap.Bounds.wrap(MatterWrap.Composite.bounds(composite), bounds);
|
||||
|
||||
if (translation) {
|
||||
Matter.Composite.translate(composite, translation);
|
||||
}
|
||||
|
||||
return translation;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Matter.Plugin.register(MatterWrap);
|
||||
|
||||
module.exports = MatterWrap;
|
||||
|
||||
/**
|
||||
* @namespace Matter.Body
|
||||
* @see http://brm.io/matter-js/docs/classes/Body.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* This plugin adds a new property `body.plugin.wrap` to instances of `Matter.Body`.
|
||||
* This is a `Matter.Bounds` instance that specifies the wrapping region.
|
||||
* @property {Matter.Bounds} body.plugin.wrap
|
||||
* @memberof Matter.Body
|
||||
*/
|
||||
|
||||
/**
|
||||
* This plugin adds a new property `composite.plugin.wrap` to instances of `Matter.Composite`.
|
||||
* This is a `Matter.Bounds` instance that specifies the wrapping region.
|
||||
* @property {Matter.Bounds} composite.plugin.wrap
|
||||
* @memberof Matter.Composite
|
||||
*/
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
});
|
|
@ -1,849 +0,0 @@
|
|||
// SVGPathSeg API polyfill
|
||||
// https://github.com/progers/pathseg
|
||||
//
|
||||
// This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from
|
||||
// SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec
|
||||
// changes which were implemented in Firefox 43 and Chrome 46.
|
||||
|
||||
(function() { "use strict";
|
||||
if (!("SVGPathSeg" in window)) {
|
||||
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg
|
||||
window.SVGPathSeg = function(type, typeAsLetter, owningPathSegList) {
|
||||
this.pathSegType = type;
|
||||
this.pathSegTypeAsLetter = typeAsLetter;
|
||||
this._owningPathSegList = owningPathSegList;
|
||||
}
|
||||
|
||||
window.SVGPathSeg.prototype.classname = "SVGPathSeg";
|
||||
|
||||
window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
|
||||
window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
|
||||
window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
|
||||
window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
|
||||
window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
|
||||
window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
|
||||
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
|
||||
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
|
||||
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
|
||||
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
|
||||
window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
|
||||
window.SVGPathSeg.PATHSEG_ARC_REL = 11;
|
||||
window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
|
||||
window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
|
||||
window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
|
||||
window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
|
||||
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
|
||||
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
|
||||
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
|
||||
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;
|
||||
|
||||
// Notify owning PathSegList on any changes so they can be synchronized back to the path element.
|
||||
window.SVGPathSeg.prototype._segmentChanged = function() {
|
||||
if (this._owningPathSegList)
|
||||
this._owningPathSegList.segmentChanged(this);
|
||||
}
|
||||
|
||||
window.SVGPathSegClosePath = function(owningPathSegList) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList);
|
||||
}
|
||||
window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegClosePath.prototype.toString = function() { return "[object SVGPathSegClosePath]"; }
|
||||
window.SVGPathSegClosePath.prototype._asPathString = function() { return this.pathSegTypeAsLetter; }
|
||||
window.SVGPathSegClosePath.prototype.clone = function() { return new window.SVGPathSegClosePath(undefined); }
|
||||
|
||||
window.SVGPathSegMovetoAbs = function(owningPathSegList, x, y) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
}
|
||||
window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegMovetoAbs.prototype.toString = function() { return "[object SVGPathSegMovetoAbs]"; }
|
||||
window.SVGPathSegMovetoAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegMovetoAbs.prototype.clone = function() { return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); }
|
||||
Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegMovetoRel = function(owningPathSegList, x, y) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
}
|
||||
window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegMovetoRel.prototype.toString = function() { return "[object SVGPathSegMovetoRel]"; }
|
||||
window.SVGPathSegMovetoRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegMovetoRel.prototype.clone = function() { return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); }
|
||||
Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegLinetoAbs = function(owningPathSegList, x, y) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
}
|
||||
window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegLinetoAbs.prototype.toString = function() { return "[object SVGPathSegLinetoAbs]"; }
|
||||
window.SVGPathSegLinetoAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegLinetoAbs.prototype.clone = function() { return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); }
|
||||
Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegLinetoRel = function(owningPathSegList, x, y) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
}
|
||||
window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegLinetoRel.prototype.toString = function() { return "[object SVGPathSegLinetoRel]"; }
|
||||
window.SVGPathSegLinetoRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegLinetoRel.prototype.clone = function() { return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); }
|
||||
Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegCurvetoCubicAbs = function(owningPathSegList, x, y, x1, y1, x2, y2) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._x1 = x1;
|
||||
this._y1 = y1;
|
||||
this._x2 = x2;
|
||||
this._y2 = y2;
|
||||
}
|
||||
window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegCurvetoCubicAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicAbs]"; }
|
||||
window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegCurvetoCubicAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegCurvetoCubicRel = function(owningPathSegList, x, y, x1, y1, x2, y2) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._x1 = x1;
|
||||
this._y1 = y1;
|
||||
this._x2 = x2;
|
||||
this._y2 = y2;
|
||||
}
|
||||
window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegCurvetoCubicRel.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicRel]"; }
|
||||
window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegCurvetoCubicRel.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegCurvetoQuadraticAbs = function(owningPathSegList, x, y, x1, y1) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._x1 = x1;
|
||||
this._y1 = y1;
|
||||
}
|
||||
window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticAbs]"; }
|
||||
window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); }
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegCurvetoQuadraticRel = function(owningPathSegList, x, y, x1, y1) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._x1 = x1;
|
||||
this._y1 = y1;
|
||||
}
|
||||
window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticRel]"; }
|
||||
window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); }
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegArcAbs = function(owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._r1 = r1;
|
||||
this._r2 = r2;
|
||||
this._angle = angle;
|
||||
this._largeArcFlag = largeArcFlag;
|
||||
this._sweepFlag = sweepFlag;
|
||||
}
|
||||
window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegArcAbs.prototype.toString = function() { return "[object SVGPathSegArcAbs]"; }
|
||||
window.SVGPathSegArcAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegArcAbs.prototype.clone = function() { return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }
|
||||
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { get: function() { return this._r1; }, set: function(r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { get: function() { return this._r2; }, set: function(r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { get: function() { return this._angle; }, set: function(angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { get: function() { return this._largeArcFlag; }, set: function(largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { get: function() { return this._sweepFlag; }, set: function(sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegArcRel = function(owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._r1 = r1;
|
||||
this._r2 = r2;
|
||||
this._angle = angle;
|
||||
this._largeArcFlag = largeArcFlag;
|
||||
this._sweepFlag = sweepFlag;
|
||||
}
|
||||
window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegArcRel.prototype.toString = function() { return "[object SVGPathSegArcRel]"; }
|
||||
window.SVGPathSegArcRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegArcRel.prototype.clone = function() { return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }
|
||||
Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { get: function() { return this._r1; }, set: function(r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { get: function() { return this._r2; }, set: function(r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { get: function() { return this._angle; }, set: function(angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { get: function() { return this._largeArcFlag; }, set: function(largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { get: function() { return this._sweepFlag; }, set: function(sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegLinetoHorizontalAbs = function(owningPathSegList, x) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList);
|
||||
this._x = x;
|
||||
}
|
||||
window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function() { return "[object SVGPathSegLinetoHorizontalAbs]"; }
|
||||
window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x; }
|
||||
window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function() { return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); }
|
||||
Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegLinetoHorizontalRel = function(owningPathSegList, x) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList);
|
||||
this._x = x;
|
||||
}
|
||||
window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegLinetoHorizontalRel.prototype.toString = function() { return "[object SVGPathSegLinetoHorizontalRel]"; }
|
||||
window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x; }
|
||||
window.SVGPathSegLinetoHorizontalRel.prototype.clone = function() { return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); }
|
||||
Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegLinetoVerticalAbs = function(owningPathSegList, y) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList);
|
||||
this._y = y;
|
||||
}
|
||||
window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegLinetoVerticalAbs.prototype.toString = function() { return "[object SVGPathSegLinetoVerticalAbs]"; }
|
||||
window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._y; }
|
||||
window.SVGPathSegLinetoVerticalAbs.prototype.clone = function() { return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); }
|
||||
Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegLinetoVerticalRel = function(owningPathSegList, y) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList);
|
||||
this._y = y;
|
||||
}
|
||||
window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegLinetoVerticalRel.prototype.toString = function() { return "[object SVGPathSegLinetoVerticalRel]"; }
|
||||
window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._y; }
|
||||
window.SVGPathSegLinetoVerticalRel.prototype.clone = function() { return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); }
|
||||
Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegCurvetoCubicSmoothAbs = function(owningPathSegList, x, y, x2, y2) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._x2 = x2;
|
||||
this._y2 = y2;
|
||||
}
|
||||
window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicSmoothAbs]"; }
|
||||
window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); }
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegCurvetoCubicSmoothRel = function(owningPathSegList, x, y, x2, y2) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._x2 = x2;
|
||||
this._y2 = y2;
|
||||
}
|
||||
window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicSmoothRel]"; }
|
||||
window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); }
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegCurvetoQuadraticSmoothAbs = function(owningPathSegList, x, y) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
}
|
||||
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticSmoothAbs]"; }
|
||||
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); }
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
window.SVGPathSegCurvetoQuadraticSmoothRel = function(owningPathSegList, x, y) {
|
||||
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList);
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
}
|
||||
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
|
||||
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticSmoothRel]"; }
|
||||
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
|
||||
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); }
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
|
||||
|
||||
// Add createSVGPathSeg* functions to window.SVGPathElement.
|
||||
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.
|
||||
window.SVGPathElement.prototype.createSVGPathSegClosePath = function() { return new window.SVGPathSegClosePath(undefined); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(x, y) { return new window.SVGPathSegMovetoAbs(undefined, x, y); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function(x, y) { return new window.SVGPathSegMovetoRel(undefined, x, y); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(x, y) { return new window.SVGPathSegLinetoAbs(undefined, x, y); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function(x, y) { return new window.SVGPathSegLinetoRel(undefined, x, y); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function(x, y, x1, y1, x2, y2) { return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function(x, y, x1, y1, x2, y2) { return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function(x, y, x1, y1) { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function(x, y, x1, y1) { return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegArcAbs = function(x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegArcRel = function(x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function(x) { return new window.SVGPathSegLinetoHorizontalAbs(undefined, x); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function(x) { return new window.SVGPathSegLinetoHorizontalRel(undefined, x); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function(y) { return new window.SVGPathSegLinetoVerticalAbs(undefined, y); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function(y) { return new window.SVGPathSegLinetoVerticalRel(undefined, y); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function(x, y, x2, y2) { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function(x, y, x2, y2) { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function(x, y) { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y); }
|
||||
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function(x, y) { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); }
|
||||
|
||||
if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) {
|
||||
// Add getPathSegAtLength to SVGPathElement.
|
||||
// Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength
|
||||
// This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.
|
||||
window.SVGPathElement.prototype.getPathSegAtLength = function(distance) {
|
||||
if (distance === undefined || !isFinite(distance))
|
||||
throw "Invalid arguments.";
|
||||
|
||||
var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||
measurementElement.setAttribute("d", this.getAttribute("d"));
|
||||
var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;
|
||||
|
||||
// If the path is empty, return 0.
|
||||
if (lastPathSegment <= 0)
|
||||
return 0;
|
||||
|
||||
do {
|
||||
measurementElement.pathSegList.removeItem(lastPathSegment);
|
||||
if (distance > measurementElement.getTotalLength())
|
||||
break;
|
||||
lastPathSegment--;
|
||||
} while (lastPathSegment > 0);
|
||||
return lastPathSegment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checking for SVGPathSegList in window checks for the case of an implementation without the
|
||||
// SVGPathSegList API.
|
||||
// The second check for appendItem is specific to Firefox 59+ which removed only parts of the
|
||||
// SVGPathSegList API (e.g., appendItem). In this case we need to re-implement the entire API
|
||||
// so the polyfill data (i.e., _list) is used throughout.
|
||||
if (!("SVGPathSegList" in window) || !("appendItem" in window.SVGPathSegList.prototype)) {
|
||||
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList
|
||||
window.SVGPathSegList = function(pathElement) {
|
||||
this._pathElement = pathElement;
|
||||
this._list = this._parsePath(this._pathElement.getAttribute("d"));
|
||||
|
||||
// Use a MutationObserver to catch changes to the path's "d" attribute.
|
||||
this._mutationObserverConfig = { "attributes": true, "attributeFilter": ["d"] };
|
||||
this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));
|
||||
this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
|
||||
}
|
||||
|
||||
window.SVGPathSegList.prototype.classname = "SVGPathSegList";
|
||||
|
||||
Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", {
|
||||
get: function() {
|
||||
this._checkPathSynchronizedToList();
|
||||
return this._list.length;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
// Add the pathSegList accessors to window.SVGPathElement.
|
||||
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
|
||||
Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", {
|
||||
get: function() {
|
||||
if (!this._pathSegList)
|
||||
this._pathSegList = new window.SVGPathSegList(this);
|
||||
return this._pathSegList;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
// FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.
|
||||
Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
|
||||
Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
|
||||
|
||||
// Process any pending mutations to the path element and update the list as needed.
|
||||
// This should be the first call of all public functions and is needed because
|
||||
// MutationObservers are not synchronous so we can have pending asynchronous mutations.
|
||||
window.SVGPathSegList.prototype._checkPathSynchronizedToList = function() {
|
||||
this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
|
||||
}
|
||||
|
||||
window.SVGPathSegList.prototype._updateListFromPathMutations = function(mutationRecords) {
|
||||
if (!this._pathElement)
|
||||
return;
|
||||
var hasPathMutations = false;
|
||||
mutationRecords.forEach(function(record) {
|
||||
if (record.attributeName == "d")
|
||||
hasPathMutations = true;
|
||||
});
|
||||
if (hasPathMutations)
|
||||
this._list = this._parsePath(this._pathElement.getAttribute("d"));
|
||||
}
|
||||
|
||||
// Serialize the list and update the path's 'd' attribute.
|
||||
window.SVGPathSegList.prototype._writeListToPath = function() {
|
||||
this._pathElementMutationObserver.disconnect();
|
||||
this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list));
|
||||
this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
|
||||
}
|
||||
|
||||
// When a path segment changes the list needs to be synchronized back to the path element.
|
||||
window.SVGPathSegList.prototype.segmentChanged = function(pathSeg) {
|
||||
this._writeListToPath();
|
||||
}
|
||||
|
||||
window.SVGPathSegList.prototype.clear = function() {
|
||||
this._checkPathSynchronizedToList();
|
||||
|
||||
this._list.forEach(function(pathSeg) {
|
||||
pathSeg._owningPathSegList = null;
|
||||
});
|
||||
this._list = [];
|
||||
this._writeListToPath();
|
||||
}
|
||||
|
||||
window.SVGPathSegList.prototype.initialize = function(newItem) {
|
||||
this._checkPathSynchronizedToList();
|
||||
|
||||
this._list = [newItem];
|
||||
newItem._owningPathSegList = this;
|
||||
this._writeListToPath();
|
||||
return newItem;
|
||||
}
|
||||
|
||||
window.SVGPathSegList.prototype._checkValidIndex = function(index) {
|
||||
if (isNaN(index) || index < 0 || index >= this.numberOfItems)
|
||||
throw "INDEX_SIZE_ERR";
|
||||
}
|
||||
|
||||
window.SVGPathSegList.prototype.getItem = function(index) {
|
||||
this._checkPathSynchronizedToList();
|
||||
|
||||
this._checkValidIndex(index);
|
||||
return this._list[index];
|
||||
}
|
||||
|
||||
window.SVGPathSegList.prototype.insertItemBefore = function(newItem, index) {
|
||||
this._checkPathSynchronizedToList();
|
||||
|
||||
// Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
|
||||
if (index > this.numberOfItems)
|
||||
index = this.numberOfItems;
|
||||
if (newItem._owningPathSegList) {
|
||||
// SVG2 spec says to make a copy.
|
||||
newItem = newItem.clone();
|
||||
}
|
||||
this._list.splice(index, 0, newItem);
|
||||
newItem._owningPathSegList = this;
|
||||
this._writeListToPath();
|
||||
return newItem;
|
||||
}
|
||||
|
||||
window.SVGPathSegList.prototype.replaceItem = function(newItem, index) {
|
||||
this._checkPathSynchronizedToList();
|
||||
|
||||
if (newItem._owningPathSegList) {
|
||||
// SVG2 spec says to make a copy.
|
||||
newItem = newItem.clone();
|
||||
}
|
||||
this._checkValidIndex(index);
|
||||
this._list[index] = newItem;
|
||||
newItem._owningPathSegList = this;
|
||||
this._writeListToPath();
|
||||
return newItem;
|
||||
}
|
||||
|
||||
window.SVGPathSegList.prototype.removeItem = function(index) {
|
||||
this._checkPathSynchronizedToList();
|
||||
|
||||
this._checkValidIndex(index);
|
||||
var item = this._list[index];
|
||||
this._list.splice(index, 1);
|
||||
this._writeListToPath();
|
||||
return item;
|
||||
}
|
||||
|
||||
window.SVGPathSegList.prototype.appendItem = function(newItem) {
|
||||
this._checkPathSynchronizedToList();
|
||||
|
||||
if (newItem._owningPathSegList) {
|
||||
// SVG2 spec says to make a copy.
|
||||
newItem = newItem.clone();
|
||||
}
|
||||
this._list.push(newItem);
|
||||
newItem._owningPathSegList = this;
|
||||
// TODO: Optimize this to just append to the existing attribute.
|
||||
this._writeListToPath();
|
||||
return newItem;
|
||||
}
|
||||
|
||||
window.SVGPathSegList._pathSegArrayAsString = function(pathSegArray) {
|
||||
var string = "";
|
||||
var first = true;
|
||||
pathSegArray.forEach(function(pathSeg) {
|
||||
if (first) {
|
||||
first = false;
|
||||
string += pathSeg._asPathString();
|
||||
} else {
|
||||
string += " " + pathSeg._asPathString();
|
||||
}
|
||||
});
|
||||
return string;
|
||||
}
|
||||
|
||||
// This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.
|
||||
window.SVGPathSegList.prototype._parsePath = function(string) {
|
||||
if (!string || string.length == 0)
|
||||
return [];
|
||||
|
||||
var owningPathSegList = this;
|
||||
|
||||
var Builder = function() {
|
||||
this.pathSegList = [];
|
||||
}
|
||||
|
||||
Builder.prototype.appendSegment = function(pathSeg) {
|
||||
this.pathSegList.push(pathSeg);
|
||||
}
|
||||
|
||||
var Source = function(string) {
|
||||
this._string = string;
|
||||
this._currentIndex = 0;
|
||||
this._endIndex = this._string.length;
|
||||
this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;
|
||||
|
||||
this._skipOptionalSpaces();
|
||||
}
|
||||
|
||||
Source.prototype._isCurrentSpace = function() {
|
||||
var character = this._string[this._currentIndex];
|
||||
return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f");
|
||||
}
|
||||
|
||||
Source.prototype._skipOptionalSpaces = function() {
|
||||
while (this._currentIndex < this._endIndex && this._isCurrentSpace())
|
||||
this._currentIndex++;
|
||||
return this._currentIndex < this._endIndex;
|
||||
}
|
||||
|
||||
Source.prototype._skipOptionalSpacesOrDelimiter = function() {
|
||||
if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",")
|
||||
return false;
|
||||
if (this._skipOptionalSpaces()) {
|
||||
if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") {
|
||||
this._currentIndex++;
|
||||
this._skipOptionalSpaces();
|
||||
}
|
||||
}
|
||||
return this._currentIndex < this._endIndex;
|
||||
}
|
||||
|
||||
Source.prototype.hasMoreData = function() {
|
||||
return this._currentIndex < this._endIndex;
|
||||
}
|
||||
|
||||
Source.prototype.peekSegmentType = function() {
|
||||
var lookahead = this._string[this._currentIndex];
|
||||
return this._pathSegTypeFromChar(lookahead);
|
||||
}
|
||||
|
||||
Source.prototype._pathSegTypeFromChar = function(lookahead) {
|
||||
switch (lookahead) {
|
||||
case "Z":
|
||||
case "z":
|
||||
return window.SVGPathSeg.PATHSEG_CLOSEPATH;
|
||||
case "M":
|
||||
return window.SVGPathSeg.PATHSEG_MOVETO_ABS;
|
||||
case "m":
|
||||
return window.SVGPathSeg.PATHSEG_MOVETO_REL;
|
||||
case "L":
|
||||
return window.SVGPathSeg.PATHSEG_LINETO_ABS;
|
||||
case "l":
|
||||
return window.SVGPathSeg.PATHSEG_LINETO_REL;
|
||||
case "C":
|
||||
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
|
||||
case "c":
|
||||
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
|
||||
case "Q":
|
||||
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
|
||||
case "q":
|
||||
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
|
||||
case "A":
|
||||
return window.SVGPathSeg.PATHSEG_ARC_ABS;
|
||||
case "a":
|
||||
return window.SVGPathSeg.PATHSEG_ARC_REL;
|
||||
case "H":
|
||||
return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
|
||||
case "h":
|
||||
return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
|
||||
case "V":
|
||||
return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
|
||||
case "v":
|
||||
return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
|
||||
case "S":
|
||||
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
|
||||
case "s":
|
||||
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
|
||||
case "T":
|
||||
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
|
||||
case "t":
|
||||
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
|
||||
default:
|
||||
return window.SVGPathSeg.PATHSEG_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
Source.prototype._nextCommandHelper = function(lookahead, previousCommand) {
|
||||
// Check for remaining coordinates in the current command.
|
||||
if ((lookahead == "+" || lookahead == "-" || lookahead == "." || (lookahead >= "0" && lookahead <= "9")) && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) {
|
||||
if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS)
|
||||
return window.SVGPathSeg.PATHSEG_LINETO_ABS;
|
||||
if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL)
|
||||
return window.SVGPathSeg.PATHSEG_LINETO_REL;
|
||||
return previousCommand;
|
||||
}
|
||||
return window.SVGPathSeg.PATHSEG_UNKNOWN;
|
||||
}
|
||||
|
||||
Source.prototype.initialCommandIsMoveTo = function() {
|
||||
// If the path is empty it is still valid, so return true.
|
||||
if (!this.hasMoreData())
|
||||
return true;
|
||||
var command = this.peekSegmentType();
|
||||
// Path must start with moveTo.
|
||||
return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL;
|
||||
}
|
||||
|
||||
// Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.
|
||||
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
|
||||
Source.prototype._parseNumber = function() {
|
||||
var exponent = 0;
|
||||
var integer = 0;
|
||||
var frac = 1;
|
||||
var decimal = 0;
|
||||
var sign = 1;
|
||||
var expsign = 1;
|
||||
|
||||
var startIndex = this._currentIndex;
|
||||
|
||||
this._skipOptionalSpaces();
|
||||
|
||||
// Read the sign.
|
||||
if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+")
|
||||
this._currentIndex++;
|
||||
else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") {
|
||||
this._currentIndex++;
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
if (this._currentIndex == this._endIndex || ((this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != "."))
|
||||
// The first character of a number must be one of [0-9+-.].
|
||||
return undefined;
|
||||
|
||||
// Read the integer part, build right-to-left.
|
||||
var startIntPartIndex = this._currentIndex;
|
||||
while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9")
|
||||
this._currentIndex++; // Advance to first non-digit.
|
||||
|
||||
if (this._currentIndex != startIntPartIndex) {
|
||||
var scanIntPartIndex = this._currentIndex - 1;
|
||||
var multiplier = 1;
|
||||
while (scanIntPartIndex >= startIntPartIndex) {
|
||||
integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0");
|
||||
multiplier *= 10;
|
||||
}
|
||||
}
|
||||
|
||||
// Read the decimals.
|
||||
if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") {
|
||||
this._currentIndex++;
|
||||
|
||||
// There must be a least one digit following the .
|
||||
if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9")
|
||||
return undefined;
|
||||
while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
|
||||
frac *= 10;
|
||||
decimal += (this._string.charAt(this._currentIndex) - "0") / frac;
|
||||
this._currentIndex += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Read the exponent part.
|
||||
if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == "E") && (this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m")) {
|
||||
this._currentIndex++;
|
||||
|
||||
// Read the sign of the exponent.
|
||||
if (this._string.charAt(this._currentIndex) == "+") {
|
||||
this._currentIndex++;
|
||||
} else if (this._string.charAt(this._currentIndex) == "-") {
|
||||
this._currentIndex++;
|
||||
expsign = -1;
|
||||
}
|
||||
|
||||
// There must be an exponent.
|
||||
if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9")
|
||||
return undefined;
|
||||
|
||||
while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
|
||||
exponent *= 10;
|
||||
exponent += (this._string.charAt(this._currentIndex) - "0");
|
||||
this._currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
var number = integer + decimal;
|
||||
number *= sign;
|
||||
|
||||
if (exponent)
|
||||
number *= Math.pow(10, expsign * exponent);
|
||||
|
||||
if (startIndex == this._currentIndex)
|
||||
return undefined;
|
||||
|
||||
this._skipOptionalSpacesOrDelimiter();
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
Source.prototype._parseArcFlag = function() {
|
||||
if (this._currentIndex >= this._endIndex)
|
||||
return undefined;
|
||||
var flag = false;
|
||||
var flagChar = this._string.charAt(this._currentIndex++);
|
||||
if (flagChar == "0")
|
||||
flag = false;
|
||||
else if (flagChar == "1")
|
||||
flag = true;
|
||||
else
|
||||
return undefined;
|
||||
|
||||
this._skipOptionalSpacesOrDelimiter();
|
||||
return flag;
|
||||
}
|
||||
|
||||
Source.prototype.parseSegment = function() {
|
||||
var lookahead = this._string[this._currentIndex];
|
||||
var command = this._pathSegTypeFromChar(lookahead);
|
||||
if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {
|
||||
// Possibly an implicit command. Not allowed if this is the first command.
|
||||
if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN)
|
||||
return null;
|
||||
command = this._nextCommandHelper(lookahead, this._previousCommand);
|
||||
if (command == window.SVGPathSeg.PATHSEG_UNKNOWN)
|
||||
return null;
|
||||
} else {
|
||||
this._currentIndex++;
|
||||
}
|
||||
|
||||
this._previousCommand = command;
|
||||
|
||||
switch (command) {
|
||||
case window.SVGPathSeg.PATHSEG_MOVETO_REL:
|
||||
return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
|
||||
case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
|
||||
return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
|
||||
case window.SVGPathSeg.PATHSEG_LINETO_REL:
|
||||
return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
|
||||
case window.SVGPathSeg.PATHSEG_LINETO_ABS:
|
||||
return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
|
||||
case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
|
||||
return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
|
||||
case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
|
||||
return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
|
||||
case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
|
||||
return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
|
||||
case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
|
||||
return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
|
||||
case window.SVGPathSeg.PATHSEG_CLOSEPATH:
|
||||
this._skipOptionalSpaces();
|
||||
return new window.SVGPathSegClosePath(owningPathSegList);
|
||||
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
|
||||
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
|
||||
return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
|
||||
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
|
||||
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
|
||||
return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
|
||||
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
|
||||
var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
|
||||
return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
|
||||
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
|
||||
var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
|
||||
return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
|
||||
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
|
||||
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
|
||||
return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
|
||||
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
|
||||
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
|
||||
return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
|
||||
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
|
||||
return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
|
||||
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
|
||||
return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
|
||||
case window.SVGPathSeg.PATHSEG_ARC_REL:
|
||||
var points = {x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber()};
|
||||
return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
|
||||
case window.SVGPathSeg.PATHSEG_ARC_ABS:
|
||||
var points = {x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber()};
|
||||
return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
|
||||
default:
|
||||
throw "Unknown path seg type."
|
||||
}
|
||||
}
|
||||
|
||||
var builder = new Builder();
|
||||
var source = new Source(string);
|
||||
|
||||
if (!source.initialCommandIsMoveTo())
|
||||
return [];
|
||||
while (source.hasMoreData()) {
|
||||
var pathSeg = source.parseSegment();
|
||||
if (!pathSeg)
|
||||
return [];
|
||||
builder.appendSegment(pathSeg);
|
||||
}
|
||||
|
||||
return builder.pathSegList;
|
||||
}
|
||||
}
|
||||
}());
|
173
demo/src/Compare.js
Normal file
173
demo/src/Compare.js
Normal file
|
@ -0,0 +1,173 @@
|
|||
/**
|
||||
* A Matter.js version comparison testbed based on MatterTools.
|
||||
*
|
||||
* Tool to interactively compare engine results of
|
||||
* development version against the previous release.
|
||||
*
|
||||
* USAGE: [host]?compare[=frames]#[example]
|
||||
* e.g. http://localhost:8000/?compare=120#mixed
|
||||
*
|
||||
* @module Compare
|
||||
*/
|
||||
|
||||
var MatterTools = require('matter-tools');
|
||||
var MatterDev = require('MatterDev');
|
||||
var MatterBuild = require('MatterBuild');
|
||||
|
||||
var compare = function(examples, isDev) {
|
||||
// create primary demo for dev build
|
||||
var demo = MatterTools.Demo.create({
|
||||
toolbar: {
|
||||
title: 'matter-js ・ ' + (isDev ? 'dev' : '') + ' ・ comparing to ' + MatterBuild.version,
|
||||
url: 'https://github.com/liabru/matter-js',
|
||||
reset: true,
|
||||
source: true,
|
||||
inspector: false,
|
||||
tools: false,
|
||||
fullscreen: true,
|
||||
exampleSelect: true
|
||||
},
|
||||
// tools disabled to keep sync between instances
|
||||
tools: {
|
||||
inspector: false,
|
||||
gui: false
|
||||
},
|
||||
inline: false,
|
||||
preventZoom: true,
|
||||
resetOnOrientation: true,
|
||||
routing: true,
|
||||
startExample: false,
|
||||
examples: examples
|
||||
});
|
||||
|
||||
// create secondary demo for release build
|
||||
var demoBuild = MatterTools.Demo.create({
|
||||
toolbar: {
|
||||
title: 'matter-js-compare-build',
|
||||
reset: false,
|
||||
source: false,
|
||||
inspector: false,
|
||||
tools: false,
|
||||
fullscreen: false,
|
||||
exampleSelect: false
|
||||
},
|
||||
// tools disabled to keep sync between instances
|
||||
tools: {
|
||||
inspector: false,
|
||||
gui: false
|
||||
},
|
||||
inline: false,
|
||||
preventZoom: true,
|
||||
resetOnOrientation: true,
|
||||
routing: false,
|
||||
startExample: false,
|
||||
examples: examples.map(function(example) {
|
||||
return Matter.Common.extend({}, example);
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* NOTE: For the actual example code, refer to the source files in `/examples/`.
|
||||
* The code below is tooling for Matter.js maintainers to compare versions of Matter.
|
||||
*/
|
||||
|
||||
// build version should not run itself
|
||||
MatterBuild.Runner.run = function() {};
|
||||
MatterBuild.Render.run = function() {};
|
||||
|
||||
// maintain original references to patched methods
|
||||
MatterDev.Runner._tick = MatterDev.Runner.tick;
|
||||
MatterDev.Render._world = MatterDev.Render.world;
|
||||
MatterBuild.Mouse._setElement = MatterBuild.Mouse.setElement;
|
||||
|
||||
// patch MatterTools to control both demo versions simultaneously
|
||||
MatterTools.Demo._setExample = MatterTools.Demo.setExample;
|
||||
MatterTools.Demo.setExample = function(_demo, example) {
|
||||
MatterBuild.Common._nextId = MatterBuild.Common._seed = 0;
|
||||
MatterDev.Common._nextId = MatterDev.Common._seed = 0;
|
||||
|
||||
MatterBuild.Plugin._registry = MatterDev.Plugin._registry;
|
||||
MatterBuild.use.apply(null, MatterDev.used);
|
||||
|
||||
window.Matter = MatterDev;
|
||||
MatterTools.Demo._setExample(
|
||||
demo, demo.examples.find(function(e) { return e.name === example.name; })
|
||||
);
|
||||
|
||||
var maxTicks = parseFloat(window.location.search.split('=')[1]);
|
||||
var ticks = 0;
|
||||
|
||||
MatterDev.Runner.tick = function(runner, engine, time) {
|
||||
if (ticks === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ticks >= maxTicks) {
|
||||
console.info(
|
||||
'Demo.Compare: ran ' + ticks + ' ticks, timestamp is now '
|
||||
+ engine.timing.timestamp.toFixed(2)
|
||||
);
|
||||
|
||||
ticks = -1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ticks += 1;
|
||||
|
||||
var demoBuildInstance = demoBuild.example.instance;
|
||||
runner.isFixed = demoBuildInstance.runner.isFixed = true;
|
||||
runner.delta = demoBuildInstance.runner.delta = 1000 / 60;
|
||||
|
||||
window.Matter = MatterBuild;
|
||||
MatterBuild.Runner.tick(demoBuildInstance.runner, demoBuildInstance.engine, time);
|
||||
window.Matter = MatterDev;
|
||||
return MatterDev.Runner._tick(runner, engine, time);
|
||||
};
|
||||
|
||||
MatterDev.Render.world = function(render) {
|
||||
window.Matter = MatterBuild;
|
||||
MatterBuild.Render.world(demoBuild.example.instance.render);
|
||||
window.Matter = MatterDev;
|
||||
return MatterDev.Render._world(render);
|
||||
};
|
||||
|
||||
MatterBuild.Mouse.setElement = function(mouse) {
|
||||
return MatterBuild.Mouse._setElement(mouse, demo.example.instance.render.canvas);
|
||||
};
|
||||
|
||||
window.Matter = MatterBuild;
|
||||
MatterTools.Demo._setExample(
|
||||
demoBuild, demoBuild.examples.find(function(e) { return e.name === example.name; })
|
||||
);
|
||||
|
||||
window.Matter = MatterDev;
|
||||
};
|
||||
|
||||
// reset both engine versions simultaneously
|
||||
MatterTools.Demo._reset = MatterTools.Demo.reset;
|
||||
MatterTools.Demo.reset = function(_demo) {
|
||||
MatterBuild.Common._nextId = MatterBuild.Common._seed = 0;
|
||||
MatterDev.Common._nextId = MatterDev.Common._seed = 0;
|
||||
|
||||
window.Matter = MatterBuild;
|
||||
MatterTools.Demo._reset(demoBuild);
|
||||
|
||||
window.Matter = MatterDev;
|
||||
MatterTools.Demo._reset(demo);
|
||||
};
|
||||
|
||||
document.body.appendChild(demo.dom.root);
|
||||
document.body.appendChild(demoBuild.dom.root);
|
||||
|
||||
MatterTools.Demo.start(demo);
|
||||
|
||||
document.title = 'Matter.js Compare' + (isDev ? ' ・ Dev' : '');
|
||||
|
||||
console.info(
|
||||
'Demo.Compare: matter-js@' + MatterDev.version +
|
||||
' with matter-js@' + MatterBuild.version
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = { compare: compare };
|
65
demo/src/Demo.js
Normal file
65
demo/src/Demo.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* A Matter.js demo and development testbed based on MatterTools.
|
||||
*
|
||||
* For a simpler, minimal Matter.js example see:
|
||||
* https://github.com/liabru/matter-js/wiki/Getting-started
|
||||
*
|
||||
* The source for examples can be found at `/examples/`.
|
||||
*
|
||||
* @module Demo
|
||||
*/
|
||||
|
||||
var MatterTools = require('matter-tools');
|
||||
|
||||
var demo = function(examples, isDev) {
|
||||
var demo = MatterTools.Demo.create({
|
||||
toolbar: {
|
||||
title: 'matter-js' + (isDev ? ' ・ dev' : ''),
|
||||
url: 'https://github.com/liabru/matter-js',
|
||||
reset: true,
|
||||
source: true,
|
||||
inspector: true,
|
||||
tools: true,
|
||||
fullscreen: true,
|
||||
exampleSelect: true
|
||||
},
|
||||
tools: {
|
||||
inspector: true,
|
||||
gui: true
|
||||
},
|
||||
inline: false,
|
||||
preventZoom: true,
|
||||
resetOnOrientation: true,
|
||||
routing: true,
|
||||
startExample: 'mixed',
|
||||
examples: examples
|
||||
});
|
||||
|
||||
window.MatterDemoInstance = demo;
|
||||
|
||||
document.body.appendChild(demo.dom.root);
|
||||
document.title = 'Matter.js Demo' + (isDev ? ' ・ Dev' : '');
|
||||
|
||||
if (isDev) {
|
||||
var buttonSource = demo.dom.buttonSource;
|
||||
var buttonCompare = buttonSource.cloneNode(true);
|
||||
buttonCompare.textContent = '⎄';
|
||||
buttonCompare.title = 'Compare';
|
||||
buttonCompare.href = '?compare';
|
||||
buttonCompare.target = '';
|
||||
buttonCompare.className = 'matter-btn matter-btn-compare';
|
||||
buttonCompare.addEventListener('click', function(event) {
|
||||
window.location = '?compare#' + demo.example.id;
|
||||
event.preventDefault();
|
||||
});
|
||||
buttonSource.parentNode.insertBefore(buttonCompare, buttonSource.nextSibling);
|
||||
|
||||
Matter.before('Render.create', function(renderOptions) {
|
||||
renderOptions.options.showDebug = true;
|
||||
});
|
||||
}
|
||||
|
||||
MatterTools.Demo.start(demo);
|
||||
};
|
||||
|
||||
module.exports = { demo: demo };
|
55
demo/src/index.ejs
Normal file
55
demo/src/index.ejs
Normal file
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,minimal-ui">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<meta name="msapplication-navbutton-color" content="#000000">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="robots" content="noindex">
|
||||
<title>Matter.js Demo</title>
|
||||
|
||||
<style type="text/css">
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.matter-btn-compare.matter-btn {
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.matter-js-compare-build.matter-demo {
|
||||
position: absolute;
|
||||
background: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.matter-js-compare-build.matter-demo .matter-header-outer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.matter-js-compare-build.matter-demo canvas {
|
||||
opacity: 0.5;
|
||||
background: transparent !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><% for (var chunk in htmlWebpackPlugin.files.js) { %>
|
||||
<script src="<%= htmlWebpackPlugin.files.js[chunk] %>"></script><% } %>
|
||||
</body>
|
||||
</html>
|
39
demo/src/index.js
Normal file
39
demo/src/index.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Initialise and start the browser demo / compare tool.
|
||||
*
|
||||
* For a simpler, minimal Matter.js example see:
|
||||
* https://github.com/liabru/matter-js/wiki/Getting-started
|
||||
*
|
||||
* The source for examples can be found at `/examples/`.
|
||||
*
|
||||
* @module Index
|
||||
*/
|
||||
|
||||
var Matter = require('matter-js');
|
||||
var Examples = require('../../examples/index');
|
||||
var compare = require('./Compare').compare;
|
||||
var demo = require('./Demo').demo;
|
||||
|
||||
// browser globals
|
||||
window.pathseg = require('pathseg');
|
||||
window.MatterTools = require('matter-tools');
|
||||
window.Matter = Matter;
|
||||
|
||||
// prepare examples
|
||||
var examples = Matter.Common.keys(Examples).map(function(id){
|
||||
return {
|
||||
id: id,
|
||||
sourceLink: 'https://github.com/liabru/matter-js/blob/master/examples/' + id + '.js',
|
||||
name: Examples[id].title,
|
||||
init: Examples[id]
|
||||
};
|
||||
});
|
||||
|
||||
// start the requested tool
|
||||
var isCompare = window.location.search.indexOf('compare') >= 0;
|
||||
var isDev = __MATTER_IS_DEV__;
|
||||
if (isCompare) {
|
||||
compare(examples, isDev);
|
||||
} else {
|
||||
demo(examples, isDev);
|
||||
}
|
|
@ -6,7 +6,7 @@ Example.airFriction = function() {
|
|||
Runner = Matter.Runner,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -31,7 +31,7 @@ Example.airFriction = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// falling blocks
|
||||
Bodies.rectangle(200, 100, 60, 60, { frictionAir: 0.001 }),
|
||||
Bodies.rectangle(400, 100, 60, 60, { frictionAir: 0.05 }),
|
||||
|
@ -56,7 +56,7 @@ Example.airFriction = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -79,3 +79,10 @@ Example.airFriction = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.airFriction.title = 'Air Friction';
|
||||
Example.airFriction.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.airFriction;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
var Example = Example || {};
|
||||
|
||||
Matter.use(
|
||||
'matter-wrap'
|
||||
);
|
||||
|
||||
Example.avalanche = function() {
|
||||
try {
|
||||
if (typeof MatterWrap !== 'undefined') {
|
||||
// either use by name from plugin registry (Browser global)
|
||||
Matter.use('matter-wrap');
|
||||
} else {
|
||||
// or require and use the plugin directly (Node.js, Webpack etc.)
|
||||
Matter.use(require('matter-wrap'));
|
||||
}
|
||||
} catch (e) {
|
||||
// could not require the plugin or install needed
|
||||
}
|
||||
|
||||
var Engine = Matter.Engine,
|
||||
Render = Matter.Render,
|
||||
Runner = Matter.Runner,
|
||||
|
@ -13,7 +21,6 @@ Example.avalanche = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -42,12 +49,12 @@ Example.avalanche = function() {
|
|||
return Bodies.circle(x, y, Common.random(10, 20), { friction: 0.00001, restitution: 0.5, density: 0.001 });
|
||||
});
|
||||
|
||||
World.add(world, stack);
|
||||
Composite.add(world, stack);
|
||||
|
||||
World.add(world, [
|
||||
Bodies.rectangle(200, 150, 700, 20, { isStatic: true, angle: Math.PI * 0.06 }),
|
||||
Bodies.rectangle(500, 350, 700, 20, { isStatic: true, angle: -Math.PI * 0.06 }),
|
||||
Bodies.rectangle(340, 580, 700, 20, { isStatic: true, angle: Math.PI * 0.04 })
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(200, 150, 700, 20, { isStatic: true, angle: Math.PI * 0.06, render: { fillStyle: '#060a19' } }),
|
||||
Bodies.rectangle(500, 350, 700, 20, { isStatic: true, angle: -Math.PI * 0.06, render: { fillStyle: '#060a19' } }),
|
||||
Bodies.rectangle(340, 580, 700, 20, { isStatic: true, angle: Math.PI * 0.04, render: { fillStyle: '#060a19' } })
|
||||
]);
|
||||
|
||||
// add mouse control
|
||||
|
@ -62,7 +69,7 @@ Example.avalanche = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -90,3 +97,10 @@ Example.avalanche = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.avalanche.title = 'Avalanche';
|
||||
Example.avalanche.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.avalanche;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
var Example = Example || {};
|
||||
|
||||
Matter.use(
|
||||
'matter-wrap'
|
||||
);
|
||||
|
||||
Example.ballPool = function() {
|
||||
try {
|
||||
if (typeof MatterWrap !== 'undefined') {
|
||||
// either use by name from plugin registry (Browser global)
|
||||
Matter.use('matter-wrap');
|
||||
} else {
|
||||
// or require and use the plugin directly (Node.js, Webpack etc.)
|
||||
Matter.use(require('matter-wrap'));
|
||||
}
|
||||
} catch (e) {
|
||||
// could not require the plugin or install needed
|
||||
}
|
||||
|
||||
var Engine = Matter.Engine,
|
||||
Render = Matter.Render,
|
||||
Runner = Matter.Runner,
|
||||
|
@ -13,7 +21,6 @@ Example.ballPool = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -38,15 +45,15 @@ Example.ballPool = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Bodies.rectangle(400, 600, 1200, 50.5, { isStatic: true })
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(400, 600, 1200, 50.5, { isStatic: true, render: { fillStyle: '#060a19' } })
|
||||
]);
|
||||
|
||||
var stack = Composites.stack(100, 0, 10, 8, 10, 10, function(x, y) {
|
||||
return Bodies.circle(x, y, Common.random(15, 30), { restitution: 0.6, friction: 0.1 });
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
Bodies.polygon(200, 460, 3, 60),
|
||||
Bodies.polygon(400, 460, 5, 60),
|
||||
|
@ -65,7 +72,7 @@ Example.ballPool = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -98,3 +105,10 @@ Example.ballPool = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.ballPool.title = 'Ball Pool';
|
||||
Example.ballPool.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.ballPool;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ Example.bridge = function() {
|
|||
Constraint = Matter.Constraint,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -44,7 +44,7 @@ Example.bridge = function() {
|
|||
density: 0.005,
|
||||
frictionAir: 0.05,
|
||||
render: {
|
||||
fillStyle: '#575375'
|
||||
fillStyle: '#060a19'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -61,7 +61,7 @@ Example.bridge = function() {
|
|||
return Bodies.rectangle(x, y, 50, 50, Common.random(20, 40));
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
bridge,
|
||||
stack,
|
||||
Bodies.rectangle(30, 490, 220, 380, {
|
||||
|
@ -100,7 +100,7 @@ Example.bridge = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -123,3 +123,10 @@ Example.bridge = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.bridge.title = 'Bridge';
|
||||
Example.bridge.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.bridge;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ Example.broadphase = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -34,7 +34,7 @@ Example.broadphase = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -57,7 +57,7 @@ Example.broadphase = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, stack);
|
||||
Composite.add(world, stack);
|
||||
|
||||
// add mouse control
|
||||
var mouse = Mouse.create(render.canvas),
|
||||
|
@ -71,7 +71,7 @@ Example.broadphase = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -94,3 +94,10 @@ Example.broadphase = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.broadphase.title = 'Broadphase';
|
||||
Example.broadphase.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.broadphase;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ Example.car = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -33,7 +33,7 @@ Example.car = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -41,16 +41,17 @@ Example.car = function() {
|
|||
Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
|
||||
]);
|
||||
|
||||
// see car function defined later in this file
|
||||
var scale = 0.9;
|
||||
World.add(world, Composites.car(150, 100, 150 * scale, 30 * scale, 30 * scale));
|
||||
Composite.add(world, Example.car.car(150, 100, 150 * scale, 30 * scale, 30 * scale));
|
||||
|
||||
scale = 0.8;
|
||||
World.add(world, Composites.car(350, 300, 150 * scale, 30 * scale, 30 * scale));
|
||||
Composite.add(world, Example.car.car(350, 300, 150 * scale, 30 * scale, 30 * scale));
|
||||
|
||||
World.add(world, [
|
||||
Bodies.rectangle(200, 150, 400, 20, { isStatic: true, angle: Math.PI * 0.06 }),
|
||||
Bodies.rectangle(500, 350, 650, 20, { isStatic: true, angle: -Math.PI * 0.06 }),
|
||||
Bodies.rectangle(300, 560, 600, 20, { isStatic: true, angle: Math.PI * 0.04 })
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(200, 150, 400, 20, { isStatic: true, angle: Math.PI * 0.06, render: { fillStyle: '#060a19' }}),
|
||||
Bodies.rectangle(500, 350, 650, 20, { isStatic: true, angle: -Math.PI * 0.06, render: { fillStyle: '#060a19' }}),
|
||||
Bodies.rectangle(300, 560, 600, 20, { isStatic: true, angle: Math.PI * 0.04, render: { fillStyle: '#060a19' }})
|
||||
]);
|
||||
|
||||
// add mouse control
|
||||
|
@ -65,7 +66,7 @@ Example.car = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -88,3 +89,82 @@ Example.car = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.car.title = 'Car';
|
||||
Example.car.for = '>=0.14.2';
|
||||
|
||||
/**
|
||||
* Creates a composite with simple car setup of bodies and constraints.
|
||||
* @method car
|
||||
* @param {number} xx
|
||||
* @param {number} yy
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
* @param {number} wheelSize
|
||||
* @return {composite} A new composite car body
|
||||
*/
|
||||
Example.car.car = function(xx, yy, width, height, wheelSize) {
|
||||
var Body = Matter.Body,
|
||||
Bodies = Matter.Bodies,
|
||||
Composite = Matter.Composite,
|
||||
Constraint = Matter.Constraint;
|
||||
|
||||
var group = Body.nextGroup(true),
|
||||
wheelBase = 20,
|
||||
wheelAOffset = -width * 0.5 + wheelBase,
|
||||
wheelBOffset = width * 0.5 - wheelBase,
|
||||
wheelYOffset = 0;
|
||||
|
||||
var car = Composite.create({ label: 'Car' }),
|
||||
body = Bodies.rectangle(xx, yy, width, height, {
|
||||
collisionFilter: {
|
||||
group: group
|
||||
},
|
||||
chamfer: {
|
||||
radius: height * 0.5
|
||||
},
|
||||
density: 0.0002
|
||||
});
|
||||
|
||||
var wheelA = Bodies.circle(xx + wheelAOffset, yy + wheelYOffset, wheelSize, {
|
||||
collisionFilter: {
|
||||
group: group
|
||||
},
|
||||
friction: 0.8
|
||||
});
|
||||
|
||||
var wheelB = Bodies.circle(xx + wheelBOffset, yy + wheelYOffset, wheelSize, {
|
||||
collisionFilter: {
|
||||
group: group
|
||||
},
|
||||
friction: 0.8
|
||||
});
|
||||
|
||||
var axelA = Constraint.create({
|
||||
bodyB: body,
|
||||
pointB: { x: wheelAOffset, y: wheelYOffset },
|
||||
bodyA: wheelA,
|
||||
stiffness: 1,
|
||||
length: 0
|
||||
});
|
||||
|
||||
var axelB = Constraint.create({
|
||||
bodyB: body,
|
||||
pointB: { x: wheelBOffset, y: wheelYOffset },
|
||||
bodyA: wheelB,
|
||||
stiffness: 1,
|
||||
length: 0
|
||||
});
|
||||
|
||||
Composite.addBody(car, body);
|
||||
Composite.addBody(car, wheelA);
|
||||
Composite.addBody(car, wheelB);
|
||||
Composite.addConstraint(car, axelA);
|
||||
Composite.addConstraint(car, axelB);
|
||||
|
||||
return car;
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.car;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ Example.catapult = function() {
|
|||
Constraint = Matter.Constraint,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies,
|
||||
Body = Matter.Body,
|
||||
Vector = Matter.Vector;
|
||||
|
@ -45,12 +45,12 @@ Example.catapult = function() {
|
|||
|
||||
var catapult = Bodies.rectangle(400, 520, 320, 20, { collisionFilter: { group: group } });
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
catapult,
|
||||
Bodies.rectangle(400, 600, 800, 50.5, { isStatic: true }),
|
||||
Bodies.rectangle(250, 555, 20, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 535, 20, 80, { isStatic: true, collisionFilter: { group: group } }),
|
||||
Bodies.rectangle(400, 600, 800, 50.5, { isStatic: true, render: { fillStyle: '#060a19' } }),
|
||||
Bodies.rectangle(250, 555, 20, 50, { isStatic: true, render: { fillStyle: '#060a19' } }),
|
||||
Bodies.rectangle(400, 535, 20, 80, { isStatic: true, collisionFilter: { group: group }, render: { fillStyle: '#060a19' } }),
|
||||
Bodies.circle(560, 100, 50, { density: 0.005 }),
|
||||
Constraint.create({
|
||||
bodyA: catapult,
|
||||
|
@ -72,7 +72,7 @@ Example.catapult = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -95,3 +95,10 @@ Example.catapult = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.catapult.title = 'Catapult';
|
||||
Example.catapult.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.catapult;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ Example.chains = function() {
|
|||
Constraint = Matter.Constraint,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -79,7 +78,7 @@ Example.chains = function() {
|
|||
stiffness: 0.5
|
||||
}));
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
ropeA,
|
||||
ropeB,
|
||||
ropeC,
|
||||
|
@ -98,7 +97,7 @@ Example.chains = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -121,3 +120,10 @@ Example.chains = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.chains.title = 'Chains';
|
||||
Example.chains.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.chains;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ Example.circleStack = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -32,11 +32,11 @@ Example.circleStack = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var stack = Composites.stack(100, 185, 10, 10, 20, 0, function(x, y) {
|
||||
var stack = Composites.stack(100, 600 - 21 - 20 * 20, 10, 10, 20, 0, function(x, y) {
|
||||
return Bodies.circle(x, y, 20);
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -57,7 +57,7 @@ Example.circleStack = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -80,3 +80,10 @@ Example.circleStack = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.circleStack.title = 'Circle Stack';
|
||||
Example.circleStack.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.circleStack;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ Example.cloth = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -31,20 +31,17 @@ Example.cloth = function() {
|
|||
var runner = Runner.create();
|
||||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var group = Body.nextGroup(true),
|
||||
particleOptions = { friction: 0.00001, collisionFilter: { group: group }, render: { visible: false }},
|
||||
constraintOptions = { stiffness: 0.06 },
|
||||
cloth = Composites.softBody(200, 200, 20, 12, 5, 5, false, 8, particleOptions, constraintOptions);
|
||||
// see cloth function defined later in this file
|
||||
var cloth = Example.cloth.cloth(200, 200, 20, 12, 5, 5, false, 8);
|
||||
|
||||
for (var i = 0; i < 20; i++) {
|
||||
cloth.bodies[i].isStatic = true;
|
||||
}
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
cloth,
|
||||
Bodies.circle(300, 500, 80, { isStatic: true }),
|
||||
Bodies.rectangle(500, 480, 80, 80, { isStatic: true }),
|
||||
Bodies.circle(300, 500, 80, { isStatic: true, render: { fillStyle: '#060a19' }}),
|
||||
Bodies.rectangle(500, 480, 80, 80, { isStatic: true, render: { fillStyle: '#060a19' }}),
|
||||
Bodies.rectangle(400, 609, 800, 50, { isStatic: true })
|
||||
]);
|
||||
|
||||
|
@ -60,7 +57,7 @@ Example.cloth = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -83,3 +80,46 @@ Example.cloth = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.cloth.title = 'Cloth';
|
||||
Example.cloth.for = '>=0.14.2';
|
||||
|
||||
/**
|
||||
* Creates a simple cloth like object.
|
||||
* @method cloth
|
||||
* @param {number} xx
|
||||
* @param {number} yy
|
||||
* @param {number} columns
|
||||
* @param {number} rows
|
||||
* @param {number} columnGap
|
||||
* @param {number} rowGap
|
||||
* @param {boolean} crossBrace
|
||||
* @param {number} particleRadius
|
||||
* @param {} particleOptions
|
||||
* @param {} constraintOptions
|
||||
* @return {composite} A new composite cloth
|
||||
*/
|
||||
Example.cloth.cloth = function(xx, yy, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) {
|
||||
var Body = Matter.Body,
|
||||
Bodies = Matter.Bodies,
|
||||
Common = Matter.Common,
|
||||
Composites = Matter.Composites;
|
||||
|
||||
var group = Body.nextGroup(true);
|
||||
particleOptions = Common.extend({ inertia: Infinity, friction: 0.00001, collisionFilter: { group: group }, render: { visible: false }}, particleOptions);
|
||||
constraintOptions = Common.extend({ stiffness: 0.06, render: { type: 'line', anchors: false } }, constraintOptions);
|
||||
|
||||
var cloth = Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y) {
|
||||
return Bodies.circle(x, y, particleRadius, particleOptions);
|
||||
});
|
||||
|
||||
Composites.mesh(cloth, columns, rows, crossBrace, constraintOptions);
|
||||
|
||||
cloth.label = 'Cloth Body';
|
||||
|
||||
return cloth;
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.cloth;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ Example.collisionFiltering = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -23,8 +22,7 @@ Example.collisionFiltering = function() {
|
|||
options: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
wireframes: false,
|
||||
background: '#111'
|
||||
wireframes: false
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -40,12 +38,12 @@ Example.collisionFiltering = function() {
|
|||
greenCategory = 0x0004,
|
||||
blueCategory = 0x0008;
|
||||
|
||||
var redColor = '#C44D58',
|
||||
blueColor = '#4ECDC4',
|
||||
greenColor = '#C7F464';
|
||||
var colorA = '#f55a3c',
|
||||
colorB = '#063e7b',
|
||||
colorC = '#f5d259';
|
||||
|
||||
// add floor
|
||||
World.add(world, Bodies.rectangle(400, 600, 900, 50, {
|
||||
Composite.add(world, Bodies.rectangle(400, 600, 900, 50, {
|
||||
isStatic: true,
|
||||
render: {
|
||||
fillStyle: 'transparent',
|
||||
|
@ -54,17 +52,17 @@ Example.collisionFiltering = function() {
|
|||
}));
|
||||
|
||||
// create a stack with varying body categories (but these bodies can all collide with each other)
|
||||
World.add(world,
|
||||
Composite.add(world,
|
||||
Composites.stack(275, 100, 5, 9, 10, 10, function(x, y, column, row) {
|
||||
var category = redCategory,
|
||||
color = redColor;
|
||||
color = colorA;
|
||||
|
||||
if (row > 5) {
|
||||
category = blueCategory;
|
||||
color = blueColor;
|
||||
color = colorB;
|
||||
} else if (row > 2) {
|
||||
category = greenCategory;
|
||||
color = greenColor;
|
||||
color = colorC;
|
||||
}
|
||||
|
||||
return Bodies.circle(x, y, 20, {
|
||||
|
@ -81,37 +79,37 @@ Example.collisionFiltering = function() {
|
|||
);
|
||||
|
||||
// this body will only collide with the walls and the green bodies
|
||||
World.add(world,
|
||||
Composite.add(world,
|
||||
Bodies.circle(310, 40, 30, {
|
||||
collisionFilter: {
|
||||
mask: defaultCategory | greenCategory
|
||||
},
|
||||
render: {
|
||||
fillStyle: greenColor
|
||||
fillStyle: colorC
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// this body will only collide with the walls and the red bodies
|
||||
World.add(world,
|
||||
Composite.add(world,
|
||||
Bodies.circle(400, 40, 30, {
|
||||
collisionFilter: {
|
||||
mask: defaultCategory | redCategory
|
||||
},
|
||||
render: {
|
||||
fillStyle: redColor
|
||||
fillStyle: colorA
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// this body will only collide with the walls and the blue bodies
|
||||
World.add(world,
|
||||
Composite.add(world,
|
||||
Bodies.circle(480, 40, 30, {
|
||||
collisionFilter: {
|
||||
mask: defaultCategory | blueCategory
|
||||
},
|
||||
render: {
|
||||
fillStyle: blueColor
|
||||
fillStyle: colorB
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@ -128,7 +126,7 @@ Example.collisionFiltering = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -154,3 +152,10 @@ Example.collisionFiltering = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.collisionFiltering.title = 'Collision Filtering';
|
||||
Example.collisionFiltering.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.collisionFiltering;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ Example.compositeManipulation = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -34,7 +33,7 @@ Example.compositeManipulation = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -46,9 +45,9 @@ Example.compositeManipulation = function() {
|
|||
return Bodies.rectangle(x, y, 40, 40);
|
||||
});
|
||||
|
||||
World.add(world, stack);
|
||||
Composite.add(world, stack);
|
||||
|
||||
world.gravity.y = 0;
|
||||
engine.gravity.y = 0;
|
||||
|
||||
Events.on(engine, 'afterUpdate', function(event) {
|
||||
var time = engine.timing.timestamp;
|
||||
|
@ -83,7 +82,7 @@ Example.compositeManipulation = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -106,3 +105,10 @@ Example.compositeManipulation = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.compositeManipulation.title = 'Composite Manipulation';
|
||||
Example.compositeManipulation.for = '>0.16.1';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.compositeManipulation;
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ Example.compound = function() {
|
|||
Runner = Matter.Runner,
|
||||
Body = Matter.Body,
|
||||
Constraint = Matter.Constraint,
|
||||
Composite = Matter.Composite,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -63,7 +63,7 @@ Example.compound = function() {
|
|||
pointB: { x: 0, y: 0 }
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
compoundBodyA,
|
||||
compoundBodyB,
|
||||
constraint,
|
||||
|
@ -82,7 +82,7 @@ Example.compound = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -105,3 +105,10 @@ Example.compound = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.compound.title = 'Compound Bodies';
|
||||
Example.compound.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.compound;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ Example.compoundStack = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -35,7 +35,7 @@ Example.compoundStack = function() {
|
|||
// add bodies
|
||||
var size = 50;
|
||||
|
||||
var stack = Composites.stack(100, 280, 12, 6, 0, 0, function(x, y) {
|
||||
var stack = Composites.stack(100, 600 - 17 - size * 6, 12, 6, 0, 0, function(x, y) {
|
||||
var partA = Bodies.rectangle(x, y, size, size / 5),
|
||||
partB = Bodies.rectangle(x, y, size / 5, size, { render: partA.render });
|
||||
|
||||
|
@ -44,7 +44,7 @@ Example.compoundStack = function() {
|
|||
});
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
|
@ -65,7 +65,7 @@ Example.compoundStack = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -88,3 +88,10 @@ Example.compoundStack = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.compoundStack.title = 'Compound Stack';
|
||||
Example.compoundStack.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.compoundStack;
|
||||
}
|
||||
|
|
|
@ -8,10 +8,13 @@ Example.concave = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Vertices = Matter.Vertices,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// provide concave decomposition support library
|
||||
Common.setDecomp(require('poly-decomp'));
|
||||
|
||||
// create engine
|
||||
var engine = Engine.create(),
|
||||
world = engine.world;
|
||||
|
@ -33,7 +36,7 @@ Example.concave = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -47,7 +50,7 @@ Example.concave = function() {
|
|||
horseShoe = Vertices.fromPath('35 7 19 17 14 38 14 58 25 79 45 85 65 84 65 66 46 67 34 59 30 44 33 29 45 23 66 23 66 7 53 7');
|
||||
|
||||
var stack = Composites.stack(50, 50, 6, 4, 10, 10, function(x, y) {
|
||||
var color = Common.choose(['#556270', '#4ECDC4', '#C7F464', '#FF6B6B', '#C44D58']);
|
||||
var color = Common.choose(['#f19648', '#f5d259', '#f55a3c', '#063e7b', '#ececd1']);
|
||||
return Bodies.fromVertices(x, y, Common.choose([arrow, chevron, star, horseShoe]), {
|
||||
render: {
|
||||
fillStyle: color,
|
||||
|
@ -57,7 +60,7 @@ Example.concave = function() {
|
|||
}, true);
|
||||
});
|
||||
|
||||
World.add(world, stack);
|
||||
Composite.add(world, stack);
|
||||
|
||||
// add mouse control
|
||||
var mouse = Mouse.create(render.canvas),
|
||||
|
@ -71,7 +74,7 @@ Example.concave = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -94,3 +97,10 @@ Example.concave = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.concave.title = 'Concave';
|
||||
Example.concave.for = '>0.16.1';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.concave;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ Example.constraints = function() {
|
|||
Constraint = Matter.Constraint,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -42,7 +42,7 @@ Example.constraints = function() {
|
|||
pointB: { x: -10, y: -10 }
|
||||
});
|
||||
|
||||
World.add(world, [body, constraint]);
|
||||
Composite.add(world, [body, constraint]);
|
||||
|
||||
// add soft global constraint
|
||||
var body = Bodies.polygon(280, 100, 3, 30);
|
||||
|
@ -54,7 +54,7 @@ Example.constraints = function() {
|
|||
stiffness: 0.001
|
||||
});
|
||||
|
||||
World.add(world, [body, constraint]);
|
||||
Composite.add(world, [body, constraint]);
|
||||
|
||||
// add damped soft global constraint
|
||||
var body = Bodies.polygon(400, 100, 4, 30);
|
||||
|
@ -67,7 +67,7 @@ Example.constraints = function() {
|
|||
damping: 0.05
|
||||
});
|
||||
|
||||
World.add(world, [body, constraint]);
|
||||
Composite.add(world, [body, constraint]);
|
||||
|
||||
// add revolute constraint
|
||||
var body = Bodies.rectangle(600, 200, 200, 20);
|
||||
|
@ -79,7 +79,7 @@ Example.constraints = function() {
|
|||
length: 0
|
||||
});
|
||||
|
||||
World.add(world, [body, ball, constraint]);
|
||||
Composite.add(world, [body, ball, constraint]);
|
||||
|
||||
// add revolute multi-body constraint
|
||||
var body = Bodies.rectangle(500, 400, 100, 20, { collisionFilter: { group: -1 } });
|
||||
|
@ -90,7 +90,7 @@ Example.constraints = function() {
|
|||
bodyB: ball
|
||||
});
|
||||
|
||||
World.add(world, [body, ball, constraint]);
|
||||
Composite.add(world, [body, ball, constraint]);
|
||||
|
||||
// add stiff multi-body constraint
|
||||
var bodyA = Bodies.polygon(100, 400, 6, 20);
|
||||
|
@ -103,7 +103,7 @@ Example.constraints = function() {
|
|||
pointB: { x: -10, y: -10 }
|
||||
});
|
||||
|
||||
World.add(world, [bodyA, bodyB, constraint]);
|
||||
Composite.add(world, [bodyA, bodyB, constraint]);
|
||||
|
||||
// add soft global constraint
|
||||
var bodyA = Bodies.polygon(300, 400, 4, 20);
|
||||
|
@ -117,7 +117,7 @@ Example.constraints = function() {
|
|||
stiffness: 0.001
|
||||
});
|
||||
|
||||
World.add(world, [bodyA, bodyB, constraint]);
|
||||
Composite.add(world, [bodyA, bodyB, constraint]);
|
||||
|
||||
// add damped soft global constraint
|
||||
var bodyA = Bodies.polygon(500, 400, 6, 30);
|
||||
|
@ -132,9 +132,9 @@ Example.constraints = function() {
|
|||
damping: 0.1
|
||||
});
|
||||
|
||||
World.add(world, [bodyA, bodyB, constraint]);
|
||||
Composite.add(world, [bodyA, bodyB, constraint]);
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -155,7 +155,7 @@ Example.constraints = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -178,3 +178,10 @@ Example.constraints = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.constraints.title = 'Constraints';
|
||||
Example.constraints.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.constraints;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ Example.doublePendulum = function() {
|
|||
Constraint = Matter.Constraint,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies,
|
||||
Vector = Matter.Vector;
|
||||
|
||||
|
@ -26,8 +25,7 @@ Example.doublePendulum = function() {
|
|||
options: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
wireframes: false,
|
||||
background: '#0f0f13'
|
||||
wireframes: false
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -54,10 +52,7 @@ Example.doublePendulum = function() {
|
|||
});
|
||||
});
|
||||
|
||||
pendulum.bodies[0].render.strokeStyle = '#4a485b';
|
||||
pendulum.bodies[1].render.strokeStyle = '#4a485b';
|
||||
|
||||
world.gravity.scale = 0.002;
|
||||
engine.gravity.scale = 0.002;
|
||||
|
||||
Composites.chain(pendulum, 0.45, 0, -0.45, 0, {
|
||||
stiffness: 0.9,
|
||||
|
@ -86,7 +81,7 @@ Example.doublePendulum = function() {
|
|||
y: lowerArm.position.y
|
||||
});
|
||||
|
||||
World.add(world, pendulum);
|
||||
Composite.add(world, pendulum);
|
||||
|
||||
var trail = [];
|
||||
|
||||
|
@ -128,7 +123,7 @@ Example.doublePendulum = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -151,3 +146,10 @@ Example.doublePendulum = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.doublePendulum.title = 'Double Pendulum';
|
||||
Example.doublePendulum.for = '>0.16.1';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.doublePendulum;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ Example.events = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -37,7 +36,7 @@ Example.events = function() {
|
|||
|
||||
// an example of using composite events on the world
|
||||
Events.on(world, 'afterAdd', function(event) {
|
||||
console.log('added to world:', event.object);
|
||||
// do something with event.object
|
||||
});
|
||||
|
||||
// an example of using beforeUpdate event on an engine
|
||||
|
@ -89,7 +88,7 @@ Example.events = function() {
|
|||
var bodyStyle = { fillStyle: '#222' };
|
||||
|
||||
// scene code
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true, render: bodyStyle }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true, render: bodyStyle }),
|
||||
Bodies.rectangle(800, 300, 50, 600, { isStatic: true, render: bodyStyle }),
|
||||
|
@ -100,7 +99,7 @@ Example.events = function() {
|
|||
return Bodies.circle(x, y, 15, { restitution: 1, render: bodyStyle });
|
||||
});
|
||||
|
||||
World.add(world, stack);
|
||||
Composite.add(world, stack);
|
||||
|
||||
var shakeScene = function(engine) {
|
||||
var bodies = Composite.allBodies(engine.world);
|
||||
|
@ -131,7 +130,7 @@ Example.events = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -177,3 +176,10 @@ Example.events = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.events.title = 'Events';
|
||||
Example.events.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.events;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ Example.friction = function() {
|
|||
Runner = Matter.Runner,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -31,7 +31,7 @@ Example.friction = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -39,18 +39,18 @@ Example.friction = function() {
|
|||
Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
|
||||
]);
|
||||
|
||||
World.add(world, [
|
||||
Bodies.rectangle(300, 180, 700, 20, { isStatic: true, angle: Math.PI * 0.06 }),
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(300, 180, 700, 20, { isStatic: true, angle: Math.PI * 0.06, render: { fillStyle: '#060a19' } }),
|
||||
Bodies.rectangle(300, 70, 40, 40, { friction: 0.001 })
|
||||
]);
|
||||
|
||||
World.add(world, [
|
||||
Bodies.rectangle(300, 350, 700, 20, { isStatic: true, angle: Math.PI * 0.06 }),
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(300, 350, 700, 20, { isStatic: true, angle: Math.PI * 0.06, render: { fillStyle: '#060a19' } }),
|
||||
Bodies.rectangle(300, 250, 40, 40, { friction: 0.0005 })
|
||||
]);
|
||||
|
||||
World.add(world, [
|
||||
Bodies.rectangle(300, 520, 700, 20, { isStatic: true, angle: Math.PI * 0.06 }),
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(300, 520, 700, 20, { isStatic: true, angle: Math.PI * 0.06, render: { fillStyle: '#060a19' } }),
|
||||
Bodies.rectangle(300, 430, 40, 40, { friction: 0 })
|
||||
]);
|
||||
|
||||
|
@ -66,7 +66,7 @@ Example.friction = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -89,3 +89,10 @@ Example.friction = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.friction.title = 'Friction';
|
||||
Example.friction.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.friction;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ Example.gravity = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -34,14 +34,14 @@ Example.gravity = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50.5, { isStatic: true }),
|
||||
Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
|
||||
Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
|
||||
]);
|
||||
|
||||
engine.world.gravity.y = -1;
|
||||
engine.gravity.y = -1;
|
||||
|
||||
var stack = Composites.stack(50, 120, 11, 5, 0, 0, function(x, y) {
|
||||
switch (Math.round(Common.random(0, 1))) {
|
||||
|
@ -58,7 +58,7 @@ Example.gravity = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, stack);
|
||||
Composite.add(world, stack);
|
||||
|
||||
// add mouse control
|
||||
var mouse = Mouse.create(render.canvas),
|
||||
|
@ -72,7 +72,7 @@ Example.gravity = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -95,3 +95,10 @@ Example.gravity = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.gravity.title = 'Reverse Gravity';
|
||||
Example.gravity.for = '>0.16.1';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.gravity;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ Example.gyro = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -59,7 +59,7 @@ Example.gyro = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -68,9 +68,10 @@ Example.gyro = function() {
|
|||
]);
|
||||
|
||||
// add gyro control
|
||||
if (typeof window !== 'undefined') {
|
||||
var updateGravity = function(event) {
|
||||
var orientation = typeof window.orientation !== 'undefined' ? window.orientation : 0,
|
||||
gravity = engine.world.gravity;
|
||||
gravity = engine.gravity;
|
||||
|
||||
if (orientation === 0) {
|
||||
gravity.x = Common.clamp(event.gamma, -90, 90) / 90;
|
||||
|
@ -88,6 +89,7 @@ Example.gyro = function() {
|
|||
};
|
||||
|
||||
window.addEventListener('deviceorientation', updateGravity);
|
||||
}
|
||||
|
||||
// add mouse control
|
||||
var mouse = Mouse.create(render.canvas),
|
||||
|
@ -101,7 +103,7 @@ Example.gyro = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -121,7 +123,16 @@ Example.gyro = function() {
|
|||
stop: function() {
|
||||
Matter.Render.stop(render);
|
||||
Matter.Runner.stop(runner);
|
||||
if (typeof window !== 'undefined') {
|
||||
window.removeEventListener('deviceorientation', updateGravity);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.gyro.title = 'Gyroscope';
|
||||
Example.gyro.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.gyro;
|
||||
}
|
||||
|
|
47
examples/index.js
Normal file
47
examples/index.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
module.exports = {
|
||||
airFriction: require('./airFriction.js'),
|
||||
avalanche: require('./avalanche.js'),
|
||||
ballPool: require('./ballPool.js'),
|
||||
bridge: require('./bridge.js'),
|
||||
broadphase: require('./broadphase.js'),
|
||||
car: require('./car.js'),
|
||||
catapult: require('./catapult.js'),
|
||||
chains: require('./chains.js'),
|
||||
circleStack: require('./circleStack.js'),
|
||||
cloth: require('./cloth.js'),
|
||||
collisionFiltering: require('./collisionFiltering.js'),
|
||||
compositeManipulation: require('./compositeManipulation.js'),
|
||||
compound: require('./compound.js'),
|
||||
compoundStack: require('./compoundStack.js'),
|
||||
concave: require('./concave.js'),
|
||||
constraints: require('./constraints.js'),
|
||||
doublePendulum: require('./doublePendulum.js'),
|
||||
events: require('./events.js'),
|
||||
friction: require('./friction.js'),
|
||||
gravity: require('./gravity.js'),
|
||||
gyro: require('./gyro.js'),
|
||||
manipulation: require('./manipulation.js'),
|
||||
mixed: require('./mixed.js'),
|
||||
newtonsCradle: require('./newtonsCradle.js'),
|
||||
ragdoll: require('./ragdoll.js'),
|
||||
pyramid: require('./pyramid.js'),
|
||||
raycasting: require('./raycasting.js'),
|
||||
restitution: require('./restitution.js'),
|
||||
rounded: require('./rounded.js'),
|
||||
sensors: require('./sensors.js'),
|
||||
sleeping: require('./sleeping.js'),
|
||||
slingshot: require('./slingshot.js'),
|
||||
softBody: require('./softBody.js'),
|
||||
sprites: require('./sprites.js'),
|
||||
stack: require('./stack.js'),
|
||||
staticFriction: require('./staticFriction.js'),
|
||||
stats: require('./stats.js'),
|
||||
stress: require('./stress.js'),
|
||||
stress2: require('./stress2.js'),
|
||||
stress3: require('./stress3.js'),
|
||||
svg: require('./svg.js'),
|
||||
terrain: require('./terrain.js'),
|
||||
timescale: require('./timescale.js'),
|
||||
views: require('./views.js'),
|
||||
wreckingBall: require('./wreckingBall.js')
|
||||
};
|
|
@ -8,7 +8,7 @@ Example.manipulation = function() {
|
|||
Events = Matter.Events,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -35,23 +35,23 @@ Example.manipulation = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var bodyA = Bodies.rectangle(100, 200, 50, 50, { isStatic: true }),
|
||||
var bodyA = Bodies.rectangle(100, 200, 50, 50, { isStatic: true, render: { fillStyle: '#060a19' } }),
|
||||
bodyB = Bodies.rectangle(200, 200, 50, 50),
|
||||
bodyC = Bodies.rectangle(300, 200, 50, 50),
|
||||
bodyD = Bodies.rectangle(400, 200, 50, 50),
|
||||
bodyE = Bodies.rectangle(550, 200, 50, 50),
|
||||
bodyF = Bodies.rectangle(700, 200, 50, 50),
|
||||
bodyG = Bodies.circle(400, 100, 25),
|
||||
partA = Bodies.rectangle(600, 200, 120, 50),
|
||||
partB = Bodies.rectangle(660, 200, 50, 190),
|
||||
bodyG = Bodies.circle(400, 100, 25, { render: { fillStyle: '#060a19' } }),
|
||||
partA = Bodies.rectangle(600, 200, 120, 50, { render: { fillStyle: '#060a19' } }),
|
||||
partB = Bodies.rectangle(660, 200, 50, 190, { render: { fillStyle: '#060a19' } }),
|
||||
compound = Body.create({
|
||||
parts: [partA, partB],
|
||||
isStatic: true
|
||||
});
|
||||
|
||||
World.add(world, [bodyA, bodyB, bodyC, bodyD, bodyE, bodyF, bodyG, compound]);
|
||||
Composite.add(world, [bodyA, bodyB, bodyC, bodyD, bodyE, bodyF, bodyG, compound]);
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -116,7 +116,7 @@ Example.manipulation = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -139,3 +139,10 @@ Example.manipulation = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.manipulation.title = 'Manipulation';
|
||||
Example.manipulation.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.manipulation;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ Example.mixed = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -59,9 +59,9 @@ Example.mixed = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, stack);
|
||||
Composite.add(world, stack);
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -81,7 +81,7 @@ Example.mixed = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -104,3 +104,10 @@ Example.mixed = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.mixed.title = 'Mixed Shapes';
|
||||
Example.mixed.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.mixed;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ Example.newtonsCradle = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World;
|
||||
Composite = Matter.Composite;
|
||||
|
||||
// create engine
|
||||
var engine = Engine.create(),
|
||||
|
@ -31,13 +31,13 @@ Example.newtonsCradle = function() {
|
|||
var runner = Runner.create();
|
||||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var cradle = Composites.newtonsCradle(280, 100, 5, 30, 200);
|
||||
World.add(world, cradle);
|
||||
// see newtonsCradle function defined later in this file
|
||||
var cradle = Example.newtonsCradle.newtonsCradle(280, 100, 5, 30, 200);
|
||||
Composite.add(world, cradle);
|
||||
Body.translate(cradle.bodies[0], { x: -180, y: -100 });
|
||||
|
||||
cradle = Composites.newtonsCradle(280, 380, 7, 20, 140);
|
||||
World.add(world, cradle);
|
||||
cradle = Example.newtonsCradle.newtonsCradle(280, 380, 7, 20, 140);
|
||||
Composite.add(world, cradle);
|
||||
Body.translate(cradle.bodies[0], { x: -140, y: -100 });
|
||||
|
||||
// add mouse control
|
||||
|
@ -52,7 +52,7 @@ Example.newtonsCradle = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -75,3 +75,40 @@ Example.newtonsCradle = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.newtonsCradle.title = 'Newton\'s Cradle';
|
||||
Example.newtonsCradle.for = '>=0.14.2';
|
||||
|
||||
/**
|
||||
* Creates a composite with a Newton's Cradle setup of bodies and constraints.
|
||||
* @method newtonsCradle
|
||||
* @param {number} xx
|
||||
* @param {number} yy
|
||||
* @param {number} number
|
||||
* @param {number} size
|
||||
* @param {number} length
|
||||
* @return {composite} A new composite newtonsCradle body
|
||||
*/
|
||||
Example.newtonsCradle.newtonsCradle = function(xx, yy, number, size, length) {
|
||||
var Composite = Matter.Composite,
|
||||
Constraint = Matter.Constraint,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
var newtonsCradle = Composite.create({ label: 'Newtons Cradle' });
|
||||
|
||||
for (var i = 0; i < number; i++) {
|
||||
var separation = 1.9,
|
||||
circle = Bodies.circle(xx + i * (size * separation), yy + length, size,
|
||||
{ inertia: Infinity, restitution: 1, friction: 0, frictionAir: 0.0001, slop: 1 }),
|
||||
constraint = Constraint.create({ pointA: { x: xx + i * (size * separation), y: yy }, bodyB: circle });
|
||||
|
||||
Composite.addBody(newtonsCradle, circle);
|
||||
Composite.addConstraint(newtonsCradle, constraint);
|
||||
}
|
||||
|
||||
return newtonsCradle;
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.newtonsCradle;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ Example.pyramid = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -32,11 +32,11 @@ Example.pyramid = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var stack = Composites.pyramid(100, 258, 15, 10, 0, 0, function(x, y) {
|
||||
var stack = Composites.pyramid(100, 605 - 25 - 16 * 20, 15, 10, 0, 0, function(x, y) {
|
||||
return Bodies.rectangle(x, y, 40, 40);
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
|
@ -57,7 +57,7 @@ Example.pyramid = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -80,3 +80,10 @@ Example.pyramid = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.pyramid.title = 'Pyramid';
|
||||
Example.pyramid.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.pyramid;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ Example.ragdoll = function() {
|
|||
Constraint = Matter.Constraint,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies,
|
||||
Vector = Matter.Vector;
|
||||
|
||||
|
@ -27,8 +26,7 @@ Example.ragdoll = function() {
|
|||
options: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
showAngleIndicator: true,
|
||||
background: '#0f0f13'
|
||||
showAngleIndicator: true
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -45,7 +43,9 @@ Example.ragdoll = function() {
|
|||
return Bodies.rectangle(x - 50, y + column * 50, 100, 1000, {
|
||||
isStatic: true,
|
||||
render: {
|
||||
fillStyle: '#222'
|
||||
fillStyle: '#060a19',
|
||||
strokeStyle: '#ffffff',
|
||||
lineWidth: 1
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -55,7 +55,7 @@ Example.ragdoll = function() {
|
|||
var sides = Math.round(Common.random(1, 8)),
|
||||
options = {
|
||||
render: {
|
||||
fillStyle: Common.choose(['#006BA6', '#0496FF', '#D81159', '#8F2D56'])
|
||||
fillStyle: Common.choose(['#f19648', '#f5d259', '#f55a3c', '#063e7b', '#ececd1'])
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -79,7 +79,7 @@ Example.ragdoll = function() {
|
|||
Composite.add(ragdolls, ragdoll);
|
||||
}
|
||||
|
||||
World.add(world, [stack, obstacles, ragdolls]);
|
||||
Composite.add(world, [stack, obstacles, ragdolls]);
|
||||
|
||||
var timeScaleTarget = 1,
|
||||
counter = 0;
|
||||
|
@ -172,7 +172,7 @@ Example.ragdoll = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -496,3 +496,10 @@ Example.ragdoll.ragdoll = function(x, y, scale, options) {
|
|||
|
||||
return person;
|
||||
};
|
||||
|
||||
Example.ragdoll.title = 'Ragdoll';
|
||||
Example.ragdoll.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.ragdoll;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ Example.raycasting = function() {
|
|||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
Events = Matter.Events,
|
||||
World = Matter.World,
|
||||
Vertices = Matter.Vertices,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
|
@ -53,10 +52,13 @@ Example.raycasting = function() {
|
|||
}
|
||||
});
|
||||
|
||||
// for testing raycasting on concave bodies
|
||||
Common.setDecomp(require('poly-decomp'));
|
||||
|
||||
var star = Vertices.fromPath('50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38'),
|
||||
concave = Bodies.fromVertices(200, 200, star);
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
concave,
|
||||
// walls
|
||||
|
@ -111,7 +113,7 @@ Example.raycasting = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -134,3 +136,10 @@ Example.raycasting = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.raycasting.title = 'Raycasting';
|
||||
Example.raycasting.for = '>0.16.1';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.raycasting;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ Example.restitution = function() {
|
|||
Runner = Matter.Runner,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -36,7 +36,7 @@ Example.restitution = function() {
|
|||
var rest = 0.9,
|
||||
space = 600 / 5;
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(100 + space * 0, 150, 50, 50, { restitution: rest }),
|
||||
Bodies.rectangle(100 + space * 1, 150, 50, 50, { restitution: rest, angle: -Math.PI * 0.15 }),
|
||||
Bodies.rectangle(100 + space * 2, 150, 50, 50, { restitution: rest, angle: -Math.PI * 0.25 }),
|
||||
|
@ -61,7 +61,7 @@ Example.restitution = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -84,3 +84,10 @@ Example.restitution = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.restitution.title = 'Restitution';
|
||||
Example.restitution.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.restitution;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ Example.rounded = function() {
|
|||
Runner = Matter.Runner,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -31,7 +31,7 @@ Example.rounded = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -39,7 +39,7 @@ Example.rounded = function() {
|
|||
Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
|
||||
]);
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(200, 200, 100, 100, {
|
||||
chamfer: { radius: 20 }
|
||||
}),
|
||||
|
@ -85,7 +85,7 @@ Example.rounded = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -108,3 +108,10 @@ Example.rounded = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.rounded.title = 'Rounded Corners (Chamfering)';
|
||||
Example.rounded.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.rounded;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ Example.sensors = function() {
|
|||
Events = Matter.Events,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -21,8 +21,7 @@ Example.sensors = function() {
|
|||
options: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
wireframes: false,
|
||||
background: '#111'
|
||||
wireframes: false
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -33,34 +32,34 @@ Example.sensors = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var redColor = '#C44D58',
|
||||
greenColor = '#C7F464';
|
||||
var colorA = '#f55a3c',
|
||||
colorB = '#f5d259';
|
||||
|
||||
var collider = Bodies.rectangle(400, 300, 500, 50, {
|
||||
isSensor: true,
|
||||
isStatic: true,
|
||||
render: {
|
||||
strokeStyle: redColor,
|
||||
strokeStyle: colorA,
|
||||
fillStyle: 'transparent',
|
||||
lineWidth: 1
|
||||
}
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
collider,
|
||||
Bodies.rectangle(400, 620, 800, 50, {
|
||||
Bodies.rectangle(400, 600, 800, 50, {
|
||||
isStatic: true,
|
||||
render: {
|
||||
fillStyle: 'transparent',
|
||||
lineWidth: 1
|
||||
fillStyle: '#060a19',
|
||||
lineWidth: 0
|
||||
}
|
||||
})
|
||||
]);
|
||||
|
||||
World.add(world,
|
||||
Composite.add(world,
|
||||
Bodies.circle(400, 40, 30, {
|
||||
render: {
|
||||
strokeStyle: greenColor,
|
||||
strokeStyle: colorB,
|
||||
fillStyle: 'transparent',
|
||||
lineWidth: 1
|
||||
}
|
||||
|
@ -74,9 +73,9 @@ Example.sensors = function() {
|
|||
var pair = pairs[i];
|
||||
|
||||
if (pair.bodyA === collider) {
|
||||
pair.bodyB.render.strokeStyle = redColor;
|
||||
pair.bodyB.render.strokeStyle = colorA;
|
||||
} else if (pair.bodyB === collider) {
|
||||
pair.bodyA.render.strokeStyle = redColor;
|
||||
pair.bodyA.render.strokeStyle = colorA;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -88,9 +87,9 @@ Example.sensors = function() {
|
|||
var pair = pairs[i];
|
||||
|
||||
if (pair.bodyA === collider) {
|
||||
pair.bodyB.render.strokeStyle = greenColor;
|
||||
pair.bodyB.render.strokeStyle = colorB;
|
||||
} else if (pair.bodyB === collider) {
|
||||
pair.bodyA.render.strokeStyle = greenColor;
|
||||
pair.bodyA.render.strokeStyle = colorB;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -107,7 +106,7 @@ Example.sensors = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -130,3 +129,10 @@ Example.sensors = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.sensors.title = 'Sensors';
|
||||
Example.sensors.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.sensors;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ Example.sleeping = function() {
|
|||
Events = Matter.Events,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -36,7 +36,7 @@ Example.sleeping = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -59,7 +59,7 @@ Example.sleeping = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, stack);
|
||||
Composite.add(world, stack);
|
||||
|
||||
for (var i = 0; i < stack.bodies.length; i++) {
|
||||
Events.on(stack.bodies[i], 'sleepStart sleepEnd', function(event) {
|
||||
|
@ -80,7 +80,7 @@ Example.sleeping = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -103,3 +103,10 @@ Example.sleeping = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.sleeping.title = 'Sleeping';
|
||||
Example.sleeping.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.sleeping;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ Example.slingshot = function() {
|
|||
Constraint = Matter.Constraint,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -34,7 +34,7 @@ Example.slingshot = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var ground = Bodies.rectangle(395, 600, 815, 50, { isStatic: true }),
|
||||
var ground = Bodies.rectangle(395, 600, 815, 50, { isStatic: true, render: { fillStyle: '#060a19' } }),
|
||||
rockOptions = { density: 0.004 },
|
||||
rock = Bodies.polygon(170, 450, 8, 20, rockOptions),
|
||||
anchor = { x: 170, y: 450 },
|
||||
|
@ -48,18 +48,18 @@ Example.slingshot = function() {
|
|||
return Bodies.rectangle(x, y, 25, 40);
|
||||
});
|
||||
|
||||
var ground2 = Bodies.rectangle(610, 250, 200, 20, { isStatic: true });
|
||||
var ground2 = Bodies.rectangle(610, 250, 200, 20, { isStatic: true, render: { fillStyle: '#060a19' } });
|
||||
|
||||
var pyramid2 = Composites.pyramid(550, 0, 5, 10, 0, 0, function(x, y) {
|
||||
return Bodies.rectangle(x, y, 25, 40);
|
||||
});
|
||||
|
||||
World.add(engine.world, [ground, pyramid, ground2, pyramid2, rock, elastic]);
|
||||
Composite.add(engine.world, [ground, pyramid, ground2, pyramid2, rock, elastic]);
|
||||
|
||||
Events.on(engine, 'afterUpdate', function() {
|
||||
if (mouseConstraint.mouse.button === -1 && (rock.position.x > 190 || rock.position.y < 430)) {
|
||||
rock = Bodies.polygon(170, 450, 7, 20, rockOptions);
|
||||
World.add(engine.world, rock);
|
||||
Composite.add(engine.world, rock);
|
||||
elastic.bodyB = rock;
|
||||
}
|
||||
});
|
||||
|
@ -76,7 +76,7 @@ Example.slingshot = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -99,3 +99,10 @@ Example.slingshot = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.slingshot.title = 'Slingshot';
|
||||
Example.slingshot.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.slingshot;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ Example.softBody = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -38,10 +38,11 @@ Example.softBody = function() {
|
|||
render: { visible: true }
|
||||
};
|
||||
|
||||
World.add(world, [
|
||||
Composites.softBody(250, 100, 5, 5, 0, 0, true, 18, particleOptions),
|
||||
Composites.softBody(400, 300, 8, 3, 0, 0, true, 15, particleOptions),
|
||||
Composites.softBody(250, 400, 4, 4, 0, 0, true, 15, particleOptions),
|
||||
Composite.add(world, [
|
||||
// see softBody function defined later in this file
|
||||
Example.softBody.softBody(250, 100, 5, 5, 0, 0, true, 18, particleOptions),
|
||||
Example.softBody.softBody(400, 300, 8, 3, 0, 0, true, 15, particleOptions),
|
||||
Example.softBody.softBody(250, 400, 4, 4, 0, 0, true, 15, particleOptions),
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -61,7 +62,7 @@ Example.softBody = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -84,3 +85,44 @@ Example.softBody = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.softBody.title = 'Soft Body';
|
||||
Example.softBody.for = '>=0.14.2';
|
||||
|
||||
/**
|
||||
* Creates a simple soft body like object.
|
||||
* @method softBody
|
||||
* @param {number} xx
|
||||
* @param {number} yy
|
||||
* @param {number} columns
|
||||
* @param {number} rows
|
||||
* @param {number} columnGap
|
||||
* @param {number} rowGap
|
||||
* @param {boolean} crossBrace
|
||||
* @param {number} particleRadius
|
||||
* @param {} particleOptions
|
||||
* @param {} constraintOptions
|
||||
* @return {composite} A new composite softBody
|
||||
*/
|
||||
Example.softBody.softBody = function(xx, yy, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) {
|
||||
var Common = Matter.Common,
|
||||
Composites = Matter.Composites,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
particleOptions = Common.extend({ inertia: Infinity }, particleOptions);
|
||||
constraintOptions = Common.extend({ stiffness: 0.2, render: { type: 'line', anchors: false } }, constraintOptions);
|
||||
|
||||
var softBody = Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y) {
|
||||
return Bodies.circle(x, y, particleRadius, particleOptions);
|
||||
});
|
||||
|
||||
Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions);
|
||||
|
||||
softBody.label = 'Soft Body';
|
||||
|
||||
return softBody;
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.softBody;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ Example.sprites = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -22,7 +22,6 @@ Example.sprites = function() {
|
|||
options: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
background: '#0f0f13',
|
||||
showAngleIndicator: false,
|
||||
wireframes: false
|
||||
}
|
||||
|
@ -43,7 +42,7 @@ Example.sprites = function() {
|
|||
world.bodies = [];
|
||||
|
||||
// these static walls will not be rendered in this sprites example, see options
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(400, -offset, 800.5 + 2 * offset, 50.5, options),
|
||||
Bodies.rectangle(400, 600 + offset, 800.5 + 2 * offset, 50.5, options),
|
||||
Bodies.rectangle(800 + offset, 300, 50.5, 600.5 + 2 * offset, options),
|
||||
|
@ -75,7 +74,7 @@ Example.sprites = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, stack);
|
||||
Composite.add(world, stack);
|
||||
|
||||
// add mouse control
|
||||
var mouse = Mouse.create(render.canvas),
|
||||
|
@ -89,7 +88,7 @@ Example.sprites = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -112,3 +111,10 @@ Example.sprites = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.sprites.title = 'Sprites';
|
||||
Example.sprites.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.sprites;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ Example.stack = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -32,11 +32,11 @@ Example.stack = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var stack = Composites.stack(200, 380, 10, 5, 0, 0, function(x, y) {
|
||||
var stack = Composites.stack(200, 606 - 25.25 - 5 * 40, 10, 5, 0, 0, function(x, y) {
|
||||
return Bodies.rectangle(x, y, 40, 40);
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
|
@ -57,7 +57,7 @@ Example.stack = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -80,3 +80,10 @@ Example.stack = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.stack.title = 'Stack';
|
||||
Example.stack.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.stack;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ Example.staticFriction = function() {
|
|||
Events = Matter.Events,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -34,7 +34,7 @@ Example.staticFriction = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var body = Bodies.rectangle(400, 500, 200, 60, { isStatic: true, chamfer: 10 }),
|
||||
var body = Bodies.rectangle(400, 500, 200, 60, { isStatic: true, chamfer: 10, render: { fillStyle: '#060a19' } }),
|
||||
size = 50,
|
||||
counter = -1;
|
||||
|
||||
|
@ -46,7 +46,7 @@ Example.staticFriction = function() {
|
|||
});
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
body,
|
||||
stack,
|
||||
// walls
|
||||
|
@ -82,7 +82,7 @@ Example.staticFriction = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -105,3 +105,10 @@ Example.staticFriction = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.staticFriction.title = 'Static Friction';
|
||||
Example.staticFriction.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.staticFriction;
|
||||
}
|
||||
|
|
91
examples/stats.js
Normal file
91
examples/stats.js
Normal file
|
@ -0,0 +1,91 @@
|
|||
var Example = Example || {};
|
||||
|
||||
Example.stats = function() {
|
||||
var Engine = Matter.Engine,
|
||||
Render = Matter.Render,
|
||||
Runner = Matter.Runner,
|
||||
Common = Matter.Common,
|
||||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
var engine = Engine.create(),
|
||||
world = engine.world;
|
||||
|
||||
// create renderer
|
||||
var render = Render.create({
|
||||
element: document.body,
|
||||
engine: engine,
|
||||
options: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
// show stats and performance monitors
|
||||
showStats: true,
|
||||
showPerformance: true
|
||||
}
|
||||
});
|
||||
|
||||
Render.run(render);
|
||||
|
||||
// create runner
|
||||
var runner = Runner.create();
|
||||
Runner.run(runner, engine);
|
||||
|
||||
// scene code
|
||||
var stack = Composites.stack(70, 30, 13, 9, 5, 5, function(x, y) {
|
||||
return Bodies.circle(x, y, 10 + Common.random() * 20);
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
stack,
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
|
||||
Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
|
||||
]);
|
||||
|
||||
// add mouse control
|
||||
var mouse = Mouse.create(render.canvas),
|
||||
mouseConstraint = MouseConstraint.create(engine, {
|
||||
mouse: mouse,
|
||||
constraint: {
|
||||
stiffness: 0.2,
|
||||
render: {
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
||||
// fit the render viewport to the scene
|
||||
Render.lookAt(render, {
|
||||
min: { x: 0, y: 0 },
|
||||
max: { x: 800, y: 600 }
|
||||
});
|
||||
|
||||
// context for MatterTools.Demo
|
||||
return {
|
||||
engine: engine,
|
||||
runner: runner,
|
||||
render: render,
|
||||
canvas: render.canvas,
|
||||
stop: function() {
|
||||
Matter.Render.stop(render);
|
||||
Matter.Runner.stop(runner);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.stats.title = 'Stats & Performance';
|
||||
Example.stats.for = '>=0.16.1';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.stats;
|
||||
}
|
|
@ -7,7 +7,7 @@ Example.stress = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -20,7 +20,9 @@ Example.stress = function() {
|
|||
engine: engine,
|
||||
options: {
|
||||
width: 800,
|
||||
height: 600
|
||||
height: 600,
|
||||
showStats: true,
|
||||
showPerformance: true
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -31,11 +33,11 @@ Example.stress = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// scene code
|
||||
var stack = Composites.stack(90, 50, 18, 15, 0, 0, function(x, y) {
|
||||
var stack = Composites.stack(90, 600 - 25 - 15 * 35, 18, 15, 0, 0, function(x, y) {
|
||||
return Bodies.rectangle(x, y, 35, 35);
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -55,7 +57,7 @@ Example.stress = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -78,3 +80,10 @@ Example.stress = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.stress.title = 'Stress';
|
||||
Example.stress.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.stress;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ Example.stress2 = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -20,7 +20,9 @@ Example.stress2 = function() {
|
|||
engine: engine,
|
||||
options: {
|
||||
width: 800,
|
||||
height: 600
|
||||
height: 600,
|
||||
showStats: true,
|
||||
showPerformance: true
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -31,11 +33,11 @@ Example.stress2 = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// scene code
|
||||
var stack = Composites.stack(100, 120, 25, 18, 0, 0, function(x, y) {
|
||||
var stack = Composites.stack(100, 600 - 25 - 18 * 25, 25, 18, 0, 0, function(x, y) {
|
||||
return Bodies.rectangle(x, y, 25, 25);
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
|
@ -55,7 +57,7 @@ Example.stress2 = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -78,3 +80,10 @@ Example.stress2 = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.stress2.title = 'Stress 2';
|
||||
Example.stress2.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.stress2;
|
||||
}
|
||||
|
|
107
examples/stress3.js
Normal file
107
examples/stress3.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
var Example = Example || {};
|
||||
|
||||
Example.stress3 = function() {
|
||||
var Engine = Matter.Engine,
|
||||
Render = Matter.Render,
|
||||
Runner = Matter.Runner,
|
||||
Composites = Matter.Composites,
|
||||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
Composite = Matter.Composite,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
var engine = Engine.create(),
|
||||
world = engine.world;
|
||||
|
||||
// create renderer
|
||||
var render = Render.create({
|
||||
element: document.body,
|
||||
engine: engine,
|
||||
options: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
showStats: true,
|
||||
showPerformance: true
|
||||
}
|
||||
});
|
||||
|
||||
Render.run(render);
|
||||
|
||||
// create runner
|
||||
var runner = Runner.create({
|
||||
isFixed: true
|
||||
});
|
||||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var scale = 0.3;
|
||||
|
||||
var stack = Composites.stack(40, 40, 38, 18, 0, 0, function(x, y) {
|
||||
var sides = Math.round(Common.random(1, 8));
|
||||
|
||||
switch (Math.round(Common.random(0, 1))) {
|
||||
case 0:
|
||||
if (Common.random() < 0.8) {
|
||||
return Bodies.rectangle(x, y, Common.random(25, 50) * scale, Common.random(25, 50) * scale);
|
||||
} else {
|
||||
return Bodies.rectangle(x, y, Common.random(80, 120) * scale, Common.random(25, 30) * scale);
|
||||
}
|
||||
case 1:
|
||||
return Bodies.polygon(x, y, sides, Common.random(25, 50) * scale);
|
||||
}
|
||||
});
|
||||
|
||||
Composite.add(world, stack);
|
||||
|
||||
Composite.add(world, [
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
|
||||
Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
|
||||
]);
|
||||
|
||||
// add mouse control
|
||||
var mouse = Mouse.create(render.canvas),
|
||||
mouseConstraint = MouseConstraint.create(engine, {
|
||||
mouse: mouse,
|
||||
constraint: {
|
||||
stiffness: 0.2,
|
||||
render: {
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
||||
// fit the render viewport to the scene
|
||||
Render.lookAt(render, {
|
||||
min: { x: 0, y: 0 },
|
||||
max: { x: 800, y: 600 }
|
||||
});
|
||||
|
||||
// context for MatterTools.Demo
|
||||
return {
|
||||
engine: engine,
|
||||
runner: runner,
|
||||
render: render,
|
||||
canvas: render.canvas,
|
||||
stop: function() {
|
||||
Matter.Render.stop(render);
|
||||
Matter.Runner.stop(runner);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.stress3.title = 'Stress 3';
|
||||
Example.stress3.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.stress3;
|
||||
}
|
|
@ -7,11 +7,14 @@ Example.svg = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Vertices = Matter.Vertices,
|
||||
Svg = Matter.Svg,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// provide concave decomposition support library
|
||||
Common.setDecomp(require('poly-decomp'));
|
||||
|
||||
// create engine
|
||||
var engine = Engine.create(),
|
||||
world = engine.world;
|
||||
|
@ -33,25 +36,30 @@ Example.svg = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var svgs = [
|
||||
'iconmonstr-check-mark-8-icon',
|
||||
'iconmonstr-paperclip-2-icon',
|
||||
'iconmonstr-puzzle-icon',
|
||||
'iconmonstr-user-icon'
|
||||
];
|
||||
if (typeof fetch !== 'undefined') {
|
||||
var select = function(root, selector) {
|
||||
return Array.prototype.slice.call(root.querySelectorAll(selector));
|
||||
};
|
||||
|
||||
for (var i = 0; i < svgs.length; i += 1) {
|
||||
(function(i) {
|
||||
$.get('./svg/' + svgs[i] + '.svg').done(function(data) {
|
||||
var vertexSets = [],
|
||||
color = Common.choose(['#556270', '#4ECDC4', '#C7F464', '#FF6B6B', '#C44D58']);
|
||||
var loadSvg = function(url) {
|
||||
return fetch(url)
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(raw) { return (new window.DOMParser()).parseFromString(raw, 'image/svg+xml'); });
|
||||
};
|
||||
|
||||
$(data).find('path').each(function(i, path) {
|
||||
var points = Svg.pathToVertices(path, 30);
|
||||
vertexSets.push(Vertices.scale(points, 0.4, 0.4));
|
||||
});
|
||||
([
|
||||
'./svg/iconmonstr-check-mark-8-icon.svg',
|
||||
'./svg/iconmonstr-paperclip-2-icon.svg',
|
||||
'./svg/iconmonstr-puzzle-icon.svg',
|
||||
'./svg/iconmonstr-user-icon.svg'
|
||||
]).forEach(function(path, i) {
|
||||
loadSvg(path).then(function(root) {
|
||||
var color = Common.choose(['#f19648', '#f5d259', '#f55a3c', '#063e7b', '#ececd1']);
|
||||
|
||||
World.add(world, Bodies.fromVertices(100 + i * 150, 200 + i * 50, vertexSets, {
|
||||
var vertexSets = select(root, 'path')
|
||||
.map(function(path) { return Vertices.scale(Svg.pathToVertices(path, 30), 0.4, 0.4); });
|
||||
|
||||
Composite.add(world, Bodies.fromVertices(100 + i * 150, 200 + i * 50, vertexSets, {
|
||||
render: {
|
||||
fillStyle: color,
|
||||
strokeStyle: color,
|
||||
|
@ -59,18 +67,15 @@ Example.svg = function() {
|
|||
}
|
||||
}, true));
|
||||
});
|
||||
})(i);
|
||||
}
|
||||
|
||||
$.get('./svg/svg.svg').done(function(data) {
|
||||
var vertexSets = [],
|
||||
color = Common.choose(['#556270', '#4ECDC4', '#C7F464', '#FF6B6B', '#C44D58']);
|
||||
|
||||
$(data).find('path').each(function(i, path) {
|
||||
vertexSets.push(Svg.pathToVertices(path, 30));
|
||||
});
|
||||
|
||||
World.add(world, Bodies.fromVertices(400, 80, vertexSets, {
|
||||
loadSvg('./svg/svg.svg').then(function(root) {
|
||||
var color = Common.choose(['#f19648', '#f5d259', '#f55a3c', '#063e7b', '#ececd1']);
|
||||
|
||||
var vertexSets = select(root, 'path')
|
||||
.map(function(path) { return Svg.pathToVertices(path, 30); });
|
||||
|
||||
Composite.add(world, Bodies.fromVertices(400, 80, vertexSets, {
|
||||
render: {
|
||||
fillStyle: color,
|
||||
strokeStyle: color,
|
||||
|
@ -78,8 +83,11 @@ Example.svg = function() {
|
|||
}
|
||||
}, true));
|
||||
});
|
||||
} else {
|
||||
Common.warn('Fetch is not available. Could not load SVG.');
|
||||
}
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
|
||||
|
@ -98,7 +106,7 @@ Example.svg = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -121,3 +129,10 @@ Example.svg = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.svg.title = 'Concave SVG Paths';
|
||||
Example.svg.for = '>0.16.1';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.svg;
|
||||
}
|
||||
|
|
|
@ -8,11 +8,14 @@ Example.terrain = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Query = Matter.Query,
|
||||
Svg = Matter.Svg,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// provide concave decomposition support library
|
||||
Common.setDecomp(require('poly-decomp'));
|
||||
|
||||
// create engine
|
||||
var engine = Engine.create(),
|
||||
world = engine.world;
|
||||
|
@ -34,25 +37,33 @@ Example.terrain = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
var terrain;
|
||||
if (typeof fetch !== 'undefined') {
|
||||
var select = function(root, selector) {
|
||||
return Array.prototype.slice.call(root.querySelectorAll(selector));
|
||||
};
|
||||
|
||||
$.get('./svg/terrain.svg').done(function(data) {
|
||||
var vertexSets = [];
|
||||
var loadSvg = function(url) {
|
||||
return fetch(url)
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(raw) { return (new window.DOMParser()).parseFromString(raw, 'image/svg+xml'); });
|
||||
};
|
||||
|
||||
$(data).find('path').each(function(i, path) {
|
||||
vertexSets.push(Svg.pathToVertices(path, 30));
|
||||
});
|
||||
loadSvg('./svg/terrain.svg')
|
||||
.then(function(root) {
|
||||
var paths = select(root, 'path');
|
||||
|
||||
terrain = Bodies.fromVertices(400, 350, vertexSets, {
|
||||
var vertexSets = paths.map(function(path) { return Svg.pathToVertices(path, 30); });
|
||||
|
||||
var terrain = Bodies.fromVertices(400, 350, vertexSets, {
|
||||
isStatic: true,
|
||||
render: {
|
||||
fillStyle: '#2e2b44',
|
||||
strokeStyle: '#2e2b44',
|
||||
fillStyle: '#060a19',
|
||||
strokeStyle: '#060a19',
|
||||
lineWidth: 1
|
||||
}
|
||||
}, true);
|
||||
|
||||
World.add(world, terrain);
|
||||
Composite.add(world, terrain);
|
||||
|
||||
var bodyOptions = {
|
||||
frictionAir: 0,
|
||||
|
@ -60,12 +71,15 @@ Example.terrain = function() {
|
|||
restitution: 0.6
|
||||
};
|
||||
|
||||
World.add(world, Composites.stack(80, 100, 20, 20, 10, 10, function(x, y) {
|
||||
Composite.add(world, Composites.stack(80, 100, 20, 20, 10, 10, function(x, y) {
|
||||
if (Query.point([terrain], { x: x, y: y }).length === 0) {
|
||||
return Bodies.polygon(x, y, 5, 12, bodyOptions);
|
||||
}
|
||||
}));
|
||||
});
|
||||
} else {
|
||||
Common.warn('Fetch is not available. Could not load SVG.');
|
||||
}
|
||||
|
||||
// add mouse control
|
||||
var mouse = Mouse.create(render.canvas),
|
||||
|
@ -79,7 +93,7 @@ Example.terrain = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -102,3 +116,10 @@ Example.terrain = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.terrain.title = 'Terrain';
|
||||
Example.terrain.for = '>0.16.1';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.terrain;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ Example.timescale = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
// create engine
|
||||
|
@ -36,7 +35,7 @@ Example.timescale = function() {
|
|||
Runner.run(runner, engine);
|
||||
|
||||
// add bodies
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
|
||||
Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
|
||||
|
@ -95,12 +94,12 @@ Example.timescale = function() {
|
|||
};
|
||||
|
||||
// add some small bouncy circles... remember Swordfish?
|
||||
World.add(world, Composites.stack(20, 100, 15, 3, 20, 40, function(x, y) {
|
||||
Composite.add(world, Composites.stack(20, 100, 15, 3, 20, 40, function(x, y) {
|
||||
return Bodies.circle(x, y, Common.random(10, 20), bodyOptions);
|
||||
}));
|
||||
|
||||
// add some larger random bouncy objects
|
||||
World.add(world, Composites.stack(50, 50, 8, 3, 0, 0, function(x, y) {
|
||||
Composite.add(world, Composites.stack(50, 50, 8, 3, 0, 0, function(x, y) {
|
||||
switch (Math.round(Common.random(0, 1))) {
|
||||
|
||||
case 0:
|
||||
|
@ -127,7 +126,7 @@ Example.timescale = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -150,3 +149,10 @@ Example.timescale = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.timescale.title = 'Time Scaling';
|
||||
Example.timescale.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.timescale;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ Example.views = function() {
|
|||
Common = Matter.Common,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Vector = Matter.Vector,
|
||||
Bounds = Matter.Bounds,
|
||||
Bodies = Matter.Bodies;
|
||||
|
@ -48,13 +48,13 @@ Example.views = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
||||
// add bodies
|
||||
var stack = Composites.stack(20, 20, 15, 4, 0, 0, function(x, y) {
|
||||
var stack = Composites.stack(20, 20, 10, 4, 0, 0, function(x, y) {
|
||||
switch (Math.round(Common.random(0, 1))) {
|
||||
|
||||
case 0:
|
||||
|
@ -70,7 +70,7 @@ Example.views = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
|
@ -85,11 +85,11 @@ Example.views = function() {
|
|||
y: render.options.height * 0.5
|
||||
};
|
||||
|
||||
// make the world bounds a little bigger than the render bounds
|
||||
world.bounds.min.x = -300;
|
||||
world.bounds.min.y = -300;
|
||||
world.bounds.max.x = 1100;
|
||||
world.bounds.max.y = 900;
|
||||
// create limits for the viewport
|
||||
var extents = {
|
||||
min: { x: -300, y: -300 },
|
||||
max: { x: 1100, y: 900 }
|
||||
};
|
||||
|
||||
// keep track of current bounds scale (view zoom)
|
||||
var boundsScaleTarget = 1,
|
||||
|
@ -98,8 +98,8 @@ Example.views = function() {
|
|||
y: 1
|
||||
};
|
||||
|
||||
// use the engine tick event to control our view
|
||||
Events.on(engine, 'beforeTick', function() {
|
||||
// use a render event to control our view
|
||||
Events.on(render, 'beforeRender', function() {
|
||||
var world = engine.world,
|
||||
mouse = mouseConstraint.mouse,
|
||||
translate;
|
||||
|
@ -148,18 +148,18 @@ Example.views = function() {
|
|||
|
||||
translate = Vector.mult(direction, speed);
|
||||
|
||||
// prevent the view moving outside the world bounds
|
||||
if (render.bounds.min.x + translate.x < world.bounds.min.x)
|
||||
translate.x = world.bounds.min.x - render.bounds.min.x;
|
||||
// prevent the view moving outside the extents
|
||||
if (render.bounds.min.x + translate.x < extents.min.x)
|
||||
translate.x = extents.min.x - render.bounds.min.x;
|
||||
|
||||
if (render.bounds.max.x + translate.x > world.bounds.max.x)
|
||||
translate.x = world.bounds.max.x - render.bounds.max.x;
|
||||
if (render.bounds.max.x + translate.x > extents.max.x)
|
||||
translate.x = extents.max.x - render.bounds.max.x;
|
||||
|
||||
if (render.bounds.min.y + translate.y < world.bounds.min.y)
|
||||
translate.y = world.bounds.min.y - render.bounds.min.y;
|
||||
if (render.bounds.min.y + translate.y < extents.min.y)
|
||||
translate.y = extents.min.y - render.bounds.min.y;
|
||||
|
||||
if (render.bounds.max.y + translate.y > world.bounds.max.y)
|
||||
translate.y = world.bounds.max.y - render.bounds.max.y;
|
||||
if (render.bounds.max.y + translate.y > extents.max.y)
|
||||
translate.y = extents.max.y - render.bounds.max.y;
|
||||
|
||||
// move the view
|
||||
Bounds.translate(render.bounds, translate);
|
||||
|
@ -181,3 +181,10 @@ Example.views = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.views.title = 'Views';
|
||||
Example.views.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.views;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ Example.wreckingBall = function() {
|
|||
Composites = Matter.Composites,
|
||||
MouseConstraint = Matter.MouseConstraint,
|
||||
Mouse = Matter.Mouse,
|
||||
World = Matter.World,
|
||||
Composite = Matter.Composite,
|
||||
Constraint = Matter.Constraint,
|
||||
Bodies = Matter.Bodies;
|
||||
|
||||
|
@ -34,13 +34,13 @@ Example.wreckingBall = function() {
|
|||
|
||||
// add bodies
|
||||
var rows = 10,
|
||||
yy = 600 - 21 - 40 * rows;
|
||||
yy = 600 - 25 - 40 * rows;
|
||||
|
||||
var stack = Composites.stack(400, yy, 5, rows, 0, 0, function(x, y) {
|
||||
return Bodies.rectangle(x, y, 40, 40);
|
||||
});
|
||||
|
||||
World.add(world, [
|
||||
Composite.add(world, [
|
||||
stack,
|
||||
// walls
|
||||
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
|
||||
|
@ -51,8 +51,8 @@ Example.wreckingBall = function() {
|
|||
|
||||
var ball = Bodies.circle(100, 400, 50, { density: 0.04, frictionAir: 0.005});
|
||||
|
||||
World.add(world, ball);
|
||||
World.add(world, Constraint.create({
|
||||
Composite.add(world, ball);
|
||||
Composite.add(world, Constraint.create({
|
||||
pointA: { x: 300, y: 100 },
|
||||
bodyB: ball
|
||||
}));
|
||||
|
@ -69,7 +69,7 @@ Example.wreckingBall = function() {
|
|||
}
|
||||
});
|
||||
|
||||
World.add(world, mouseConstraint);
|
||||
Composite.add(world, mouseConstraint);
|
||||
|
||||
// keep the mouse in sync with rendering
|
||||
render.mouse = mouse;
|
||||
|
@ -92,3 +92,10 @@ Example.wreckingBall = function() {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
Example.wreckingBall.title = 'Wrecking Ball';
|
||||
Example.wreckingBall.for = '>=0.14.2';
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = Example.wreckingBall;
|
||||
}
|
||||
|
|
30427
package-lock.json
generated
Normal file
30427
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
70
package.json
70
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "matter-js",
|
||||
"version": "0.14.2",
|
||||
"version": "0.17.1",
|
||||
"license": "MIT",
|
||||
"homepage": "http://brm.io/matter-js/",
|
||||
"author": "Liam Brummitt <liam@brm.io> (http://brm.io/)",
|
||||
|
@ -20,40 +20,46 @@
|
|||
"rigid body physics"
|
||||
],
|
||||
"devDependencies": {
|
||||
"browserify": "^14.0.0",
|
||||
"cheerio": "^0.22.0",
|
||||
"connect-livereload": "^0.6.0",
|
||||
"event-stream": "^3.3.2",
|
||||
"fast-json-patch": "^1.1.4",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-bump": "^2.6.1",
|
||||
"gulp-clone": "^1.0.0",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-conventional-changelog": "^1.1.0",
|
||||
"gulp-derequire": "^2.1.0",
|
||||
"gulp-eslint": "^3.0.1",
|
||||
"gulp-github-release": "^1.2.1",
|
||||
"gulp-header": "^1.7.1",
|
||||
"gulp-preprocess": "^2.0.0",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-replace": "^0.5.4",
|
||||
"gulp-tag-version": "^1.3.0",
|
||||
"gulp-uglify": "^2.0.1",
|
||||
"gulp-util": "^3.0.8",
|
||||
"gulp-webdriver": "^2.0.3",
|
||||
"gulp-webserver": "^0.9.1",
|
||||
"mkdirp": "^0.5.1",
|
||||
"rimraf": "^2.4.2",
|
||||
"run-sequence": "^1.1.4",
|
||||
"through2": "^2.0.3",
|
||||
"vinyl-transform": "^1.0.0",
|
||||
"watchify": "^3.9.0",
|
||||
"yuidocjs": "^0.10.2"
|
||||
"conventional-changelog-cli": "^2.1.1",
|
||||
"eslint": "^6.8.0",
|
||||
"html-webpack-plugin": "^4.5.1",
|
||||
"jest": "^25.1.0",
|
||||
"jest-worker": "^24.9.0",
|
||||
"json-stringify-pretty-compact": "^2.0.0",
|
||||
"matter-tools": "^0.14.0",
|
||||
"matter-wrap": "^0.2.0",
|
||||
"mock-require": "^3.0.3",
|
||||
"pathseg": "^1.2.0",
|
||||
"poly-decomp": "^0.3.0",
|
||||
"puppeteer-core": "^5.5.0",
|
||||
"terser-webpack-plugin": "^4.2.3",
|
||||
"webpack": "^4.46.0",
|
||||
"webpack-bundle-analyzer": "^4.4.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"webpack-dev-server": "^3.11.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "gulp build:dev && gulp lint"
|
||||
"start": "npm run dev",
|
||||
"dev": "npm run serve -- --open",
|
||||
"serve": "webpack-dev-server --no-cache --mode development --config webpack.demo.config.js",
|
||||
"watch": "nodemon --watch webpack.demo.config.js --exec \"npm run serve\"",
|
||||
"build": "webpack --mode=production --no-hot --no-watch & webpack --mode=production --no-hot --no-watch --env.MINIMIZE",
|
||||
"build-alpha": "webpack --mode=production --env.ALPHA & webpack --mode=production --env.MINIMIZE --env.ALPHA",
|
||||
"build-demo": "rm -rf ./demo/js && webpack --no-hot --no-watch --config webpack.demo.config.js --mode=production && webpack --no-hot --no-watch --config webpack.demo.config.js --mode=production --env.MINIMIZE",
|
||||
"lint": "eslint 'src/**/*.js' 'demo/src/**/*.js' 'examples/*.js' 'webpack.*.js'",
|
||||
"doc": "yuidoc --config yuidoc.json --project-version $npm_package_version",
|
||||
"doc-watch": "nodemon --delay 3 --watch 'matter-doc-theme' --watch src -e 'js,html,css,handlebars' --exec 'npm run doc'",
|
||||
"test": "npm run test-node",
|
||||
"test-all": "jest --no-cache",
|
||||
"test-save": "SAVE=true npm run test-node",
|
||||
"test-watch": "npm run test-node -- --watch",
|
||||
"test-node": "jest --no-cache ./test/Examples.spec.js",
|
||||
"test-browser": "jest --no-cache ./test/Browser.spec.js",
|
||||
"changelog": "conventional-changelog -i CHANGELOG.md -s -r",
|
||||
"release": "npm version --no-git-tag-version",
|
||||
"preversion": "git checkout master && npm run lint && SAVE=true npm run test-all",
|
||||
"version": "git checkout -b release/$npm_package_version && npm run build"
|
||||
},
|
||||
"dependencies": {},
|
||||
"files": [
|
||||
"src",
|
||||
"build",
|
||||
|
|
|
@ -49,7 +49,6 @@ var Axes = require('../geometry/Axes');
|
|||
force: { x: 0, y: 0 },
|
||||
torque: 0,
|
||||
positionImpulse: { x: 0, y: 0 },
|
||||
previousPositionImpulse: { x: 0, y: 0 },
|
||||
constraintImpulse: { x: 0, y: 0, angle: 0 },
|
||||
totalContacts: 0,
|
||||
speed: 0,
|
||||
|
@ -76,13 +75,15 @@ var Axes = require('../geometry/Axes');
|
|||
render: {
|
||||
visible: true,
|
||||
opacity: 1,
|
||||
strokeStyle: null,
|
||||
fillStyle: null,
|
||||
lineWidth: null,
|
||||
sprite: {
|
||||
xScale: 1,
|
||||
yScale: 1,
|
||||
xOffset: 0,
|
||||
yOffset: 0
|
||||
},
|
||||
lineWidth: 0
|
||||
}
|
||||
},
|
||||
events: null,
|
||||
bounds: null,
|
||||
|
@ -166,10 +167,12 @@ var Axes = require('../geometry/Axes');
|
|||
});
|
||||
|
||||
// render properties
|
||||
var defaultFillStyle = (body.isStatic ? '#2e2b44' : Common.choose(['#006BA6', '#0496FF', '#FFBC42', '#D81159', '#8F2D56'])),
|
||||
defaultStrokeStyle = '#000';
|
||||
var defaultFillStyle = (body.isStatic ? '#14151f' : Common.choose(['#f19648', '#f5d259', '#f55a3c', '#063e7b', '#ececd1'])),
|
||||
defaultStrokeStyle = body.isStatic ? '#555' : '#ccc',
|
||||
defaultLineWidth = body.isStatic && body.render.fillStyle === null ? 1 : 0;
|
||||
body.render.fillStyle = body.render.fillStyle || defaultFillStyle;
|
||||
body.render.strokeStyle = body.render.strokeStyle || defaultStrokeStyle;
|
||||
body.render.lineWidth = body.render.lineWidth || defaultLineWidth;
|
||||
body.render.sprite.xOffset += -(body.bounds.min.x - body.position.x) / (body.bounds.max.x - body.bounds.min.x);
|
||||
body.render.sprite.yOffset += -(body.bounds.min.y - body.position.y) / (body.bounds.max.y - body.bounds.min.y);
|
||||
};
|
||||
|
@ -192,8 +195,7 @@ var Axes = require('../geometry/Axes');
|
|||
}
|
||||
|
||||
for (property in settings) {
|
||||
|
||||
if (!settings.hasOwnProperty(property))
|
||||
if (!Object.prototype.hasOwnProperty.call(settings, property))
|
||||
continue;
|
||||
|
||||
value = settings[property];
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
/**
|
||||
* The `Matter.Composite` module contains methods for creating and manipulating composite bodies.
|
||||
* A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure.
|
||||
* It is important to use the functions in this module to modify composites, rather than directly modifying their properties.
|
||||
* Note that the `Matter.World` object is also a type of `Matter.Composite` and as such all composite methods here can also operate on a `Matter.World`.
|
||||
* A composite is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite` objects.
|
||||
*
|
||||
* They are a container that can represent complex objects made of multiple parts, even if they are not physically connected.
|
||||
* A composite could contain anything from a single body all the way up to a whole world.
|
||||
*
|
||||
* When making any changes to composites, use the included functions rather than changing their properties directly.
|
||||
*
|
||||
* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
|
||||
*
|
||||
|
@ -67,11 +69,11 @@ var Body = require('./Body');
|
|||
};
|
||||
|
||||
/**
|
||||
* Generic add function. Adds one or many body(s), constraint(s) or a composite(s) to the given composite.
|
||||
* Generic single or multi-add function. Adds a single or an array of body(s), constraint(s) or composite(s) to the given composite.
|
||||
* Triggers `beforeAdd` and `afterAdd` events on the `composite`.
|
||||
* @method add
|
||||
* @param {composite} composite
|
||||
* @param {} object
|
||||
* @param {object|array} object A single or an array of body(s), constraint(s) or composite(s)
|
||||
* @return {composite} The original composite with the objects added
|
||||
*/
|
||||
Composite.add = function(composite, object) {
|
||||
|
@ -117,7 +119,7 @@ var Body = require('./Body');
|
|||
* Triggers `beforeRemove` and `afterRemove` events on the `composite`.
|
||||
* @method remove
|
||||
* @param {composite} composite
|
||||
* @param {} object
|
||||
* @param {object|array} object
|
||||
* @param {boolean} [deep=false]
|
||||
* @return {composite} The original composite with the objects removed
|
||||
*/
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
/**
|
||||
* The `Matter.World` module contains methods for creating and manipulating the world composite.
|
||||
* A `Matter.World` is a `Matter.Composite` body, which is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`.
|
||||
* A `Matter.World` has a few additional properties including `gravity` and `bounds`.
|
||||
* It is important to use the functions in the `Matter.Composite` module to modify the world composite, rather than directly modifying its properties.
|
||||
* There are also a few methods here that alias those in `Matter.Composite` for easier readability.
|
||||
* This module has now been replaced by `Matter.Composite`.
|
||||
*
|
||||
* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
|
||||
* All usage should be migrated to the equivalent functions found on `Matter.Composite`.
|
||||
* For example `World.add(world, body)` now becomes `Composite.add(world, body)`.
|
||||
*
|
||||
* The property `world.gravity` has been moved to `engine.gravity`.
|
||||
*
|
||||
* For back-compatibility purposes this module will remain as a direct alias to `Matter.Composite` in the short term during migration.
|
||||
* Eventually this alias module will be marked as deprecated and then later removed in a future release.
|
||||
*
|
||||
* @class World
|
||||
* @extends Composite
|
||||
*/
|
||||
|
||||
var World = {};
|
||||
|
@ -16,132 +17,19 @@ var World = {};
|
|||
module.exports = World;
|
||||
|
||||
var Composite = require('./Composite');
|
||||
var Constraint = require('../constraint/Constraint');
|
||||
var Common = require('../core/Common');
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* Creates a new world composite. The options parameter is an object that specifies any properties you wish to override the defaults.
|
||||
* See the properties section below for detailed information on what you can pass via the `options` object.
|
||||
* @method create
|
||||
* @constructor
|
||||
* @param {} options
|
||||
* @return {world} A new world
|
||||
*/
|
||||
World.create = function(options) {
|
||||
var composite = Composite.create();
|
||||
|
||||
var defaults = {
|
||||
label: 'World',
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: 1,
|
||||
scale: 0.001
|
||||
},
|
||||
bounds: {
|
||||
min: { x: -Infinity, y: -Infinity },
|
||||
max: { x: Infinity, y: Infinity }
|
||||
}
|
||||
};
|
||||
|
||||
return Common.extend(composite, defaults, options);
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* Properties Documentation
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The gravity to apply on the world.
|
||||
*
|
||||
* @property gravity
|
||||
* @type object
|
||||
*/
|
||||
|
||||
/**
|
||||
* The gravity x component.
|
||||
*
|
||||
* @property gravity.x
|
||||
* @type object
|
||||
* @default 0
|
||||
*/
|
||||
|
||||
/**
|
||||
* The gravity y component.
|
||||
*
|
||||
* @property gravity.y
|
||||
* @type object
|
||||
* @default 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* The gravity scale factor.
|
||||
*
|
||||
* @property gravity.scale
|
||||
* @type object
|
||||
* @default 0.001
|
||||
*/
|
||||
|
||||
/**
|
||||
* A `Bounds` object that defines the world bounds for collision detection.
|
||||
*
|
||||
* @property bounds
|
||||
* @type bounds
|
||||
* @default { min: { x: -Infinity, y: -Infinity }, max: { x: Infinity, y: Infinity } }
|
||||
*/
|
||||
|
||||
// World is a Composite body
|
||||
// see src/module/Outro.js for these aliases:
|
||||
|
||||
/**
|
||||
* An alias for Composite.add
|
||||
* @method add
|
||||
* @param {world} world
|
||||
* @param {} object
|
||||
* @return {composite} The original world with the objects added
|
||||
*/
|
||||
|
||||
/**
|
||||
* An alias for Composite.remove
|
||||
* @method remove
|
||||
* @param {world} world
|
||||
* @param {} object
|
||||
* @param {boolean} [deep=false]
|
||||
* @return {composite} The original world with the objects removed
|
||||
*/
|
||||
|
||||
/**
|
||||
* An alias for Composite.clear
|
||||
* @method clear
|
||||
* @param {world} world
|
||||
* @param {boolean} keepStatic
|
||||
*/
|
||||
|
||||
/**
|
||||
* An alias for Composite.addComposite
|
||||
* @method addComposite
|
||||
* @param {world} world
|
||||
* @param {composite} composite
|
||||
* @return {world} The original world with the objects from composite added
|
||||
*/
|
||||
|
||||
/**
|
||||
* An alias for Composite.addBody
|
||||
* @method addBody
|
||||
* @param {world} world
|
||||
* @param {body} body
|
||||
* @return {world} The original world with the body added
|
||||
*/
|
||||
|
||||
/**
|
||||
* An alias for Composite.addConstraint
|
||||
* @method addConstraint
|
||||
* @param {world} world
|
||||
* @param {constraint} constraint
|
||||
* @return {world} The original world with the constraint added
|
||||
* See above, aliases for back compatibility only
|
||||
*/
|
||||
World.create = Composite.create;
|
||||
World.add = Composite.add;
|
||||
World.remove = Composite.remove;
|
||||
World.clear = Composite.clear;
|
||||
World.addComposite = Composite.addComposite;
|
||||
World.addBody = Composite.addBody;
|
||||
World.addConstraint = Composite.addConstraint;
|
||||
|
||||
})();
|
||||
|
|
38
src/collision/Contact.js
Normal file
38
src/collision/Contact.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* The `Matter.Contact` module contains methods for creating and manipulating collision contacts.
|
||||
*
|
||||
* @class Contact
|
||||
*/
|
||||
|
||||
var Contact = {};
|
||||
|
||||
module.exports = Contact;
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* Creates a new contact.
|
||||
* @method create
|
||||
* @param {vertex} vertex
|
||||
* @return {contact} A new contact
|
||||
*/
|
||||
Contact.create = function(vertex) {
|
||||
return {
|
||||
id: Contact.id(vertex),
|
||||
vertex: vertex,
|
||||
normalImpulse: 0,
|
||||
tangentImpulse: 0
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates a contact id.
|
||||
* @method id
|
||||
* @param {vertex} vertex
|
||||
* @return {string} Unique contactID
|
||||
*/
|
||||
Contact.id = function(vertex) {
|
||||
return vertex.body.id + '_' + vertex.index;
|
||||
};
|
||||
|
||||
})();
|
|
@ -27,10 +27,6 @@ var Bounds = require('../geometry/Bounds');
|
|||
var collisions = [],
|
||||
pairsTable = engine.pairs.table;
|
||||
|
||||
// @if DEBUG
|
||||
var metrics = engine.metrics;
|
||||
// @endif
|
||||
|
||||
for (var i = 0; i < broadphasePairs.length; i++) {
|
||||
var bodyA = broadphasePairs[i][0],
|
||||
bodyB = broadphasePairs[i][1];
|
||||
|
@ -41,10 +37,6 @@ var Bounds = require('../geometry/Bounds');
|
|||
if (!Detector.canCollide(bodyA.collisionFilter, bodyB.collisionFilter))
|
||||
continue;
|
||||
|
||||
// @if DEBUG
|
||||
metrics.midphaseTests += 1;
|
||||
// @endif
|
||||
|
||||
// mid phase
|
||||
if (Bounds.overlaps(bodyA.bounds, bodyB.bounds)) {
|
||||
for (var j = bodyA.parts.length > 1 ? 1 : 0; j < bodyA.parts.length; j++) {
|
||||
|
@ -68,17 +60,8 @@ var Bounds = require('../geometry/Bounds');
|
|||
// narrow phase
|
||||
var collision = SAT.collides(partA, partB, previousCollision);
|
||||
|
||||
// @if DEBUG
|
||||
metrics.narrowphaseTests += 1;
|
||||
if (collision.reused)
|
||||
metrics.narrowReuseCount += 1;
|
||||
// @endif
|
||||
|
||||
if (collision.collided) {
|
||||
collisions.push(collision);
|
||||
// @if DEBUG
|
||||
metrics.narrowDetections += 1;
|
||||
// @endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ var Grid = {};
|
|||
module.exports = Grid;
|
||||
|
||||
var Pair = require('./Pair');
|
||||
var Detector = require('./Detector');
|
||||
var Common = require('../core/Common');
|
||||
|
||||
(function() {
|
||||
|
@ -22,8 +21,6 @@ var Common = require('../core/Common');
|
|||
*/
|
||||
Grid.create = function(options) {
|
||||
var defaults = {
|
||||
controller: Grid,
|
||||
detector: Detector.collisions,
|
||||
buckets: {},
|
||||
pairs: {},
|
||||
pairsList: [],
|
||||
|
@ -66,20 +63,15 @@ var Common = require('../core/Common');
|
|||
bucketId,
|
||||
gridChanged = false;
|
||||
|
||||
// @if DEBUG
|
||||
var metrics = engine.metrics;
|
||||
metrics.broadphaseTests = 0;
|
||||
// @endif
|
||||
|
||||
for (i = 0; i < bodies.length; i++) {
|
||||
var body = bodies[i];
|
||||
|
||||
if (body.isSleeping && !forceUpdate)
|
||||
continue;
|
||||
|
||||
// don't update out of world bodies
|
||||
if (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x
|
||||
|| body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y)
|
||||
// temporary back compatibility bounds check
|
||||
if (world.bounds && (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x
|
||||
|| body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y))
|
||||
continue;
|
||||
|
||||
var newRegion = Grid._getRegion(grid, body);
|
||||
|
@ -87,10 +79,6 @@ var Common = require('../core/Common');
|
|||
// if the body has changed grid region
|
||||
if (!body.region || newRegion.id !== body.region.id || forceUpdate) {
|
||||
|
||||
// @if DEBUG
|
||||
metrics.broadphaseTests += 1;
|
||||
// @endif
|
||||
|
||||
if (!body.region || forceUpdate)
|
||||
body.region = newRegion;
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ var Pair = {};
|
|||
|
||||
module.exports = Pair;
|
||||
|
||||
var Contact = require('./Contact');
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
|
@ -19,12 +21,15 @@ module.exports = Pair;
|
|||
*/
|
||||
Pair.create = function(collision, timestamp) {
|
||||
var bodyA = collision.bodyA,
|
||||
bodyB = collision.bodyB;
|
||||
bodyB = collision.bodyB,
|
||||
parentA = collision.parentA,
|
||||
parentB = collision.parentB;
|
||||
|
||||
var pair = {
|
||||
id: Pair.id(bodyA, bodyB),
|
||||
bodyA: bodyA,
|
||||
bodyB: bodyB,
|
||||
contacts: {},
|
||||
activeContacts: [],
|
||||
separation: 0,
|
||||
isActive: true,
|
||||
|
@ -32,12 +37,11 @@ module.exports = Pair;
|
|||
isSensor: bodyA.isSensor || bodyB.isSensor,
|
||||
timeCreated: timestamp,
|
||||
timeUpdated: timestamp,
|
||||
collision: null,
|
||||
inverseMass: 0,
|
||||
friction: 0,
|
||||
frictionStatic: 0,
|
||||
restitution: 0,
|
||||
slop: 0
|
||||
inverseMass: parentA.inverseMass + parentB.inverseMass,
|
||||
friction: Math.min(parentA.friction, parentB.friction),
|
||||
frictionStatic: Math.max(parentA.frictionStatic, parentB.frictionStatic),
|
||||
restitution: Math.max(parentA.restitution, parentB.restitution),
|
||||
slop: Math.max(parentA.slop, parentB.slop)
|
||||
};
|
||||
|
||||
Pair.update(pair, collision, timestamp);
|
||||
|
@ -53,28 +57,31 @@ module.exports = Pair;
|
|||
* @param {number} timestamp
|
||||
*/
|
||||
Pair.update = function(pair, collision, timestamp) {
|
||||
pair.collision = collision;
|
||||
|
||||
if (collision.collided) {
|
||||
var supports = collision.supports,
|
||||
var contacts = pair.contacts,
|
||||
supports = collision.supports,
|
||||
activeContacts = pair.activeContacts,
|
||||
parentA = collision.parentA,
|
||||
parentB = collision.parentB;
|
||||
|
||||
pair.collision = collision;
|
||||
pair.inverseMass = parentA.inverseMass + parentB.inverseMass;
|
||||
pair.friction = Math.min(parentA.friction, parentB.friction);
|
||||
pair.frictionStatic = Math.max(parentA.frictionStatic, parentB.frictionStatic);
|
||||
pair.restitution = Math.max(parentA.restitution, parentB.restitution);
|
||||
pair.slop = Math.max(parentA.slop, parentB.slop);
|
||||
activeContacts.length = 0;
|
||||
|
||||
if (collision.collided) {
|
||||
for (var i = 0; i < supports.length; i++) {
|
||||
activeContacts[i] = supports[i].contact;
|
||||
}
|
||||
var support = supports[i],
|
||||
contactId = Contact.id(support),
|
||||
contact = contacts[contactId];
|
||||
|
||||
// optimise array size
|
||||
var supportCount = supports.length;
|
||||
if (supportCount < activeContacts.length) {
|
||||
activeContacts.length = supportCount;
|
||||
if (contact) {
|
||||
activeContacts.push(contact);
|
||||
} else {
|
||||
activeContacts.push(contacts[contactId] = Contact.create(support));
|
||||
}
|
||||
}
|
||||
|
||||
pair.separation = collision.depth;
|
||||
|
|
|
@ -48,33 +48,23 @@ var Bounds = require('../geometry/Bounds');
|
|||
* Find a solution for pair positions.
|
||||
* @method solvePosition
|
||||
* @param {pair[]} pairs
|
||||
* @param {body[]} bodies
|
||||
* @param {number} timeScale
|
||||
*/
|
||||
Resolver.solvePosition = function(pairs, bodies, timeScale) {
|
||||
Resolver.solvePosition = function(pairs, timeScale) {
|
||||
var i,
|
||||
normalX,
|
||||
normalY,
|
||||
pair,
|
||||
collision,
|
||||
bodyA,
|
||||
bodyB,
|
||||
normal,
|
||||
separation,
|
||||
penetration,
|
||||
positionImpulseA,
|
||||
positionImpulseB,
|
||||
bodyBtoA,
|
||||
contactShare,
|
||||
bodyBtoAX,
|
||||
bodyBtoAY,
|
||||
positionImpulse,
|
||||
impulseCoefficient = timeScale * Resolver._positionDampen;
|
||||
|
||||
for (i = 0; i < bodies.length; i++) {
|
||||
var body = bodies[i];
|
||||
body.previousPositionImpulse.x = body.positionImpulse.x;
|
||||
body.previousPositionImpulse.y = body.positionImpulse.y;
|
||||
}
|
||||
contactCount = {},
|
||||
tempA = Vector._temp[0],
|
||||
tempB = Vector._temp[1],
|
||||
tempC = Vector._temp[2],
|
||||
tempD = Vector._temp[3];
|
||||
|
||||
// find impulses required to resolve penetration
|
||||
for (i = 0; i < pairs.length; i++) {
|
||||
|
@ -88,35 +78,39 @@ var Bounds = require('../geometry/Bounds');
|
|||
bodyB = collision.parentB;
|
||||
normal = collision.normal;
|
||||
|
||||
positionImpulseA = bodyA.previousPositionImpulse;
|
||||
positionImpulseB = bodyB.previousPositionImpulse;
|
||||
// get current separation between body edges involved in collision
|
||||
bodyBtoA = Vector.sub(Vector.add(bodyB.positionImpulse, bodyB.position, tempA),
|
||||
Vector.add(bodyA.positionImpulse,
|
||||
Vector.sub(bodyB.position, collision.penetration, tempB), tempC), tempD);
|
||||
|
||||
penetration = collision.penetration;
|
||||
pair.separation = Vector.dot(normal, bodyBtoA);
|
||||
}
|
||||
|
||||
bodyBtoAX = positionImpulseB.x - positionImpulseA.x + penetration.x;
|
||||
bodyBtoAY = positionImpulseB.y - positionImpulseA.y + penetration.y;
|
||||
for (i = 0; i < pairs.length; i++) {
|
||||
pair = pairs[i];
|
||||
|
||||
normalX = normal.x;
|
||||
normalY = normal.y;
|
||||
if (!pair.isActive || pair.isSensor)
|
||||
continue;
|
||||
|
||||
separation = normalX * bodyBtoAX + normalY * bodyBtoAY;
|
||||
pair.separation = separation;
|
||||
|
||||
positionImpulse = (separation - pair.slop) * impulseCoefficient;
|
||||
collision = pair.collision;
|
||||
bodyA = collision.parentA;
|
||||
bodyB = collision.parentB;
|
||||
normal = collision.normal;
|
||||
positionImpulse = (pair.separation - pair.slop) * timeScale;
|
||||
|
||||
if (bodyA.isStatic || bodyB.isStatic)
|
||||
positionImpulse *= 2;
|
||||
|
||||
if (!(bodyA.isStatic || bodyA.isSleeping)) {
|
||||
contactShare = positionImpulse / bodyA.totalContacts;
|
||||
bodyA.positionImpulse.x += normalX * contactShare;
|
||||
bodyA.positionImpulse.y += normalY * contactShare;
|
||||
contactShare = Resolver._positionDampen / bodyA.totalContacts;
|
||||
bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare;
|
||||
bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare;
|
||||
}
|
||||
|
||||
if (!(bodyB.isStatic || bodyB.isSleeping)) {
|
||||
contactShare = positionImpulse / bodyB.totalContacts;
|
||||
bodyB.positionImpulse.x -= normalX * contactShare;
|
||||
bodyB.positionImpulse.y -= normalY * contactShare;
|
||||
contactShare = Resolver._positionDampen / bodyB.totalContacts;
|
||||
bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare;
|
||||
bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -300,6 +300,32 @@ var Common = require('../core/Common');
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the world-space position of `constraint.pointA`, accounting for `constraint.bodyA`.
|
||||
* @method pointAWorld
|
||||
* @param {constraint} constraint
|
||||
* @returns {vector} the world-space position
|
||||
*/
|
||||
Constraint.pointAWorld = function(constraint) {
|
||||
return {
|
||||
x: (constraint.bodyA ? constraint.bodyA.position.x : 0) + constraint.pointA.x,
|
||||
y: (constraint.bodyA ? constraint.bodyA.position.y : 0) + constraint.pointA.y
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the world-space position of `constraint.pointB`, accounting for `constraint.bodyB`.
|
||||
* @method pointBWorld
|
||||
* @param {constraint} constraint
|
||||
* @returns {vector} the world-space position
|
||||
*/
|
||||
Constraint.pointBWorld = function(constraint) {
|
||||
return {
|
||||
x: (constraint.bodyB ? constraint.bodyB.position.x : 0) + constraint.pointB.x,
|
||||
y: (constraint.bodyB ? constraint.bodyB.position.y : 0) + constraint.pointB.y
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* Properties Documentation
|
||||
|
|
|
@ -13,6 +13,8 @@ module.exports = Common;
|
|||
Common._nextId = 0;
|
||||
Common._seed = 0;
|
||||
Common._nowStartTime = +(new Date());
|
||||
Common._warnedOnce = {};
|
||||
Common._decomp = null;
|
||||
|
||||
/**
|
||||
* Extends the object in the first argument using the object in the second argument.
|
||||
|
@ -252,12 +254,12 @@ module.exports = Common;
|
|||
|
||||
/**
|
||||
* Returns the current timestamp since the time origin (e.g. from page load).
|
||||
* The result will be high-resolution including decimal places if available.
|
||||
* The result is in milliseconds and will use high-resolution timing if available.
|
||||
* @method now
|
||||
* @return {number} the current timestamp
|
||||
* @return {number} the current timestamp in milliseconds
|
||||
*/
|
||||
Common.now = function() {
|
||||
if (window.performance) {
|
||||
if (typeof window !== 'undefined' && window.performance) {
|
||||
if (window.performance.now) {
|
||||
return window.performance.now();
|
||||
} else if (window.performance.webkitNow) {
|
||||
|
@ -265,6 +267,10 @@ module.exports = Common;
|
|||
}
|
||||
}
|
||||
|
||||
if (Date.now) {
|
||||
return Date.now();
|
||||
}
|
||||
|
||||
return (new Date()) - Common._nowStartTime;
|
||||
};
|
||||
|
||||
|
@ -358,6 +364,35 @@ module.exports = Common;
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Uses `Common.warn` to log the given message one time only.
|
||||
* @method warnOnce
|
||||
* @param ...objs {} The objects to log.
|
||||
*/
|
||||
Common.warnOnce = function() {
|
||||
var message = Array.prototype.slice.call(arguments).join(' ');
|
||||
|
||||
if (!Common._warnedOnce[message]) {
|
||||
Common.warn(message);
|
||||
Common._warnedOnce[message] = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows a deprecated console warning when the function on the given object is called.
|
||||
* The target function will be replaced with a new function that first shows the warning
|
||||
* and then calls the original function.
|
||||
* @method deprecated
|
||||
* @param {object} obj The object or module
|
||||
* @param {string} name The property name of the function on obj
|
||||
* @param {string} warning The one-time message to show if the function is called
|
||||
*/
|
||||
Common.deprecated = function(obj, prop, warning) {
|
||||
obj[prop] = Common.chain(function() {
|
||||
Common.warnOnce('🔅 deprecated 🔅', warning);
|
||||
}, obj[prop]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the next unique sequential ID.
|
||||
* @method nextId
|
||||
|
@ -537,17 +572,40 @@ module.exports = Common;
|
|||
};
|
||||
|
||||
/**
|
||||
* Used to require external libraries outside of the bundle.
|
||||
* It first looks for the `globalName` on the environment's global namespace.
|
||||
* If the global is not found, it will fall back to using the standard `require` using the `moduleName`.
|
||||
* @private
|
||||
* @method _requireGlobal
|
||||
* @param {string} globalName The global module name
|
||||
* @param {string} moduleName The fallback CommonJS module name
|
||||
* @return {} The loaded module
|
||||
* Provide the [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module to enable
|
||||
* concave vertex decomposition support when using `Bodies.fromVertices` e.g. `Common.setDecomp(require('poly-decomp'))`.
|
||||
* @method setDecomp
|
||||
* @param {} decomp The [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module.
|
||||
*/
|
||||
Common._requireGlobal = function(globalName, moduleName) {
|
||||
var obj = (typeof window !== 'undefined' ? window[globalName] : typeof global !== 'undefined' ? global[globalName] : null);
|
||||
return obj || require(moduleName);
|
||||
Common.setDecomp = function(decomp) {
|
||||
Common._decomp = decomp;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module provided through `Common.setDecomp`,
|
||||
* otherwise returns the global `decomp` if set.
|
||||
* @method getDecomp
|
||||
* @return {} The [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module if provided.
|
||||
*/
|
||||
Common.getDecomp = function() {
|
||||
// get user provided decomp if set
|
||||
var decomp = Common._decomp;
|
||||
|
||||
try {
|
||||
// otherwise from window global
|
||||
if (!decomp && typeof window !== 'undefined') {
|
||||
decomp = window.decomp;
|
||||
}
|
||||
|
||||
// otherwise from node global
|
||||
if (!decomp && typeof global !== 'undefined') {
|
||||
decomp = global.decomp;
|
||||
}
|
||||
} catch (e) {
|
||||
// decomp not available
|
||||
decomp = null;
|
||||
}
|
||||
|
||||
return decomp;
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -12,12 +12,10 @@ var Engine = {};
|
|||
|
||||
module.exports = Engine;
|
||||
|
||||
var World = require('../body/World');
|
||||
var Sleeping = require('./Sleeping');
|
||||
var Resolver = require('../collision/Resolver');
|
||||
var Render = require('../render/Render');
|
||||
var Detector = require('../collision/Detector');
|
||||
var Pairs = require('../collision/Pairs');
|
||||
var Metrics = require('./Metrics');
|
||||
var Grid = require('../collision/Grid');
|
||||
var Events = require('./Events');
|
||||
var Composite = require('../body/Composite');
|
||||
|
@ -35,16 +33,9 @@ var Body = require('../body/Body');
|
|||
* @param {object} [options]
|
||||
* @return {engine} engine
|
||||
*/
|
||||
Engine.create = function(element, options) {
|
||||
// options may be passed as the first (and only) argument
|
||||
options = Common.isElement(element) ? options : element;
|
||||
element = Common.isElement(element) ? element : null;
|
||||
Engine.create = function(options) {
|
||||
options = options || {};
|
||||
|
||||
if (element || options.render) {
|
||||
Common.warn('Engine.create: engine.render is deprecated (see docs)');
|
||||
}
|
||||
|
||||
var defaults = {
|
||||
positionIterations: 6,
|
||||
velocityIterations: 4,
|
||||
|
@ -52,45 +43,30 @@ var Body = require('../body/Body');
|
|||
enableSleeping: false,
|
||||
events: [],
|
||||
plugin: {},
|
||||
grid: null,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: 1,
|
||||
scale: 0.001
|
||||
},
|
||||
timing: {
|
||||
timestamp: 0,
|
||||
timeScale: 1
|
||||
},
|
||||
broadphase: {
|
||||
controller: Grid
|
||||
timeScale: 1,
|
||||
lastDelta: 0,
|
||||
lastElapsed: 0
|
||||
}
|
||||
};
|
||||
|
||||
var engine = Common.extend(defaults, options);
|
||||
|
||||
// @deprecated
|
||||
if (element || engine.render) {
|
||||
var renderDefaults = {
|
||||
element: element,
|
||||
controller: Render
|
||||
};
|
||||
|
||||
engine.render = Common.extend(renderDefaults, engine.render);
|
||||
}
|
||||
|
||||
// @deprecated
|
||||
if (engine.render && engine.render.controller) {
|
||||
engine.render = engine.render.controller.create(engine.render);
|
||||
}
|
||||
|
||||
// @deprecated
|
||||
if (engine.render) {
|
||||
engine.render.engine = engine;
|
||||
}
|
||||
|
||||
engine.world = options.world || World.create(engine.world);
|
||||
engine.world = options.world || Composite.create({ label: 'World' });
|
||||
engine.grid = Grid.create(options.grid || options.broadphase);
|
||||
engine.pairs = Pairs.create();
|
||||
engine.broadphase = engine.broadphase.controller.create(engine.broadphase);
|
||||
engine.metrics = engine.metrics || { extended: false };
|
||||
|
||||
// @if DEBUG
|
||||
engine.metrics = Metrics.create(engine.metrics);
|
||||
// @endif
|
||||
// temporary back compatibility
|
||||
engine.world.gravity = engine.gravity;
|
||||
engine.broadphase = engine.grid;
|
||||
engine.metrics = {};
|
||||
|
||||
return engine;
|
||||
};
|
||||
|
@ -111,17 +87,20 @@ var Body = require('../body/Body');
|
|||
* @param {number} [correction=1]
|
||||
*/
|
||||
Engine.update = function(engine, delta, correction) {
|
||||
var startTime = Common.now();
|
||||
|
||||
delta = delta || 1000 / 60;
|
||||
correction = correction || 1;
|
||||
|
||||
var world = engine.world,
|
||||
timing = engine.timing,
|
||||
broadphase = engine.broadphase,
|
||||
broadphasePairs = [],
|
||||
grid = engine.grid,
|
||||
gridPairs = [],
|
||||
i;
|
||||
|
||||
// increment timestamp
|
||||
timing.timestamp += delta * timing.timeScale;
|
||||
timing.lastDelta = delta * timing.timeScale;
|
||||
|
||||
// create an event object
|
||||
var event = {
|
||||
|
@ -134,17 +113,12 @@ var Body = require('../body/Body');
|
|||
var allBodies = Composite.allBodies(world),
|
||||
allConstraints = Composite.allConstraints(world);
|
||||
|
||||
// @if DEBUG
|
||||
// reset metrics logging
|
||||
Metrics.reset(engine.metrics);
|
||||
// @endif
|
||||
|
||||
// if sleeping enabled, call the sleeping controller
|
||||
if (engine.enableSleeping)
|
||||
Sleeping.update(allBodies, timing.timeScale);
|
||||
|
||||
// applies gravity to all bodies
|
||||
Engine._bodiesApplyGravity(allBodies, world.gravity);
|
||||
Engine._bodiesApplyGravity(allBodies, engine.gravity);
|
||||
|
||||
// update all body position and rotation by integration
|
||||
Engine._bodiesUpdate(allBodies, delta, timing.timeScale, correction, world.bounds);
|
||||
|
@ -157,18 +131,14 @@ var Body = require('../body/Body');
|
|||
Constraint.postSolveAll(allBodies);
|
||||
|
||||
// broadphase pass: find potential collision pairs
|
||||
if (broadphase.controller) {
|
||||
|
||||
// if world is dirty, we must flush the whole grid
|
||||
if (world.isModified)
|
||||
broadphase.controller.clear(broadphase);
|
||||
Grid.clear(grid);
|
||||
|
||||
// update the grid buckets based on current bodies
|
||||
broadphase.controller.update(broadphase, allBodies, engine, world.isModified);
|
||||
broadphasePairs = broadphase.pairsList;
|
||||
} else {
|
||||
// if no broadphase set, we just pass all bodies
|
||||
broadphasePairs = allBodies;
|
||||
}
|
||||
Grid.update(grid, allBodies, engine, world.isModified);
|
||||
gridPairs = grid.pairsList;
|
||||
|
||||
// clear all composite modified flags
|
||||
if (world.isModified) {
|
||||
|
@ -176,7 +146,7 @@ var Body = require('../body/Body');
|
|||
}
|
||||
|
||||
// narrowphase pass: find actual collisions, then create or update collision pairs
|
||||
var collisions = broadphase.detector(broadphasePairs, engine);
|
||||
var collisions = Detector.collisions(gridPairs, engine);
|
||||
|
||||
// update collision pairs
|
||||
var pairs = engine.pairs,
|
||||
|
@ -195,7 +165,7 @@ var Body = require('../body/Body');
|
|||
// iteratively resolve position between collisions
|
||||
Resolver.preSolvePosition(pairs.list);
|
||||
for (i = 0; i < engine.positionIterations; i++) {
|
||||
Resolver.solvePosition(pairs.list, allBodies, timing.timeScale);
|
||||
Resolver.solvePosition(pairs.list, timing.timeScale);
|
||||
}
|
||||
Resolver.postSolvePosition(allBodies);
|
||||
|
||||
|
@ -219,16 +189,14 @@ var Body = require('../body/Body');
|
|||
if (pairs.collisionEnd.length > 0)
|
||||
Events.trigger(engine, 'collisionEnd', { pairs: pairs.collisionEnd });
|
||||
|
||||
// @if DEBUG
|
||||
// update metrics log
|
||||
Metrics.update(engine.metrics, engine);
|
||||
// @endif
|
||||
|
||||
// clear force buffers
|
||||
Engine._bodiesClearForces(allBodies);
|
||||
|
||||
Events.trigger(engine, 'afterUpdate', event);
|
||||
|
||||
// log the time elapsed computing this update
|
||||
engine.timing.lastElapsed = Common.now() - startTime;
|
||||
|
||||
return engine;
|
||||
};
|
||||
|
||||
|
@ -262,16 +230,12 @@ var Body = require('../body/Body');
|
|||
* @param {engine} engine
|
||||
*/
|
||||
Engine.clear = function(engine) {
|
||||
var world = engine.world;
|
||||
var world = engine.world,
|
||||
bodies = Composite.allBodies(world);
|
||||
|
||||
Pairs.clear(engine.pairs);
|
||||
|
||||
var broadphase = engine.broadphase;
|
||||
if (broadphase.controller) {
|
||||
var bodies = Composite.allBodies(world);
|
||||
broadphase.controller.clear(broadphase);
|
||||
broadphase.controller.update(broadphase, bodies, engine, true);
|
||||
}
|
||||
Grid.clear(engine.grid);
|
||||
Grid.update(engine.grid, bodies, engine, true);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -341,7 +305,8 @@ var Body = require('../body/Body');
|
|||
};
|
||||
|
||||
/**
|
||||
* An alias for `Runner.run`, see `Matter.Runner` for more information.
|
||||
* A deprecated alias for `Runner.run`, use `Matter.Runner.run(engine)` instead and see `Matter.Runner` for more information.
|
||||
* @deprecated use Matter.Runner.run(engine) instead
|
||||
* @method run
|
||||
* @param {engine} engine
|
||||
*/
|
||||
|
@ -470,32 +435,47 @@ var Body = require('../body/Body');
|
|||
*/
|
||||
|
||||
/**
|
||||
* An instance of a `Render` controller. The default value is a `Matter.Render` instance created by `Engine.create`.
|
||||
* One may also develop a custom renderer module based on `Matter.Render` and pass an instance of it to `Engine.create` via `options.render`.
|
||||
* A `Number` that represents the total execution time elapsed during the last `Engine.update` in milliseconds.
|
||||
* It is updated by timing from the start of the last `Engine.update` call until it ends.
|
||||
*
|
||||
* A minimal custom renderer object must define at least three functions: `create`, `clear` and `world` (see `Matter.Render`).
|
||||
* It is also possible to instead pass the _module_ reference via `options.render.controller` and `Engine.create` will instantiate one for you.
|
||||
* This value will also include the total execution time of all event handlers directly or indirectly triggered by the engine update.
|
||||
*
|
||||
* @property render
|
||||
* @type render
|
||||
* @deprecated see Demo.js for an example of creating a renderer
|
||||
* @default a Matter.Render instance
|
||||
* @property timing.lastElapsed
|
||||
* @type number
|
||||
* @default 0
|
||||
*/
|
||||
|
||||
/**
|
||||
* An instance of a broadphase controller. The default value is a `Matter.Grid` instance created by `Engine.create`.
|
||||
* A `Number` that represents the `delta` value used in the last engine update.
|
||||
*
|
||||
* @property timing.lastDelta
|
||||
* @type number
|
||||
* @default 0
|
||||
*/
|
||||
|
||||
/**
|
||||
* A `Matter.Grid` instance.
|
||||
*
|
||||
* @property grid
|
||||
* @type grid
|
||||
* @default a Matter.Grid instance
|
||||
*/
|
||||
|
||||
/**
|
||||
* Replaced by and now alias for `engine.grid`.
|
||||
*
|
||||
* @deprecated use `engine.grid`
|
||||
* @property broadphase
|
||||
* @type grid
|
||||
* @default a Matter.Grid instance
|
||||
*/
|
||||
|
||||
/**
|
||||
* A `World` composite object that will contain all simulated bodies and constraints.
|
||||
* The root `Matter.Composite` instance that will contain all bodies, constraints and other composites to be simulated by this engine.
|
||||
*
|
||||
* @property world
|
||||
* @type world
|
||||
* @default a Matter.World instance
|
||||
* @type composite
|
||||
* @default a Matter.Composite instance
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -505,4 +485,35 @@ var Body = require('../body/Body');
|
|||
* @type {}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The gravity to apply on all bodies in `engine.world`.
|
||||
*
|
||||
* @property gravity
|
||||
* @type object
|
||||
*/
|
||||
|
||||
/**
|
||||
* The gravity x component.
|
||||
*
|
||||
* @property gravity.x
|
||||
* @type object
|
||||
* @default 0
|
||||
*/
|
||||
|
||||
/**
|
||||
* The gravity y component.
|
||||
*
|
||||
* @property gravity.y
|
||||
* @type object
|
||||
* @default 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* The gravity scale factor.
|
||||
*
|
||||
* @property gravity.scale
|
||||
* @type object
|
||||
* @default 0.001
|
||||
*/
|
||||
|
||||
})();
|
||||
|
|
|
@ -27,7 +27,7 @@ var Common = require('./Common');
|
|||
* @readOnly
|
||||
* @type {String}
|
||||
*/
|
||||
Matter.version = '@@VERSION@@';
|
||||
Matter.version = typeof __MATTER_VERSION__ !== 'undefined' ? __MATTER_VERSION__ : '*';
|
||||
|
||||
/**
|
||||
* A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`.
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
// @if DEBUG
|
||||
/**
|
||||
* _Internal Class_, not generally used outside of the engine's internals.
|
||||
*
|
||||
*/
|
||||
|
||||
var Metrics = {};
|
||||
|
||||
module.exports = Metrics;
|
||||
|
||||
var Composite = require('../body/Composite');
|
||||
var Common = require('./Common');
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* Creates a new metrics.
|
||||
* @method create
|
||||
* @private
|
||||
* @return {metrics} A new metrics
|
||||
*/
|
||||
Metrics.create = function(options) {
|
||||
var defaults = {
|
||||
extended: false,
|
||||
narrowDetections: 0,
|
||||
narrowphaseTests: 0,
|
||||
narrowReuse: 0,
|
||||
narrowReuseCount: 0,
|
||||
midphaseTests: 0,
|
||||
broadphaseTests: 0,
|
||||
narrowEff: 0.0001,
|
||||
midEff: 0.0001,
|
||||
broadEff: 0.0001,
|
||||
collisions: 0,
|
||||
buckets: 0,
|
||||
bodies: 0,
|
||||
pairs: 0
|
||||
};
|
||||
|
||||
return Common.extend(defaults, false, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets metrics.
|
||||
* @method reset
|
||||
* @private
|
||||
* @param {metrics} metrics
|
||||
*/
|
||||
Metrics.reset = function(metrics) {
|
||||
if (metrics.extended) {
|
||||
metrics.narrowDetections = 0;
|
||||
metrics.narrowphaseTests = 0;
|
||||
metrics.narrowReuse = 0;
|
||||
metrics.narrowReuseCount = 0;
|
||||
metrics.midphaseTests = 0;
|
||||
metrics.broadphaseTests = 0;
|
||||
metrics.narrowEff = 0;
|
||||
metrics.midEff = 0;
|
||||
metrics.broadEff = 0;
|
||||
metrics.collisions = 0;
|
||||
metrics.buckets = 0;
|
||||
metrics.pairs = 0;
|
||||
metrics.bodies = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates metrics.
|
||||
* @method update
|
||||
* @private
|
||||
* @param {metrics} metrics
|
||||
* @param {engine} engine
|
||||
*/
|
||||
Metrics.update = function(metrics, engine) {
|
||||
if (metrics.extended) {
|
||||
var world = engine.world,
|
||||
bodies = Composite.allBodies(world);
|
||||
|
||||
metrics.collisions = metrics.narrowDetections;
|
||||
metrics.pairs = engine.pairs.list.length;
|
||||
metrics.bodies = bodies.length;
|
||||
metrics.midEff = (metrics.narrowDetections / (metrics.midphaseTests || 1)).toFixed(2);
|
||||
metrics.narrowEff = (metrics.narrowDetections / (metrics.narrowphaseTests || 1)).toFixed(2);
|
||||
metrics.broadEff = (1 - (metrics.broadphaseTests / (bodies.length || 1))).toFixed(2);
|
||||
metrics.narrowReuse = (metrics.narrowReuseCount / (metrics.narrowphaseTests || 1)).toFixed(2);
|
||||
//var broadphase = engine.broadphase[engine.broadphase.current];
|
||||
//if (broadphase.instance)
|
||||
// metrics.buckets = Common.keys(broadphase.instance.buckets).length;
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
// @endif
|
|
@ -266,6 +266,8 @@ var Common = require('./Common');
|
|||
* Only the following range types are supported:
|
||||
* - Tilde ranges e.g. `~1.2.3`
|
||||
* - Caret ranges e.g. `^1.2.3`
|
||||
* - Greater than ranges e.g. `>1.2.3`
|
||||
* - Greater than or equal ranges e.g. `>=1.2.3`
|
||||
* - Exact version e.g. `1.2.3`
|
||||
* - Any version `*`
|
||||
* @method versionParse
|
||||
|
@ -273,29 +275,28 @@ var Common = require('./Common');
|
|||
* @return {object} The version range parsed into its components.
|
||||
*/
|
||||
Plugin.versionParse = function(range) {
|
||||
var pattern = /^\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-]+)?$/;
|
||||
var pattern = /^(\*)|(\^|~|>=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-]+)?$/;
|
||||
|
||||
if (!pattern.test(range)) {
|
||||
Common.warn('Plugin.versionParse:', range, 'is not a valid version or range.');
|
||||
}
|
||||
|
||||
var identifiers = range.split('-');
|
||||
range = identifiers[0];
|
||||
|
||||
var isRange = isNaN(Number(range[0])),
|
||||
version = isRange ? range.substr(1) : range,
|
||||
parts = Common.map(version.split('.'), function(part) {
|
||||
return Number(part);
|
||||
});
|
||||
var parts = pattern.exec(range);
|
||||
var major = Number(parts[4]);
|
||||
var minor = Number(parts[5]);
|
||||
var patch = Number(parts[6]);
|
||||
|
||||
return {
|
||||
isRange: isRange,
|
||||
version: version,
|
||||
isRange: Boolean(parts[1] || parts[2]),
|
||||
version: parts[3],
|
||||
range: range,
|
||||
operator: isRange ? range[0] : '',
|
||||
parts: parts,
|
||||
prerelease: identifiers[1],
|
||||
number: parts[0] * 1e8 + parts[1] * 1e4 + parts[2]
|
||||
operator: parts[1] || parts[2] || '',
|
||||
major: major,
|
||||
minor: minor,
|
||||
patch: patch,
|
||||
parts: [major, minor, patch],
|
||||
prerelease: parts[7],
|
||||
number: major * 1e8 + minor * 1e4 + patch
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -311,30 +312,36 @@ var Common = require('./Common');
|
|||
Plugin.versionSatisfies = function(version, range) {
|
||||
range = range || '*';
|
||||
|
||||
var rangeParsed = Plugin.versionParse(range),
|
||||
rangeParts = rangeParsed.parts,
|
||||
versionParsed = Plugin.versionParse(version),
|
||||
versionParts = versionParsed.parts;
|
||||
var r = Plugin.versionParse(range),
|
||||
v = Plugin.versionParse(version);
|
||||
|
||||
if (rangeParsed.isRange) {
|
||||
if (rangeParsed.operator === '*' || version === '*') {
|
||||
if (r.isRange) {
|
||||
if (r.operator === '*' || version === '*') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rangeParsed.operator === '~') {
|
||||
return versionParts[0] === rangeParts[0] && versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2];
|
||||
if (r.operator === '>') {
|
||||
return v.number > r.number;
|
||||
}
|
||||
|
||||
if (rangeParsed.operator === '^') {
|
||||
if (rangeParts[0] > 0) {
|
||||
return versionParts[0] === rangeParts[0] && versionParsed.number >= rangeParsed.number;
|
||||
if (r.operator === '>=') {
|
||||
return v.number >= r.number;
|
||||
}
|
||||
|
||||
if (rangeParts[1] > 0) {
|
||||
return versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2];
|
||||
if (r.operator === '~') {
|
||||
return v.major === r.major && v.minor === r.minor && v.patch >= r.patch;
|
||||
}
|
||||
|
||||
return versionParts[2] === rangeParts[2];
|
||||
if (r.operator === '^') {
|
||||
if (r.major > 0) {
|
||||
return v.major === r.major && v.number >= r.number;
|
||||
}
|
||||
|
||||
if (r.minor > 0) {
|
||||
return v.minor === r.minor && v.patch >= r.patch;
|
||||
}
|
||||
|
||||
return v.patch === r.patch;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,6 @@ var Common = require('./Common');
|
|||
/**
|
||||
* A game loop utility that updates the engine and renderer by one step (a 'tick').
|
||||
* Features delta smoothing, time correction and fixed or dynamic timing.
|
||||
* Triggers `beforeTick`, `tick` and `afterTick` events on the engine.
|
||||
* Consider just `Engine.update(engine, delta)` if you're using your own loop.
|
||||
* @method tick
|
||||
* @param {runner} runner
|
||||
|
@ -119,7 +118,6 @@ var Common = require('./Common');
|
|||
};
|
||||
|
||||
Events.trigger(runner, 'beforeTick', event);
|
||||
Events.trigger(engine, 'beforeTick', event); // @deprecated
|
||||
|
||||
if (runner.isFixed) {
|
||||
// fixed timestep
|
||||
|
@ -164,35 +162,13 @@ var Common = require('./Common');
|
|||
}
|
||||
|
||||
Events.trigger(runner, 'tick', event);
|
||||
Events.trigger(engine, 'tick', event); // @deprecated
|
||||
|
||||
// if world has been modified, clear the render scene graph
|
||||
if (engine.world.isModified
|
||||
&& engine.render
|
||||
&& engine.render.controller
|
||||
&& engine.render.controller.clear) {
|
||||
engine.render.controller.clear(engine.render); // @deprecated
|
||||
}
|
||||
|
||||
// update
|
||||
Events.trigger(runner, 'beforeUpdate', event);
|
||||
Engine.update(engine, delta, correction);
|
||||
Events.trigger(runner, 'afterUpdate', event);
|
||||
|
||||
// render
|
||||
// @deprecated
|
||||
if (engine.render && engine.render.controller) {
|
||||
Events.trigger(runner, 'beforeRender', event);
|
||||
Events.trigger(engine, 'beforeRender', event); // @deprecated
|
||||
|
||||
engine.render.controller.world(engine.render);
|
||||
|
||||
Events.trigger(runner, 'afterRender', event);
|
||||
Events.trigger(engine, 'afterRender', event); // @deprecated
|
||||
}
|
||||
|
||||
Events.trigger(runner, 'afterTick', event);
|
||||
Events.trigger(engine, 'afterTick', event); // @deprecated
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -271,28 +247,6 @@ var Common = require('./Common');
|
|||
* @param {} event.name The name of the event
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired before rendering
|
||||
*
|
||||
* @event beforeRender
|
||||
* @param {} event An event object
|
||||
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||
* @param {} event.source The source object of the event
|
||||
* @param {} event.name The name of the event
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired after rendering
|
||||
*
|
||||
* @event afterRender
|
||||
* @param {} event An event object
|
||||
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||
* @param {} event.source The source object of the event
|
||||
* @param {} event.name The name of the event
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Properties Documentation
|
||||
|
|
|
@ -18,7 +18,6 @@ var Common = require('../core/Common');
|
|||
var Body = require('../body/Body');
|
||||
var Bounds = require('../geometry/Bounds');
|
||||
var Vector = require('../geometry/Vector');
|
||||
var decomp;
|
||||
|
||||
(function() {
|
||||
|
||||
|
@ -177,33 +176,46 @@ var decomp;
|
|||
};
|
||||
|
||||
/**
|
||||
* Creates a body using the supplied vertices (or an array containing multiple sets of vertices).
|
||||
* If the vertices are convex, they will pass through as supplied.
|
||||
* Otherwise if the vertices are concave, they will be decomposed if [poly-decomp.js](https://github.com/schteppe/poly-decomp.js) is available.
|
||||
* Note that this process is not guaranteed to support complex sets of vertices (e.g. those with holes may fail).
|
||||
* By default the decomposition will discard collinear edges (to improve performance).
|
||||
* It can also optionally discard any parts that have an area less than `minimumArea`.
|
||||
* If the vertices can not be decomposed, the result will fall back to using the convex hull.
|
||||
* The options parameter is an object that specifies any `Matter.Body` properties you wish to override the defaults.
|
||||
* Utility to create a compound body based on set(s) of vertices.
|
||||
*
|
||||
* _Note:_ To optionally enable automatic concave vertices decomposition the [poly-decomp](https://github.com/schteppe/poly-decomp.js)
|
||||
* package must be first installed and provided see `Common.setDecomp`, otherwise the convex hull of each vertex set will be used.
|
||||
*
|
||||
* The resulting vertices are reorientated about their centre of mass,
|
||||
* and offset such that `body.position` corresponds to this point.
|
||||
*
|
||||
* The resulting offset may be found if needed by subtracting `body.bounds` from the original input bounds.
|
||||
* To later move the centre of mass see `Body.setCentre`.
|
||||
*
|
||||
* Note that automatic conconcave decomposition results are not always optimal.
|
||||
* For best results, simplify the input vertices as much as possible first.
|
||||
* By default this function applies some addtional simplification to help.
|
||||
*
|
||||
* Some outputs may also require further manual processing afterwards to be robust.
|
||||
* In particular some parts may need to be overlapped to avoid collision gaps.
|
||||
* Thin parts and sharp points should be avoided or removed where possible.
|
||||
*
|
||||
* The options parameter object specifies any `Matter.Body` properties you wish to override the defaults.
|
||||
*
|
||||
* See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
|
||||
* @method fromVertices
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param [[vector]] vertexSets
|
||||
* @param {object} [options]
|
||||
* @param {bool} [flagInternal=false]
|
||||
* @param {number} [removeCollinear=0.01]
|
||||
* @param {number} [minimumArea=10]
|
||||
* @param {array} vertexSets One or more arrays of vertex points e.g. `[[{ x: 0, y: 0 }...], ...]`.
|
||||
* @param {object} [options] The body options.
|
||||
* @param {bool} [flagInternal=false] Optionally marks internal edges with `isInternal`.
|
||||
* @param {number} [removeCollinear=0.01] Threshold when simplifying vertices along the same edge.
|
||||
* @param {number} [minimumArea=10] Threshold when removing small parts.
|
||||
* @param {number} [removeDuplicatePoints=0.01] Threshold when simplifying nearby vertices.
|
||||
* @return {body}
|
||||
*/
|
||||
Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea) {
|
||||
if (!decomp) {
|
||||
decomp = Common._requireGlobal('decomp', 'poly-decomp');
|
||||
}
|
||||
|
||||
var body,
|
||||
Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea, removeDuplicatePoints) {
|
||||
var decomp = Common.getDecomp(),
|
||||
canDecomp,
|
||||
body,
|
||||
parts,
|
||||
isConvex,
|
||||
isConcave,
|
||||
vertices,
|
||||
i,
|
||||
j,
|
||||
|
@ -211,16 +223,16 @@ var decomp;
|
|||
v,
|
||||
z;
|
||||
|
||||
// check decomp is as expected
|
||||
canDecomp = Boolean(decomp && decomp.quickDecomp);
|
||||
|
||||
options = options || {};
|
||||
parts = [];
|
||||
|
||||
flagInternal = typeof flagInternal !== 'undefined' ? flagInternal : false;
|
||||
removeCollinear = typeof removeCollinear !== 'undefined' ? removeCollinear : 0.01;
|
||||
minimumArea = typeof minimumArea !== 'undefined' ? minimumArea : 10;
|
||||
|
||||
if (!decomp) {
|
||||
Common.warn('Bodies.fromVertices: poly-decomp.js required. Could not decompose vertices. Fallback to convex hull.');
|
||||
}
|
||||
removeDuplicatePoints = typeof removeDuplicatePoints !== 'undefined' ? removeDuplicatePoints : 0.01;
|
||||
|
||||
// ensure vertexSets is an array of arrays
|
||||
if (!Common.isArray(vertexSets[0])) {
|
||||
|
@ -230,8 +242,15 @@ var decomp;
|
|||
for (v = 0; v < vertexSets.length; v += 1) {
|
||||
vertices = vertexSets[v];
|
||||
isConvex = Vertices.isConvex(vertices);
|
||||
isConcave = !isConvex;
|
||||
|
||||
if (isConvex || !decomp) {
|
||||
if (isConcave && !canDecomp) {
|
||||
Common.warnOnce(
|
||||
'Bodies.fromVertices: Install the \'poly-decomp\' library and use Common.setDecomp or provide \'decomp\' as a global to decompose concave vertices.'
|
||||
);
|
||||
}
|
||||
|
||||
if (isConvex || !canDecomp) {
|
||||
if (isConvex) {
|
||||
vertices = Vertices.clockwiseSort(vertices);
|
||||
} else {
|
||||
|
@ -253,6 +272,8 @@ var decomp;
|
|||
decomp.makeCCW(concave);
|
||||
if (removeCollinear !== false)
|
||||
decomp.removeCollinearPoints(concave, removeCollinear);
|
||||
if (removeDuplicatePoints !== false && decomp.removeDuplicatePoints)
|
||||
decomp.removeDuplicatePoints(concave, removeDuplicatePoints);
|
||||
|
||||
// use the quick decomposition algorithm (Bayazit)
|
||||
var decomposed = decomp.quickDecomp(concave);
|
||||
|
@ -324,6 +345,8 @@ var decomp;
|
|||
if (parts.length > 1) {
|
||||
// create the parent body to be returned, that contains generated compound parts
|
||||
body = Body.create(Common.extend({ parts: parts.slice(0) }, options));
|
||||
|
||||
// offset such that body.position is at the centre off mass
|
||||
Body.setPosition(body, { x: x, y: y });
|
||||
|
||||
return body;
|
||||
|
|
|
@ -16,6 +16,7 @@ var Constraint = require('../constraint/Constraint');
|
|||
var Common = require('../core/Common');
|
||||
var Body = require('../body/Body');
|
||||
var Bodies = require('./Bodies');
|
||||
var deprecated = Common.deprecated;
|
||||
|
||||
(function() {
|
||||
|
||||
|
@ -202,7 +203,8 @@ var Bodies = require('./Bodies');
|
|||
};
|
||||
|
||||
/**
|
||||
* Creates a composite with a Newton's Cradle setup of bodies and constraints.
|
||||
* This has now moved to the [newtonsCradle example](https://github.com/liabru/matter-js/blob/master/examples/newtonsCradle.js), follow that instead as this function is deprecated here.
|
||||
* @deprecated moved to newtonsCradle example
|
||||
* @method newtonsCradle
|
||||
* @param {number} xx
|
||||
* @param {number} yy
|
||||
|
@ -227,8 +229,11 @@ var Bodies = require('./Bodies');
|
|||
return newtonsCradle;
|
||||
};
|
||||
|
||||
deprecated(Composites, 'newtonsCradle', 'Composites.newtonsCradle ➤ moved to newtonsCradle example');
|
||||
|
||||
/**
|
||||
* Creates a composite with simple car setup of bodies and constraints.
|
||||
* This has now moved to the [car example](https://github.com/liabru/matter-js/blob/master/examples/car.js), follow that instead as this function is deprecated here.
|
||||
* @deprecated moved to car example
|
||||
* @method car
|
||||
* @param {number} xx
|
||||
* @param {number} yy
|
||||
|
@ -294,8 +299,12 @@ var Bodies = require('./Bodies');
|
|||
return car;
|
||||
};
|
||||
|
||||
deprecated(Composites, 'car', 'Composites.car ➤ moved to car example');
|
||||
|
||||
/**
|
||||
* Creates a simple soft body like object.
|
||||
* This has now moved to the [softBody example](https://github.com/liabru/matter-js/blob/master/examples/softBody.js)
|
||||
* and the [cloth example](https://github.com/liabru/matter-js/blob/master/examples/cloth.js), follow those instead as this function is deprecated here.
|
||||
* @deprecated moved to softBody and cloth examples
|
||||
* @method softBody
|
||||
* @param {number} xx
|
||||
* @param {number} yy
|
||||
|
@ -324,4 +333,5 @@ var Bodies = require('./Bodies');
|
|||
return softBody;
|
||||
};
|
||||
|
||||
deprecated(Composites, 'softBody', 'Composites.softBody ➤ moved to softBody and cloth examples');
|
||||
})();
|
||||
|
|
|
@ -44,14 +44,7 @@ var Common = require('../core/Common');
|
|||
y: point.y,
|
||||
index: i,
|
||||
body: body,
|
||||
isInternal: false,
|
||||
contact: null
|
||||
};
|
||||
|
||||
vertex.contact = {
|
||||
vertex: vertex,
|
||||
normalImpulse: 0,
|
||||
tangentImpulse: 0
|
||||
isInternal: false
|
||||
};
|
||||
|
||||
vertices.push(vertex);
|
||||
|
@ -70,7 +63,7 @@ var Common = require('../core/Common');
|
|||
* @return {vertices} vertices
|
||||
*/
|
||||
Vertices.fromPath = function(path, body) {
|
||||
var pathPattern = /L?\s*([\-\d\.e]+)[\s,]*([\-\d\.e]+)*/ig,
|
||||
var pathPattern = /L?\s*([-\d.e]+)[\s,]*([-\d.e]+)*/ig,
|
||||
points = [];
|
||||
|
||||
path.replace(pathPattern, function(match, x, y) {
|
||||
|
|
|
@ -1,50 +1,34 @@
|
|||
var Matter = module.exports = require('../core/Matter');
|
||||
|
||||
Matter.Axes = require('../geometry/Axes');
|
||||
Matter.Bodies = require('../factory/Bodies');
|
||||
Matter.Body = require('../body/Body');
|
||||
Matter.Composite = require('../body/Composite');
|
||||
Matter.World = require('../body/World');
|
||||
|
||||
Matter.Detector = require('../collision/Detector');
|
||||
Matter.Grid = require('../collision/Grid');
|
||||
Matter.Pairs = require('../collision/Pairs');
|
||||
Matter.Pair = require('../collision/Pair');
|
||||
Matter.Query = require('../collision/Query');
|
||||
Matter.Resolver = require('../collision/Resolver');
|
||||
Matter.SAT = require('../collision/SAT');
|
||||
|
||||
Matter.Constraint = require('../constraint/Constraint');
|
||||
Matter.MouseConstraint = require('../constraint/MouseConstraint');
|
||||
|
||||
Matter.Bounds = require('../geometry/Bounds');
|
||||
Matter.Common = require('../core/Common');
|
||||
Matter.Composite = require('../body/Composite');
|
||||
Matter.Composites = require('../factory/Composites');
|
||||
Matter.Constraint = require('../constraint/Constraint');
|
||||
Matter.Contact = require('../collision/Contact');
|
||||
Matter.Detector = require('../collision/Detector');
|
||||
Matter.Engine = require('../core/Engine');
|
||||
Matter.Events = require('../core/Events');
|
||||
Matter.Grid = require('../collision/Grid');
|
||||
Matter.Mouse = require('../core/Mouse');
|
||||
Matter.Runner = require('../core/Runner');
|
||||
Matter.Sleeping = require('../core/Sleeping');
|
||||
Matter.MouseConstraint = require('../constraint/MouseConstraint');
|
||||
Matter.Pair = require('../collision/Pair');
|
||||
Matter.Pairs = require('../collision/Pairs');
|
||||
Matter.Plugin = require('../core/Plugin');
|
||||
|
||||
// @if DEBUG
|
||||
Matter.Metrics = require('../core/Metrics');
|
||||
// @endif
|
||||
|
||||
Matter.Bodies = require('../factory/Bodies');
|
||||
Matter.Composites = require('../factory/Composites');
|
||||
|
||||
Matter.Axes = require('../geometry/Axes');
|
||||
Matter.Bounds = require('../geometry/Bounds');
|
||||
Matter.Query = require('../collision/Query');
|
||||
Matter.Render = require('../render/Render');
|
||||
Matter.Resolver = require('../collision/Resolver');
|
||||
Matter.Runner = require('../core/Runner');
|
||||
Matter.SAT = require('../collision/SAT');
|
||||
Matter.Sleeping = require('../core/Sleeping');
|
||||
Matter.Svg = require('../geometry/Svg');
|
||||
Matter.Vector = require('../geometry/Vector');
|
||||
Matter.Vertices = require('../geometry/Vertices');
|
||||
Matter.World = require('../body/World');
|
||||
|
||||
Matter.Render = require('../render/Render');
|
||||
Matter.RenderPixi = require('../render/RenderPixi');
|
||||
|
||||
// aliases
|
||||
|
||||
Matter.World.add = Matter.Composite.add;
|
||||
Matter.World.remove = Matter.Composite.remove;
|
||||
Matter.World.addComposite = Matter.Composite.addComposite;
|
||||
Matter.World.addBody = Matter.Composite.addBody;
|
||||
Matter.World.addConstraint = Matter.Composite.addConstraint;
|
||||
Matter.World.clear = Matter.Composite.clear;
|
||||
// temporary back compatibility
|
||||
Matter.Engine.run = Matter.Runner.run;
|
||||
Matter.Common.deprecated(Matter.Engine, 'run', 'Engine.run ➤ use Matter.Runner.run(engine) instead');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* The `Matter.Render` module is a simple HTML5 canvas based renderer for visualising instances of `Matter.Engine`.
|
||||
* The `Matter.Render` module is a simple canvas based renderer for visualising instances of `Matter.Engine`.
|
||||
* It is intended for development and debugging purposes, but may also be suitable for simple games.
|
||||
* It includes a number of drawing options including wireframe, vector with support for sprites and viewports.
|
||||
*
|
||||
|
@ -14,7 +14,6 @@ var Common = require('../core/Common');
|
|||
var Composite = require('../body/Composite');
|
||||
var Bounds = require('../geometry/Bounds');
|
||||
var Events = require('../core/Events');
|
||||
var Grid = require('../collision/Grid');
|
||||
var Vector = require('../geometry/Vector');
|
||||
var Mouse = require('../core/Mouse');
|
||||
|
||||
|
@ -32,6 +31,9 @@ var Mouse = require('../core/Mouse');
|
|||
|| window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
|
||||
}
|
||||
|
||||
Render._goodFps = 30;
|
||||
Render._goodDelta = 1000 / 60;
|
||||
|
||||
/**
|
||||
* Creates a new renderer. The options parameter is an object that specifies any properties you wish to override the defaults.
|
||||
* All properties have default values, and many are pre-calculated automatically based on other properties.
|
||||
|
@ -48,17 +50,32 @@ var Mouse = require('../core/Mouse');
|
|||
canvas: null,
|
||||
mouse: null,
|
||||
frameRequestId: null,
|
||||
timing: {
|
||||
historySize: 60,
|
||||
delta: 0,
|
||||
deltaHistory: [],
|
||||
lastTime: 0,
|
||||
lastTimestamp: 0,
|
||||
lastElapsed: 0,
|
||||
timestampElapsed: 0,
|
||||
timestampElapsedHistory: [],
|
||||
engineDeltaHistory: [],
|
||||
engineElapsedHistory: [],
|
||||
elapsedHistory: []
|
||||
},
|
||||
options: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
pixelRatio: 1,
|
||||
background: '#18181d',
|
||||
wireframeBackground: '#0f0f13',
|
||||
background: '#14151f',
|
||||
wireframeBackground: '#14151f',
|
||||
hasBounds: !!options.bounds,
|
||||
enabled: true,
|
||||
wireframes: true,
|
||||
showSleeping: true,
|
||||
showDebug: false,
|
||||
showStats: false,
|
||||
showPerformance: false,
|
||||
showBroadphase: false,
|
||||
showBounds: false,
|
||||
showVelocity: false,
|
||||
|
@ -68,7 +85,6 @@ var Mouse = require('../core/Mouse');
|
|||
showPositions: false,
|
||||
showAngleIndicator: false,
|
||||
showIds: false,
|
||||
showShadows: false,
|
||||
showVertexNumbers: false,
|
||||
showConvexHulls: false,
|
||||
showInternalEdges: false,
|
||||
|
@ -121,7 +137,18 @@ var Mouse = require('../core/Mouse');
|
|||
Render.run = function(render) {
|
||||
(function loop(time){
|
||||
render.frameRequestId = _requestAnimationFrame(loop);
|
||||
Render.world(render);
|
||||
|
||||
_updateTiming(render, time);
|
||||
|
||||
Render.world(render, time);
|
||||
|
||||
if (render.options.showStats || render.options.showDebug) {
|
||||
Render.stats(render, render.context, time);
|
||||
}
|
||||
|
||||
if (render.options.showPerformance || render.options.showDebug) {
|
||||
Render.performance(render, render.context, time);
|
||||
}
|
||||
})();
|
||||
};
|
||||
|
||||
|
@ -289,13 +316,16 @@ var Mouse = require('../core/Mouse');
|
|||
* @method world
|
||||
* @param {render} render
|
||||
*/
|
||||
Render.world = function(render) {
|
||||
var engine = render.engine,
|
||||
Render.world = function(render, time) {
|
||||
var startTime = Common.now(),
|
||||
engine = render.engine,
|
||||
world = engine.world,
|
||||
canvas = render.canvas,
|
||||
context = render.context,
|
||||
options = render.options,
|
||||
allBodies = Composite.allBodies(world),
|
||||
timing = render.timing;
|
||||
|
||||
var allBodies = Composite.allBodies(world),
|
||||
allConstraints = Composite.allConstraints(world),
|
||||
background = options.wireframes ? options.wireframeBackground : options.background,
|
||||
bodies = [],
|
||||
|
@ -406,11 +436,8 @@ var Mouse = require('../core/Mouse');
|
|||
|
||||
Render.constraints(constraints, context);
|
||||
|
||||
if (options.showBroadphase && engine.broadphase.controller === Grid)
|
||||
Render.grid(render, engine.broadphase, context);
|
||||
|
||||
if (options.showDebug)
|
||||
Render.debug(render, context);
|
||||
if (options.showBroadphase)
|
||||
Render.grid(render, engine.grid, context);
|
||||
|
||||
if (options.hasBounds) {
|
||||
// revert view transforms
|
||||
|
@ -418,72 +445,182 @@ var Mouse = require('../core/Mouse');
|
|||
}
|
||||
|
||||
Events.trigger(render, 'afterRender', event);
|
||||
|
||||
// log the time elapsed computing this update
|
||||
timing.lastElapsed = Common.now() - startTime;
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
* Renders statistics about the engine and world useful for debugging.
|
||||
* @private
|
||||
* @method debug
|
||||
* @method stats
|
||||
* @param {render} render
|
||||
* @param {RenderingContext} context
|
||||
* @param {Number} time
|
||||
*/
|
||||
Render.stats = function(render, context, time) {
|
||||
var engine = render.engine,
|
||||
world = engine.world,
|
||||
bodies = Composite.allBodies(world),
|
||||
parts = 0,
|
||||
width = 55,
|
||||
height = 44,
|
||||
x = 0,
|
||||
y = 0;
|
||||
|
||||
// count parts
|
||||
for (var i = 0; i < bodies.length; i += 1) {
|
||||
parts += bodies[i].parts.length;
|
||||
}
|
||||
|
||||
// sections
|
||||
var sections = {
|
||||
'Part': parts,
|
||||
'Body': bodies.length,
|
||||
'Cons': Composite.allConstraints(world).length,
|
||||
'Comp': Composite.allComposites(world).length,
|
||||
'Pair': engine.pairs.list.length
|
||||
};
|
||||
|
||||
// background
|
||||
context.fillStyle = '#0e0f19';
|
||||
context.fillRect(x, y, width * 5.5, height);
|
||||
|
||||
context.font = '12px Arial';
|
||||
context.textBaseline = 'top';
|
||||
context.textAlign = 'right';
|
||||
|
||||
// sections
|
||||
for (var key in sections) {
|
||||
var section = sections[key];
|
||||
// label
|
||||
context.fillStyle = '#aaa';
|
||||
context.fillText(key, x + width, y + 8);
|
||||
|
||||
// value
|
||||
context.fillStyle = '#eee';
|
||||
context.fillText(section, x + width, y + 26);
|
||||
|
||||
x += width;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders engine and render performance information.
|
||||
* @private
|
||||
* @method performance
|
||||
* @param {render} render
|
||||
* @param {RenderingContext} context
|
||||
*/
|
||||
Render.debug = function(render, context) {
|
||||
var c = context,
|
||||
engine = render.engine,
|
||||
world = engine.world,
|
||||
metrics = engine.metrics,
|
||||
options = render.options,
|
||||
bodies = Composite.allBodies(world),
|
||||
space = " ";
|
||||
Render.performance = function(render, context) {
|
||||
var engine = render.engine,
|
||||
timing = render.timing,
|
||||
deltaHistory = timing.deltaHistory,
|
||||
elapsedHistory = timing.elapsedHistory,
|
||||
timestampElapsedHistory = timing.timestampElapsedHistory,
|
||||
engineDeltaHistory = timing.engineDeltaHistory,
|
||||
engineElapsedHistory = timing.engineElapsedHistory,
|
||||
lastEngineDelta = engine.timing.lastDelta;
|
||||
|
||||
if (engine.timing.timestamp - (render.debugTimestamp || 0) >= 500) {
|
||||
var text = "";
|
||||
var deltaMean = _mean(deltaHistory),
|
||||
elapsedMean = _mean(elapsedHistory),
|
||||
engineDeltaMean = _mean(engineDeltaHistory),
|
||||
engineElapsedMean = _mean(engineElapsedHistory),
|
||||
timestampElapsedMean = _mean(timestampElapsedHistory),
|
||||
rateMean = (timestampElapsedMean / deltaMean) || 0,
|
||||
fps = (1000 / deltaMean) || 0;
|
||||
|
||||
if (metrics.timing) {
|
||||
text += "fps: " + Math.round(metrics.timing.fps) + space;
|
||||
var graphHeight = 4,
|
||||
gap = 12,
|
||||
width = 60,
|
||||
height = 34,
|
||||
x = 10,
|
||||
y = 69;
|
||||
|
||||
// background
|
||||
context.fillStyle = '#0e0f19';
|
||||
context.fillRect(0, 50, gap * 4 + width * 5 + 22, height);
|
||||
|
||||
// show FPS
|
||||
Render.status(
|
||||
context, x, y, width, graphHeight, deltaHistory.length,
|
||||
Math.round(fps) + ' fps',
|
||||
fps / Render._goodFps,
|
||||
function(i) { return (deltaHistory[i] / deltaMean) - 1; }
|
||||
);
|
||||
|
||||
// show engine delta
|
||||
Render.status(
|
||||
context, x + gap + width, y, width, graphHeight, engineDeltaHistory.length,
|
||||
lastEngineDelta.toFixed(2) + ' dt',
|
||||
Render._goodDelta / lastEngineDelta,
|
||||
function(i) { return (engineDeltaHistory[i] / engineDeltaMean) - 1; }
|
||||
);
|
||||
|
||||
// show engine update time
|
||||
Render.status(
|
||||
context, x + (gap + width) * 2, y, width, graphHeight, engineElapsedHistory.length,
|
||||
engineElapsedMean.toFixed(2) + ' ut',
|
||||
1 - (engineElapsedMean / Render._goodFps),
|
||||
function(i) { return (engineElapsedHistory[i] / engineElapsedMean) - 1; }
|
||||
);
|
||||
|
||||
// show render time
|
||||
Render.status(
|
||||
context, x + (gap + width) * 3, y, width, graphHeight, elapsedHistory.length,
|
||||
elapsedMean.toFixed(2) + ' rt',
|
||||
1 - (elapsedMean / Render._goodFps),
|
||||
function(i) { return (elapsedHistory[i] / elapsedMean) - 1; }
|
||||
);
|
||||
|
||||
// show effective speed
|
||||
Render.status(
|
||||
context, x + (gap + width) * 4, y, width, graphHeight, timestampElapsedHistory.length,
|
||||
rateMean.toFixed(2) + ' x',
|
||||
rateMean * rateMean * rateMean,
|
||||
function(i) { return (((timestampElapsedHistory[i] / deltaHistory[i]) / rateMean) || 0) - 1; }
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a label, indicator and a chart.
|
||||
* @private
|
||||
* @method status
|
||||
* @param {RenderingContext} context
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
* @param {number} count
|
||||
* @param {string} label
|
||||
* @param {string} indicator
|
||||
* @param {function} plotY
|
||||
*/
|
||||
Render.status = function(context, x, y, width, height, count, label, indicator, plotY) {
|
||||
// background
|
||||
context.strokeStyle = '#888';
|
||||
context.fillStyle = '#444';
|
||||
context.lineWidth = 1;
|
||||
context.fillRect(x, y + 7, width, 1);
|
||||
|
||||
// chart
|
||||
context.beginPath();
|
||||
context.moveTo(x, y + 7 - height * Common.clamp(0.4 * plotY(0), -2, 2));
|
||||
for (var i = 0; i < width; i += 1) {
|
||||
context.lineTo(x + i, y + 7 - (i < count ? height * Common.clamp(0.4 * plotY(i), -2, 2) : 0));
|
||||
}
|
||||
context.stroke();
|
||||
|
||||
// @if DEBUG
|
||||
if (metrics.extended) {
|
||||
if (metrics.timing) {
|
||||
text += "delta: " + metrics.timing.delta.toFixed(3) + space;
|
||||
text += "correction: " + metrics.timing.correction.toFixed(3) + space;
|
||||
}
|
||||
// indicator
|
||||
context.fillStyle = 'hsl(' + Common.clamp(25 + 95 * indicator, 0, 120) + ',100%,60%)';
|
||||
context.fillRect(x, y - 7, 4, 4);
|
||||
|
||||
text += "bodies: " + bodies.length + space;
|
||||
|
||||
if (engine.broadphase.controller === Grid)
|
||||
text += "buckets: " + metrics.buckets + space;
|
||||
|
||||
text += "\n";
|
||||
|
||||
text += "collisions: " + metrics.collisions + space;
|
||||
text += "pairs: " + engine.pairs.list.length + space;
|
||||
text += "broad: " + metrics.broadEff + space;
|
||||
text += "mid: " + metrics.midEff + space;
|
||||
text += "narrow: " + metrics.narrowEff + space;
|
||||
}
|
||||
// @endif
|
||||
|
||||
render.debugString = text;
|
||||
render.debugTimestamp = engine.timing.timestamp;
|
||||
}
|
||||
|
||||
if (render.debugString) {
|
||||
c.font = "12px Arial";
|
||||
|
||||
if (options.wireframes) {
|
||||
c.fillStyle = 'rgba(255,255,255,0.5)';
|
||||
} else {
|
||||
c.fillStyle = 'rgba(0,0,0,0.5)';
|
||||
}
|
||||
|
||||
var split = render.debugString.split('\n');
|
||||
|
||||
for (var i = 0; i < split.length; i++) {
|
||||
c.fillText(split[i], 50, 50 + i * 18);
|
||||
}
|
||||
}
|
||||
// label
|
||||
context.font = '12px Arial';
|
||||
context.textBaseline = 'middle';
|
||||
context.textAlign = 'right';
|
||||
context.fillStyle = '#eee';
|
||||
context.fillText(label, x + width, y - 5);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -563,55 +700,6 @@ var Mouse = require('../core/Mouse');
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
* @private
|
||||
* @method bodyShadows
|
||||
* @param {render} render
|
||||
* @param {body[]} bodies
|
||||
* @param {RenderingContext} context
|
||||
*/
|
||||
Render.bodyShadows = function(render, bodies, context) {
|
||||
var c = context,
|
||||
engine = render.engine;
|
||||
|
||||
for (var i = 0; i < bodies.length; i++) {
|
||||
var body = bodies[i];
|
||||
|
||||
if (!body.render.visible)
|
||||
continue;
|
||||
|
||||
if (body.circleRadius) {
|
||||
c.beginPath();
|
||||
c.arc(body.position.x, body.position.y, body.circleRadius, 0, 2 * Math.PI);
|
||||
c.closePath();
|
||||
} else {
|
||||
c.beginPath();
|
||||
c.moveTo(body.vertices[0].x, body.vertices[0].y);
|
||||
for (var j = 1; j < body.vertices.length; j++) {
|
||||
c.lineTo(body.vertices[j].x, body.vertices[j].y);
|
||||
}
|
||||
c.closePath();
|
||||
}
|
||||
|
||||
var distanceX = body.position.x - render.options.width * 0.5,
|
||||
distanceY = body.position.y - render.options.height * 0.2,
|
||||
distance = Math.abs(distanceX) + Math.abs(distanceY);
|
||||
|
||||
c.shadowColor = 'rgba(0,0,0,0.15)';
|
||||
c.shadowOffsetX = 0.05 * distanceX;
|
||||
c.shadowOffsetY = 0.05 * distanceY;
|
||||
c.shadowBlur = 1 + 12 * Math.min(1, distance / 1000);
|
||||
|
||||
c.fill();
|
||||
|
||||
c.shadowColor = null;
|
||||
c.shadowOffsetX = null;
|
||||
c.shadowOffsetY = null;
|
||||
c.shadowBlur = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
* @private
|
||||
|
@ -1322,7 +1410,56 @@ var Mouse = require('../core/Mouse');
|
|||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
* Updates render timing.
|
||||
* @method _updateTiming
|
||||
* @private
|
||||
* @param {render} render
|
||||
* @param {number} time
|
||||
*/
|
||||
var _updateTiming = function(render, time) {
|
||||
var engine = render.engine,
|
||||
timing = render.timing,
|
||||
historySize = timing.historySize,
|
||||
timestamp = engine.timing.timestamp;
|
||||
|
||||
timing.delta = time - timing.lastTime || Render._goodDelta;
|
||||
timing.lastTime = time;
|
||||
|
||||
timing.timestampElapsed = timestamp - timing.lastTimestamp || 0;
|
||||
timing.lastTimestamp = timestamp;
|
||||
|
||||
timing.deltaHistory.unshift(timing.delta);
|
||||
timing.deltaHistory.length = Math.min(timing.deltaHistory.length, historySize);
|
||||
|
||||
timing.engineDeltaHistory.unshift(engine.timing.lastDelta);
|
||||
timing.engineDeltaHistory.length = Math.min(timing.engineDeltaHistory.length, historySize);
|
||||
|
||||
timing.timestampElapsedHistory.unshift(timing.timestampElapsed);
|
||||
timing.timestampElapsedHistory.length = Math.min(timing.timestampElapsedHistory.length, historySize);
|
||||
|
||||
timing.engineElapsedHistory.unshift(engine.timing.lastElapsed);
|
||||
timing.engineElapsedHistory.length = Math.min(timing.engineElapsedHistory.length, historySize);
|
||||
|
||||
timing.elapsedHistory.unshift(timing.lastElapsed);
|
||||
timing.elapsedHistory.length = Math.min(timing.elapsedHistory.length, historySize);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the mean value of the given numbers.
|
||||
* @method _mean
|
||||
* @private
|
||||
* @param {Number[]} values
|
||||
* @return {Number} the mean of given values
|
||||
*/
|
||||
var _mean = function(values) {
|
||||
var result = 0;
|
||||
for (var i = 0; i < values.length; i += 1) {
|
||||
result += values[i];
|
||||
}
|
||||
return (result / values.length) || 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @method _createCanvas
|
||||
* @private
|
||||
* @param {} width
|
||||
|
@ -1455,37 +1592,6 @@ var Mouse = require('../core/Mouse');
|
|||
* @default null
|
||||
*/
|
||||
|
||||
/**
|
||||
* The configuration options of the renderer.
|
||||
*
|
||||
* @property options
|
||||
* @type {}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The target width in pixels of the `render.canvas` to be created.
|
||||
*
|
||||
* @property options.width
|
||||
* @type number
|
||||
* @default 800
|
||||
*/
|
||||
|
||||
/**
|
||||
* The target height in pixels of the `render.canvas` to be created.
|
||||
*
|
||||
* @property options.height
|
||||
* @type number
|
||||
* @default 600
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag that specifies if `render.bounds` should be used when rendering.
|
||||
*
|
||||
* @property options.hasBounds
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A `Bounds` object that specifies the drawing view region.
|
||||
* Rendering will be automatically transformed and scaled to fit within the canvas size (`render.options.width` and `render.options.height`).
|
||||
|
@ -1510,4 +1616,254 @@ var Mouse = require('../core/Mouse');
|
|||
* @type {}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The mouse to render if `render.options.showMousePosition` is enabled.
|
||||
*
|
||||
* @property mouse
|
||||
* @type mouse
|
||||
* @default null
|
||||
*/
|
||||
|
||||
/**
|
||||
* The configuration options of the renderer.
|
||||
*
|
||||
* @property options
|
||||
* @type {}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The target width in pixels of the `render.canvas` to be created.
|
||||
* See also the `options.pixelRatio` property to change render quality.
|
||||
*
|
||||
* @property options.width
|
||||
* @type number
|
||||
* @default 800
|
||||
*/
|
||||
|
||||
/**
|
||||
* The target height in pixels of the `render.canvas` to be created.
|
||||
* See also the `options.pixelRatio` property to change render quality.
|
||||
*
|
||||
* @property options.height
|
||||
* @type number
|
||||
* @default 600
|
||||
*/
|
||||
|
||||
/**
|
||||
* The [pixel ratio](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio) to use when rendering.
|
||||
*
|
||||
* @property options.pixelRatio
|
||||
* @type number
|
||||
* @default 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* A CSS background color string to use when `render.options.wireframes` is disabled.
|
||||
* This may be also set to `'transparent'` or equivalent.
|
||||
*
|
||||
* @property options.background
|
||||
* @type string
|
||||
* @default '#14151f'
|
||||
*/
|
||||
|
||||
/**
|
||||
* A CSS background color string to use when `render.options.wireframes` is enabled.
|
||||
* This may be also set to `'transparent'` or equivalent.
|
||||
*
|
||||
* @property options.wireframeBackground
|
||||
* @type string
|
||||
* @default '#14151f'
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag that specifies if `render.bounds` should be used when rendering.
|
||||
*
|
||||
* @property options.hasBounds
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable all debug information overlays together.
|
||||
* This includes and has priority over the values of:
|
||||
*
|
||||
* - `render.options.showStats`
|
||||
* - `render.options.showPerformance`
|
||||
*
|
||||
* @property options.showDebug
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the engine stats info overlay.
|
||||
* From left to right, the values shown are:
|
||||
*
|
||||
* - body parts total
|
||||
* - body total
|
||||
* - constraints total
|
||||
* - composites total
|
||||
* - collision pairs total
|
||||
*
|
||||
* @property options.showStats
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable performance charts.
|
||||
* From left to right, the values shown are:
|
||||
*
|
||||
* - average render frequency (e.g. 60 fps)
|
||||
* - exact engine delta time used for last update (e.g. 16.66ms)
|
||||
* - average engine execution duration (e.g. 5.00ms)
|
||||
* - average render execution duration (e.g. 0.40ms)
|
||||
* - average effective play speed (e.g. '1.00x' is 'real-time')
|
||||
*
|
||||
* Each value is recorded over a fixed sample of past frames (60 frames).
|
||||
*
|
||||
* A chart shown below each value indicates the variance from the average over the sample.
|
||||
* The more stable or fixed the value is the flatter the chart will appear.
|
||||
*
|
||||
* @property options.showPerformance
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable rendering entirely.
|
||||
*
|
||||
* @property options.enabled
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to toggle wireframe rendering otherwise solid fill rendering is used.
|
||||
*
|
||||
* @property options.wireframes
|
||||
* @type boolean
|
||||
* @default true
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable sleeping bodies indicators.
|
||||
*
|
||||
* @property options.showSleeping
|
||||
* @type boolean
|
||||
* @default true
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the debug information overlay.
|
||||
*
|
||||
* @property options.showDebug
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the collision broadphase debug overlay.
|
||||
*
|
||||
* @property options.showBroadphase
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the body bounds debug overlay.
|
||||
*
|
||||
* @property options.showBounds
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the body velocity debug overlay.
|
||||
*
|
||||
* @property options.showVelocity
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the body collisions debug overlay.
|
||||
*
|
||||
* @property options.showCollisions
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the collision resolver separations debug overlay.
|
||||
*
|
||||
* @property options.showSeparations
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the body axes debug overlay.
|
||||
*
|
||||
* @property options.showAxes
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the body positions debug overlay.
|
||||
*
|
||||
* @property options.showPositions
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the body angle debug overlay.
|
||||
*
|
||||
* @property options.showAngleIndicator
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the body and part ids debug overlay.
|
||||
*
|
||||
* @property options.showIds
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the body vertex numbers debug overlay.
|
||||
*
|
||||
* @property options.showVertexNumbers
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the body convex hulls debug overlay.
|
||||
*
|
||||
* @property options.showConvexHulls
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the body internal edges debug overlay.
|
||||
*
|
||||
* @property options.showInternalEdges
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag to enable or disable the mouse position debug overlay.
|
||||
*
|
||||
* @property options.showMousePosition
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
})();
|
||||
|
|
|
@ -1,515 +0,0 @@
|
|||
/**
|
||||
* The `Matter.RenderPixi` module is an example renderer using pixi.js.
|
||||
* See also `Matter.Render` for a canvas based renderer.
|
||||
*
|
||||
* @class RenderPixi
|
||||
* @deprecated the Matter.RenderPixi module will soon be removed from the Matter.js core.
|
||||
* It will likely be moved to its own repository (but maintenance will be limited).
|
||||
*/
|
||||
|
||||
var RenderPixi = {};
|
||||
|
||||
module.exports = RenderPixi;
|
||||
|
||||
var Bounds = require('../geometry/Bounds');
|
||||
var Composite = require('../body/Composite');
|
||||
var Common = require('../core/Common');
|
||||
var Events = require('../core/Events');
|
||||
var Vector = require('../geometry/Vector');
|
||||
|
||||
(function() {
|
||||
|
||||
var _requestAnimationFrame,
|
||||
_cancelAnimationFrame;
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
_requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
|
||||
|| window.mozRequestAnimationFrame || window.msRequestAnimationFrame
|
||||
|| function(callback){ window.setTimeout(function() { callback(Common.now()); }, 1000 / 60); };
|
||||
|
||||
_cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
|
||||
|| window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Pixi.js WebGL renderer
|
||||
* @method create
|
||||
* @param {object} options
|
||||
* @return {RenderPixi} A new renderer
|
||||
* @deprecated
|
||||
*/
|
||||
RenderPixi.create = function(options) {
|
||||
Common.warn('RenderPixi.create: Matter.RenderPixi is deprecated (see docs)');
|
||||
|
||||
var defaults = {
|
||||
controller: RenderPixi,
|
||||
engine: null,
|
||||
element: null,
|
||||
frameRequestId: null,
|
||||
canvas: null,
|
||||
renderer: null,
|
||||
container: null,
|
||||
spriteContainer: null,
|
||||
pixiOptions: null,
|
||||
options: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
background: '#fafafa',
|
||||
wireframeBackground: '#222',
|
||||
hasBounds: false,
|
||||
enabled: true,
|
||||
wireframes: true,
|
||||
showSleeping: true,
|
||||
showDebug: false,
|
||||
showBroadphase: false,
|
||||
showBounds: false,
|
||||
showVelocity: false,
|
||||
showCollisions: false,
|
||||
showAxes: false,
|
||||
showPositions: false,
|
||||
showAngleIndicator: false,
|
||||
showIds: false,
|
||||
showShadows: false
|
||||
}
|
||||
};
|
||||
|
||||
var render = Common.extend(defaults, options),
|
||||
transparent = !render.options.wireframes && render.options.background === 'transparent';
|
||||
|
||||
// init pixi
|
||||
render.pixiOptions = render.pixiOptions || {
|
||||
view: render.canvas,
|
||||
transparent: transparent,
|
||||
antialias: true,
|
||||
backgroundColor: options.background
|
||||
};
|
||||
|
||||
render.mouse = options.mouse;
|
||||
render.engine = options.engine;
|
||||
render.renderer = render.renderer || new PIXI.WebGLRenderer(render.options.width, render.options.height, render.pixiOptions);
|
||||
render.container = render.container || new PIXI.Container();
|
||||
render.spriteContainer = render.spriteContainer || new PIXI.Container();
|
||||
render.canvas = render.canvas || render.renderer.view;
|
||||
render.bounds = render.bounds || {
|
||||
min: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
max: {
|
||||
x: render.options.width,
|
||||
y: render.options.height
|
||||
}
|
||||
};
|
||||
|
||||
// event listeners
|
||||
Events.on(render.engine, 'beforeUpdate', function() {
|
||||
RenderPixi.clear(render);
|
||||
});
|
||||
|
||||
// caches
|
||||
render.textures = {};
|
||||
render.sprites = {};
|
||||
render.primitives = {};
|
||||
|
||||
// use a sprite batch for performance
|
||||
render.container.addChild(render.spriteContainer);
|
||||
|
||||
// insert canvas
|
||||
if (Common.isElement(render.element)) {
|
||||
render.element.appendChild(render.canvas);
|
||||
} else {
|
||||
Common.warn('No "render.element" passed, "render.canvas" was not inserted into document.');
|
||||
}
|
||||
|
||||
// prevent menus on canvas
|
||||
render.canvas.oncontextmenu = function() { return false; };
|
||||
render.canvas.onselectstart = function() { return false; };
|
||||
|
||||
return render;
|
||||
};
|
||||
|
||||
/**
|
||||
* Continuously updates the render canvas on the `requestAnimationFrame` event.
|
||||
* @method run
|
||||
* @param {render} render
|
||||
* @deprecated
|
||||
*/
|
||||
RenderPixi.run = function(render) {
|
||||
(function loop(time){
|
||||
render.frameRequestId = _requestAnimationFrame(loop);
|
||||
RenderPixi.world(render);
|
||||
})();
|
||||
};
|
||||
|
||||
/**
|
||||
* Ends execution of `Render.run` on the given `render`, by canceling the animation frame request event loop.
|
||||
* @method stop
|
||||
* @param {render} render
|
||||
* @deprecated
|
||||
*/
|
||||
RenderPixi.stop = function(render) {
|
||||
_cancelAnimationFrame(render.frameRequestId);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the scene graph
|
||||
* @method clear
|
||||
* @param {RenderPixi} render
|
||||
* @deprecated
|
||||
*/
|
||||
RenderPixi.clear = function(render) {
|
||||
var container = render.container,
|
||||
spriteContainer = render.spriteContainer;
|
||||
|
||||
// clear stage container
|
||||
while (container.children[0]) {
|
||||
container.removeChild(container.children[0]);
|
||||
}
|
||||
|
||||
// clear sprite batch
|
||||
while (spriteContainer.children[0]) {
|
||||
spriteContainer.removeChild(spriteContainer.children[0]);
|
||||
}
|
||||
|
||||
var bgSprite = render.sprites['bg-0'];
|
||||
|
||||
// clear caches
|
||||
render.textures = {};
|
||||
render.sprites = {};
|
||||
render.primitives = {};
|
||||
|
||||
// set background sprite
|
||||
render.sprites['bg-0'] = bgSprite;
|
||||
if (bgSprite)
|
||||
container.addChildAt(bgSprite, 0);
|
||||
|
||||
// add sprite batch back into container
|
||||
render.container.addChild(render.spriteContainer);
|
||||
|
||||
// reset background state
|
||||
render.currentBackground = null;
|
||||
|
||||
// reset bounds transforms
|
||||
container.scale.set(1, 1);
|
||||
container.position.set(0, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the background of the canvas
|
||||
* @method setBackground
|
||||
* @param {RenderPixi} render
|
||||
* @param {string} background
|
||||
* @deprecated
|
||||
*/
|
||||
RenderPixi.setBackground = function(render, background) {
|
||||
if (render.currentBackground !== background) {
|
||||
var isColor = background.indexOf && background.indexOf('#') !== -1,
|
||||
bgSprite = render.sprites['bg-0'];
|
||||
|
||||
if (isColor) {
|
||||
// if solid background color
|
||||
var color = Common.colorToNumber(background);
|
||||
render.renderer.backgroundColor = color;
|
||||
|
||||
// remove background sprite if existing
|
||||
if (bgSprite)
|
||||
render.container.removeChild(bgSprite);
|
||||
} else {
|
||||
// initialise background sprite if needed
|
||||
if (!bgSprite) {
|
||||
var texture = _getTexture(render, background);
|
||||
|
||||
bgSprite = render.sprites['bg-0'] = new PIXI.Sprite(texture);
|
||||
bgSprite.position.x = 0;
|
||||
bgSprite.position.y = 0;
|
||||
render.container.addChildAt(bgSprite, 0);
|
||||
}
|
||||
}
|
||||
|
||||
render.currentBackground = background;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
* @method world
|
||||
* @param {engine} engine
|
||||
* @deprecated
|
||||
*/
|
||||
RenderPixi.world = function(render) {
|
||||
var engine = render.engine,
|
||||
world = engine.world,
|
||||
renderer = render.renderer,
|
||||
container = render.container,
|
||||
options = render.options,
|
||||
bodies = Composite.allBodies(world),
|
||||
allConstraints = Composite.allConstraints(world),
|
||||
constraints = [],
|
||||
i;
|
||||
|
||||
if (options.wireframes) {
|
||||
RenderPixi.setBackground(render, options.wireframeBackground);
|
||||
} else {
|
||||
RenderPixi.setBackground(render, options.background);
|
||||
}
|
||||
|
||||
// handle bounds
|
||||
var boundsWidth = render.bounds.max.x - render.bounds.min.x,
|
||||
boundsHeight = render.bounds.max.y - render.bounds.min.y,
|
||||
boundsScaleX = boundsWidth / render.options.width,
|
||||
boundsScaleY = boundsHeight / render.options.height;
|
||||
|
||||
if (options.hasBounds) {
|
||||
// Hide bodies that are not in view
|
||||
for (i = 0; i < bodies.length; i++) {
|
||||
var body = bodies[i];
|
||||
body.render.sprite.visible = Bounds.overlaps(body.bounds, render.bounds);
|
||||
}
|
||||
|
||||
// filter out constraints that are not in view
|
||||
for (i = 0; i < allConstraints.length; i++) {
|
||||
var constraint = allConstraints[i],
|
||||
bodyA = constraint.bodyA,
|
||||
bodyB = constraint.bodyB,
|
||||
pointAWorld = constraint.pointA,
|
||||
pointBWorld = constraint.pointB;
|
||||
|
||||
if (bodyA) pointAWorld = Vector.add(bodyA.position, constraint.pointA);
|
||||
if (bodyB) pointBWorld = Vector.add(bodyB.position, constraint.pointB);
|
||||
|
||||
if (!pointAWorld || !pointBWorld)
|
||||
continue;
|
||||
|
||||
if (Bounds.contains(render.bounds, pointAWorld) || Bounds.contains(render.bounds, pointBWorld))
|
||||
constraints.push(constraint);
|
||||
}
|
||||
|
||||
// transform the view
|
||||
container.scale.set(1 / boundsScaleX, 1 / boundsScaleY);
|
||||
container.position.set(-render.bounds.min.x * (1 / boundsScaleX), -render.bounds.min.y * (1 / boundsScaleY));
|
||||
} else {
|
||||
constraints = allConstraints;
|
||||
}
|
||||
|
||||
for (i = 0; i < bodies.length; i++)
|
||||
RenderPixi.body(render, bodies[i]);
|
||||
|
||||
for (i = 0; i < constraints.length; i++)
|
||||
RenderPixi.constraint(render, constraints[i]);
|
||||
|
||||
renderer.render(container);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Description
|
||||
* @method constraint
|
||||
* @param {engine} engine
|
||||
* @param {constraint} constraint
|
||||
* @deprecated
|
||||
*/
|
||||
RenderPixi.constraint = function(render, constraint) {
|
||||
var engine = render.engine,
|
||||
bodyA = constraint.bodyA,
|
||||
bodyB = constraint.bodyB,
|
||||
pointA = constraint.pointA,
|
||||
pointB = constraint.pointB,
|
||||
container = render.container,
|
||||
constraintRender = constraint.render,
|
||||
primitiveId = 'c-' + constraint.id,
|
||||
primitive = render.primitives[primitiveId];
|
||||
|
||||
// initialise constraint primitive if not existing
|
||||
if (!primitive)
|
||||
primitive = render.primitives[primitiveId] = new PIXI.Graphics();
|
||||
|
||||
// don't render if constraint does not have two end points
|
||||
if (!constraintRender.visible || !constraint.pointA || !constraint.pointB) {
|
||||
primitive.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// add to scene graph if not already there
|
||||
if (Common.indexOf(container.children, primitive) === -1)
|
||||
container.addChild(primitive);
|
||||
|
||||
// render the constraint on every update, since they can change dynamically
|
||||
primitive.clear();
|
||||
primitive.beginFill(0, 0);
|
||||
primitive.lineStyle(constraintRender.lineWidth, Common.colorToNumber(constraintRender.strokeStyle), 1);
|
||||
|
||||
if (bodyA) {
|
||||
primitive.moveTo(bodyA.position.x + pointA.x, bodyA.position.y + pointA.y);
|
||||
} else {
|
||||
primitive.moveTo(pointA.x, pointA.y);
|
||||
}
|
||||
|
||||
if (bodyB) {
|
||||
primitive.lineTo(bodyB.position.x + pointB.x, bodyB.position.y + pointB.y);
|
||||
} else {
|
||||
primitive.lineTo(pointB.x, pointB.y);
|
||||
}
|
||||
|
||||
primitive.endFill();
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
* @method body
|
||||
* @param {engine} engine
|
||||
* @param {body} body
|
||||
* @deprecated
|
||||
*/
|
||||
RenderPixi.body = function(render, body) {
|
||||
var engine = render.engine,
|
||||
bodyRender = body.render;
|
||||
|
||||
if (!bodyRender.visible)
|
||||
return;
|
||||
|
||||
if (bodyRender.sprite && bodyRender.sprite.texture) {
|
||||
var spriteId = 'b-' + body.id,
|
||||
sprite = render.sprites[spriteId],
|
||||
spriteContainer = render.spriteContainer;
|
||||
|
||||
// initialise body sprite if not existing
|
||||
if (!sprite)
|
||||
sprite = render.sprites[spriteId] = _createBodySprite(render, body);
|
||||
|
||||
// add to scene graph if not already there
|
||||
if (Common.indexOf(spriteContainer.children, sprite) === -1)
|
||||
spriteContainer.addChild(sprite);
|
||||
|
||||
// update body sprite
|
||||
sprite.position.x = body.position.x;
|
||||
sprite.position.y = body.position.y;
|
||||
sprite.rotation = body.angle;
|
||||
sprite.scale.x = bodyRender.sprite.xScale || 1;
|
||||
sprite.scale.y = bodyRender.sprite.yScale || 1;
|
||||
} else {
|
||||
var primitiveId = 'b-' + body.id,
|
||||
primitive = render.primitives[primitiveId],
|
||||
container = render.container;
|
||||
|
||||
// initialise body primitive if not existing
|
||||
if (!primitive) {
|
||||
primitive = render.primitives[primitiveId] = _createBodyPrimitive(render, body);
|
||||
primitive.initialAngle = body.angle;
|
||||
}
|
||||
|
||||
// add to scene graph if not already there
|
||||
if (Common.indexOf(container.children, primitive) === -1)
|
||||
container.addChild(primitive);
|
||||
|
||||
// update body primitive
|
||||
primitive.position.x = body.position.x;
|
||||
primitive.position.y = body.position.y;
|
||||
primitive.rotation = body.angle - primitive.initialAngle;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a body sprite
|
||||
* @method _createBodySprite
|
||||
* @private
|
||||
* @param {RenderPixi} render
|
||||
* @param {body} body
|
||||
* @return {PIXI.Sprite} sprite
|
||||
* @deprecated
|
||||
*/
|
||||
var _createBodySprite = function(render, body) {
|
||||
var bodyRender = body.render,
|
||||
texturePath = bodyRender.sprite.texture,
|
||||
texture = _getTexture(render, texturePath),
|
||||
sprite = new PIXI.Sprite(texture);
|
||||
|
||||
sprite.anchor.x = body.render.sprite.xOffset;
|
||||
sprite.anchor.y = body.render.sprite.yOffset;
|
||||
|
||||
return sprite;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a body primitive
|
||||
* @method _createBodyPrimitive
|
||||
* @private
|
||||
* @param {RenderPixi} render
|
||||
* @param {body} body
|
||||
* @return {PIXI.Graphics} graphics
|
||||
* @deprecated
|
||||
*/
|
||||
var _createBodyPrimitive = function(render, body) {
|
||||
var bodyRender = body.render,
|
||||
options = render.options,
|
||||
primitive = new PIXI.Graphics(),
|
||||
fillStyle = Common.colorToNumber(bodyRender.fillStyle),
|
||||
strokeStyle = Common.colorToNumber(bodyRender.strokeStyle),
|
||||
strokeStyleIndicator = Common.colorToNumber(bodyRender.strokeStyle),
|
||||
strokeStyleWireframe = Common.colorToNumber('#bbb'),
|
||||
strokeStyleWireframeIndicator = Common.colorToNumber('#CD5C5C'),
|
||||
part;
|
||||
|
||||
primitive.clear();
|
||||
|
||||
// handle compound parts
|
||||
for (var k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
|
||||
part = body.parts[k];
|
||||
|
||||
if (!options.wireframes) {
|
||||
primitive.beginFill(fillStyle, 1);
|
||||
primitive.lineStyle(bodyRender.lineWidth, strokeStyle, 1);
|
||||
} else {
|
||||
primitive.beginFill(0, 0);
|
||||
primitive.lineStyle(1, strokeStyleWireframe, 1);
|
||||
}
|
||||
|
||||
primitive.moveTo(part.vertices[0].x - body.position.x, part.vertices[0].y - body.position.y);
|
||||
|
||||
for (var j = 1; j < part.vertices.length; j++) {
|
||||
primitive.lineTo(part.vertices[j].x - body.position.x, part.vertices[j].y - body.position.y);
|
||||
}
|
||||
|
||||
primitive.lineTo(part.vertices[0].x - body.position.x, part.vertices[0].y - body.position.y);
|
||||
|
||||
primitive.endFill();
|
||||
|
||||
// angle indicator
|
||||
if (options.showAngleIndicator || options.showAxes) {
|
||||
primitive.beginFill(0, 0);
|
||||
|
||||
if (options.wireframes) {
|
||||
primitive.lineStyle(1, strokeStyleWireframeIndicator, 1);
|
||||
} else {
|
||||
primitive.lineStyle(1, strokeStyleIndicator);
|
||||
}
|
||||
|
||||
primitive.moveTo(part.position.x - body.position.x, part.position.y - body.position.y);
|
||||
primitive.lineTo(((part.vertices[0].x + part.vertices[part.vertices.length-1].x) / 2 - body.position.x),
|
||||
((part.vertices[0].y + part.vertices[part.vertices.length-1].y) / 2 - body.position.y));
|
||||
|
||||
primitive.endFill();
|
||||
}
|
||||
}
|
||||
|
||||
return primitive;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the requested texture (a PIXI.Texture) via its path
|
||||
* @method _getTexture
|
||||
* @private
|
||||
* @param {RenderPixi} render
|
||||
* @param {string} imagePath
|
||||
* @return {PIXI.Texture} texture
|
||||
* @deprecated
|
||||
*/
|
||||
var _getTexture = function(render, imagePath) {
|
||||
var texture = render.textures[imagePath];
|
||||
|
||||
if (!texture)
|
||||
texture = render.textures[imagePath] = PIXI.Texture.fromImage(imagePath);
|
||||
|
||||
return texture;
|
||||
};
|
||||
|
||||
})();
|
114
test/Browser.spec.js
Normal file
114
test/Browser.spec.js
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* eslint-env es6 */
|
||||
"use strict";
|
||||
|
||||
jest.setTimeout(120 * 1000);
|
||||
|
||||
const puppeteer = require('puppeteer-core');
|
||||
const Example = require('../examples/index');
|
||||
const fs = require('fs');
|
||||
|
||||
const examples = Object.keys(Example);
|
||||
|
||||
const browserPath = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome';
|
||||
const demoPagePath = 'http://localhost:8000/';
|
||||
const totalUpdates = 5;
|
||||
|
||||
if (!fs.existsSync(browserPath)) {
|
||||
// Skip if browser is missing
|
||||
console.warn('Could not find browser. Browser tests skipped.');
|
||||
describe.skip('Browser integration tests');
|
||||
} else {
|
||||
describe('Browser integration tests', () => {
|
||||
let results;
|
||||
|
||||
// Set up the environment and run examples
|
||||
beforeAll(async () => results = await runExamplesBrowser(totalUpdates));
|
||||
|
||||
it('all examples run without throwing error or warning', () => {
|
||||
if (results.error) {
|
||||
console.error(results.error);
|
||||
expect(Boolean(results.error)).toBe(false);
|
||||
}
|
||||
if (results.warns) {
|
||||
console.error(results.warns);
|
||||
expect(results.warns.size).toBe(0);
|
||||
}
|
||||
if (!results.error && !results.warns) {
|
||||
for (const example of examples) {
|
||||
expect(results[example].id).toBe(example);
|
||||
expect(results[example].timestamp).toBeGreaterThan(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const runExamplesBrowser = async updates => {
|
||||
// Set up browser environment
|
||||
const browser = await puppeteer.launch({ executablePath: browserPath });
|
||||
const page = await browser.newPage();
|
||||
const results = {};
|
||||
let example;
|
||||
|
||||
// Load local demo page and catch errors
|
||||
let pageError;
|
||||
let pageWarns;
|
||||
|
||||
const onPageError = error => pageError = error;
|
||||
const onPageConsole = async message => {
|
||||
const type = message.type();
|
||||
if (example && type === 'error' || type === 'warning') {
|
||||
const log = `[${example}] ${message.type()} ${message.text()}`;
|
||||
pageWarns = pageWarns || new Set();
|
||||
pageWarns.add(log);
|
||||
}
|
||||
}
|
||||
|
||||
page.addListener('pageerror', onPageError);
|
||||
page.addListener('console', onPageConsole);
|
||||
|
||||
await page.goto(demoPagePath).catch(onPageError);
|
||||
|
||||
// For every example
|
||||
for (example of examples) {
|
||||
// Bail on error
|
||||
if (pageError) {
|
||||
break;
|
||||
}
|
||||
|
||||
// In the demo page context
|
||||
results[example] = await page.evaluate(async (example, updates) => {
|
||||
const demo = window.MatterDemoInstance;
|
||||
|
||||
// Set the current example
|
||||
MatterTools.Demo.setExampleById(demo, example);
|
||||
const instance = demo.example.instance;
|
||||
let ticks = 0;
|
||||
|
||||
// Wait while running
|
||||
await new Promise((resolve) => {
|
||||
Matter.Events.on(instance.runner, 'tick', () => {
|
||||
// Stop after enough updates
|
||||
if (ticks >= updates) {
|
||||
Matter.Runner.stop(instance.runner);
|
||||
resolve();
|
||||
}
|
||||
ticks += 1;
|
||||
});
|
||||
});
|
||||
|
||||
// Return results
|
||||
return {
|
||||
id: demo.example.id,
|
||||
timestamp: instance.engine.timing.timestamp
|
||||
};
|
||||
}, example, updates);
|
||||
}
|
||||
|
||||
// Tear down
|
||||
await browser.close();
|
||||
|
||||
results.error = pageError;
|
||||
results.warns = pageWarns;
|
||||
return results;
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue