0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2024-12-24 13:29:01 -05:00
liabru-matter-js/examples/views.js

135 lines
No EOL
5.2 KiB
JavaScript

(function() {
var World = Matter.World,
Bodies = Matter.Bodies,
Composites = Matter.Composites,
Common = Matter.Common,
Events = Matter.Events,
Bounds = Matter.Bounds,
Vector = Matter.Vector,
Mouse = Matter.Mouse;
Example.views = function(demo) {
var engine = demo.engine,
world = engine.world,
sceneEvents = demo.sceneEvents,
mouseConstraint = demo.mouseConstraint;
var stack = Composites.stack(20, 20, 15, 4, 0, 0, function(x, y) {
switch (Math.round(Common.random(0, 1))) {
case 0:
if (Common.random() < 0.8) {
return Bodies.rectangle(x, y, Common.random(20, 50), Common.random(20, 50));
} else {
return Bodies.rectangle(x, y, Common.random(80, 120), Common.random(20, 30));
}
break;
case 1:
var sides = Math.round(Common.random(1, 8));
sides = (sides === 3) ? 4 : sides;
return Bodies.polygon(x, y, sides, Common.random(20, 50));
}
});
World.add(world, stack);
// get the centre of the viewport
var viewportCentre = {
x: demo.render.options.width * 0.5,
y: demo.render.options.height * 0.5
};
// make the world bounds a little bigger than the render bounds
world.bounds.min.x = -300;
world.bounds.min.y = -300;
world.bounds.max.x = 1100;
world.bounds.max.y = 900;
// keep track of current bounds scale (view zoom)
var boundsScaleTarget = 1,
boundsScale = {
x: 1,
y: 1
};
// use the engine tick event to control our view
sceneEvents.push(
Events.on(engine, 'beforeTick', function() {
var world = engine.world,
mouse = mouseConstraint.mouse,
render = demo.render,
translate;
// mouse wheel controls zoom
var scaleFactor = mouse.wheelDelta * -0.1;
if (scaleFactor !== 0) {
if ((scaleFactor < 0 && boundsScale.x >= 0.6) || (scaleFactor > 0 && boundsScale.x <= 1.4)) {
boundsScaleTarget += scaleFactor;
}
}
// if scale has changed
if (Math.abs(boundsScale.x - boundsScaleTarget) > 0.01) {
// smoothly tween scale factor
scaleFactor = (boundsScaleTarget - boundsScale.x) * 0.2;
boundsScale.x += scaleFactor;
boundsScale.y += scaleFactor;
// scale the render bounds
render.bounds.max.x = render.bounds.min.x + render.options.width * boundsScale.x;
render.bounds.max.y = render.bounds.min.y + render.options.height * boundsScale.y;
// translate so zoom is from centre of view
translate = {
x: render.options.width * scaleFactor * -0.5,
y: render.options.height * scaleFactor * -0.5
};
Bounds.translate(render.bounds, translate);
// update mouse
Mouse.setScale(mouse, boundsScale);
Mouse.setOffset(mouse, render.bounds.min);
}
// get vector from mouse relative to centre of viewport
var deltaCentre = Vector.sub(mouse.absolute, viewportCentre),
centreDist = Vector.magnitude(deltaCentre);
// translate the view if mouse has moved over 50px from the centre of viewport
if (centreDist > 50) {
// create a vector to translate the view, allowing the user to control view speed
var direction = Vector.normalise(deltaCentre),
speed = Math.min(10, Math.pow(centreDist - 50, 2) * 0.0002);
translate = Vector.mult(direction, speed);
// prevent the view moving outside the world bounds
if (render.bounds.min.x + translate.x < world.bounds.min.x)
translate.x = world.bounds.min.x - render.bounds.min.x;
if (render.bounds.max.x + translate.x > world.bounds.max.x)
translate.x = world.bounds.max.x - render.bounds.max.x;
if (render.bounds.min.y + translate.y < world.bounds.min.y)
translate.y = world.bounds.min.y - render.bounds.min.y;
if (render.bounds.max.y + translate.y > world.bounds.max.y)
translate.y = world.bounds.max.y - render.bounds.max.y;
// move the view
Bounds.translate(render.bounds, translate);
// we must update the mouse too
Mouse.setOffset(mouse, render.bounds.min);
}
})
);
// must enable renderOptions.hasBounds for views to work
var renderOptions = demo.render.options;
renderOptions.hasBounds = true;
};
})();