- BC20280055's blog
3D地球
- @ 2025-11-7 22:20:14
3D地球模型
body {
margin: 0;
padding: 0;
background-color: #000000;
overflow: hidden;
font-family: Arial, sans-serif;
}
#container {
width: 100%;
height: 100vh;
display: block;
}
#instructions {
position: absolute;
top: 20px;
left: 0;
width: 100%;
text-align: center;
color: white;
font-size: 14px;
font-family: Arial, sans-serif;
text-shadow: 2px 2px 4px #000000;
pointer-events: none; /* 不阻挡鼠标事件 */
z-index: 10;
}
</style>
拖动地球旋转 | Drag to rotate the Earth
<!-- 引入Three.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// 基本Three.js设置
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 2;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById('container').appendChild(renderer.domElement);
// 创建地球几何体
const geometry = new THREE.SphereGeometry(1, 64, 64);
// 加载贴图
const textureLoader = new THREE.TextureLoader();
const map = textureLoader.load('https://threejs.org/examples/textures/planets/earth_atmos_2048.jpg');
const bumpMap = textureLoader.load('https://threejs.org/examples/textures/planets/earth_normal_2048.jpg');
const specularMap = textureLoader.load('https://threejs.org/examples/textures/planets/earth_specular_2048.jpg');
// 创建材质
const material = new THREE.MeshPhongMaterial({
map: map,
bumpMap: bumpMap,
bumpScale: 0.05,
specularMap: specularMap,
specular: new THREE.Color(0x333333),
shininess: 5
});
// 创建地球网格
const earth = new THREE.Mesh(geometry, material);
scene.add(earth);
// 添加灯光
const ambientLight = new THREE.AmbientLight(0x404040, 1);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(2, 1, 3).normalize();
scene.add(directionalLight);
// 鼠标交互控制
let isDragging = false;
let previousMousePosition = {
x: 0,
y: 0
};
// 鼠标按下事件
function onMouseDown(event) {
isDragging = true;
previousMousePosition = {
x: event.clientX,
y: event.clientY
};
}
// 鼠标移动事件
function onMouseMove(event) {
if (isDragging) {
const deltaX = event.clientX - previousMousePosition.x;
const deltaY = event.clientY - previousMousePosition.y;
// 更新地球旋转
earth.rotation.y += deltaX * 0.01;
earth.rotation.x += deltaY * 0.01;
previousMousePosition = {
x: event.clientX,
y: event.clientY
};
}
}
// 鼠标释放事件
function onMouseUp() {
isDragging = false;
}
// 鼠标离开画布事件
function onMouseLeave() {
isDragging = false;
}
// 禁用右键菜单
function onContextMenu(event) {
event.preventDefault();
}
// 绑定事件监听器
renderer.domElement.addEventListener('mousedown', onMouseDown, false);
window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('mouseup', onMouseUp, false);
renderer.domElement.addEventListener('mouseleave', onMouseLeave, false);
renderer.domElement.addEventListener('contextmenu', onContextMenu, false);
// 响应式调整
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
window.addEventListener('resize', onWindowResize, false);
// 动画循环
function animate() {
requestAnimationFrame(animate);
// 非拖动状态下自动旋转
if (!isDragging) {
earth.rotation.y += 0.001;
}
renderer.render(scene, camera);
}
animate();
</script>