今年刚刚接触threejs。这玩意封装得挺不错。为了使大家感观上能够了解threejs.这里直接分享一段代码。看完就知道threejs的套路了。所有的学习资料,源代码,从github上已经足够。5000多的源码分享,天啊。。。
https://github.com/search?q=threejs
有几个例子也比较好的:https://github.com/luosijie/threejs-examples
以下一个案例,配置运行起来可以直接了解到threejs的结构。threejs的JS引用文件自己去官方找。https://threejs.org/
效果示意图:
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - Simple text from json</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 10px;
width: 100%;
text-align: center;
}
</style>
</head>
<body>
<div id="info">
<script src="../build/three.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/loaders/VRMLLoader.js"></script>
<script src="js/WebGL.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script src="https://cdn.bootcss.com/jszip/2.1.0/jszip.min.js"></script>
<script src="https://cdn.bootcss.com/jszip-utils/0.0.2/jszip-utils.min.js"></script>
<script>
var camera, scene, renderer;
var components = [];
var selComps = [];
var controls;
var mouseInfo;
var tube;
var ptone;
initComp();
animate();
function initComp() {
document.addEventListener('mousedown', onDocumentMouseDown, false);
document.addEventListener('mousemove', onDocumentMouseMove, false);
document.addEventListener('mouseup', onDocumentMouseUp, false);
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1e10);
camera.up.set(0, 1, 0);
controls = new THREE.OrbitControls(camera);
scene = new THREE.Scene();
camera.position.set(100,100,100);
scene.position = new THREE.Vector3(0,0,0);
scene.up = new THREE.Vector3(0,0,1);
dxplane();
cube();
sphere();
cylinder();
var axes = new THREE.AxisHelper(100);
scene.add(axes);
controls.update();
var ambientLight = new THREE.AmbientLight(0x606060);
scene.add(ambientLight);
//平行光源
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 0.75, 0.5).normalize();
scene.add(directionalLight);
scene.background = new THREE.Color(0xffffff);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
} // end init
function initLight() {
scene.add(new THREE.AmbientLight(0x444444));
light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 0, 0);
light.castShadow = true;
light.shadow.camera.top = 10;
light.shadow.camera.bottom = -10;
light.shadow.camera.left = -10;
light.shadow.camera.right = 10;
//告诉平行光需要开启阴影投射
light.castShadow = true;
scene.add(light);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
if (renderer)
renderer.render(scene, camera);
}
function onDocumentMouseDown(event) {
console.log(event);
if (event.button != 0) return;
mouseInfo = { start: [event.x, event.y] };
}
function onDocumentMouseUp(event) {
if (event.button != 0) return;
if (event.x - mouseInfo.start[0] != 0 || event.y - mouseInfo.start[1] != 0) return;
var vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5);
vector = vector.unproject(camera);
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
var intersects = raycaster.intersectObjects(components);
console.log(intersects)
// console.log(intersects.length)
if (selComps.length > 0) {
selComps[0].object.material.transparent = false;
selComps[0].object.material.opacity = 1;
selComps = [];
}
if (intersects.length > 0) {
// console.log(intersects[0]);
intersects[0].object.material.transparent = true;
intersects[0].object.material.opacity = 0.5;
selComps.push(intersects[0]);
}
}
function onDocumentMouseMove(event) {
if (controls.showRay) {
var vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5);
vector = vector.unproject(camera);
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
var intersects = raycaster.intersectObjects(components);
if (intersects.length > 0) {
var points = [];
points.push(new THREE.Vector3(-30, 39.8, 30));
points.push(intersects[0].point);
var mat = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.6 });
var tubeGeometry = new THREE.TubeGeometry(new THREE.SplineCurve3(points), 60, 0.001);
if (tube) scene.remove(tube);
if (controls.showRay) {
tube = new THREE.Mesh(tubeGeometry, mat);
scene.add(tube);
}
}
}
}
//创建一个平面
function dxplane() {
var planeGeo = new THREE.PlaneGeometry(100, 100, 10, 10);//创建平面
var planeMat = new THREE.MeshLambertMaterial({ //创建材料
color: 0x666666,
wireframe: false
});
var planeMesh = new THREE.Mesh(planeGeo, planeMat);//创建网格模型
planeMesh.position.set(0, 0, -20);//设置平面的坐标
planeMesh.rotation.x = -0.5 * Math.PI;//将平面绕X轴逆时针旋转90度
scene.add(planeMesh);//将平面添加到场景中
}
//创建一个立方体
function cube() {
var cubeGeo = new THREE.CubeGeometry(20, 20, 20, 5, 5, 5);//创建立方体
var cubeMat = new THREE.MeshLambertMaterial({//创建材料
color: 0x003300,
wireframe: false
});
var cubeMesh = new THREE.Mesh(cubeGeo, cubeMat);//创建立方体网格模型
cubeMesh.position.set(20, 10, 0);//设置立方体的坐标
scene.add(cubeMesh);//将立方体添加到场景中
}
//创建一个球
function sphere() {
var sphereGeo = new THREE.SphereGeometry(16, 40, 40);//创建球体
var sphereMat = new THREE.MeshLambertMaterial({//创建材料
color: 0x0000FF,
wireframe: false
});
var sphereMesh = new THREE.Mesh(sphereGeo, sphereMat);//创建球体网格模型
sphereMesh.position.set(-25, 10, 0);//设置球的坐标
scene.add(sphereMesh);//将球体添加到场景
}
//创建圆柱体
function cylinder() {
//创建圆柱体
var cylinderGeo = new THREE.CylinderGeometry(15, 15, 40, 40, 40);
var cylinderMat = new THREE.MeshLambertMaterial({//创建材料
color: 0xFF6600,
wireframe: false
});
//创建圆柱体网格模型
var cylinderMesh = new THREE.Mesh(cylinderGeo, cylinderMat);
cylinderMesh.position.set(0, 20, -40);//设置圆柱坐标
cylinderMesh.up.set(0, 0, 1);
scene.add(cylinderMesh);//向场景添加圆柱体
}
</script>
</body>
</html>