mirror of
https://github.com/liabru/matter-js.git
synced 2024-12-26 13:49:01 -05:00
Merge branch 'runner-improve' into browserify
This commit is contained in:
commit
9e3438f359
99 changed files with 1404935 additions and 534 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,3 +6,4 @@ matter-doc-theme
|
|||
build/matter-dev.js
|
||||
build/matter-dev.min.js
|
||||
demo/js/lib/matter-dev.js
|
||||
test/browser/diffs
|
15
.jshintrc
15
.jshintrc
|
@ -25,5 +25,18 @@
|
|||
"sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.
|
||||
"trailing" : false, // Prohibit trailing whitespaces.
|
||||
"white" : false, // Check against strict whitespace and indentation rules.
|
||||
"indent" : 4 // Specify indentation spacing
|
||||
"indent" : 4, // Specify indentation spacing
|
||||
|
||||
// variables
|
||||
"undef": true,
|
||||
"-W079": true, // Silence redefinition errors (they are false positives).
|
||||
"predef": [
|
||||
"Matter", "window", "document", "Element", "MatterTools", "PIXI", "phantom", "module",
|
||||
"$", "Image", "navigator", "setTimeout", "decomp", "HTMLElement", "require",
|
||||
"Body", "Composite", "World", "Contact", "Detector", "Grid",
|
||||
"Pairs", "Pair", "Resolver", "SAT", "Constraint", "MouseConstraint",
|
||||
"Common", "Engine", "Mouse", "Sleeping", "Bodies", "Composites",
|
||||
"Axes", "Bounds", "Vector", "Vertices", "Render", "RenderPixi",
|
||||
"Events", "Query", "Runner", "Svg", "Metrics"
|
||||
]
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
.idea
|
||||
node_modules
|
||||
npm-debug.log
|
||||
doc
|
||||
matter-doc-theme
|
||||
build/matter-dev.js
|
||||
build/matter-dev.min.js
|
||||
demo/js/lib/matter-dev.js
|
||||
demo/js/lib/matter-dev.js
|
||||
test/browser/diffs
|
11
.travis.yml
11
.travis.yml
|
@ -1,6 +1,11 @@
|
|||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- "0.10"
|
||||
before_install: npm install -g grunt-cli
|
||||
install: npm install
|
||||
before_script: grunt
|
||||
before_install:
|
||||
- npm install -g grunt-cli
|
||||
- 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
|
36
Gruntfile.js
36
Gruntfile.js
|
@ -45,7 +45,7 @@ module.exports = function(grunt) {
|
|||
options: {
|
||||
jshintrc: '.jshintrc'
|
||||
},
|
||||
all: ['src/**/*.js', 'demo/js/*.js', '!src/module/*']
|
||||
all: ['src/**/*.js', 'demo/js/*.js', 'test/browser/TestDemo.js', '!src/module/*']
|
||||
},
|
||||
connect: {
|
||||
watch: {
|
||||
|
@ -54,6 +54,11 @@ module.exports = function(grunt) {
|
|||
open: 'http://localhost:9000/demo/dev.html',
|
||||
livereload: 9001
|
||||
}
|
||||
},
|
||||
serve: {
|
||||
options: {
|
||||
port: 8000
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -95,6 +100,19 @@ module.exports = function(grunt) {
|
|||
src: 'build/<%= buildName %>.js',
|
||||
dest: 'build/<%= buildName %>.js'
|
||||
}
|
||||
},
|
||||
shell: {
|
||||
testDemo: {
|
||||
command: function(arg) {
|
||||
arg = arg ? ' --' + arg : '';
|
||||
return 'phantomjs test/browser/TestDemo.js' + arg;
|
||||
},
|
||||
options: {
|
||||
execOptions: {
|
||||
timeout: 1000 * 60
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -106,11 +124,25 @@ module.exports = function(grunt) {
|
|||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-contrib-yuidoc');
|
||||
grunt.loadNpmTasks('grunt-preprocess');
|
||||
grunt.loadNpmTasks('grunt-shell');
|
||||
|
||||
grunt.registerTask('default', ['test', 'build']);
|
||||
grunt.registerTask('test', ['jshint']);
|
||||
grunt.registerTask('test', ['build:dev', 'connect:serve', 'jshint', 'test:demo']);
|
||||
grunt.registerTask('dev', ['build:dev', 'connect:watch', 'watch']);
|
||||
|
||||
grunt.registerTask('test:demo', function() {
|
||||
var updateAll = grunt.option('updateAll'),
|
||||
diff = grunt.option('diff');
|
||||
|
||||
if (updateAll) {
|
||||
grunt.task.run('shell:testDemo:updateAll');
|
||||
} else if (diff) {
|
||||
grunt.task.run('shell:testDemo:diff');
|
||||
} else {
|
||||
grunt.task.run('shell:testDemo');
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('build', function(mode) {
|
||||
var isDev = (mode === 'dev'),
|
||||
isRelease = (mode === 'release'),
|
||||
|
|
668
build/matter.js
668
build/matter.js
File diff suppressed because it is too large
Load diff
8
build/matter.min.js
vendored
8
build/matter.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -25,15 +25,18 @@
|
|||
}
|
||||
|
||||
var Demo = {};
|
||||
Matter.Demo = Demo;
|
||||
|
||||
var _engine,
|
||||
_runner,
|
||||
_gui,
|
||||
_inspector,
|
||||
_sceneName,
|
||||
_mouseConstraint,
|
||||
_sceneEvents = [],
|
||||
_useInspector = window.location.hash.indexOf('-inspect') !== -1,
|
||||
_isMobile = /(ipad|iphone|ipod|android)/gi.test(navigator.userAgent);
|
||||
_isMobile = /(ipad|iphone|ipod|android)/gi.test(navigator.userAgent),
|
||||
_isAutomatedTest = window._phantom ? true : false;
|
||||
|
||||
// initialise the demo
|
||||
|
||||
|
@ -56,8 +59,14 @@
|
|||
_mouseConstraint = MouseConstraint.create(_engine);
|
||||
World.add(_engine.world, _mouseConstraint);
|
||||
|
||||
// engine reference for external use
|
||||
Matter.Demo._engine = _engine;
|
||||
|
||||
// skip runner when performing automated tests
|
||||
if (_isAutomatedTest) return;
|
||||
|
||||
// run the engine
|
||||
Engine.run(_engine);
|
||||
_runner = Engine.run(_engine);
|
||||
|
||||
// default scene function name
|
||||
_sceneName = 'mixed';
|
||||
|
@ -344,7 +353,7 @@
|
|||
|
||||
World.add(_engine.world, [ground, pyramid, ground2, pyramid2, rock, elastic]);
|
||||
|
||||
Events.on(_engine, 'tick', function() {
|
||||
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);
|
||||
|
@ -491,7 +500,7 @@
|
|||
_world.gravity.y = 0;
|
||||
|
||||
_sceneEvents.push(
|
||||
Events.on(_engine, 'tick', function(event) {
|
||||
Events.on(_engine, 'afterUpdate', function(event) {
|
||||
var time = _engine.timing.timestamp;
|
||||
|
||||
Composite.translate(stack, {
|
||||
|
@ -986,7 +995,7 @@
|
|||
counter = 0;
|
||||
|
||||
_sceneEvents.push(
|
||||
Events.on(_engine, 'tick', function(event) {
|
||||
Events.on(_engine, 'afterUpdate', function(event) {
|
||||
// tween the timescale for bullet time slow-mo
|
||||
_engine.timing.timeScale += (timeScaleTarget - _engine.timing.timeScale) * 0.05;
|
||||
|
||||
|
@ -1482,7 +1491,7 @@
|
|||
World.add(_world, [stack, concave]);
|
||||
|
||||
_sceneEvents.push(
|
||||
Events.on(_engine, 'afterRender', function() {
|
||||
Events.on(_engine.render, 'afterRender', function() {
|
||||
var mouse = _mouseConstraint.mouse,
|
||||
context = _engine.render.context,
|
||||
bodies = Composite.allBodies(_engine.world),
|
||||
|
@ -1610,7 +1619,7 @@
|
|||
|
||||
// create a Matter.Gui
|
||||
if (!_isMobile && Gui) {
|
||||
_gui = Gui.create(_engine);
|
||||
_gui = Gui.create(_engine, _runner);
|
||||
|
||||
// need to add mouse constraint back in after gui clear or load is pressed
|
||||
Events.on(_gui, 'clear load', function() {
|
||||
|
@ -1626,7 +1635,7 @@
|
|||
|
||||
// create a Matter.Inspector
|
||||
if (!_isMobile && Inspector && _useInspector) {
|
||||
_inspector = Inspector.create(_engine);
|
||||
_inspector = Inspector.create(_engine, _runner);
|
||||
|
||||
Events.on(_inspector, 'import', function() {
|
||||
_mouseConstraint = MouseConstraint.create(_engine);
|
||||
|
@ -1729,6 +1738,16 @@
|
|||
Events.off(_world, _sceneEvents[i]);
|
||||
}
|
||||
|
||||
if (_runner && _runner.events) {
|
||||
for (i = 0; i < _sceneEvents.length; i++)
|
||||
Events.off(_runner, _sceneEvents[i]);
|
||||
}
|
||||
|
||||
if (_engine.render.events) {
|
||||
for (i = 0; i < _sceneEvents.length; i++)
|
||||
Events.off(_engine.render, _sceneEvents[i]);
|
||||
}
|
||||
|
||||
_sceneEvents = [];
|
||||
|
||||
// reset id pool
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
var _engine,
|
||||
_sceneName = 'mixed',
|
||||
_sceneWidth,
|
||||
_sceneHeight;
|
||||
_sceneHeight,
|
||||
_deviceOrientationEvent;
|
||||
|
||||
Demo.init = function() {
|
||||
var canvasContainer = document.getElementById('canvas-container'),
|
||||
|
@ -44,10 +45,15 @@
|
|||
}, 800);
|
||||
});
|
||||
|
||||
window.addEventListener('deviceorientation', Demo.updateGravity, true);
|
||||
window.addEventListener('deviceorientation', function(event) {
|
||||
_deviceOrientationEvent = event;
|
||||
Demo.updateGravity(event);
|
||||
}, true);
|
||||
|
||||
window.addEventListener('touchstart', Demo.fullscreen);
|
||||
|
||||
window.addEventListener('orientationchange', function() {
|
||||
Demo.updateGravity();
|
||||
Demo.updateGravity(_deviceOrientationEvent);
|
||||
Demo.updateScene();
|
||||
Demo.fullscreen();
|
||||
}, false);
|
||||
|
@ -101,7 +107,7 @@
|
|||
Demo[_sceneName]();
|
||||
};
|
||||
|
||||
Demo.updateGravity = function () {
|
||||
Demo.updateGravity = function(event) {
|
||||
if (!_engine)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* matter-tools-dev.min.js 0.5.0-dev 2015-05-24
|
||||
* matter-tools-dev.min.js 0.5.0-dev 2015-07-27
|
||||
* https://github.com/liabru/matter-tools
|
||||
* License: MIT
|
||||
*/
|
||||
|
@ -10,7 +10,7 @@
|
|||
var Gui = {};
|
||||
(function() {
|
||||
var _isWebkit = "WebkitAppearance" in document.documentElement.style;
|
||||
Gui.create = function(engine, options) {
|
||||
Gui.create = function(engine, runner, options) {
|
||||
var _datGuiSupported = window.dat && window.localStorage;
|
||||
if (!_datGuiSupported) {
|
||||
console.log("Could not create GUI. Check dat.gui library is loaded first.");
|
||||
|
@ -19,6 +19,7 @@
|
|||
var datGui = new dat.GUI(options);
|
||||
var gui = {
|
||||
engine:engine,
|
||||
runner:runner,
|
||||
datGui:datGui,
|
||||
broadphase:"grid",
|
||||
broadphaseCache:{
|
||||
|
@ -98,7 +99,7 @@
|
|||
return clone;
|
||||
};
|
||||
var _initDatGui = function(gui) {
|
||||
var engine = gui.engine, datGui = gui.datGui;
|
||||
var engine = gui.engine, runner = gui.runner, datGui = gui.datGui;
|
||||
var funcs = {
|
||||
addBody:function() {
|
||||
_addBody(gui);
|
||||
|
@ -115,7 +116,7 @@
|
|||
Events.trigger(gui, "load");
|
||||
},
|
||||
inspect:function() {
|
||||
if (!Inspector.instance) gui.inspector = Inspector.create(gui.engine);
|
||||
if (!Inspector.instance) gui.inspector = Inspector.create(gui.engine, gui.runner);
|
||||
},
|
||||
recordGif:function() {
|
||||
if (!gui.isRecording) {
|
||||
|
@ -152,10 +153,10 @@
|
|||
}
|
||||
};
|
||||
var metrics = datGui.addFolder("Metrics");
|
||||
metrics.add(engine.timing, "fps").listen();
|
||||
metrics.add(runner, "fps").listen();
|
||||
if (engine.metrics.extended) {
|
||||
metrics.add(engine.timing, "delta").listen();
|
||||
metrics.add(engine.timing, "correction").listen();
|
||||
metrics.add(runner, "delta").listen();
|
||||
metrics.add(runner, "correction").listen();
|
||||
metrics.add(engine.metrics, "bodies").listen();
|
||||
metrics.add(engine.metrics, "collisions").listen();
|
||||
metrics.add(engine.metrics, "pairs").listen();
|
||||
|
@ -201,7 +202,7 @@
|
|||
physics.add(engine.timing, "timeScale", 0, 1.2).step(.05).listen();
|
||||
physics.add(engine, "velocityIterations", 1, 10).step(1);
|
||||
physics.add(engine, "positionIterations", 1, 10).step(1);
|
||||
physics.add(engine, "enabled");
|
||||
physics.add(runner, "enabled");
|
||||
physics.open();
|
||||
var render = datGui.addFolder("Render");
|
||||
render.add(gui, "renderer", [ "canvas", "webgl" ]).onFinishChange(function(value) {
|
||||
|
@ -269,7 +270,7 @@
|
|||
return;
|
||||
}
|
||||
var engine = gui.engine, skipFrame = false;
|
||||
Matter.Events.on(engine, "beforeTick", function(event) {
|
||||
Matter.Events.on(gui.runner, "beforeTick", function(event) {
|
||||
if (gui.isRecording && !skipFrame) {
|
||||
gui.gif.addFrame(engine.render.context, {
|
||||
copy:true,
|
||||
|
@ -283,13 +284,14 @@
|
|||
var Inspector = {};
|
||||
(function() {
|
||||
var _key, _isWebkit = "WebkitAppearance" in document.documentElement.style, $body;
|
||||
Inspector.create = function(engine, options) {
|
||||
Inspector.create = function(engine, runner, options) {
|
||||
if (!jQuery || !$.fn.jstree || !window.key) {
|
||||
console.log("Could not create inspector. Check keymaster, jQuery, jsTree libraries are loaded first.");
|
||||
return;
|
||||
}
|
||||
var inspector = {
|
||||
engine:engine,
|
||||
runner:runner,
|
||||
isPaused:false,
|
||||
selected:[],
|
||||
selectStart:null,
|
||||
|
@ -566,7 +568,7 @@
|
|||
};
|
||||
var _initEngineEvents = function(inspector) {
|
||||
var engine = inspector.engine, mouse = inspector.mouse, mousePosition = _getMousePosition(inspector), controls = inspector.controls;
|
||||
Events.on(engine, "tick", function() {
|
||||
Events.on(inspector.engine, "beforeUpdate", function() {
|
||||
mousePosition = _getMousePosition(inspector);
|
||||
var mouseDelta = mousePosition.x - inspector.mousePrevPosition.x, keyDelta = _key.isPressed("up") + _key.isPressed("right") - _key.isPressed("down") - _key.isPressed("left"), delta = mouseDelta + keyDelta;
|
||||
if (engine.world.isModified) {
|
||||
|
@ -672,7 +674,7 @@
|
|||
_updateSelectedMouseDownOffset(inspector);
|
||||
}
|
||||
});
|
||||
Events.on(engine, "afterRender", function() {
|
||||
Events.on(inspector.engine.render, "afterRender", function() {
|
||||
var renderController = engine.render.controller, context = engine.render.context;
|
||||
if (renderController.inspector) renderController.inspector(inspector, context);
|
||||
});
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"rigid body physics"
|
||||
],
|
||||
"devDependencies": {
|
||||
"fast-json-patch": "^0.5.4",
|
||||
"grunt": "~0.4.2",
|
||||
"grunt-browserify": "~3.7.0",
|
||||
"grunt-contrib-connect": "~0.6.0",
|
||||
|
@ -28,7 +29,8 @@
|
|||
"grunt-contrib-uglify": "~0.2.7",
|
||||
"grunt-contrib-watch": "~0.5.3",
|
||||
"grunt-contrib-yuidoc": "~0.5.1",
|
||||
"grunt-preprocess": "^4.1.0"
|
||||
"grunt-preprocess": "^4.1.0",
|
||||
"grunt-shell": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "npm install && grunt dev",
|
||||
|
|
|
@ -58,6 +58,7 @@ module.exports = Resolver;
|
|||
normal,
|
||||
bodyBtoA,
|
||||
contactShare,
|
||||
positionImpulse,
|
||||
contactCount = {},
|
||||
tempA = Vector._temp[0],
|
||||
tempB = Vector._temp[1],
|
||||
|
|
|
@ -13,7 +13,7 @@ var Body = require('../body/Body');
|
|||
|
||||
/**
|
||||
* The `Matter.Engine` module contains methods for creating and manipulating engines.
|
||||
* An engine is a controller that manages updating and rendering the simulation of the world.
|
||||
* An engine is a controller that manages updating the simulation of the world.
|
||||
* See `Matter.Runner` for an optional game loop utility.
|
||||
*
|
||||
* See [Demo.js](https://github.com/liabru/matter-js/blob/master/demo/js/Demo.js)
|
||||
|
@ -28,9 +28,6 @@ module.exports = Engine;
|
|||
|
||||
(function() {
|
||||
|
||||
var _fps = 60,
|
||||
_delta = 1000 / _fps;
|
||||
|
||||
/**
|
||||
* Creates a new engine. 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.
|
||||
|
@ -47,49 +44,55 @@ module.exports = Engine;
|
|||
element = Common.isElement(element) ? element : null;
|
||||
|
||||
var defaults = {
|
||||
enabled: true,
|
||||
positionIterations: 6,
|
||||
velocityIterations: 4,
|
||||
constraintIterations: 2,
|
||||
enableSleeping: false,
|
||||
events: [],
|
||||
timing: {
|
||||
fps: _fps,
|
||||
timestamp: 0,
|
||||
delta: _delta,
|
||||
correction: 1,
|
||||
deltaMin: 1000 / _fps,
|
||||
deltaMax: 1000 / (_fps * 0.5),
|
||||
timeScale: 1,
|
||||
isFixed: false,
|
||||
frameRequestId: 0
|
||||
},
|
||||
render: {
|
||||
element: element,
|
||||
controller: Render
|
||||
timeScale: 1
|
||||
},
|
||||
broadphase: {
|
||||
controller: Grid
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var engine = Common.extend(defaults, options);
|
||||
|
||||
engine.render = engine.render.controller.create(engine.render);
|
||||
if (element || engine.render) {
|
||||
var renderDefaults = {
|
||||
element: element,
|
||||
controller: Render
|
||||
};
|
||||
|
||||
engine.render = Common.extend(renderDefaults, engine.render);
|
||||
}
|
||||
|
||||
if (engine.render && engine.render.controller) {
|
||||
engine.render = engine.render.controller.create(engine.render);
|
||||
}
|
||||
|
||||
engine.world = World.create(engine.world);
|
||||
engine.pairs = Pairs.create();
|
||||
engine.broadphase = engine.broadphase.controller.create(engine.broadphase);
|
||||
engine.metrics = engine.metrics || { extended: false };
|
||||
|
||||
// @if DEBUG
|
||||
engine.metrics = engine.metrics || Metrics.create();
|
||||
engine.metrics = Metrics.create(engine.metrics);
|
||||
// @endif
|
||||
|
||||
return engine;
|
||||
};
|
||||
|
||||
/**
|
||||
* Moves the simulation forward in time by `delta` ms.
|
||||
* Moves the simulation forward in time by `delta` ms.
|
||||
* The `correction` argument is an optional `Number` that specifies the time correction factor to apply to the update.
|
||||
* This can help improve the accuracy of the simulation in cases where `delta` is changing between updates.
|
||||
* The value of `correction` is defined as `delta / lastDelta`, i.e. the percentage change of `delta` over the last step.
|
||||
* Therefore the value is always `1` (no correction) when `delta` constant (or when no correction is desired, which is the default).
|
||||
* See the paper on <a href="http://lonesock.net/article/verlet.html">Time Corrected Verlet</a> for more information.
|
||||
*
|
||||
* Triggers `beforeUpdate` and `afterUpdate` events.
|
||||
* Triggers `collisionStart`, `collisionActive` and `collisionEnd` events.
|
||||
* @method update
|
||||
|
@ -108,11 +111,10 @@ module.exports = Engine;
|
|||
|
||||
// increment timestamp
|
||||
timing.timestamp += delta * timing.timeScale;
|
||||
timing.correction = correction;
|
||||
|
||||
// create an event object
|
||||
var event = {
|
||||
timestamp: engine.timing.timestamp
|
||||
timestamp: timing.timestamp
|
||||
};
|
||||
|
||||
Events.trigger(engine, 'beforeUpdate', event);
|
||||
|
@ -211,22 +213,6 @@ module.exports = Engine;
|
|||
|
||||
return engine;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the world by calling its defined renderer `engine.render.controller`. Triggers `beforeRender` and `afterRender` events.
|
||||
* @method render
|
||||
* @param {engine} engine
|
||||
*/
|
||||
Engine.render = function(engine) {
|
||||
// create an event object
|
||||
var event = {
|
||||
timestamp: engine.timing.timestamp
|
||||
};
|
||||
|
||||
Events.trigger(engine, 'beforeRender', event);
|
||||
engine.render.controller.world(engine);
|
||||
Events.trigger(engine, 'afterRender', event);
|
||||
};
|
||||
|
||||
/**
|
||||
* Merges two engines by keeping the configuration of `engineA` but replacing the world with the one from `engineB`.
|
||||
|
@ -336,38 +322,12 @@ module.exports = Engine;
|
|||
* @param {engine} engine
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Events Documentation
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired at the start of a tick, before any updates to the engine or timing
|
||||
*
|
||||
* @event beforeTick
|
||||
* @param {} event An event object
|
||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||
* @param {} event.source The source object of the event
|
||||
* @param {} event.name The name of the event
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired after engine timing updated, but just before engine state updated
|
||||
*
|
||||
* @event tick
|
||||
* @param {} event An event object
|
||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||
* @param {} event.source The source object of the event
|
||||
* @param {} event.name The name of the event
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired just before an update
|
||||
*
|
||||
* @event beforeUpdate
|
||||
* @param {} event An event object
|
||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||
* @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
|
||||
*/
|
||||
|
@ -377,37 +337,7 @@ module.exports = Engine;
|
|||
*
|
||||
* @event afterUpdate
|
||||
* @param {} event An event object
|
||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||
* @param {} event.source The source object of the event
|
||||
* @param {} event.name The name of the event
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired just before rendering
|
||||
*
|
||||
* @event beforeRender
|
||||
* @param {} event An event object
|
||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||
* @param {} event.source The source object of the event
|
||||
* @param {} event.name The name of the event
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired after rendering
|
||||
*
|
||||
* @event afterRender
|
||||
* @param {} event An event object
|
||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||
* @param {} event.source The source object of the event
|
||||
* @param {} event.name The name of the event
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired after engine update and after rendering
|
||||
*
|
||||
* @event afterTick
|
||||
* @param {} event An event object
|
||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||
* @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
|
||||
*/
|
||||
|
@ -418,7 +348,7 @@ module.exports = Engine;
|
|||
* @event collisionStart
|
||||
* @param {} event An event object
|
||||
* @param {} event.pairs List of affected pairs
|
||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||
* @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
|
||||
*/
|
||||
|
@ -429,7 +359,7 @@ module.exports = Engine;
|
|||
* @event collisionActive
|
||||
* @param {} event An event object
|
||||
* @param {} event.pairs List of affected pairs
|
||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||
* @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
|
||||
*/
|
||||
|
@ -440,7 +370,7 @@ module.exports = Engine;
|
|||
* @event collisionEnd
|
||||
* @param {} event An event object
|
||||
* @param {} event.pairs List of affected pairs
|
||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||
* @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
|
||||
*/
|
||||
|
@ -451,14 +381,6 @@ module.exports = Engine;
|
|||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag that specifies whether the engine is running or not.
|
||||
*
|
||||
* @property enabled
|
||||
* @type boolean
|
||||
* @default true
|
||||
*/
|
||||
|
||||
/**
|
||||
* An integer `Number` that specifies the number of position iterations to perform each update.
|
||||
* The higher the value, the higher quality the simulation will be at the expense of performance.
|
||||
|
@ -516,46 +438,13 @@ module.exports = Engine;
|
|||
|
||||
/**
|
||||
* A `Number` that specifies the current simulation-time in milliseconds starting from `0`.
|
||||
* It is incremented on every `Engine.update` by the `timing.delta`.
|
||||
* It is incremented on every `Engine.update` by the given `delta` argument.
|
||||
*
|
||||
* @property timing.timestamp
|
||||
* @type number
|
||||
* @default 0
|
||||
*/
|
||||
|
||||
/**
|
||||
* A `Boolean` that specifies if the `Engine.run` game loop should use a fixed timestep (otherwise it is variable).
|
||||
* If timing is fixed, then the apparent simulation speed will change depending on the frame rate (but behaviour will be deterministic).
|
||||
* If the timing is variable, then the apparent simulation speed will be constant (approximately, but at the cost of determininism).
|
||||
*
|
||||
* @property timing.isFixed
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A `Number` that specifies the time step between updates in milliseconds.
|
||||
* If `engine.timing.isFixed` is set to `true`, then `delta` is fixed.
|
||||
* If it is `false`, then `delta` can dynamically change to maintain the correct apparent simulation speed.
|
||||
*
|
||||
* @property timing.delta
|
||||
* @type number
|
||||
* @default 1000 / 60
|
||||
*/
|
||||
|
||||
/**
|
||||
* A `Number` that specifies the time correction factor to apply to the current timestep.
|
||||
* It is automatically handled when using `Engine.run`, but is also only optional even if you use your own game loop.
|
||||
* The value is defined as `delta / lastDelta`, i.e. the percentage change of `delta` between steps.
|
||||
* This value is always `1` (no correction) when frame rate is constant or `engine.timing.isFixed` is `true`.
|
||||
* If the framerate and hence `delta` are changing, then correction should be applied to the current update to account for the change.
|
||||
* See the paper on <a href="http://lonesock.net/article/verlet.html">Time Corrected Verlet</a> for more information.
|
||||
*
|
||||
* @property timing.correction
|
||||
* @type number
|
||||
* @default 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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`.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @if DEBUG
|
||||
var Composite = require('../body/Composite');
|
||||
var Common = require('./Common');
|
||||
|
||||
/**
|
||||
* _Internal Class_, not generally used outside of the engine's internals.
|
||||
|
@ -18,8 +19,8 @@ module.exports = Metrics;
|
|||
* @private
|
||||
* @return {metrics} A new metrics
|
||||
*/
|
||||
Metrics.create = function() {
|
||||
return {
|
||||
Metrics.create = function(options) {
|
||||
var defaults = {
|
||||
extended: false,
|
||||
narrowDetections: 0,
|
||||
narrowphaseTests: 0,
|
||||
|
@ -35,6 +36,8 @@ module.exports = Metrics;
|
|||
bodies: 0,
|
||||
pairs: 0
|
||||
};
|
||||
|
||||
return Common.extend(defaults, false, options);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,9 @@ var Common = require('./Common');
|
|||
/**
|
||||
* The `Matter.Runner` module is an optional utility which provides a game loop,
|
||||
* that handles updating and rendering a `Matter.Engine` for you within a browser.
|
||||
* It is intended for demo and testing purposes, but may be adequate for simple games.
|
||||
* If you are using your own game loop instead, then you do not need the `Matter.Runner` module.
|
||||
* Instead just call `Engine.update(engine, delta)` in your own loop.
|
||||
* Note that the method `Engine.run` is an alias for `Runner.run`.
|
||||
*
|
||||
* See [Demo.js](https://github.com/liabru/matter-js/blob/master/demo/js/Demo.js)
|
||||
|
@ -19,114 +22,285 @@ module.exports = Runner;
|
|||
|
||||
(function() {
|
||||
|
||||
var _fps = 60,
|
||||
_deltaSampleSize = _fps,
|
||||
_delta = 1000 / _fps;
|
||||
if (typeof window === 'undefined') {
|
||||
// TODO: support Runner on non-browser environments.
|
||||
return;
|
||||
}
|
||||
|
||||
var _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
|
||||
|| window.mozRequestAnimationFrame || window.msRequestAnimationFrame
|
||||
|| function(callback){ window.setTimeout(function() { callback(Common.now()); }, _delta); };
|
||||
|| function(callback){ window.setTimeout(function() { callback(Common.now()); }, 1000 / 60); };
|
||||
|
||||
var _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
|
||||
|| window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
|
||||
|
||||
/**
|
||||
* Provides a basic game loop that handles updating the engine for you.
|
||||
* Calls `Engine.update` and `Engine.render` on the `requestAnimationFrame` event automatically.
|
||||
* Handles time correction and non-fixed dynamic timing (if enabled).
|
||||
* Triggers `beforeTick`, `tick` and `afterTick` events.
|
||||
* @method run
|
||||
* @param {engine} engine
|
||||
* Creates a new Runner. The options parameter is an object that specifies any properties you wish to override the defaults.
|
||||
* @method create
|
||||
* @param {} options
|
||||
*/
|
||||
Runner.run = function(engine) {
|
||||
var counterTimestamp = 0,
|
||||
frameCounter = 0,
|
||||
deltaHistory = [],
|
||||
timePrev,
|
||||
timeScalePrev = 1;
|
||||
Runner.create = function(options) {
|
||||
var defaults = {
|
||||
fps: 60,
|
||||
correction: 1,
|
||||
deltaSampleSize: 60,
|
||||
counterTimestamp: 0,
|
||||
frameCounter: 0,
|
||||
deltaHistory: [],
|
||||
timePrev: null,
|
||||
timeScalePrev: 1,
|
||||
frameRequestId: null,
|
||||
isFixed: false,
|
||||
enabled: true
|
||||
};
|
||||
|
||||
(function render(time){
|
||||
var timing = engine.timing,
|
||||
delta,
|
||||
correction = 1;
|
||||
var runner = Common.extend(defaults, options);
|
||||
|
||||
timing.frameRequestId = _requestAnimationFrame(render);
|
||||
runner.delta = runner.delta || 1000 / runner.fps;
|
||||
runner.deltaMin = runner.deltaMin || 1000 / runner.fps;
|
||||
runner.deltaMax = runner.deltaMax || 1000 / (runner.fps * 0.5);
|
||||
runner.fps = 1000 / runner.delta;
|
||||
|
||||
if (!engine.enabled)
|
||||
return;
|
||||
|
||||
// create an event object
|
||||
var event = {
|
||||
timestamp: time
|
||||
};
|
||||
|
||||
Events.trigger(engine, 'beforeTick', event);
|
||||
|
||||
if (timing.isFixed) {
|
||||
// fixed timestep
|
||||
delta = timing.delta;
|
||||
} else {
|
||||
// dynamic timestep based on wall clock between calls
|
||||
delta = (time - timePrev) || timing.delta;
|
||||
timePrev = time;
|
||||
|
||||
// optimistically filter delta over a few frames, to improve stability
|
||||
deltaHistory.push(delta);
|
||||
deltaHistory = deltaHistory.slice(-_deltaSampleSize);
|
||||
delta = Math.min.apply(null, deltaHistory);
|
||||
|
||||
// limit delta
|
||||
delta = delta < timing.deltaMin ? timing.deltaMin : delta;
|
||||
delta = delta > timing.deltaMax ? timing.deltaMax : delta;
|
||||
|
||||
// time correction for delta
|
||||
correction = delta / timing.delta;
|
||||
|
||||
// update engine timing object
|
||||
timing.delta = delta;
|
||||
}
|
||||
|
||||
// time correction for time scaling
|
||||
if (timeScalePrev !== 0)
|
||||
correction *= timing.timeScale / timeScalePrev;
|
||||
|
||||
if (timing.timeScale === 0)
|
||||
correction = 0;
|
||||
|
||||
timeScalePrev = timing.timeScale;
|
||||
|
||||
// fps counter
|
||||
frameCounter += 1;
|
||||
if (time - counterTimestamp >= 1000) {
|
||||
timing.fps = frameCounter * ((time - counterTimestamp) / 1000);
|
||||
counterTimestamp = time;
|
||||
frameCounter = 0;
|
||||
}
|
||||
|
||||
Events.trigger(engine, 'tick', event);
|
||||
|
||||
// if world has been modified, clear the render scene graph
|
||||
if (engine.world.isModified && engine.render.controller.clear)
|
||||
engine.render.controller.clear(engine.render);
|
||||
|
||||
// update
|
||||
Engine.update(engine, delta, correction);
|
||||
|
||||
// render
|
||||
Engine.render(engine);
|
||||
|
||||
Events.trigger(engine, 'afterTick', event);
|
||||
})();
|
||||
return runner;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ends execution of `Runner.run` on the given `engine`, by canceling the animation frame request event loop.
|
||||
* If you wish to only temporarily pause the engine, see `engine.enabled` instead.
|
||||
* @method stop
|
||||
* Continuously ticks a `Matter.Engine` by calling `Runner.tick` on the `requestAnimationFrame` event.
|
||||
* @method run
|
||||
* @param {engine} engine
|
||||
*/
|
||||
Runner.stop = function(engine) {
|
||||
_cancelAnimationFrame(engine.timing.frameRequestId);
|
||||
Runner.run = function(runner, engine) {
|
||||
// create runner if engine is first argument
|
||||
if (typeof runner.positionIterations !== 'undefined') {
|
||||
engine = runner;
|
||||
runner = Runner.create();
|
||||
}
|
||||
|
||||
(function render(time){
|
||||
runner.frameRequestId = _requestAnimationFrame(render);
|
||||
|
||||
if (time && runner.enabled) {
|
||||
Runner.tick(runner, engine, time);
|
||||
}
|
||||
})();
|
||||
|
||||
return runner;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param {engine} engine
|
||||
* @param {number} time
|
||||
*/
|
||||
Runner.tick = function(runner, engine, time) {
|
||||
var timing = engine.timing,
|
||||
correction = 1,
|
||||
delta;
|
||||
|
||||
// create an event object
|
||||
var event = {
|
||||
timestamp: timing.timestamp
|
||||
};
|
||||
|
||||
Events.trigger(runner, 'beforeTick', event);
|
||||
Events.trigger(engine, 'beforeTick', event); // @deprecated
|
||||
|
||||
if (runner.isFixed) {
|
||||
// fixed timestep
|
||||
delta = runner.delta;
|
||||
} else {
|
||||
// dynamic timestep based on wall clock between calls
|
||||
delta = (time - runner.timePrev) || runner.delta;
|
||||
runner.timePrev = time;
|
||||
|
||||
// optimistically filter delta over a few frames, to improve stability
|
||||
runner.deltaHistory.push(delta);
|
||||
runner.deltaHistory = runner.deltaHistory.slice(-runner.deltaSampleSize);
|
||||
delta = Math.min.apply(null, runner.deltaHistory);
|
||||
|
||||
// limit delta
|
||||
delta = delta < runner.deltaMin ? runner.deltaMin : delta;
|
||||
delta = delta > runner.deltaMax ? runner.deltaMax : delta;
|
||||
|
||||
// correction for delta
|
||||
correction = delta / runner.delta;
|
||||
|
||||
// update engine timing object
|
||||
runner.delta = delta;
|
||||
}
|
||||
|
||||
// time correction for time scaling
|
||||
if (runner.timeScalePrev !== 0)
|
||||
correction *= timing.timeScale / runner.timeScalePrev;
|
||||
|
||||
if (timing.timeScale === 0)
|
||||
correction = 0;
|
||||
|
||||
runner.timeScalePrev = timing.timeScale;
|
||||
runner.correction = correction;
|
||||
|
||||
// fps counter
|
||||
runner.frameCounter += 1;
|
||||
if (time - runner.counterTimestamp >= 1000) {
|
||||
runner.fps = runner.frameCounter * ((time - runner.counterTimestamp) / 1000);
|
||||
runner.counterTimestamp = time;
|
||||
runner.frameCounter = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// update
|
||||
Events.trigger(runner, 'beforeUpdate', event);
|
||||
Engine.update(engine, delta, correction);
|
||||
Events.trigger(runner, 'afterUpdate', event);
|
||||
|
||||
// render
|
||||
if (engine.render) {
|
||||
Events.trigger(runner, 'beforeRender', event);
|
||||
Events.trigger(engine, 'beforeRender', event); // @deprecated
|
||||
|
||||
engine.render.controller.world(engine);
|
||||
|
||||
Events.trigger(runner, 'afterRender', event);
|
||||
Events.trigger(engine, 'afterRender', event); // @deprecated
|
||||
}
|
||||
|
||||
Events.trigger(runner, 'afterTick', event);
|
||||
Events.trigger(engine, 'afterTick', event); // @deprecated
|
||||
};
|
||||
|
||||
/**
|
||||
* Ends execution of `Runner.run` on the given `runner`, by canceling the animation frame request event loop.
|
||||
* If you wish to only temporarily pause the engine, see `engine.enabled` instead.
|
||||
* @method stop
|
||||
* @param {runner} runner
|
||||
*/
|
||||
Runner.stop = function(runner) {
|
||||
_cancelAnimationFrame(runner.frameRequestId);
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* Events Documentation
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired at the start of a tick, before any updates to the engine or timing
|
||||
*
|
||||
* @event beforeTick
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired after engine timing updated, but just before update
|
||||
*
|
||||
* @event tick
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired at the end of a tick, after engine update and after rendering
|
||||
*
|
||||
* @event afterTick
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired before update
|
||||
*
|
||||
* @event beforeUpdate
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired after update
|
||||
*
|
||||
* @event afterUpdate
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Properties Documentation
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* A flag that specifies whether the runner is running or not.
|
||||
*
|
||||
* @property enabled
|
||||
* @type boolean
|
||||
* @default true
|
||||
*/
|
||||
|
||||
/**
|
||||
* A `Boolean` that specifies if the runner should use a fixed timestep (otherwise it is variable).
|
||||
* If timing is fixed, then the apparent simulation speed will change depending on the frame rate (but behaviour will be deterministic).
|
||||
* If the timing is variable, then the apparent simulation speed will be constant (approximately, but at the cost of determininism).
|
||||
*
|
||||
* @property isFixed
|
||||
* @type boolean
|
||||
* @default false
|
||||
*/
|
||||
|
||||
/**
|
||||
* A `Number` that specifies the time step between updates in milliseconds.
|
||||
* If `engine.timing.isFixed` is set to `true`, then `delta` is fixed.
|
||||
* If it is `false`, then `delta` can dynamically change to maintain the correct apparent simulation speed.
|
||||
*
|
||||
* @property delta
|
||||
* @type number
|
||||
* @default 1000 / 60
|
||||
*/
|
||||
|
||||
})();
|
||||
|
|
|
@ -30,7 +30,7 @@ module.exports = Svg;
|
|||
var i, il, total, point, segment, segments,
|
||||
segmentsQueue, lastSegment,
|
||||
lastPoint, segmentIndex, points = [],
|
||||
length = 0, x = 0, y = 0;
|
||||
lx, ly, length = 0, x = 0, y = 0;
|
||||
|
||||
sampleLength = sampleLength || 15;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
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');
|
||||
|
||||
/**
|
||||
|
@ -134,6 +135,12 @@ module.exports = Render;
|
|||
constraints = [],
|
||||
i;
|
||||
|
||||
var event = {
|
||||
timestamp: engine.timing.timestamp
|
||||
};
|
||||
|
||||
Events.trigger(render, 'beforeRender', event);
|
||||
|
||||
// apply background if it has changed
|
||||
if (render.currentBackground !== background)
|
||||
_applyBackground(render, background);
|
||||
|
@ -231,6 +238,8 @@ module.exports = Render;
|
|||
// revert view transforms
|
||||
context.setTransform(options.pixelRatio, 0, 0, options.pixelRatio, 0, 0);
|
||||
}
|
||||
|
||||
Events.trigger(render, 'afterRender', event);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -394,7 +403,8 @@ module.exports = Render;
|
|||
options = render.options,
|
||||
body,
|
||||
part,
|
||||
i;
|
||||
i,
|
||||
k;
|
||||
|
||||
for (i = 0; i < bodies.length; i++) {
|
||||
body = bodies[i];
|
||||
|
@ -691,7 +701,8 @@ module.exports = Render;
|
|||
options = render.options,
|
||||
body,
|
||||
part,
|
||||
i;
|
||||
i,
|
||||
k;
|
||||
|
||||
c.beginPath();
|
||||
|
||||
|
@ -1027,7 +1038,7 @@ module.exports = Render;
|
|||
|
||||
}
|
||||
|
||||
context.setLineDash([0]);
|
||||
context.setLineDash([]);
|
||||
context.translate(-0.5, -0.5);
|
||||
}
|
||||
|
||||
|
@ -1123,6 +1134,32 @@ module.exports = Render;
|
|||
render.currentBackground = background;
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* Events Documentation
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Properties Documentation
|
||||
|
|
192
test/browser/TestDemo.js
Normal file
192
test/browser/TestDemo.js
Normal file
|
@ -0,0 +1,192 @@
|
|||
var page = require('webpage').create();
|
||||
var fs = require('fs');
|
||||
var Resurrect = require('./lib/resurrect');
|
||||
var compare = require('fast-json-patch').compare;
|
||||
var system = require('system');
|
||||
|
||||
var demo,
|
||||
frames = 10,
|
||||
testUrl = 'http://localhost:8000/demo/dev.html',
|
||||
refsPath = 'test/browser/refs',
|
||||
diffsPath = 'test/browser/diffs';
|
||||
|
||||
var update = arg('--update'),
|
||||
updateAll = typeof arg('--updateAll') !== 'undefined',
|
||||
diff = arg('--diff');
|
||||
|
||||
var resurrect = new Resurrect({ cleanup: true, revive: false }),
|
||||
created = [],
|
||||
changed = [];
|
||||
|
||||
var test = function(status) {
|
||||
if (status === 'fail') {
|
||||
console.log('failed to load', testUrl);
|
||||
console.log('check dev server is running!');
|
||||
console.log('use `grunt dev`');
|
||||
phantom.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
var demos = page.evaluate(function() {
|
||||
var demoSelect = document.getElementById('demo-select'),
|
||||
options = Array.prototype.slice.call(demoSelect);
|
||||
return options.map(function(o) { return o.value; });
|
||||
});
|
||||
|
||||
fs.removeTree(diffsPath);
|
||||
|
||||
if (diff) {
|
||||
fs.makeDirectory(diffsPath);
|
||||
}
|
||||
|
||||
for (var i = 0; i < demos.length; i += 1) {
|
||||
demo = demos[i];
|
||||
|
||||
var hasChanged = false,
|
||||
hasCreated = false,
|
||||
forceUpdate = update === demo || updateAll,
|
||||
worldStartPath = refsPath + '/' + demo + '/' + demo + '-0.json',
|
||||
worldEndPath = refsPath + '/' + demo + '/' + demo + '-' + frames + '.json',
|
||||
worldStartDiffPath = diffsPath + '/' + demo + '/' + demo + '-0.json',
|
||||
worldEndDiffPath = diffsPath + '/' + demo + '/' + demo + '-' + frames + '.json';
|
||||
|
||||
var worldStart = page.evaluate(function(demo) {
|
||||
var engine = Matter.Demo._engine;
|
||||
if (!(demo in Matter.Demo)) {
|
||||
throw '\'' + demo + '\' is not defined in Matter.Demo';
|
||||
}
|
||||
Matter.Demo[demo]();
|
||||
return engine.world;
|
||||
}, demo);
|
||||
|
||||
var worldEnd = page.evaluate(function(demo, frames) {
|
||||
var engine = Matter.Demo._engine,
|
||||
runner = Matter.Runner.create();
|
||||
|
||||
for (var j = 0; j <= frames; j += 1) {
|
||||
Matter.Runner.tick(runner, engine, j * runner.delta);
|
||||
}
|
||||
|
||||
return engine.world;
|
||||
}, demo, frames);
|
||||
|
||||
worldEnd = resurrect.resurrect(resurrect.stringify(worldEnd, precisionLimiter));
|
||||
worldStart = resurrect.resurrect(resurrect.stringify(worldStart, precisionLimiter));
|
||||
|
||||
if (fs.exists(worldStartPath)) {
|
||||
var worldStartRef = resurrect.resurrect(fs.read(worldStartPath));
|
||||
var worldStartDiff = compare(worldStartRef, worldStart);
|
||||
|
||||
if (worldStartDiff.length !== 0) {
|
||||
if (diff) {
|
||||
fs.write(worldStartDiffPath, JSON.stringify(worldStartDiff, precisionLimiter, 2), 'w');
|
||||
}
|
||||
|
||||
if (forceUpdate) {
|
||||
hasCreated = true;
|
||||
fs.write(worldStartPath, resurrect.stringify(worldStart, precisionLimiter, 2), 'w');
|
||||
} else {
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hasCreated = true;
|
||||
fs.write(worldStartPath, resurrect.stringify(worldStart, precisionLimiter, 2), 'w');
|
||||
}
|
||||
|
||||
if (fs.exists(worldEndPath)) {
|
||||
var worldEndRef = resurrect.resurrect(fs.read(worldEndPath));
|
||||
var worldEndDiff = compare(worldEndRef, worldEnd);
|
||||
|
||||
if (worldEndDiff.length !== 0) {
|
||||
if (diff) {
|
||||
fs.write(worldEndDiffPath, JSON.stringify(worldEndDiff, precisionLimiter, 2), 'w');
|
||||
}
|
||||
|
||||
if (forceUpdate) {
|
||||
hasCreated = true;
|
||||
fs.write(worldEndPath, resurrect.stringify(worldEnd, precisionLimiter, 2), 'w');
|
||||
} else {
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hasCreated = true;
|
||||
fs.write(worldEndPath, resurrect.stringify(worldEnd, precisionLimiter, 2), 'w');
|
||||
}
|
||||
|
||||
if (hasChanged) {
|
||||
changed.push("'" + demo + "'");
|
||||
system.stdout.write('x');
|
||||
} else if (hasCreated) {
|
||||
created.push("'" + demo + "'");
|
||||
system.stdout.write('+');
|
||||
} else {
|
||||
system.stdout.write('.');
|
||||
}
|
||||
}
|
||||
|
||||
if (created.length > 0) {
|
||||
console.log('\nupdated', created.join(', '));
|
||||
}
|
||||
|
||||
var isOk = changed.length === 0 ? 1 : 0;
|
||||
|
||||
console.log('');
|
||||
|
||||
if (isOk) {
|
||||
console.log('ok');
|
||||
} else {
|
||||
console.log('\nchanges detected on:');
|
||||
console.log(changed.join(', '));
|
||||
console.log('\nreview, then --update [name] or --updateAll');
|
||||
console.log('use --diff for diff log');
|
||||
}
|
||||
|
||||
phantom.exit(!isOk);
|
||||
};
|
||||
|
||||
var precisionLimiter = function(key, value) {
|
||||
if (typeof value === 'number') {
|
||||
return parseFloat(value.toFixed(5));
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
function arg(name) {
|
||||
var index = system.args.indexOf(name);
|
||||
if (index >= 0) {
|
||||
return system.args[index + 1] || true;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
page.onError = function(msg, trace) {
|
||||
setTimeout(function() {
|
||||
var msgStack = ['testing \'' + demo + '\'', msg];
|
||||
|
||||
if (trace && trace.length) {
|
||||
trace.forEach(function(t) {
|
||||
msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (fn: ' + t.function +')' : ''));
|
||||
});
|
||||
}
|
||||
|
||||
console.log(msgStack.join('\n'));
|
||||
phantom.exit(1);
|
||||
}, 0);
|
||||
};
|
||||
|
||||
|
||||
page.onResourceReceived = function(res) {
|
||||
setTimeout(function() {
|
||||
if (res.stage === 'end'
|
||||
&& (res.status !== 304 && res.status !== 200 && res.status !== null)) {
|
||||
console.log('error', res.status, res.url);
|
||||
phantom.exit(1);
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
phantom.onError = page.onError;
|
||||
|
||||
page.open(testUrl, test);
|
542
test/browser/lib/resurrect.js
Normal file
542
test/browser/lib/resurrect.js
Normal file
|
@ -0,0 +1,542 @@
|
|||
/**
|
||||
* # ResurrectJS
|
||||
* @version 1.0.3
|
||||
* @license Public Domain
|
||||
*
|
||||
* ResurrectJS preserves object behavior (prototypes) and reference
|
||||
* circularity with a special JSON encoding. Unlike regular JSON,
|
||||
* Date, RegExp, DOM objects, and `undefined` are also properly
|
||||
* preserved.
|
||||
*
|
||||
* ## Examples
|
||||
*
|
||||
* function Foo() {}
|
||||
* Foo.prototype.greet = function() { return "hello"; };
|
||||
*
|
||||
* // Behavior is preserved:
|
||||
* var necromancer = new Resurrect();
|
||||
* var json = necromancer.stringify(new Foo());
|
||||
* var foo = necromancer.resurrect(json);
|
||||
* foo.greet(); // => "hello"
|
||||
*
|
||||
* // References to the same object are preserved:
|
||||
* json = necromancer.stringify([foo, foo]);
|
||||
* var array = necromancer.resurrect(json);
|
||||
* array[0] === array[1]; // => true
|
||||
* array[1].greet(); // => "hello"
|
||||
*
|
||||
* // Dates are restored properly
|
||||
* json = necromancer.stringify(new Date());
|
||||
* var date = necromancer.resurrect(json);
|
||||
* Object.prototype.toString.call(date); // => "[object Date]"
|
||||
*
|
||||
* ## Options
|
||||
*
|
||||
* Options are provided to the constructor as an object with these
|
||||
* properties:
|
||||
*
|
||||
* prefix ('#'): A prefix string used for temporary properties added
|
||||
* to objects during serialization and deserialization. It is
|
||||
* important that you don't use any properties beginning with this
|
||||
* string. This option must be consistent between both
|
||||
* serialization and deserialization.
|
||||
*
|
||||
* cleanup (false): Perform full property cleanup after both
|
||||
* serialization and deserialization using the `delete`
|
||||
* operator. This may cause performance penalties (breaking hidden
|
||||
* classes in V8) on objects that ResurrectJS touches, so enable
|
||||
* with care.
|
||||
*
|
||||
* revive (true): Restore behavior (__proto__) to objects that have
|
||||
* been resurrected. If this is set to false during serialization,
|
||||
* resurrection information will not be encoded. You still get
|
||||
* circularity and Date support.
|
||||
*
|
||||
* resolver (Resurrect.NamespaceResolver(window)): Converts between
|
||||
* a name and a prototype. Create a custom resolver if your
|
||||
* constructors are not stored in global variables. The resolver
|
||||
* has two methods: getName(object) and getPrototype(string).
|
||||
*
|
||||
* For example,
|
||||
*
|
||||
* var necromancer = new Resurrect({
|
||||
* prefix: '__#',
|
||||
* cleanup: true
|
||||
* });
|
||||
*
|
||||
* ## Caveats
|
||||
*
|
||||
* * With the default resolver, all constructors must be named and
|
||||
* stored in the global variable under that name. This is required
|
||||
* so that the prototypes can be looked up and reconnected at
|
||||
* resurrection time.
|
||||
*
|
||||
* * The wrapper objects Boolean, String, and Number will be
|
||||
* unwrapped. This means extra properties added to these objects
|
||||
* will not be preserved.
|
||||
*
|
||||
* * Functions cannot ever be serialized. Resurrect will throw an
|
||||
* error if a function is found when traversing a data structure.
|
||||
*
|
||||
* @see http://nullprogram.com/blog/2013/03/28/
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Object} [options] See options documentation.
|
||||
* @namespace
|
||||
* @constructor
|
||||
*/
|
||||
function Resurrect(options) {
|
||||
this.table = null;
|
||||
this.prefix = '#';
|
||||
this.cleanup = false;
|
||||
this.revive = true;
|
||||
for (var option in options) {
|
||||
if (options.hasOwnProperty(option)) {
|
||||
this[option] = options[option];
|
||||
}
|
||||
}
|
||||
this.refcode = this.prefix + 'id';
|
||||
this.origcode = this.prefix + 'original';
|
||||
this.buildcode = this.prefix + '.';
|
||||
this.valuecode = this.prefix + 'v';
|
||||
}
|
||||
|
||||
if (module)
|
||||
module.exports = Resurrect;
|
||||
|
||||
/**
|
||||
* Portable access to the global object (window, global).
|
||||
* Uses indirect eval.
|
||||
* @constant
|
||||
*/
|
||||
Resurrect.GLOBAL = (0, eval)('this');
|
||||
|
||||
/**
|
||||
* Escape special regular expression characters in a string.
|
||||
* @param {string} string
|
||||
* @returns {string} The string escaped for exact matches.
|
||||
* @see http://stackoverflow.com/a/6969486
|
||||
*/
|
||||
Resurrect.escapeRegExp = function (string) {
|
||||
return string.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||
};
|
||||
|
||||
/* Helper Objects */
|
||||
|
||||
/**
|
||||
* @param {string} [message]
|
||||
* @constructor
|
||||
*/
|
||||
Resurrect.prototype.Error = function ResurrectError(message) {
|
||||
this.message = message || '';
|
||||
this.stack = new Error().stack;
|
||||
};
|
||||
Resurrect.prototype.Error.prototype = Object.create(Error.prototype);
|
||||
Resurrect.prototype.Error.prototype.name = 'ResurrectError';
|
||||
|
||||
/**
|
||||
* Resolves prototypes through the properties on an object and
|
||||
* constructor names.
|
||||
* @param {Object} scope
|
||||
* @constructor
|
||||
*/
|
||||
Resurrect.NamespaceResolver = function(scope) {
|
||||
this.scope = scope;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the prototype of the given property name from an object. If
|
||||
* not found, it throws an error.
|
||||
* @param {string} name
|
||||
* @returns {Object}
|
||||
* @method
|
||||
*/
|
||||
Resurrect.NamespaceResolver.prototype.getPrototype = function(name) {
|
||||
var constructor = this.scope[name];
|
||||
if (constructor) {
|
||||
return constructor.prototype;
|
||||
} else {
|
||||
throw new Resurrect.prototype.Error('Unknown constructor: ' + name);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the prototype name for an object, to be fetched later with getPrototype.
|
||||
* @param {Object} object
|
||||
* @returns {?string} Null if the constructor is Object.
|
||||
* @method
|
||||
*/
|
||||
Resurrect.NamespaceResolver.prototype.getName = function(object) {
|
||||
var constructor = object.constructor.name;
|
||||
if (constructor == null) { // IE
|
||||
var funcPattern = /^\s*function\s*([A-Za-z0-9_$]*)/;
|
||||
constructor = funcPattern.exec(object.constructor)[1];
|
||||
}
|
||||
|
||||
if (constructor === '') {
|
||||
var msg = "Can't serialize objects with anonymous constructors.";
|
||||
throw new Resurrect.prototype.Error(msg);
|
||||
} else if (constructor === 'Object' || constructor === 'Array') {
|
||||
return null;
|
||||
} else {
|
||||
return constructor;
|
||||
}
|
||||
};
|
||||
|
||||
/* Set the default resolver searches the global object. */
|
||||
Resurrect.prototype.resolver =
|
||||
new Resurrect.NamespaceResolver(Resurrect.GLOBAL);
|
||||
|
||||
/**
|
||||
* Create a DOM node from HTML source; behaves like a constructor.
|
||||
* @param {string} html
|
||||
* @constructor
|
||||
*/
|
||||
Resurrect.Node = function(html) {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = html;
|
||||
return div.firstChild;
|
||||
};
|
||||
|
||||
/* Type Tests */
|
||||
|
||||
/**
|
||||
* @param {string} type
|
||||
* @returns {Function} A function that tests for type.
|
||||
*/
|
||||
Resurrect.is = function(type) {
|
||||
var string = '[object ' + type + ']';
|
||||
return function(object) {
|
||||
return Object.prototype.toString.call(object) === string;
|
||||
};
|
||||
};
|
||||
|
||||
Resurrect.isArray = Resurrect.is('Array');
|
||||
Resurrect.isString = Resurrect.is('String');
|
||||
Resurrect.isBoolean = Resurrect.is('Boolean');
|
||||
Resurrect.isNumber = Resurrect.is('Number');
|
||||
Resurrect.isFunction = Resurrect.is('Function');
|
||||
Resurrect.isDate = Resurrect.is('Date');
|
||||
Resurrect.isRegExp = Resurrect.is('RegExp');
|
||||
Resurrect.isObject = Resurrect.is('Object');
|
||||
|
||||
Resurrect.isAtom = function(object) {
|
||||
return !Resurrect.isObject(object) && !Resurrect.isArray(object);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {*} object
|
||||
* @returns {boolean} True if object is a primitive or a primitive wrapper.
|
||||
*/
|
||||
Resurrect.isPrimitive = function(object) {
|
||||
return object == null ||
|
||||
Resurrect.isNumber(object) ||
|
||||
Resurrect.isString(object) ||
|
||||
Resurrect.isBoolean(object);
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Create a reference (encoding) to an object.
|
||||
* @param {(Object|undefined)} object
|
||||
* @returns {Object}
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.ref = function(object) {
|
||||
var ref = {};
|
||||
if (object === undefined) {
|
||||
ref[this.prefix] = -1;
|
||||
} else {
|
||||
ref[this.prefix] = object[this.refcode];
|
||||
}
|
||||
return ref;
|
||||
};
|
||||
|
||||
/**
|
||||
* Lookup an object in the table by reference object.
|
||||
* @param {Object} ref
|
||||
* @returns {(Object|undefined)}
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.deref = function(ref) {
|
||||
return this.table[ref[this.prefix]];
|
||||
};
|
||||
|
||||
/**
|
||||
* Put a temporary identifier on an object and store it in the table.
|
||||
* @param {Object} object
|
||||
* @returns {number} The unique identifier number.
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.tag = function(object) {
|
||||
if (this.revive) {
|
||||
var constructor = this.resolver.getName(object);
|
||||
if (constructor) {
|
||||
var proto = Object.getPrototypeOf(object);
|
||||
if (this.resolver.getPrototype(constructor) !== proto) {
|
||||
throw new this.Error('Constructor mismatch!');
|
||||
} else {
|
||||
object[this.prefix] = constructor;
|
||||
}
|
||||
}
|
||||
}
|
||||
object[this.refcode] = this.table.length;
|
||||
this.table.push(object);
|
||||
return object[this.refcode];
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a builder object (encoding) for serialization.
|
||||
* @param {string} name The name of the constructor.
|
||||
* @param value The value to pass to the constructor.
|
||||
* @returns {Object}
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.builder = function(name, value) {
|
||||
var builder = {};
|
||||
builder[this.buildcode] = name;
|
||||
builder[this.valuecode] = value;
|
||||
return builder;
|
||||
};
|
||||
|
||||
/**
|
||||
* Build a value from a deserialized builder.
|
||||
* @param {Object} ref
|
||||
* @returns {Object}
|
||||
* @method
|
||||
* @see http://stackoverflow.com/a/14378462
|
||||
* @see http://nullprogram.com/blog/2013/03/24/
|
||||
*/
|
||||
Resurrect.prototype.build = function(ref) {
|
||||
var type = ref[this.buildcode].split(/\./).reduce(function(object, name) {
|
||||
return object[name];
|
||||
}, Resurrect.GLOBAL);
|
||||
/* Brilliant hack by kybernetikos: */
|
||||
var args = [null].concat(ref[this.valuecode]);
|
||||
var factory = type.bind.apply(type, args);
|
||||
var result = new factory();
|
||||
if (Resurrect.isPrimitive(result)) {
|
||||
return result.valueOf(); // unwrap
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dereference or build an object or value from an encoding.
|
||||
* @param {Object} ref
|
||||
* @returns {(Object|undefined)}
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.decode = function(ref) {
|
||||
if (this.prefix in ref) {
|
||||
return this.deref(ref);
|
||||
} else if (this.buildcode in ref) {
|
||||
return this.build(ref);
|
||||
} else {
|
||||
throw new this.Error('Unknown encoding.');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Object} object
|
||||
* @returns {boolean} True if the provided object is tagged for serialization.
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.isTagged = function(object) {
|
||||
return (this.refcode in object) && (object[this.refcode] != null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Visit root and all its ancestors, visiting atoms with f.
|
||||
* @param {*} root
|
||||
* @param {Function} f
|
||||
* @param {Function} replacer
|
||||
* @returns {*} A fresh copy of root to be serialized.
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.visit = function(root, f, replacer) {
|
||||
if (Resurrect.isAtom(root)) {
|
||||
return f(root);
|
||||
} else if (!this.isTagged(root)) {
|
||||
var copy = null;
|
||||
if (Resurrect.isArray(root)) {
|
||||
copy = [];
|
||||
root[this.refcode] = this.tag(copy);
|
||||
for (var i = 0; i < root.length; i++) {
|
||||
copy.push(this.visit(root[i], f, replacer));
|
||||
}
|
||||
} else { /* Object */
|
||||
copy = Object.create(Object.getPrototypeOf(root));
|
||||
root[this.refcode] = this.tag(copy);
|
||||
for (var key in root) {
|
||||
var value = root[key];
|
||||
if (root.hasOwnProperty(key)) {
|
||||
if (replacer && value !== undefined) {
|
||||
// Call replacer like JSON.stringify's replacer
|
||||
value = replacer.call(root, key, root[key]);
|
||||
if (value === undefined) {
|
||||
continue; // Omit from result
|
||||
}
|
||||
}
|
||||
copy[key] = this.visit(value, f, replacer);
|
||||
}
|
||||
}
|
||||
}
|
||||
copy[this.origcode] = root;
|
||||
return this.ref(copy);
|
||||
} else {
|
||||
return this.ref(root);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Manage special atom values, possibly returning an encoding.
|
||||
* @param {*} atom
|
||||
* @returns {*}
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.handleAtom = function(atom) {
|
||||
var Node = Resurrect.GLOBAL.Node || function() {};
|
||||
if (Resurrect.isFunction(atom)) {
|
||||
throw new this.Error("Can't serialize functions.");
|
||||
} else if (atom instanceof Node) {
|
||||
var xmls = new XMLSerializer();
|
||||
return this.builder('Resurrect.Node', [xmls.serializeToString(atom)]);
|
||||
} else if (Resurrect.isDate(atom)) {
|
||||
return this.builder('Date', [atom.toISOString()]);
|
||||
} else if (Resurrect.isRegExp(atom)) {
|
||||
var args = atom.toString().match(/\/(.+)\/([gimy]*)/).slice(1);
|
||||
return this.builder('RegExp', args);
|
||||
} else if (atom === undefined) {
|
||||
return this.ref(undefined);
|
||||
} else if (Resurrect.isNumber(atom) && (isNaN(atom) || !isFinite(atom))) {
|
||||
return this.builder('Number', [atom.toString()]);
|
||||
} else {
|
||||
return atom;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides intrusive keys from a user-supplied replacer.
|
||||
* @param {Function} replacer function of two arguments (key, value)
|
||||
* @returns {Function} A function that skips the replacer for intrusive keys.
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.replacerWrapper = function(replacer) {
|
||||
var skip = new RegExp('^' + Resurrect.escapeRegExp(this.prefix));
|
||||
return function(k, v) {
|
||||
if (skip.test(k)) {
|
||||
return v;
|
||||
} else {
|
||||
return replacer(k, v);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize an arbitrary JavaScript object, carefully preserving it.
|
||||
* @param {*} object
|
||||
* @param {(Function|Array)} replacer
|
||||
* @param {string} space
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.stringify = function(object, replacer, space) {
|
||||
if (Resurrect.isFunction(replacer)) {
|
||||
replacer = this.replacerWrapper(replacer);
|
||||
} else if (Resurrect.isArray(replacer)) {
|
||||
var acceptKeys = replacer;
|
||||
replacer = function(k, v) {
|
||||
return acceptKeys.indexOf(k) >= 0 ? v : undefined;
|
||||
};
|
||||
}
|
||||
if (Resurrect.isAtom(object)) {
|
||||
return JSON.stringify(this.handleAtom(object), replacer, space);
|
||||
} else {
|
||||
this.table = [];
|
||||
this.visit(object, this.handleAtom.bind(this), replacer);
|
||||
for (var i = 0; i < this.table.length; i++) {
|
||||
if (this.cleanup) {
|
||||
delete this.table[i][this.origcode][this.refcode];
|
||||
} else {
|
||||
this.table[i][this.origcode][this.refcode] = null;
|
||||
}
|
||||
delete this.table[i][this.refcode];
|
||||
delete this.table[i][this.origcode];
|
||||
}
|
||||
var table = this.table;
|
||||
this.table = null;
|
||||
return JSON.stringify(table, null, space);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Restore the __proto__ of the given object to the proper value.
|
||||
* @param {Object} object
|
||||
* @returns {Object} Its argument, or a copy, with the prototype restored.
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.fixPrototype = function(object) {
|
||||
if (this.prefix in object) {
|
||||
var name = object[this.prefix];
|
||||
var prototype = this.resolver.getPrototype(name);
|
||||
if ('__proto__' in object) {
|
||||
object.__proto__ = prototype;
|
||||
if (this.cleanup) {
|
||||
delete object[this.prefix];
|
||||
}
|
||||
return object;
|
||||
} else { // IE
|
||||
var copy = Object.create(prototype);
|
||||
for (var key in object) {
|
||||
if (object.hasOwnProperty(key) && key !== this.prefix) {
|
||||
copy[key] = object[key];
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
} else {
|
||||
return object;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deserialize an encoded object, restoring circularity and behavior.
|
||||
* @param {string} string
|
||||
* @returns {*} The decoded object or value.
|
||||
* @method
|
||||
*/
|
||||
Resurrect.prototype.resurrect = function(string) {
|
||||
var result = null;
|
||||
var data = JSON.parse(string);
|
||||
if (Resurrect.isArray(data)) {
|
||||
this.table = data;
|
||||
/* Restore __proto__. */
|
||||
if (this.revive) {
|
||||
for (var i = 0; i < this.table.length; i++) {
|
||||
this.table[i] = this.fixPrototype(this.table[i]);
|
||||
}
|
||||
}
|
||||
/* Re-establish object references and construct atoms. */
|
||||
for (i = 0; i < this.table.length; i++) {
|
||||
var object = this.table[i];
|
||||
for (var key in object) {
|
||||
if (object.hasOwnProperty(key)) {
|
||||
if (!(Resurrect.isAtom(object[key]))) {
|
||||
object[key] = this.decode(object[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = this.table[0];
|
||||
} else if (Resurrect.isObject(data)) {
|
||||
this.table = [];
|
||||
result = this.decode(data);
|
||||
} else {
|
||||
result = data;
|
||||
}
|
||||
this.table = null;
|
||||
return result;
|
||||
};
|
1427
test/browser/refs/airFriction/airFriction-0.json
Normal file
1427
test/browser/refs/airFriction/airFriction-0.json
Normal file
File diff suppressed because it is too large
Load diff
1497
test/browser/refs/airFriction/airFriction-10.json
Normal file
1497
test/browser/refs/airFriction/airFriction-10.json
Normal file
File diff suppressed because it is too large
Load diff
36249
test/browser/refs/avalanche/avalanche-0.json
Normal file
36249
test/browser/refs/avalanche/avalanche-0.json
Normal file
File diff suppressed because it is too large
Load diff
37319
test/browser/refs/avalanche/avalanche-10.json
Normal file
37319
test/browser/refs/avalanche/avalanche-10.json
Normal file
File diff suppressed because it is too large
Load diff
66852
test/browser/refs/ballPool/ballPool-0.json
Normal file
66852
test/browser/refs/ballPool/ballPool-0.json
Normal file
File diff suppressed because it is too large
Load diff
68422
test/browser/refs/ballPool/ballPool-10.json
Normal file
68422
test/browser/refs/ballPool/ballPool-10.json
Normal file
File diff suppressed because it is too large
Load diff
3307
test/browser/refs/beachBalls/beachBalls-0.json
Normal file
3307
test/browser/refs/beachBalls/beachBalls-0.json
Normal file
File diff suppressed because it is too large
Load diff
3397
test/browser/refs/beachBalls/beachBalls-10.json
Normal file
3397
test/browser/refs/beachBalls/beachBalls-10.json
Normal file
File diff suppressed because it is too large
Load diff
8066
test/browser/refs/bridge/bridge-0.json
Normal file
8066
test/browser/refs/bridge/bridge-0.json
Normal file
File diff suppressed because it is too large
Load diff
8396
test/browser/refs/bridge/bridge-10.json
Normal file
8396
test/browser/refs/bridge/bridge-10.json
Normal file
File diff suppressed because it is too large
Load diff
22924
test/browser/refs/broadphase/broadphase-0.json
Normal file
22924
test/browser/refs/broadphase/broadphase-0.json
Normal file
File diff suppressed because it is too large
Load diff
23964
test/browser/refs/broadphase/broadphase-10.json
Normal file
23964
test/browser/refs/broadphase/broadphase-10.json
Normal file
File diff suppressed because it is too large
Load diff
4332
test/browser/refs/car/car-0.json
Normal file
4332
test/browser/refs/car/car-0.json
Normal file
File diff suppressed because it is too large
Load diff
4462
test/browser/refs/car/car-10.json
Normal file
4462
test/browser/refs/car/car-10.json
Normal file
File diff suppressed because it is too large
Load diff
2923
test/browser/refs/catapult/catapult-0.json
Normal file
2923
test/browser/refs/catapult/catapult-0.json
Normal file
File diff suppressed because it is too large
Load diff
3053
test/browser/refs/catapult/catapult-10.json
Normal file
3053
test/browser/refs/catapult/catapult-10.json
Normal file
File diff suppressed because it is too large
Load diff
7493
test/browser/refs/chains/chains-0.json
Normal file
7493
test/browser/refs/chains/chains-0.json
Normal file
File diff suppressed because it is too large
Load diff
7733
test/browser/refs/chains/chains-10.json
Normal file
7733
test/browser/refs/chains/chains-10.json
Normal file
File diff suppressed because it is too large
Load diff
40902
test/browser/refs/circleStack/circleStack-0.json
Normal file
40902
test/browser/refs/circleStack/circleStack-0.json
Normal file
File diff suppressed because it is too large
Load diff
41942
test/browser/refs/circleStack/circleStack-10.json
Normal file
41942
test/browser/refs/circleStack/circleStack-10.json
Normal file
File diff suppressed because it is too large
Load diff
82964
test/browser/refs/cloth/cloth-0.json
Normal file
82964
test/browser/refs/cloth/cloth-0.json
Normal file
File diff suppressed because it is too large
Load diff
85424
test/browser/refs/cloth/cloth-10.json
Normal file
85424
test/browser/refs/cloth/cloth-10.json
Normal file
File diff suppressed because it is too large
Load diff
22345
test/browser/refs/collisionFiltering/collisionFiltering-0.json
Normal file
22345
test/browser/refs/collisionFiltering/collisionFiltering-0.json
Normal file
File diff suppressed because it is too large
Load diff
22915
test/browser/refs/collisionFiltering/collisionFiltering-10.json
Normal file
22915
test/browser/refs/collisionFiltering/collisionFiltering-10.json
Normal file
File diff suppressed because it is too large
Load diff
3821
test/browser/refs/compositeManipulation/compositeManipulation-0.json
Normal file
3821
test/browser/refs/compositeManipulation/compositeManipulation-0.json
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1668
test/browser/refs/compound/compound-0.json
Normal file
1668
test/browser/refs/compound/compound-0.json
Normal file
File diff suppressed because it is too large
Load diff
1728
test/browser/refs/compound/compound-10.json
Normal file
1728
test/browser/refs/compound/compound-10.json
Normal file
File diff suppressed because it is too large
Load diff
17966
test/browser/refs/compoundStack/compoundStack-0.json
Normal file
17966
test/browser/refs/compoundStack/compoundStack-0.json
Normal file
File diff suppressed because it is too large
Load diff
18726
test/browser/refs/compoundStack/compoundStack-10.json
Normal file
18726
test/browser/refs/compoundStack/compoundStack-10.json
Normal file
File diff suppressed because it is too large
Load diff
6237
test/browser/refs/concave/concave-0.json
Normal file
6237
test/browser/refs/concave/concave-0.json
Normal file
File diff suppressed because it is too large
Load diff
6517
test/browser/refs/concave/concave-10.json
Normal file
6517
test/browser/refs/concave/concave-10.json
Normal file
File diff suppressed because it is too large
Load diff
11979
test/browser/refs/events/events-0.json
Normal file
11979
test/browser/refs/events/events-0.json
Normal file
File diff suppressed because it is too large
Load diff
12339
test/browser/refs/events/events-10.json
Normal file
12339
test/browser/refs/events/events-10.json
Normal file
File diff suppressed because it is too large
Load diff
2021
test/browser/refs/friction/friction-0.json
Normal file
2021
test/browser/refs/friction/friction-0.json
Normal file
File diff suppressed because it is too large
Load diff
2121
test/browser/refs/friction/friction-10.json
Normal file
2121
test/browser/refs/friction/friction-10.json
Normal file
File diff suppressed because it is too large
Load diff
22915
test/browser/refs/gravity/gravity-0.json
Normal file
22915
test/browser/refs/gravity/gravity-0.json
Normal file
File diff suppressed because it is too large
Load diff
23955
test/browser/refs/gravity/gravity-10.json
Normal file
23955
test/browser/refs/gravity/gravity-10.json
Normal file
File diff suppressed because it is too large
Load diff
2695
test/browser/refs/manipulation/manipulation-0.json
Normal file
2695
test/browser/refs/manipulation/manipulation-0.json
Normal file
File diff suppressed because it is too large
Load diff
2829
test/browser/refs/manipulation/manipulation-10.json
Normal file
2829
test/browser/refs/manipulation/manipulation-10.json
Normal file
File diff suppressed because it is too large
Load diff
17880
test/browser/refs/mixed/mixed-0.json
Normal file
17880
test/browser/refs/mixed/mixed-0.json
Normal file
File diff suppressed because it is too large
Load diff
18515
test/browser/refs/mixed/mixed-10.json
Normal file
18515
test/browser/refs/mixed/mixed-10.json
Normal file
File diff suppressed because it is too large
Load diff
8705
test/browser/refs/mixedSolid/mixedSolid-0.json
Normal file
8705
test/browser/refs/mixedSolid/mixedSolid-0.json
Normal file
File diff suppressed because it is too large
Load diff
9105
test/browser/refs/mixedSolid/mixedSolid-10.json
Normal file
9105
test/browser/refs/mixedSolid/mixedSolid-10.json
Normal file
File diff suppressed because it is too large
Load diff
6563
test/browser/refs/newtonsCradle/newtonsCradle-0.json
Normal file
6563
test/browser/refs/newtonsCradle/newtonsCradle-0.json
Normal file
File diff suppressed because it is too large
Load diff
6723
test/browser/refs/newtonsCradle/newtonsCradle-10.json
Normal file
6723
test/browser/refs/newtonsCradle/newtonsCradle-10.json
Normal file
File diff suppressed because it is too large
Load diff
12605
test/browser/refs/pyramid/pyramid-0.json
Normal file
12605
test/browser/refs/pyramid/pyramid-0.json
Normal file
File diff suppressed because it is too large
Load diff
13285
test/browser/refs/pyramid/pyramid-10.json
Normal file
13285
test/browser/refs/pyramid/pyramid-10.json
Normal file
File diff suppressed because it is too large
Load diff
14451
test/browser/refs/raycasting/raycasting-0.json
Normal file
14451
test/browser/refs/raycasting/raycasting-0.json
Normal file
File diff suppressed because it is too large
Load diff
15101
test/browser/refs/raycasting/raycasting-10.json
Normal file
15101
test/browser/refs/raycasting/raycasting-10.json
Normal file
File diff suppressed because it is too large
Load diff
2091
test/browser/refs/restitution/restitution-0.json
Normal file
2091
test/browser/refs/restitution/restitution-0.json
Normal file
File diff suppressed because it is too large
Load diff
2181
test/browser/refs/restitution/restitution-10.json
Normal file
2181
test/browser/refs/restitution/restitution-10.json
Normal file
File diff suppressed because it is too large
Load diff
4610
test/browser/refs/rounded/rounded-0.json
Normal file
4610
test/browser/refs/rounded/rounded-0.json
Normal file
File diff suppressed because it is too large
Load diff
4730
test/browser/refs/rounded/rounded-10.json
Normal file
4730
test/browser/refs/rounded/rounded-10.json
Normal file
File diff suppressed because it is too large
Load diff
9198
test/browser/refs/sleeping/sleeping-0.json
Normal file
9198
test/browser/refs/sleeping/sleeping-0.json
Normal file
File diff suppressed because it is too large
Load diff
9598
test/browser/refs/sleeping/sleeping-10.json
Normal file
9598
test/browser/refs/sleeping/sleeping-10.json
Normal file
File diff suppressed because it is too large
Load diff
7069
test/browser/refs/slingshot/slingshot-0.json
Normal file
7069
test/browser/refs/slingshot/slingshot-0.json
Normal file
File diff suppressed because it is too large
Load diff
7439
test/browser/refs/slingshot/slingshot-10.json
Normal file
7439
test/browser/refs/slingshot/slingshot-10.json
Normal file
File diff suppressed because it is too large
Load diff
31055
test/browser/refs/softBody/softBody-0.json
Normal file
31055
test/browser/refs/softBody/softBody-0.json
Normal file
File diff suppressed because it is too large
Load diff
31745
test/browser/refs/softBody/softBody-10.json
Normal file
31745
test/browser/refs/softBody/softBody-10.json
Normal file
File diff suppressed because it is too large
Load diff
11829
test/browser/refs/sprites/sprites-0.json
Normal file
11829
test/browser/refs/sprites/sprites-0.json
Normal file
File diff suppressed because it is too large
Load diff
12269
test/browser/refs/sprites/sprites-10.json
Normal file
12269
test/browser/refs/sprites/sprites-10.json
Normal file
File diff suppressed because it is too large
Load diff
10052
test/browser/refs/stack/stack-0.json
Normal file
10052
test/browser/refs/stack/stack-0.json
Normal file
File diff suppressed because it is too large
Load diff
10592
test/browser/refs/stack/stack-10.json
Normal file
10592
test/browser/refs/stack/stack-10.json
Normal file
File diff suppressed because it is too large
Load diff
2390
test/browser/refs/staticFriction/staticFriction-0.json
Normal file
2390
test/browser/refs/staticFriction/staticFriction-0.json
Normal file
File diff suppressed because it is too large
Load diff
2500
test/browser/refs/staticFriction/staticFriction-10.json
Normal file
2500
test/browser/refs/staticFriction/staticFriction-10.json
Normal file
File diff suppressed because it is too large
Load diff
50312
test/browser/refs/stress/stress-0.json
Normal file
50312
test/browser/refs/stress/stress-0.json
Normal file
File diff suppressed because it is too large
Load diff
53052
test/browser/refs/stress/stress-10.json
Normal file
53052
test/browser/refs/stress/stress-10.json
Normal file
File diff suppressed because it is too large
Load diff
83252
test/browser/refs/stress2/stress2-0.json
Normal file
83252
test/browser/refs/stress2/stress2-0.json
Normal file
File diff suppressed because it is too large
Load diff
87792
test/browser/refs/stress2/stress2-10.json
Normal file
87792
test/browser/refs/stress2/stress2-10.json
Normal file
File diff suppressed because it is too large
Load diff
889
test/browser/refs/svg/svg-0.json
Normal file
889
test/browser/refs/svg/svg-0.json
Normal file
|
@ -0,0 +1,889 @@
|
|||
[
|
||||
{
|
||||
"bodies": {
|
||||
"#": 1
|
||||
},
|
||||
"bounds": {
|
||||
"#": 86
|
||||
},
|
||||
"composites": {
|
||||
"#": 89
|
||||
},
|
||||
"constraints": {
|
||||
"#": 90
|
||||
},
|
||||
"gravity": {
|
||||
"#": 94
|
||||
},
|
||||
"id": 0,
|
||||
"isModified": true,
|
||||
"label": "World",
|
||||
"parent": "",
|
||||
"type": "composite"
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 2
|
||||
},
|
||||
{
|
||||
"#": 23
|
||||
},
|
||||
{
|
||||
"#": 44
|
||||
},
|
||||
{
|
||||
"#": 65
|
||||
}
|
||||
],
|
||||
{
|
||||
"angle": 0,
|
||||
"anglePrev": 0,
|
||||
"angularSpeed": 0,
|
||||
"angularVelocity": 0,
|
||||
"area": 40930.25,
|
||||
"axes": {
|
||||
"#": 3
|
||||
},
|
||||
"bounds": {
|
||||
"#": 6
|
||||
},
|
||||
"collisionFilter": {
|
||||
"#": 9
|
||||
},
|
||||
"constraintImpulse": {
|
||||
"#": 10
|
||||
},
|
||||
"density": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"force": {
|
||||
"#": 11
|
||||
},
|
||||
"friction": 1,
|
||||
"frictionAir": 0.01,
|
||||
"frictionStatic": 0.5,
|
||||
"id": 0,
|
||||
"inertia": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"inverseInertia": 0,
|
||||
"inverseMass": 0,
|
||||
"isSleeping": false,
|
||||
"isStatic": true,
|
||||
"label": "Rectangle Body",
|
||||
"mass": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"motion": 0,
|
||||
"parent": null,
|
||||
"position": {
|
||||
"#": 12
|
||||
},
|
||||
"positionImpulse": {
|
||||
"#": 13
|
||||
},
|
||||
"positionPrev": {
|
||||
"#": 14
|
||||
},
|
||||
"render": {
|
||||
"#": 15
|
||||
},
|
||||
"restitution": 0,
|
||||
"sleepCounter": 0,
|
||||
"sleepThreshold": 60,
|
||||
"slop": 0.05,
|
||||
"speed": 0,
|
||||
"timeScale": 1,
|
||||
"torque": 0,
|
||||
"totalContacts": 0,
|
||||
"type": "body",
|
||||
"velocity": {
|
||||
"#": 17
|
||||
},
|
||||
"vertices": {
|
||||
"#": 18
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 4
|
||||
},
|
||||
{
|
||||
"#": 5
|
||||
}
|
||||
],
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"max": {
|
||||
"#": 7
|
||||
},
|
||||
"min": {
|
||||
"#": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 805.25,
|
||||
"y": 20.25
|
||||
},
|
||||
{
|
||||
"x": -5.25,
|
||||
"y": -30.25
|
||||
},
|
||||
{
|
||||
"category": 1,
|
||||
"group": 0,
|
||||
"mask": 4294967295
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 400,
|
||||
"y": -5
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 400,
|
||||
"y": -5
|
||||
},
|
||||
{
|
||||
"fillStyle": "#eeeeee",
|
||||
"lineWidth": 1.5,
|
||||
"sprite": {
|
||||
"#": 16
|
||||
},
|
||||
"strokeStyle": "#bbbbbb",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"xScale": 1,
|
||||
"yScale": 1
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 19
|
||||
},
|
||||
{
|
||||
"#": 20
|
||||
},
|
||||
{
|
||||
"#": 21
|
||||
},
|
||||
{
|
||||
"#": 22
|
||||
}
|
||||
],
|
||||
{
|
||||
"body": null,
|
||||
"index": 0,
|
||||
"isInternal": false,
|
||||
"x": -5.25,
|
||||
"y": -30.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 1,
|
||||
"isInternal": false,
|
||||
"x": 805.25,
|
||||
"y": -30.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 2,
|
||||
"isInternal": false,
|
||||
"x": 805.25,
|
||||
"y": 20.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 3,
|
||||
"isInternal": false,
|
||||
"x": -5.25,
|
||||
"y": 20.25
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"anglePrev": 0,
|
||||
"angularSpeed": 0,
|
||||
"angularVelocity": 0,
|
||||
"area": 40930.25,
|
||||
"axes": {
|
||||
"#": 24
|
||||
},
|
||||
"bounds": {
|
||||
"#": 27
|
||||
},
|
||||
"collisionFilter": {
|
||||
"#": 30
|
||||
},
|
||||
"constraintImpulse": {
|
||||
"#": 31
|
||||
},
|
||||
"density": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"force": {
|
||||
"#": 32
|
||||
},
|
||||
"friction": 1,
|
||||
"frictionAir": 0.01,
|
||||
"frictionStatic": 0.5,
|
||||
"id": 1,
|
||||
"inertia": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"inverseInertia": 0,
|
||||
"inverseMass": 0,
|
||||
"isSleeping": false,
|
||||
"isStatic": true,
|
||||
"label": "Rectangle Body",
|
||||
"mass": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"motion": 0,
|
||||
"parent": null,
|
||||
"position": {
|
||||
"#": 33
|
||||
},
|
||||
"positionImpulse": {
|
||||
"#": 34
|
||||
},
|
||||
"positionPrev": {
|
||||
"#": 35
|
||||
},
|
||||
"render": {
|
||||
"#": 36
|
||||
},
|
||||
"restitution": 0,
|
||||
"sleepCounter": 0,
|
||||
"sleepThreshold": 60,
|
||||
"slop": 0.05,
|
||||
"speed": 0,
|
||||
"timeScale": 1,
|
||||
"torque": 0,
|
||||
"totalContacts": 0,
|
||||
"type": "body",
|
||||
"velocity": {
|
||||
"#": 38
|
||||
},
|
||||
"vertices": {
|
||||
"#": 39
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 25
|
||||
},
|
||||
{
|
||||
"#": 26
|
||||
}
|
||||
],
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"max": {
|
||||
"#": 28
|
||||
},
|
||||
"min": {
|
||||
"#": 29
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 805.25,
|
||||
"y": 630.25
|
||||
},
|
||||
{
|
||||
"x": -5.25,
|
||||
"y": 579.75
|
||||
},
|
||||
{
|
||||
"category": 1,
|
||||
"group": 0,
|
||||
"mask": 4294967295
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 400,
|
||||
"y": 605
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 400,
|
||||
"y": 605
|
||||
},
|
||||
{
|
||||
"fillStyle": "#eeeeee",
|
||||
"lineWidth": 1.5,
|
||||
"sprite": {
|
||||
"#": 37
|
||||
},
|
||||
"strokeStyle": "#bbbbbb",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"xScale": 1,
|
||||
"yScale": 1
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 40
|
||||
},
|
||||
{
|
||||
"#": 41
|
||||
},
|
||||
{
|
||||
"#": 42
|
||||
},
|
||||
{
|
||||
"#": 43
|
||||
}
|
||||
],
|
||||
{
|
||||
"body": null,
|
||||
"index": 0,
|
||||
"isInternal": false,
|
||||
"x": -5.25,
|
||||
"y": 579.75
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 1,
|
||||
"isInternal": false,
|
||||
"x": 805.25,
|
||||
"y": 579.75
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 2,
|
||||
"isInternal": false,
|
||||
"x": 805.25,
|
||||
"y": 630.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 3,
|
||||
"isInternal": false,
|
||||
"x": -5.25,
|
||||
"y": 630.25
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"anglePrev": 0,
|
||||
"angularSpeed": 0,
|
||||
"angularVelocity": 0,
|
||||
"area": 30830.25,
|
||||
"axes": {
|
||||
"#": 45
|
||||
},
|
||||
"bounds": {
|
||||
"#": 48
|
||||
},
|
||||
"collisionFilter": {
|
||||
"#": 51
|
||||
},
|
||||
"constraintImpulse": {
|
||||
"#": 52
|
||||
},
|
||||
"density": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"force": {
|
||||
"#": 53
|
||||
},
|
||||
"friction": 1,
|
||||
"frictionAir": 0.01,
|
||||
"frictionStatic": 0.5,
|
||||
"id": 2,
|
||||
"inertia": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"inverseInertia": 0,
|
||||
"inverseMass": 0,
|
||||
"isSleeping": false,
|
||||
"isStatic": true,
|
||||
"label": "Rectangle Body",
|
||||
"mass": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"motion": 0,
|
||||
"parent": null,
|
||||
"position": {
|
||||
"#": 54
|
||||
},
|
||||
"positionImpulse": {
|
||||
"#": 55
|
||||
},
|
||||
"positionPrev": {
|
||||
"#": 56
|
||||
},
|
||||
"render": {
|
||||
"#": 57
|
||||
},
|
||||
"restitution": 0,
|
||||
"sleepCounter": 0,
|
||||
"sleepThreshold": 60,
|
||||
"slop": 0.05,
|
||||
"speed": 0,
|
||||
"timeScale": 1,
|
||||
"torque": 0,
|
||||
"totalContacts": 0,
|
||||
"type": "body",
|
||||
"velocity": {
|
||||
"#": 59
|
||||
},
|
||||
"vertices": {
|
||||
"#": 60
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 46
|
||||
},
|
||||
{
|
||||
"#": 47
|
||||
}
|
||||
],
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"max": {
|
||||
"#": 49
|
||||
},
|
||||
"min": {
|
||||
"#": 50
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 830.25,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"x": 779.75,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"category": 1,
|
||||
"group": 0,
|
||||
"mask": 4294967295
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 805,
|
||||
"y": 300
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 805,
|
||||
"y": 300
|
||||
},
|
||||
{
|
||||
"fillStyle": "#eeeeee",
|
||||
"lineWidth": 1.5,
|
||||
"sprite": {
|
||||
"#": 58
|
||||
},
|
||||
"strokeStyle": "#bbbbbb",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"xScale": 1,
|
||||
"yScale": 1
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 61
|
||||
},
|
||||
{
|
||||
"#": 62
|
||||
},
|
||||
{
|
||||
"#": 63
|
||||
},
|
||||
{
|
||||
"#": 64
|
||||
}
|
||||
],
|
||||
{
|
||||
"body": null,
|
||||
"index": 0,
|
||||
"isInternal": false,
|
||||
"x": 779.75,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 1,
|
||||
"isInternal": false,
|
||||
"x": 830.25,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 2,
|
||||
"isInternal": false,
|
||||
"x": 830.25,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 3,
|
||||
"isInternal": false,
|
||||
"x": 779.75,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"anglePrev": 0,
|
||||
"angularSpeed": 0,
|
||||
"angularVelocity": 0,
|
||||
"area": 30830.25,
|
||||
"axes": {
|
||||
"#": 66
|
||||
},
|
||||
"bounds": {
|
||||
"#": 69
|
||||
},
|
||||
"collisionFilter": {
|
||||
"#": 72
|
||||
},
|
||||
"constraintImpulse": {
|
||||
"#": 73
|
||||
},
|
||||
"density": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"force": {
|
||||
"#": 74
|
||||
},
|
||||
"friction": 1,
|
||||
"frictionAir": 0.01,
|
||||
"frictionStatic": 0.5,
|
||||
"id": 3,
|
||||
"inertia": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"inverseInertia": 0,
|
||||
"inverseMass": 0,
|
||||
"isSleeping": false,
|
||||
"isStatic": true,
|
||||
"label": "Rectangle Body",
|
||||
"mass": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"motion": 0,
|
||||
"parent": null,
|
||||
"position": {
|
||||
"#": 75
|
||||
},
|
||||
"positionImpulse": {
|
||||
"#": 76
|
||||
},
|
||||
"positionPrev": {
|
||||
"#": 77
|
||||
},
|
||||
"render": {
|
||||
"#": 78
|
||||
},
|
||||
"restitution": 0,
|
||||
"sleepCounter": 0,
|
||||
"sleepThreshold": 60,
|
||||
"slop": 0.05,
|
||||
"speed": 0,
|
||||
"timeScale": 1,
|
||||
"torque": 0,
|
||||
"totalContacts": 0,
|
||||
"type": "body",
|
||||
"velocity": {
|
||||
"#": 80
|
||||
},
|
||||
"vertices": {
|
||||
"#": 81
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 67
|
||||
},
|
||||
{
|
||||
"#": 68
|
||||
}
|
||||
],
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"max": {
|
||||
"#": 70
|
||||
},
|
||||
"min": {
|
||||
"#": 71
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 20.25,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"x": -30.25,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"category": 1,
|
||||
"group": 0,
|
||||
"mask": 4294967295
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": -5,
|
||||
"y": 300
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": -5,
|
||||
"y": 300
|
||||
},
|
||||
{
|
||||
"fillStyle": "#eeeeee",
|
||||
"lineWidth": 1.5,
|
||||
"sprite": {
|
||||
"#": 79
|
||||
},
|
||||
"strokeStyle": "#bbbbbb",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"xScale": 1,
|
||||
"yScale": 1
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 82
|
||||
},
|
||||
{
|
||||
"#": 83
|
||||
},
|
||||
{
|
||||
"#": 84
|
||||
},
|
||||
{
|
||||
"#": 85
|
||||
}
|
||||
],
|
||||
{
|
||||
"body": null,
|
||||
"index": 0,
|
||||
"isInternal": false,
|
||||
"x": -30.25,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 1,
|
||||
"isInternal": false,
|
||||
"x": 20.25,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 2,
|
||||
"isInternal": false,
|
||||
"x": 20.25,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 3,
|
||||
"isInternal": false,
|
||||
"x": -30.25,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"max": {
|
||||
"#": 87
|
||||
},
|
||||
"min": {
|
||||
"#": 88
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"-Infinity"
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"-Infinity"
|
||||
]
|
||||
}
|
||||
},
|
||||
[],
|
||||
[
|
||||
{
|
||||
"#": 91
|
||||
}
|
||||
],
|
||||
{
|
||||
"angularStiffness": 1,
|
||||
"bodyB": "",
|
||||
"id": 1,
|
||||
"label": "Mouse Constraint",
|
||||
"length": 0.01,
|
||||
"pointA": {
|
||||
"#": 92
|
||||
},
|
||||
"pointB": "",
|
||||
"render": {
|
||||
"#": 93
|
||||
},
|
||||
"stiffness": 0.1,
|
||||
"type": "constraint"
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"lineWidth": 3,
|
||||
"strokeStyle": "#90EE90",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
}
|
||||
]
|
929
test/browser/refs/svg/svg-10.json
Normal file
929
test/browser/refs/svg/svg-10.json
Normal file
|
@ -0,0 +1,929 @@
|
|||
[
|
||||
{
|
||||
"bodies": {
|
||||
"#": 1
|
||||
},
|
||||
"bounds": {
|
||||
"#": 90
|
||||
},
|
||||
"composites": {
|
||||
"#": 93
|
||||
},
|
||||
"constraints": {
|
||||
"#": 94
|
||||
},
|
||||
"gravity": {
|
||||
"#": 98
|
||||
},
|
||||
"id": 0,
|
||||
"isModified": false,
|
||||
"label": "World",
|
||||
"parent": "",
|
||||
"type": "composite"
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 2
|
||||
},
|
||||
{
|
||||
"#": 24
|
||||
},
|
||||
{
|
||||
"#": 46
|
||||
},
|
||||
{
|
||||
"#": 68
|
||||
}
|
||||
],
|
||||
{
|
||||
"angle": 0,
|
||||
"anglePrev": 0,
|
||||
"angularSpeed": 0,
|
||||
"angularVelocity": 0,
|
||||
"area": 40930.25,
|
||||
"axes": {
|
||||
"#": 3
|
||||
},
|
||||
"bounds": {
|
||||
"#": 6
|
||||
},
|
||||
"collisionFilter": {
|
||||
"#": 9
|
||||
},
|
||||
"constraintImpulse": {
|
||||
"#": 10
|
||||
},
|
||||
"density": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"force": {
|
||||
"#": 11
|
||||
},
|
||||
"friction": 1,
|
||||
"frictionAir": 0.01,
|
||||
"frictionStatic": 0.5,
|
||||
"id": 0,
|
||||
"inertia": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"inverseInertia": 0,
|
||||
"inverseMass": 0,
|
||||
"isSleeping": false,
|
||||
"isStatic": true,
|
||||
"label": "Rectangle Body",
|
||||
"mass": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"motion": 0,
|
||||
"parent": null,
|
||||
"position": {
|
||||
"#": 12
|
||||
},
|
||||
"positionImpulse": {
|
||||
"#": 13
|
||||
},
|
||||
"positionPrev": {
|
||||
"#": 14
|
||||
},
|
||||
"region": {
|
||||
"#": 15
|
||||
},
|
||||
"render": {
|
||||
"#": 16
|
||||
},
|
||||
"restitution": 0,
|
||||
"sleepCounter": 0,
|
||||
"sleepThreshold": 60,
|
||||
"slop": 0.05,
|
||||
"speed": 0,
|
||||
"timeScale": 1,
|
||||
"torque": 0,
|
||||
"totalContacts": 0,
|
||||
"type": "body",
|
||||
"velocity": {
|
||||
"#": 18
|
||||
},
|
||||
"vertices": {
|
||||
"#": 19
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 4
|
||||
},
|
||||
{
|
||||
"#": 5
|
||||
}
|
||||
],
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"max": {
|
||||
"#": 7
|
||||
},
|
||||
"min": {
|
||||
"#": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 805.25,
|
||||
"y": 20.25
|
||||
},
|
||||
{
|
||||
"x": -5.25,
|
||||
"y": -30.25
|
||||
},
|
||||
{
|
||||
"category": 1,
|
||||
"group": 0,
|
||||
"mask": 4294967295
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 400,
|
||||
"y": -5
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 400,
|
||||
"y": -5
|
||||
},
|
||||
{
|
||||
"endCol": 16,
|
||||
"endRow": 0,
|
||||
"id": "-1,16,-1,0",
|
||||
"startCol": -1,
|
||||
"startRow": -1
|
||||
},
|
||||
{
|
||||
"fillStyle": "#eeeeee",
|
||||
"lineWidth": 1.5,
|
||||
"sprite": {
|
||||
"#": 17
|
||||
},
|
||||
"strokeStyle": "#bbbbbb",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"xScale": 1,
|
||||
"yScale": 1
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 20
|
||||
},
|
||||
{
|
||||
"#": 21
|
||||
},
|
||||
{
|
||||
"#": 22
|
||||
},
|
||||
{
|
||||
"#": 23
|
||||
}
|
||||
],
|
||||
{
|
||||
"body": null,
|
||||
"index": 0,
|
||||
"isInternal": false,
|
||||
"x": -5.25,
|
||||
"y": -30.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 1,
|
||||
"isInternal": false,
|
||||
"x": 805.25,
|
||||
"y": -30.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 2,
|
||||
"isInternal": false,
|
||||
"x": 805.25,
|
||||
"y": 20.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 3,
|
||||
"isInternal": false,
|
||||
"x": -5.25,
|
||||
"y": 20.25
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"anglePrev": 0,
|
||||
"angularSpeed": 0,
|
||||
"angularVelocity": 0,
|
||||
"area": 40930.25,
|
||||
"axes": {
|
||||
"#": 25
|
||||
},
|
||||
"bounds": {
|
||||
"#": 28
|
||||
},
|
||||
"collisionFilter": {
|
||||
"#": 31
|
||||
},
|
||||
"constraintImpulse": {
|
||||
"#": 32
|
||||
},
|
||||
"density": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"force": {
|
||||
"#": 33
|
||||
},
|
||||
"friction": 1,
|
||||
"frictionAir": 0.01,
|
||||
"frictionStatic": 0.5,
|
||||
"id": 1,
|
||||
"inertia": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"inverseInertia": 0,
|
||||
"inverseMass": 0,
|
||||
"isSleeping": false,
|
||||
"isStatic": true,
|
||||
"label": "Rectangle Body",
|
||||
"mass": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"motion": 0,
|
||||
"parent": null,
|
||||
"position": {
|
||||
"#": 34
|
||||
},
|
||||
"positionImpulse": {
|
||||
"#": 35
|
||||
},
|
||||
"positionPrev": {
|
||||
"#": 36
|
||||
},
|
||||
"region": {
|
||||
"#": 37
|
||||
},
|
||||
"render": {
|
||||
"#": 38
|
||||
},
|
||||
"restitution": 0,
|
||||
"sleepCounter": 0,
|
||||
"sleepThreshold": 60,
|
||||
"slop": 0.05,
|
||||
"speed": 0,
|
||||
"timeScale": 1,
|
||||
"torque": 0,
|
||||
"totalContacts": 0,
|
||||
"type": "body",
|
||||
"velocity": {
|
||||
"#": 40
|
||||
},
|
||||
"vertices": {
|
||||
"#": 41
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 26
|
||||
},
|
||||
{
|
||||
"#": 27
|
||||
}
|
||||
],
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"max": {
|
||||
"#": 29
|
||||
},
|
||||
"min": {
|
||||
"#": 30
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 805.25,
|
||||
"y": 630.25
|
||||
},
|
||||
{
|
||||
"x": -5.25,
|
||||
"y": 579.75
|
||||
},
|
||||
{
|
||||
"category": 1,
|
||||
"group": 0,
|
||||
"mask": 4294967295
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 400,
|
||||
"y": 605
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 400,
|
||||
"y": 605
|
||||
},
|
||||
{
|
||||
"endCol": 16,
|
||||
"endRow": 13,
|
||||
"id": "-1,16,12,13",
|
||||
"startCol": -1,
|
||||
"startRow": 12
|
||||
},
|
||||
{
|
||||
"fillStyle": "#eeeeee",
|
||||
"lineWidth": 1.5,
|
||||
"sprite": {
|
||||
"#": 39
|
||||
},
|
||||
"strokeStyle": "#bbbbbb",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"xScale": 1,
|
||||
"yScale": 1
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 42
|
||||
},
|
||||
{
|
||||
"#": 43
|
||||
},
|
||||
{
|
||||
"#": 44
|
||||
},
|
||||
{
|
||||
"#": 45
|
||||
}
|
||||
],
|
||||
{
|
||||
"body": null,
|
||||
"index": 0,
|
||||
"isInternal": false,
|
||||
"x": -5.25,
|
||||
"y": 579.75
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 1,
|
||||
"isInternal": false,
|
||||
"x": 805.25,
|
||||
"y": 579.75
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 2,
|
||||
"isInternal": false,
|
||||
"x": 805.25,
|
||||
"y": 630.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 3,
|
||||
"isInternal": false,
|
||||
"x": -5.25,
|
||||
"y": 630.25
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"anglePrev": 0,
|
||||
"angularSpeed": 0,
|
||||
"angularVelocity": 0,
|
||||
"area": 30830.25,
|
||||
"axes": {
|
||||
"#": 47
|
||||
},
|
||||
"bounds": {
|
||||
"#": 50
|
||||
},
|
||||
"collisionFilter": {
|
||||
"#": 53
|
||||
},
|
||||
"constraintImpulse": {
|
||||
"#": 54
|
||||
},
|
||||
"density": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"force": {
|
||||
"#": 55
|
||||
},
|
||||
"friction": 1,
|
||||
"frictionAir": 0.01,
|
||||
"frictionStatic": 0.5,
|
||||
"id": 2,
|
||||
"inertia": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"inverseInertia": 0,
|
||||
"inverseMass": 0,
|
||||
"isSleeping": false,
|
||||
"isStatic": true,
|
||||
"label": "Rectangle Body",
|
||||
"mass": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"motion": 0,
|
||||
"parent": null,
|
||||
"position": {
|
||||
"#": 56
|
||||
},
|
||||
"positionImpulse": {
|
||||
"#": 57
|
||||
},
|
||||
"positionPrev": {
|
||||
"#": 58
|
||||
},
|
||||
"region": {
|
||||
"#": 59
|
||||
},
|
||||
"render": {
|
||||
"#": 60
|
||||
},
|
||||
"restitution": 0,
|
||||
"sleepCounter": 0,
|
||||
"sleepThreshold": 60,
|
||||
"slop": 0.05,
|
||||
"speed": 0,
|
||||
"timeScale": 1,
|
||||
"torque": 0,
|
||||
"totalContacts": 0,
|
||||
"type": "body",
|
||||
"velocity": {
|
||||
"#": 62
|
||||
},
|
||||
"vertices": {
|
||||
"#": 63
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 48
|
||||
},
|
||||
{
|
||||
"#": 49
|
||||
}
|
||||
],
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"max": {
|
||||
"#": 51
|
||||
},
|
||||
"min": {
|
||||
"#": 52
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 830.25,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"x": 779.75,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"category": 1,
|
||||
"group": 0,
|
||||
"mask": 4294967295
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 805,
|
||||
"y": 300
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 805,
|
||||
"y": 300
|
||||
},
|
||||
{
|
||||
"endCol": 17,
|
||||
"endRow": 12,
|
||||
"id": "16,17,-1,12",
|
||||
"startCol": 16,
|
||||
"startRow": -1
|
||||
},
|
||||
{
|
||||
"fillStyle": "#eeeeee",
|
||||
"lineWidth": 1.5,
|
||||
"sprite": {
|
||||
"#": 61
|
||||
},
|
||||
"strokeStyle": "#bbbbbb",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"xScale": 1,
|
||||
"yScale": 1
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 64
|
||||
},
|
||||
{
|
||||
"#": 65
|
||||
},
|
||||
{
|
||||
"#": 66
|
||||
},
|
||||
{
|
||||
"#": 67
|
||||
}
|
||||
],
|
||||
{
|
||||
"body": null,
|
||||
"index": 0,
|
||||
"isInternal": false,
|
||||
"x": 779.75,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 1,
|
||||
"isInternal": false,
|
||||
"x": 830.25,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 2,
|
||||
"isInternal": false,
|
||||
"x": 830.25,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 3,
|
||||
"isInternal": false,
|
||||
"x": 779.75,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"anglePrev": 0,
|
||||
"angularSpeed": 0,
|
||||
"angularVelocity": 0,
|
||||
"area": 30830.25,
|
||||
"axes": {
|
||||
"#": 69
|
||||
},
|
||||
"bounds": {
|
||||
"#": 72
|
||||
},
|
||||
"collisionFilter": {
|
||||
"#": 75
|
||||
},
|
||||
"constraintImpulse": {
|
||||
"#": 76
|
||||
},
|
||||
"density": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"force": {
|
||||
"#": 77
|
||||
},
|
||||
"friction": 1,
|
||||
"frictionAir": 0.01,
|
||||
"frictionStatic": 0.5,
|
||||
"id": 3,
|
||||
"inertia": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"inverseInertia": 0,
|
||||
"inverseMass": 0,
|
||||
"isSleeping": false,
|
||||
"isStatic": true,
|
||||
"label": "Rectangle Body",
|
||||
"mass": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"motion": 0,
|
||||
"parent": null,
|
||||
"position": {
|
||||
"#": 78
|
||||
},
|
||||
"positionImpulse": {
|
||||
"#": 79
|
||||
},
|
||||
"positionPrev": {
|
||||
"#": 80
|
||||
},
|
||||
"region": {
|
||||
"#": 81
|
||||
},
|
||||
"render": {
|
||||
"#": 82
|
||||
},
|
||||
"restitution": 0,
|
||||
"sleepCounter": 0,
|
||||
"sleepThreshold": 60,
|
||||
"slop": 0.05,
|
||||
"speed": 0,
|
||||
"timeScale": 1,
|
||||
"torque": 0,
|
||||
"totalContacts": 0,
|
||||
"type": "body",
|
||||
"velocity": {
|
||||
"#": 84
|
||||
},
|
||||
"vertices": {
|
||||
"#": 85
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 70
|
||||
},
|
||||
{
|
||||
"#": 71
|
||||
}
|
||||
],
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"max": {
|
||||
"#": 73
|
||||
},
|
||||
"min": {
|
||||
"#": 74
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 20.25,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"x": -30.25,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"category": 1,
|
||||
"group": 0,
|
||||
"mask": 4294967295
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": -5,
|
||||
"y": 300
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": -5,
|
||||
"y": 300
|
||||
},
|
||||
{
|
||||
"endCol": 0,
|
||||
"endRow": 12,
|
||||
"id": "-1,0,-1,12",
|
||||
"startCol": -1,
|
||||
"startRow": -1
|
||||
},
|
||||
{
|
||||
"fillStyle": "#eeeeee",
|
||||
"lineWidth": 1.5,
|
||||
"sprite": {
|
||||
"#": 83
|
||||
},
|
||||
"strokeStyle": "#bbbbbb",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"xScale": 1,
|
||||
"yScale": 1
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
[
|
||||
{
|
||||
"#": 86
|
||||
},
|
||||
{
|
||||
"#": 87
|
||||
},
|
||||
{
|
||||
"#": 88
|
||||
},
|
||||
{
|
||||
"#": 89
|
||||
}
|
||||
],
|
||||
{
|
||||
"body": null,
|
||||
"index": 0,
|
||||
"isInternal": false,
|
||||
"x": -30.25,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 1,
|
||||
"isInternal": false,
|
||||
"x": 20.25,
|
||||
"y": -5.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 2,
|
||||
"isInternal": false,
|
||||
"x": 20.25,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"body": null,
|
||||
"index": 3,
|
||||
"isInternal": false,
|
||||
"x": -30.25,
|
||||
"y": 605.25
|
||||
},
|
||||
{
|
||||
"max": {
|
||||
"#": 91
|
||||
},
|
||||
"min": {
|
||||
"#": 92
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"-Infinity"
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"-Infinity"
|
||||
]
|
||||
}
|
||||
},
|
||||
[],
|
||||
[
|
||||
{
|
||||
"#": 95
|
||||
}
|
||||
],
|
||||
{
|
||||
"angularStiffness": 1,
|
||||
"bodyB": "",
|
||||
"id": 1,
|
||||
"label": "Mouse Constraint",
|
||||
"length": 0.01,
|
||||
"pointA": {
|
||||
"#": 96
|
||||
},
|
||||
"pointB": "",
|
||||
"render": {
|
||||
"#": 97
|
||||
},
|
||||
"stiffness": 0.1,
|
||||
"type": "constraint"
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"lineWidth": 3,
|
||||
"strokeStyle": "#90EE90",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
}
|
||||
]
|
96
test/browser/refs/terrain/terrain-0.json
Normal file
96
test/browser/refs/terrain/terrain-0.json
Normal file
|
@ -0,0 +1,96 @@
|
|||
[
|
||||
{
|
||||
"bodies": {
|
||||
"#": 1
|
||||
},
|
||||
"bounds": {
|
||||
"#": 2
|
||||
},
|
||||
"composites": {
|
||||
"#": 5
|
||||
},
|
||||
"constraints": {
|
||||
"#": 6
|
||||
},
|
||||
"gravity": {
|
||||
"#": 10
|
||||
},
|
||||
"id": 0,
|
||||
"isModified": true,
|
||||
"label": "World",
|
||||
"parent": "",
|
||||
"type": "composite"
|
||||
},
|
||||
[],
|
||||
{
|
||||
"max": {
|
||||
"#": 3
|
||||
},
|
||||
"min": {
|
||||
"#": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"-Infinity"
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"-Infinity"
|
||||
]
|
||||
}
|
||||
},
|
||||
[],
|
||||
[
|
||||
{
|
||||
"#": 7
|
||||
}
|
||||
],
|
||||
{
|
||||
"angularStiffness": 1,
|
||||
"bodyB": "",
|
||||
"id": 1,
|
||||
"label": "Mouse Constraint",
|
||||
"length": 0.01,
|
||||
"pointA": {
|
||||
"#": 8
|
||||
},
|
||||
"pointB": "",
|
||||
"render": {
|
||||
"#": 9
|
||||
},
|
||||
"stiffness": 0.1,
|
||||
"type": "constraint"
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"lineWidth": 3,
|
||||
"strokeStyle": "#90EE90",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
}
|
||||
]
|
96
test/browser/refs/terrain/terrain-10.json
Normal file
96
test/browser/refs/terrain/terrain-10.json
Normal file
|
@ -0,0 +1,96 @@
|
|||
[
|
||||
{
|
||||
"bodies": {
|
||||
"#": 1
|
||||
},
|
||||
"bounds": {
|
||||
"#": 2
|
||||
},
|
||||
"composites": {
|
||||
"#": 5
|
||||
},
|
||||
"constraints": {
|
||||
"#": 6
|
||||
},
|
||||
"gravity": {
|
||||
"#": 10
|
||||
},
|
||||
"id": 0,
|
||||
"isModified": false,
|
||||
"label": "World",
|
||||
"parent": "",
|
||||
"type": "composite"
|
||||
},
|
||||
[],
|
||||
{
|
||||
"max": {
|
||||
"#": 3
|
||||
},
|
||||
"min": {
|
||||
"#": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"Infinity"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"-Infinity"
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"#.": "Number",
|
||||
"#v": [
|
||||
"-Infinity"
|
||||
]
|
||||
}
|
||||
},
|
||||
[],
|
||||
[
|
||||
{
|
||||
"#": 7
|
||||
}
|
||||
],
|
||||
{
|
||||
"angularStiffness": 1,
|
||||
"bodyB": "",
|
||||
"id": 1,
|
||||
"label": "Mouse Constraint",
|
||||
"length": 0.01,
|
||||
"pointA": {
|
||||
"#": 8
|
||||
},
|
||||
"pointB": "",
|
||||
"render": {
|
||||
"#": 9
|
||||
},
|
||||
"stiffness": 0.1,
|
||||
"type": "constraint"
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"lineWidth": 3,
|
||||
"strokeStyle": "#90EE90",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1
|
||||
}
|
||||
]
|
21617
test/browser/refs/timescale/timescale-0.json
Normal file
21617
test/browser/refs/timescale/timescale-0.json
Normal file
File diff suppressed because it is too large
Load diff
22347
test/browser/refs/timescale/timescale-10.json
Normal file
22347
test/browser/refs/timescale/timescale-10.json
Normal file
File diff suppressed because it is too large
Load diff
14237
test/browser/refs/views/views-0.json
Normal file
14237
test/browser/refs/views/views-0.json
Normal file
File diff suppressed because it is too large
Load diff
14877
test/browser/refs/views/views-10.json
Normal file
14877
test/browser/refs/views/views-10.json
Normal file
File diff suppressed because it is too large
Load diff
10579
test/browser/refs/wreckingBall/wreckingBall-0.json
Normal file
10579
test/browser/refs/wreckingBall/wreckingBall-0.json
Normal file
File diff suppressed because it is too large
Load diff
11129
test/browser/refs/wreckingBall/wreckingBall-10.json
Normal file
11129
test/browser/refs/wreckingBall/wreckingBall-10.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue