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>