Reputation: 45
I can't figure this out i have searched for hours on the web can't find anything is their anyway to do this if so please let me know i expect this to be possible i found this snippted somewhare so how can i do this is it possible and more importantly can anyone show me how to do this a little less ruff and how to do it becuse i have no idea ps i need to be able to do it frome the editor
<!DOCTYPE html>
<html lang="en">
<body>
<div id="container"></div>
<div id="info">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/105/three.min.js"></script>
<input type="button" onClick="shake()" value="click me"></input>
<script>
////////////////////////////
/// INITIALIZATION
////////////////////////////
var screenShake = ScreenShake();
// Create an empty scene
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x9fff89);
// Create a basic perspective camera
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set(0,0,50);
camera.lookAt(0,0,0);
// Create a renderer with Antialiasing
var renderer = new THREE.WebGLRenderer({antialias:true});
// Configure renderer size
renderer.setSize( window.innerWidth, window.innerHeight );
// Append Renderer to DOM
document.body.appendChild( renderer.domElement );
////////////////////////
/// MESHES CREATION
////////////////////////
var ball = new THREE.Mesh(new THREE.SphereBufferGeometry(4, 16, 16),
new THREE.MeshNormalMaterial);
scene.add(ball)
for (let i=0 ; i<30 ; i++) {
makeMesh();
};
function makeMesh() {
var mesh = new THREE.Mesh(new THREE.BoxBufferGeometry(5, 5, 5),
new THREE.MeshNormalMaterial);
mesh.position.set(rand(), rand(), rand());
scene.add(mesh);
function rand() {return (Math.random()-0.5)*60}
}
////////////////////////
/// SCREEN SHAKE
////////////////////////
function ScreenShake() {
return {
// When a function outside ScreenShake handle the camera, it should
// always check that ScreenShake.enabled is false before.
enabled: false,
_timestampStart: undefined,
_timestampEnd: undefined,
_startPoint: undefined,
_endPoint: undefined,
// update(camera) must be called in the loop function of the renderer,
// it will repositioned the camera according to the requested shaking.
update: function update(camera) {
if ( this.enabled == true ) {
const now = Date.now();
if ( this._timestampEnd > now ) {
let interval = (Date.now() - this._timestampStart) /
(this._timestampEnd - this._timestampStart) ;
this.computePosition( camera, interval );
} else {
camera.position.copy(this._startPoint);
this.enabled = false;
};
};
},
// This initialize the values of the shaking.
// vecToAdd param is the offset of the camera position at the climax of its wave.
shake: function shake(camera, vecToAdd, milliseconds) {
this.enabled = true ;
this._timestampStart = Date.now();
this._timestampEnd = this._timestampStart + milliseconds;
this._startPoint = new THREE.Vector3().copy(camera.position);
this._endPoint = new THREE.Vector3().addVectors( camera.position, vecToAdd );
},
computePosition: function computePosition(camera, interval) {
// This creates the wavy movement of the camera along the interval.
// The first bloc call this.getQuadra() with a positive indice between
// 0 and 1, then the second call it again with a negative indice between
// 0 and -1, etc. Variable position will get the sign of the indice, and
// get wavy.
if (interval < 0.4) {
var position = this.getQuadra( interval / 0.4 );
} else if (interval < 0.7) {
var position = this.getQuadra( (interval-0.4) / 0.3 ) * -0.6;
} else if (interval < 0.9) {
var position = this.getQuadra( (interval-0.7) / 0.2 ) * 0.3;
} else {
var position = this.getQuadra( (interval-0.9) / 0.1 ) * -0.1;
}
// Here the camera is positioned according to the wavy 'position' variable.
camera.position.lerpVectors( this._startPoint, this._endPoint, position );
},
// This is a quadratic function that return 0 at first, then return 0.5 when t=0.5,
// then return 0 when t=1 ;
getQuadra: function getQuadra(t) {
return 9.436896e-16 + (4*t) - (4*(t*t)) ;
}
};
};
//////////////////////
//// EVENT
//////////////////////
function shake() {
screenShake.shake( camera, new THREE.Vector3(0.5, -1, 1.5), 250 );
}
//////////////////////
//// LOOP
//////////////////////
loop()
function loop() {
if (ball.position.z < 45) {
ball.position.z += 0.5 ;
} else {
ball.position.z = 0;
screenShake.shake( camera, new THREE.Vector3(0, 0, 2.5), 250 );
};
screenShake.update(camera);
requestAnimationFrame( loop );
renderer.render( scene, camera );
}
</script>
</body>
</html>
Upvotes: 2
Views: 1851
Reputation: 1518
This part is critical to your asked question. The camera shakes according to the vecToAdd
in presumably (x, y, z)
. I tuned it to shake less rough in z-direction (probably by 0.25
px).
//////////////////////
//// LOOP
//////////////////////
loop()
function loop() {
if (ball.position.z < 45) {
ball.position.z += 0.5;
} else {
ball.position.z = 0;
screenShake.shake(camera, new THREE.Vector3(0, 0, 0.25), 250);
};
screenShake.update(camera);
requestAnimationFrame(loop);
renderer.render(scene, camera);
}
Upvotes: 2