Enhance Earth interaction and bump version to 0.21.0

This commit is contained in:
linkong
2026-03-26 11:09:57 +08:00
parent a04f4f9e67
commit 7b53cf9a06
12 changed files with 211 additions and 56 deletions

View File

@@ -81,6 +81,8 @@ export let renderer;
let simplex;
let isDragging = false;
let previousMousePosition = { x: 0, y: 0 };
let targetRotation = { x: 0, y: 0 };
let inertialVelocity = { x: 0, y: 0 };
let hoveredCable = null;
let hoveredSatellite = null;
let hoveredSatelliteIndex = null;
@@ -108,6 +110,10 @@ const scratchCableCenter = new THREE.Vector3();
const scratchCableDirection = new THREE.Vector3();
const cleanupFns = [];
const DRAG_ROTATION_FACTOR = 0.005;
const DRAG_SMOOTHING_FACTOR = 0.18;
const INERTIA_DAMPING = 0.92;
const INERTIA_MIN_VELOCITY = 0.00008;
function bindListener(target, eventName, handler, options) {
if (!target) return;
@@ -327,6 +333,11 @@ export function init() {
addLights();
initInfoCard();
const earthObj = createEarth(scene);
targetRotation = {
x: earthObj.rotation.x,
y: earthObj.rotation.y,
};
inertialVelocity = { x: 0, y: 0 };
createClouds(scene, earthObj);
createTerrain(scene, earthObj, simplex);
createStars(scene);
@@ -461,16 +472,17 @@ function setupEventListeners() {
const handleMouseMove = (event) => onMouseMove(event);
const handleMouseDown = (event) => onMouseDown(event);
const handleMouseUp = () => onMouseUp();
const handleMouseLeave = () => onMouseLeave();
const handleClick = (event) => onClick(event);
const handlePageHide = () => destroy();
bindListener(window, "resize", handleResize);
bindListener(window, "pagehide", handlePageHide);
bindListener(window, "beforeunload", handlePageHide);
bindListener(renderer.domElement, "mousemove", handleMouseMove);
bindListener(window, "mousemove", handleMouseMove);
bindListener(renderer.domElement, "mousedown", handleMouseDown);
bindListener(renderer.domElement, "mouseup", handleMouseUp);
bindListener(renderer.domElement, "mouseleave", handleMouseUp);
bindListener(window, "mouseup", handleMouseUp);
bindListener(renderer.domElement, "mouseleave", handleMouseLeave);
bindListener(renderer.domElement, "click", handleClick);
}
@@ -512,8 +524,13 @@ function onMouseMove(event) {
const deltaX = event.clientX - previousMousePosition.x;
const deltaY = event.clientY - previousMousePosition.y;
earth.rotation.y += deltaX * 0.005;
earth.rotation.x += deltaY * 0.005;
const rotationDeltaY = deltaX * DRAG_ROTATION_FACTOR;
const rotationDeltaX = deltaY * DRAG_ROTATION_FACTOR;
targetRotation.y += rotationDeltaY;
targetRotation.x += rotationDeltaX;
inertialVelocity.y = rotationDeltaY;
inertialVelocity.x = rotationDeltaX;
previousMousePosition = { x: event.clientX, y: event.clientY };
hideTooltip();
return;
@@ -624,10 +641,18 @@ function onMouseMove(event) {
}
function onMouseDown(event) {
const earth = getEarth();
isDragging = true;
dragStartTime = Date.now();
isLongDrag = false;
previousMousePosition = { x: event.clientX, y: event.clientY };
inertialVelocity = { x: 0, y: 0 };
if (earth) {
targetRotation = {
x: earth.rotation.x,
y: earth.rotation.y,
};
}
document.getElementById("container")?.classList.add("dragging");
hideTooltip();
}
@@ -637,6 +662,10 @@ function onMouseUp() {
document.getElementById("container")?.classList.remove("dragging");
}
function onMouseLeave() {
hideTooltip();
}
function onClick(event) {
const earth = getEarth();
if (!earth) return;
@@ -735,6 +764,36 @@ function animate() {
if (getAutoRotate() && earth) {
earth.rotation.y += CONFIG.rotationSpeed * (deltaTime / 16);
targetRotation.y = earth.rotation.y;
targetRotation.x = earth.rotation.x;
}
if (earth) {
if (isDragging) {
// Smoothly follow the drag target to match the legacy interaction feel.
earth.rotation.x +=
(targetRotation.x - earth.rotation.x) * DRAG_SMOOTHING_FACTOR;
earth.rotation.y +=
(targetRotation.y - earth.rotation.y) * DRAG_SMOOTHING_FACTOR;
} else if (
Math.abs(inertialVelocity.x) > INERTIA_MIN_VELOCITY ||
Math.abs(inertialVelocity.y) > INERTIA_MIN_VELOCITY
) {
// Continue rotating after release and gradually decay the motion.
targetRotation.x += inertialVelocity.x * (deltaTime / 16);
targetRotation.y += inertialVelocity.y * (deltaTime / 16);
earth.rotation.x +=
(targetRotation.x - earth.rotation.x) * DRAG_SMOOTHING_FACTOR;
earth.rotation.y +=
(targetRotation.y - earth.rotation.y) * DRAG_SMOOTHING_FACTOR;
inertialVelocity.x *= Math.pow(INERTIA_DAMPING, deltaTime / 16);
inertialVelocity.y *= Math.pow(INERTIA_DAMPING, deltaTime / 16);
} else {
inertialVelocity.x = 0;
inertialVelocity.y = 0;
targetRotation.x = earth.rotation.x;
targetRotation.y = earth.rotation.y;
}
}
applyCableVisualState();