<!doctype html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <title>3D地月环绕</title> <style type="text/css"> *{ margin: 0; padding: 0; } canvas{ background-image: url(resource/Demo04/imgs/starts.jpg); background-size: cover; } .label{ color: #FFF; font-size: 16px; } </style> <script type="module"> import *as THREE from '/libs/build/three.module.js'; import { OrbitControls } from '/libs/jsm/controls/OrbitControls.js'; import { CSS2DRenderer,CSS2DObject } from '/libs/jsm/renderers/CSS2DRenderer.js';
let camera,scene,renderer,labelRenderer; let moon,earth; let clock = new THREE.Clock(); const textureLoader = new THREE.TextureLoader();
function init(){ const EARTH_RADIUS = 2.5; const MOON_RADIUS = 0.27; camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,200); camera.position.set(10,5,20); scene = new THREE.Scene(); const dirLight = new THREE.SpotLight(0xFFFFFF); dirLight.position.set(0,0,10); dirLight.intensity = 2; dirLight.castShadow = true; scene.add(dirLight); const aLight = new THREE.AmbientLight(0xFFFFFF); aLight.intensity = 0.3; scene.add(aLight);
const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS,16,16); const moonMaterial = new THREE.MeshPhongMaterial({ map:textureLoader.load('resource/Demo04/textures/planets/moon_1024.jpg') }); moon = new THREE.Mesh(moonGeometry,moonMaterial); moon.receiveShadow = true; moon.castShadow = true; scene.add(moon); const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS,16,16); const earthMaterial = new THREE.MeshPhongMaterial({ shininess:5, map:textureLoader.load('resource/Demo04/textures/planets/earth_atmos_2048.jpg'), specularMap:textureLoader.load('resource/Demo04/textures/planets/earth_specular_2048.jpg'), normalMap:textureLoader.load('resource/Demo04/textures/planets/earth_normal_2048.jpg') }) earth = new THREE.Mesh(earthGeometry,earthMaterial); earth.receiveShadow = true; earth.castShadow = true; scene.add(earth);
const earthDiv = document.createElement('div'); earthDiv.className = 'label'; earthDiv.textContent = '地球'; const eartchLabel = new CSS2DObject(earthDiv); eartchLabel.position.set(0,EARTH_RADIUS+0.5,0); earth.add(eartchLabel); const MoonDiv = document.createElement('div'); MoonDiv.className = 'label'; MoonDiv.textContent = '月球'; const MoonLabel = new CSS2DObject(MoonDiv); MoonLabel.position.set(0,MOON_RADIUS+0.5,0); moon.add(MoonLabel);
renderer = new THREE.WebGLRenderer({ alpha:true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth,window.innerHeight); renderer.shadowMap.enabled = true; document.body.appendChild(renderer.domElement);
labelRenderer = new CSS2DRenderer(); labelRenderer.setSize(window.innerWidth,window.innerHeight); labelRenderer.domElement.style.position = 'absolute'; labelRenderer.domElement.style.top = '0px'; document.body.appendChild(labelRenderer.domElement);
const controls = new OrbitControls(camera,labelRenderer.domElement); controls.addEventListener('change',()=>{ renderer.render(scene,camera); labelRenderer.render(scene,camera); }) } var oldTime = 0; function animate(){ const elapsed = clock.getElapsedTime(); moon.position.set(Math.sin(elapsed)*5,0,Math.cos(elapsed)*5); let axis = new THREE.Vector3(0,1,0); earth.rotateOnAxis(axis,(elapsed - oldTime) * Math.PI / 10); renderer.render(scene,camera); labelRenderer.render(scene,camera); oldTime = elapsed; requestAnimationFrame(animate); }
init() animate()
window.onreset = function (){ camera.aspect = window.innerWidth/window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth,window.innerHeight); } </script> </head>
<body>
</body>
</html>
|