Search K
Appearance
Appearance
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
html,
body {
overflow: hidden;
}
.webgl {
position: fixed;
top: 0;
left: 0;
outline: none;
height: 100vh;
width: 100vw;
}
</style>
</head>
<body>
<canvas class="webgl"></canvas>
<script type="module">
import * as THREE from "../libs/three.module.js"
import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/OrbitControls.js'
let renderer = null;
let camera = null;
let scene = null;
let controls = null;
let canvas = null;
let loader = null;
let plantMesh, ringMesh, torusMesh, starGroup, satellite = null;
// 声明一个变量angle表示角度位置
let angle = 0;
// 定义渲染尺寸
const sizes = {
width: window.innerWidth,
height: window.innerHeight
}
// 初始化渲染器
const initRenderer = () => {
canvas = document.querySelector('canvas.webgl');
renderer = new THREE.WebGLRenderer({ canvas, antialias: true })
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
}
// 初始化场景
const initScene = () => {
scene = new THREE.Scene()
scene.background = new THREE.Color(0x1A1A1A)
// 场景雾化
scene.fog = new THREE.Fog(0x1A1A1A, 1, 1000)
}
// 初始化相机
const initCamera = () => {
camera = new THREE.PerspectiveCamera(40, sizes.width / sizes.height, 0.1, 1000)
scene.add(camera)
camera.position.set(20, 100, 450)
}
// 初始化控制器
const initControl = () => {
controls = new OrbitControls(camera, renderer.domElement)
// 开启控制器的移动惯性,鼠标交互过程会更加流畅和逼真
controls.enableDamping = true
}
// 初始化灯光
const initLight = () => {
const light = new THREE.AmbientLight(0xdeedff, 1.5)
scene.add(light)
}
// 创建星球
const initMesh = () => {
// Lambert 材质,考虑光照影响的材质,用于创建暗淡的、不光亮的物体。
const material = new THREE.MeshLambertMaterial({
color: 0x03c03c,
wireframe: true,
});
// 创建球体
const sphereGeometry = new THREE.SphereGeometry(80, 32, 32)
plantMesh = new THREE.Mesh(sphereGeometry, material)
scene.add(plantMesh)
// 创建紫色轨道
const torusMaterial = new THREE.MeshLambertMaterial({
color: 0xaa61ed,
wireframe: true
})
const torusGeometry = new THREE.TorusGeometry(150, 8, 2, 120)
torusMesh = new THREE.Mesh(torusGeometry, torusMaterial)
torusMesh.rotation.x = Math.PI / 2
torusMesh.rotation.y = 0.4 * (Math.PI / 2);
scene.add(torusMesh)
// 添加蓝色轨道
const ringMaterial = new THREE.MeshLambertMaterial({
color: 0x40a9ff,
wireframe: true
})
const ringGeometry = new THREE.RingGeometry(140, 160, 120)
ringMesh = new THREE.Mesh(ringGeometry, ringMaterial)
ringMesh.rotation.x = Math.PI / 2
ringMesh.rotation.y = -0.1 * (Math.PI / 2);
scene.add(ringMesh)
}
// 创建星星
const initStar = () => {
// 创建一个网格组
starGroup = new THREE.Group()
// 创建1000颗星星
for (let i = 0; i < 1000; i++) {
// 创建20面几何体
const geometry = new THREE.IcosahedronGeometry(Math.random() * 2, 0);
// 卡通网格材质
const material = new THREE.MeshToonMaterial({ color: 0xeeeeee });
// 创建20面几何体模拟星星,随机设置星星的位置与旋转方向
const mesh = new THREE.Mesh(geometry, material)
mesh.position.x = (Math.random() - 0.5) * 700;
mesh.position.y = (Math.random() - 0.5) * 700;
mesh.position.z = (Math.random() - 0.5) * 700;
mesh.rotation.x = Math.random() * 2 * Math.PI;
mesh.rotation.y = Math.random() * 2 * Math.PI;
mesh.rotation.z = Math.random() * 2 * Math.PI;
starGroup.add(mesh)
}
scene.add(starGroup)
}
// 创建卫星
const initSatellite = () => {
const IcoGeometry = new THREE.IcosahedronGeometry(16, 0);
const IcoMaterial = new THREE.MeshToonMaterial({ color: 0xfffc00 });
satellite = new THREE.Mesh(IcoGeometry, IcoMaterial);
scene.add(satellite);
}
// 场景和相机放入渲染器中
const render = (time = 1) => {
const axis = new THREE.Vector3(0, 0, 1);
time *= 0.001
// 中心球体旋转
plantMesh.rotation.y = time
// 设置轨道动画
ringMesh.rotateOnAxis(axis, Math.PI / 400);
torusMesh.rotateOnAxis(axis, Math.PI / 400);
// 卫星动画
// 每次执行渲染函数redner时候,角度累加0.005
angle += 0.005;
// 圆周运动网格模型x坐标计算 绕转半径200
satellite.position.x = 250 * Math.sin(angle)
// 圆周运动网格模型y坐标计算 绕转半径200
satellite.position.z = 250 * Math.cos(angle)
// 星星动画
starGroup.rotation.y += 0.0009;
starGroup.rotation.z -= 0.0003;
// 加载渲染器
renderer.render(scene, camera)
// 开始动画
requestAnimationFrame(render)
}
// 页面缩放事件监听
window.addEventListener('resize', () => {
sizes.width = window.innerWidth;
sizes.height = window.innerHeight;
// 更新渲染
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
// 更新相机
camera.aspect = sizes.width / sizes.height;
camera.updateProjectionMatrix();
});
initScene()
initRenderer()
initCamera()
initControl()
initLight()
initMesh()
initStar()
initSatellite()
requestAnimationFrame(render)
</script>
</body>
</html>
// 创建星球
const initMesh = () => {
// Lambert 材质,考虑光照影响的材质,用于创建暗淡的、不光亮的物体。
const material = new THREE.MeshLambertMaterial({
color: 0x03c03c,
wireframe: true,
});
// 创建球体
const sphereGeometry = new THREE.SphereGeometry(80, 32, 32)
plantMesh = new THREE.Mesh(sphereGeometry, material)
scene.add(plantMesh)
// 创建紫色轨道
const torusMaterial = new THREE.MeshLambertMaterial({
color: 0xaa61ed,
wireframe: true
})
const torusGeometry = new THREE.TorusGeometry(150, 8, 2, 120)
torusMesh = new THREE.Mesh(torusGeometry, torusMaterial)
torusMesh.rotation.x = Math.PI / 2
torusMesh.rotation.y = 0.4 * (Math.PI / 2);
scene.add(torusMesh)
// 添加蓝色轨道
const ringMaterial = new THREE.MeshLambertMaterial({
color: 0x40a9ff,
wireframe: true
})
const ringGeometry = new THREE.RingGeometry(140, 160, 120)
ringMesh = new THREE.Mesh(ringGeometry, ringMaterial)
ringMesh.rotation.x = Math.PI / 2
ringMesh.rotation.y = -0.1 * (Math.PI / 2);
scene.add(ringMesh)
}
// 场景和相机放入渲染器中
const render = (time = 1) => {
const axis = new THREE.Vector3(0, 0, 1);
time *= 0.001
// 中心球体旋转
plantMesh.rotation.y = time
// 设置轨道动画
ringMesh.rotateOnAxis(axis, Math.PI / 400);
torusMesh.rotateOnAxis(axis, Math.PI / 400);
// 加载渲染器
renderer.render(scene, camera)
// 开始动画
requestAnimationFrame(render)
}
星星需要不断的运动,并且形状、位置都不一样。
const starGroup = null
// 创建星星
const initStar = () => {
// 创建一个网格组
starGroup = new THREE.Group()
// 创建1000颗星星
for (let i = 0; i < 1000; i++) {
// 创建20面几何体
const geometry = new THREE.IcosahedronGeometry(Math.random() * 2, 0);
// 卡通网格材质
const material = new THREE.MeshToonMaterial({ color: 0xeeeeee });
// 创建20面几何体模拟星星,随机设置星星的位置与旋转方向
const mesh = new THREE.Mesh(geometry, material)
mesh.position.x = (Math.random() - 0.5) * 700;
mesh.position.y = (Math.random() - 0.5) * 700;
mesh.position.z = (Math.random() - 0.5) * 700;
mesh.rotation.x = Math.random() * 2 * Math.PI;
mesh.rotation.y = Math.random() * 2 * Math.PI;
mesh.rotation.z = Math.random() * 2 * Math.PI;
starGroup.add(mesh)
}
scene.add(starGroup)
}
// 场景和相机放入渲染器中
const render = (time = 1) => {
time *= 0.001
// 星星动画
starGroup.rotation.y += 0.0009;
starGroup.rotation.z -= 0.0003;
// 加载渲染器
renderer.render(scene, camera)
// 开始动画
requestAnimationFrame(render)
}
var angle = 0
// 创建卫星
const initSatellite = () => {
const IcoGeometry = new THREE.IcosahedronGeometry(16, 0);
const IcoMaterial = new THREE.MeshToonMaterial({ color: 0xfffc00 });
satellite = new THREE.Mesh(IcoGeometry, IcoMaterial);
scene.add(satellite);
}
// 场景和相机放入渲染器中
const render = (time = 1) => {
const axis = new THREE.Vector3(0, 0, 1);
time *= 0.001
// 卫星动画
// 每次执行渲染函数redner时候,角度累加0.005
angle += 0.005;
// 圆周运动网格模型x坐标计算 绕转半径200
satellite.position.x = 250 * Math.sin(angle)
// 圆周运动网格模型y坐标计算 绕转半径200
satellite.position.z = 250 * Math.cos(angle)
// 加载渲染器
renderer.render(scene, camera)
// 开始动画
requestAnimationFrame(render)
}
TIP