html部分
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<title>飞机</title>
<script type="text/javascript" src="js/three.js"></script>
<script type="text/javascript" src="js/main.js"/></script>
<style type="text/css">
.world {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
background: linear-gradient(to bottom, #40405c 0%, #6f71aa 80%, #8a76ab 100%);
}
</style>
</head>
<body>
<div class="world" id="world"></div>
</body>
</html>
js部分
//将会用到的颜色
var Colors = {
red:0xf25346,
white:0xd8d0d1,
brown:0x59332e,
pink:0xF5986E,
brownDark:0x23190f,
blue:0x68c3c0,
};
var scene,
camera, fieldOfView, aspectRatio, nearPlane, farPlane,
renderer, container;
//相对于屏幕鼠标坐标
var HEIGHT, WIDTH,
mousePos = { x: 0, y: 0 };
//初始化
function createScene() {
HEIGHT = window.innerHeight;
WIDTH = window.innerWidth;
scene = new THREE.Scene();
aspectRatio = WIDTH / HEIGHT;
fieldOfView = 60;
nearPlane = 1;
farPlane = 10000;
camera = new THREE.PerspectiveCamera(
fieldOfView,
aspectRatio,
nearPlane,
farPlane
);
scene.fog = new THREE.Fog(0xFFE4FF, 100,950);
camera.position.x = 0;
camera.position.z = 200;
camera.position.y = 100;
renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.setSize(WIDTH, HEIGHT);
renderer.shadowMap.enabled = true;
container = document.getElementById('world');
container.appendChild(renderer.domElement);
window.addEventListener('resize', handleWindowResize, false);
}
// 窗口改变
function handleWindowResize() {
HEIGHT = window.innerHeight;
WIDTH = window.innerWidth;
renderer.setSize(WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
}
// 光源
var ambientLight, hemisphereLight, shadowLight;
function createLights() {
hemisphereLight = new THREE.HemisphereLight(0xaaaaaa,0x000000, .9)
shadowLight = new THREE.DirectionalLight(0xffffff, .9);
shadowLight.position.set(150, 350, 350);
shadowLight.castShadow = true;
shadowLight.shadow.camera.left = -400;
shadowLight.shadow.camera.right = 400;
shadowLight.shadow.camera.top = 400;
shadowLight.shadow.camera.bottom = -400;
shadowLight.shadow.camera.near = 1;
shadowLight.shadow.camera.far = 900;
shadowLight.shadow.mapSize.width = 2048;
shadowLight.shadow.mapSize.height = 2048;
scene.add(hemisphereLight);
scene.add(shadowLight);
}
var AirPlane = function(){
this.mesh = new THREE.Object3D();
this.mesh.name = "airPlane";
// Create the cabin
var geomCockpit = new THREE.BoxGeometry(60,50,50,1,1,1);//长宽高 都是一段
var matCockpit = new THREE.MeshPhongMaterial({color:Colors.blue, shading:THREE.FlatShading});
var cockpit = new THREE.Mesh(geomCockpit, matCockpit);
cockpit.castShadow = true;
cockpit.receiveShadow = true;
this.mesh.add(cockpit);
// Create Engine
var geomEngine = new THREE.BoxGeometry(20,50,50,1,1,1);
var matEngine = new THREE.MeshPhongMaterial({color:Colors.white, shading:THREE.FlatShading});
var engine = new THREE.Mesh(geomEngine, matEngine);
engine.position.x = 40;
engine.castShadow = true;
engine.receiveShadow = true;
this.mesh.add(engine);
// Create Tailplane
var geomTailPlane = new THREE.BoxGeometry(15,20,5,1,1,1);
var matTailPlane = new THREE.MeshPhongMaterial({color:Colors.red, shading:THREE.FlatShading});
var tailPlane = new THREE.Mesh(geomTailPlane, matTailPlane);
tailPlane.position.set(-35,25,0);
tailPlane.castShadow = true;
tailPlane.receiveShadow = true;
this.mesh.add(tailPlane);
// Create Wing
var geomSideWing = new THREE.BoxGeometry(40,8,150,1,1,1);
var matSideWing = new THREE.MeshPhongMaterial({color:Colors.red, shading:THREE.FlatShading});
var sideWing = new THREE.Mesh(geomSideWing, matSideWing);
sideWing.position.set(0,0,0);
sideWing.castShadow = true;
sideWing.receiveShadow = true;
this.mesh.add(sideWing);
// 螺旋桨
var geomPropeller = new THREE.BoxGeometry(20,10,10,1,1,1);
var matPropeller = new THREE.MeshPhongMaterial({color:Colors.brown, shading:THREE.FlatShading});
this.propeller = new THREE.Mesh(geomPropeller, matPropeller);
this.propeller.castShadow = true;
this.propeller.receiveShadow = true;
// Blades
var geomBlade = new THREE.BoxGeometry(1,100,20,1,1,1);
var matBlade = new THREE.MeshPhongMaterial({color:Colors.brownDark, shading:THREE.FlatShading});
var blade = new THREE.Mesh(geomBlade, matBlade);
blade.position.set(8,0,0);
blade.castShadow = true;
blade.receiveShadow = true;
this.propeller.add(blade);
this.propeller.position.set(50,0,0);
this.mesh.add(this.propeller);
};
Sky = function(){
this.mesh = new THREE.Object3D();
this.nClouds = 20;
this.clouds = [];
var stepAngle = Math.PI*2 / this.nClouds;
for(var i=0; i<this.nClouds; i++){
var c = new Cloud();
this.clouds.push(c);
var a = stepAngle*i;
var h = 750 + Math.random()*200;
c.mesh.position.y = Math.sin(a)*h;
c.mesh.position.x = Math.cos(a)*h;
c.mesh.position.z = -400-Math.random()*400;
c.mesh.rotation.z = a + Math.PI/2;
var s = 1+Math.random()*2;
c.mesh.scale.set(s,s,s);
this.mesh.add(c.mesh);
}
}
Sea = function(){
var geom = new THREE.CylinderGeometry(600,600,800,40,10);
geom.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI/2));
var mat = new THREE.MeshPhongMaterial({
color:Colors.blue,
transparent:true,
opacity:.6,
shading:THREE.FlatShading,
});
this.mesh = new THREE.Mesh(geom, mat);
this.mesh.receiveShadow = true;
}
Cloud = function(){
this.mesh = new THREE.Object3D();
this.mesh.name = "cloud";
var geom = new THREE.CubeGeometry(20,20,20);
var mat = new THREE.MeshPhongMaterial({
color:Colors.white,
});
var nBlocs = 3+Math.floor(Math.random()*3);
for (var i=0; i<nBlocs; i++ ){
var m = new THREE.Mesh(geom.clone(), mat);
m.position.x = i*15;
m.position.y = Math.random()*10;
m.position.z = Math.random()*10;
m.rotation.z = Math.random()*Math.PI*2;
m.rotation.y = Math.random()*Math.PI*2;
var s = .1 + Math.random()*.9;
m.scale.set(s,s,s);
m.castShadow = true;
m.receiveShadow = true;
this.mesh.add(m);
}
}
// 3D模型
var sea;
var airplane;
function createPlane(){
airplane = new AirPlane();
airplane.mesh.scale.set(.25,.25,.25);
airplane.mesh.position.y = 100;
scene.add(airplane.mesh);
}
function createSea(){
sea = new Sea();
sea.mesh.position.y = -600;
scene.add(sea.mesh);
}
function createSky(){
sky = new Sky();
sky.mesh.position.y = -600;
scene.add(sky.mesh);
}
function loop(){
updatePlane();
sea.mesh.rotation.z += .004;
sky.mesh.rotation.z += .01;
renderer.render(scene, camera);
requestAnimationFrame(loop);
}
function updatePlane(){
var targetY = normalize(mousePos.y,-.75,.75,25, 175);
var targetX = normalize(mousePos.x,-.75,.75,-100, 100);
airplane.mesh.position.y = targetY;
airplane.mesh.position.x = targetX;
airplane.propeller.rotation.x += 0.3;
}
function normalize(v,vmin,vmax,tmin, tmax){
var nv = Math.max(Math.min(v,vmax), vmin);
var dv = vmax-vmin;
var pc = (nv-vmin)/dv;
var dt = tmax-tmin;
var tv = tmin + (pc*dt);
return tv;
}
function init(event){
document.addEventListener('mousemove', handleMouseMove, false);
createScene();
createLights();
createPlane();
createSea();
createSky();
loop();
}
//键盘事件
(function setKeyEvents(){
window.addEventListener('keydown',function(e){
console.log(e);
switch(e.keyCode){
case 81:
camera.position.x += 1;
console.log('q');
break;
case 69:
camera.position.x -= 1;
console.log('e');
break;
case 39:
camera.position.y += 1;
console.log('右');
break;
case 37:
camera.position.y -= 1;
console.log('左');
break;
case 38:
camera.position.z += 1;
console.log('上');
break;
case 40:
camera.position.z -= 1;
console.log('下');
}
renderer.render(scene, camera);
});
})();
// 鼠标事件
var mousePos = { x: 0, y: 0 };
function handleMouseMove(event) {
var tx = -1 + (event.clientX / WIDTH)*2;
var ty = 1 - (event.clientY / HEIGHT)*2;
mousePos = {x:tx, y:ty};
}
window.addEventListener('load', init, false);