JavaScript
语言:
JaveScriptBabelCoffeeScript
确定
var r = new Random(Random.engines.mt19937().autoSeed());
//create physical world
var world = Physics();
PLAYGROUND.LoadingScreen = false;
PLAYGROUND.Transitions.plugin = false;
//extend renderer
Physics.renderer('canvas-ext', 'canvas', function(parent) {
return {
init: function(options) {
parent.init.call(this, options);
},
drawBody: function(body, view) {
var t = this._interpolateTime;
body.styles.fillStyle = 'hsla(' + (body.colorIndex) + ', 80%, 50%, 1)';
if (body.obj_type != 'circle') {
body.styles.fillStyle = 'hsla(' + app.staticBallsColor + ', 50%, 20%, 1)';
//app.layer.globalCompositeOperation('source-over');
} else {
//app.layer.globalCompositeOperation('lighter');
}
var x = body.state.pos.get(0) + t * body.state.vel.get(0);
var y = body.state.pos.get(1) + t * body.state.vel.get(1);
app.layer.fillStyle(body.styles.fillStyle);
app.layer.beginPath();
app.layer.arc(x, y, body.radius, Math.PI * 2, false);
app.layer.closePath();
app.layer.fill();
if (body.state.pos.y > app.height + 50) {
body.state.pos.y = -100;
body.state.pos.x = r.integer(10, app.width - 10);
body.state.vel.zero();
body.state.vel.y = r.real(0.02, 0.04);
body.state.vel.x = r.real(-0.04, 0.04);
body.colorIndex += 35;
body.colorIndex = body.colorIndex % 360;
if (body.colorIndex + 35 != app.currentColorIndex) {
app.currentColorIndex = body.colorIndex;
}
};
},
//hack physicsjs canvas render
render: function(bodies, meta) {
var body, view, pos;
this._world.emit('beforeRender', {
renderer: this,
meta: meta
});
if (this.options.meta) {
this.drawMeta(meta);
}
this._interpolateTime = meta.interpolateTime;
for (var id in this._layers) {
this._layers[id].render(false);
}
return this;
}
};
});
//start app
var app = playground({
width: 320 * 2,
height: 240 * 2,
timewarp: 1,
backgroundAlpha: 0.1,
initialColorIndex: r.integer(0, 360),
currentColorIndex: null,
staticBallsColor: null,
slowMotionTween: null,
createBalls: function() {
for (var i = 0; i < 200; i++) {
var ball = Physics.body('circle', {
obj_type: 'circle',
colorIndex: this.initialColorIndex,
x: r.integer(10, app.width - 10),
y: -10,
vx: r.real(-0.04, 0.04),
vy: r.real(0.02, 0.04),
radius: r.integer(2, 5),
styles: {
fillStyle: 'hsla(' + 70 * i + ', 70%, 30%, 1)',
}
});
world.add(ball);
};
},
createStaticBall: function(X, Y, radius) {
return Physics.body('circle', {
x: X,
y: Y,
colorIndex: this.initialColorIndex,
treatment: 'static',
radius: radius,
styles: {
fillStyle: 'hsla(200, 70%, 30%, 1)',
}
});
},
create: function() {
this.currentColorIndex = this.initialColorIndex;
this.staticBallsColor = this.initialColorIndex;
this.createBalls();
var staticBall_1 = this.createStaticBall(this.width - 80, this.height - 40, 50);
var staticBall_2 = this.createStaticBall(80, this.height - 40, 50);
var staticBall_3 = this.createStaticBall(this.width / 2, this.height / 2, 25);
world.add(staticBall_1);
world.add(staticBall_2);
world.add(staticBall_3);
var last = 'left';
function tiggerMovementTween() {
if (staticBall_3.state.pos.x == this.width || staticBall_3.state.pos.x == 0) {
this.tween(staticBall_3.state.pos)
.discard()
.to({
x: this.width / 2
}, 2, 'outCirc');
} else if (staticBall_3.state.pos.x == this.width / 2) {
if (last == 'left') {
last = 'right';
this.tween(staticBall_3.state.pos)
.discard()
.to({
x: this.width
}, 2, 'outCirc');
} else if (last == 'right') {
last = 'left';
this.tween(staticBall_3.state.pos)
.discard()
.to({
x: 0
}, 2, 'outCirc');
}
}
this.tween(this)
.to({
staticBallsColor: this.currentColorIndex
}, 2, 'outCirc');
document.body.style.background = 'hsla(' + this.currentColorIndex + ', 90%, 10%, 1)';
}
document.body.style.background = 'hsla(' + this.currentColorIndex + ', 90%, 10%, 1)';
this.slowMotionTween = this.tween(this)
.to({
timewarp: 0.1,
backgroundAlpha: 0.05
}, 2, 'inOutQuart')
.wait(1)
.to({
timewarp: 1,
backgroundAlpha: 1
}, 1, 'inOutQuart')
.loop();
this.slowMotionTween.on("loop", tiggerMovementTween, this);
// bounds of the window
var viewportBounds = Physics.aabb(0, -100, this.width, this.height + 100);
// constrain objects to these bounds
world.add(Physics.behavior('edge-collision-detection', {
aabb: viewportBounds,
restitution: 0.99,
cof: 0.99
}));
var renderer = Physics.renderer('canvas-ext', {
el: this.layer.canvas,
ctx: this.layer.ctx,
width: 320,
height: 240,
meta: false, // don't display meta data
autoResize: false,
styles: {
// set colors for the circle bodies
'circle': {
strokeStyle: 'hsla(60, 50%, 20%, 0)',
lineWidth: 1,
fillStyle: 'hsla(60, 50%, 50%, 1)',
angleIndicator: 'hsla(60, 37%, 17%, 0)'
}
}
});
world.add([
Physics.behavior('body-impulse-response'),
Physics.behavior('body-collision-detection'),
Physics.behavior('sweep-prune')
]);
world.add(Physics.behavior('constant-acceleration', {
acc: {
x: 0,
y: 0.0002
} // this is the default
}));
this.layer.clear('rgba(24,24,24,1)');
// add the renderer
world.add(renderer);
},
step: function(dt) {
world.step(Date.now());
},
render: function() {
this.layer.clear('rgba(24,24,24,' + this.backgroundAlpha + ')');
world.render();
world.warp(this.timewarp);
}
});