moonphase kann jetz HD Texturen
This commit is contained in:
@@ -2257,6 +2257,12 @@ body.moonphase-page.has-modal {
|
|||||||
color: #c8ffc0;
|
color: #c8ffc0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.moon-hd-btn.is-active {
|
||||||
|
background: rgba(201, 168, 76, 0.18);
|
||||||
|
border-color: var(--gold);
|
||||||
|
color: var(--gold-pale);
|
||||||
|
}
|
||||||
|
|
||||||
.moon-phase-name {
|
.moon-phase-name {
|
||||||
font-family: 'Orbitron', sans-serif;
|
font-family: 'Orbitron', sans-serif;
|
||||||
font-size: 1.15rem;
|
font-size: 1.15rem;
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 21 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 40 MiB |
+231
-123
@@ -166,6 +166,7 @@ try {
|
|||||||
>PNG export</button>
|
>PNG export</button>
|
||||||
<button type="button" class="date-shift-btn moon-crater-btn" id="showAllCratersBtn">Alle Krater</button>
|
<button type="button" class="date-shift-btn moon-crater-btn" id="showAllCratersBtn">Alle Krater</button>
|
||||||
<button type="button" class="date-shift-btn moon-crater-btn" id="showTerminatorCratersBtn">Krater am Terminator</button>
|
<button type="button" class="date-shift-btn moon-crater-btn" id="showTerminatorCratersBtn">Krater am Terminator</button>
|
||||||
|
<button type="button" class="date-shift-btn moon-hd-btn" id="hdTextureBtn" title="Hochauflösende Texturen und Höhenkarte laden (60MB)">HD</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -328,6 +329,7 @@ const nextDayBtn = document.getElementById('nextDayBtn');
|
|||||||
const nowBtn = document.getElementById('nowBtn');
|
const nowBtn = document.getElementById('nowBtn');
|
||||||
const resetViewBtn = document.getElementById('resetViewBtn');
|
const resetViewBtn = document.getElementById('resetViewBtn');
|
||||||
const freeCameraBtn = document.getElementById('freeCameraBtn');
|
const freeCameraBtn = document.getElementById('freeCameraBtn');
|
||||||
|
const hdTextureBtn = document.getElementById('hdTextureBtn');
|
||||||
const playPauseBtn = document.getElementById('playPauseBtn');
|
const playPauseBtn = document.getElementById('playPauseBtn');
|
||||||
const playbackSpeedGroup = document.getElementById('playbackSpeedGroup');
|
const playbackSpeedGroup = document.getElementById('playbackSpeedGroup');
|
||||||
const exportMoonBtn = document.getElementById('exportMoonBtn');
|
const exportMoonBtn = document.getElementById('exportMoonBtn');
|
||||||
@@ -358,6 +360,8 @@ let moonPlaybackSpeed = 1;
|
|||||||
let isMoonExportRunning = false;
|
let isMoonExportRunning = false;
|
||||||
let moonExportRestoreFocus = null;
|
let moonExportRestoreFocus = null;
|
||||||
let freeCameraMode = false;
|
let freeCameraMode = false;
|
||||||
|
let hdTexturesLoaded = false;
|
||||||
|
let hdTexturesLoading = false;
|
||||||
let cameraOrbitTheta = 0;
|
let cameraOrbitTheta = 0;
|
||||||
let cameraOrbitPhi = Math.PI / 2;
|
let cameraOrbitPhi = Math.PI / 2;
|
||||||
let moonDragStartOrbitTheta = 0;
|
let moonDragStartOrbitTheta = 0;
|
||||||
@@ -369,8 +373,10 @@ const craterOverlayScale = 0.940;
|
|||||||
const SYNODIC_MONTH = 29.530588853;
|
const SYNODIC_MONTH = 29.530588853;
|
||||||
const KNOWN_NEW_MOON_JD = 2451550.1;
|
const KNOWN_NEW_MOON_JD = 2451550.1;
|
||||||
const MOON_AXIS_INCLINATION = 1.54242;
|
const MOON_AXIS_INCLINATION = 1.54242;
|
||||||
const MOON_TEXTURE_PATH = 'images/moons/moon_8192.jpg';
|
const MOON_TEXTURE_PATH = 'images/moons/moon_4096.jpg';
|
||||||
const MOON_DISPLACEMENT_MAP_PATH = 'images/moons/moon_displacement_16bit.jpg';
|
const MOON_DISPLACEMENT_MAP_PATH = 'images/moons/moon_displacement_16b_low.jpg';
|
||||||
|
const MOON_TEXTURE_PATH_HD = 'images/moons/moon_16384.jpg';
|
||||||
|
const MOON_DISPLACEMENT_MAP_PATH_HD = 'images/moons/moon_displacement_16bit.jpg';
|
||||||
const MOON_TEXTURE_BASE_ROTATION_Y = -Math.PI / 2;
|
const MOON_TEXTURE_BASE_ROTATION_Y = -Math.PI / 2;
|
||||||
const MOON_SPHERE_RADIUS = 1.6;
|
const MOON_SPHERE_RADIUS = 1.6;
|
||||||
const MOON_PROJECTED_RADIUS_SCALE = 0.962;
|
const MOON_PROJECTED_RADIUS_SCALE = 0.962;
|
||||||
@@ -378,8 +384,8 @@ const MOON_DISPLACEMENT_SCALE = 0.0095;
|
|||||||
const MOON_DISPLACEMENT_BIAS = -0.1;
|
const MOON_DISPLACEMENT_BIAS = -0.1;
|
||||||
const MOON_BUMP_SCALE = 2.0;
|
const MOON_BUMP_SCALE = 2.0;
|
||||||
const MOON_CAMERA_BASE_Z = 6.8;
|
const MOON_CAMERA_BASE_Z = 6.8;
|
||||||
const MOON_ZOOM_MIN = 0.8;
|
const MOON_ZOOM_MIN = 0.2;
|
||||||
const MOON_ZOOM_MAX = 3.5;
|
const MOON_ZOOM_MAX = 4.1;
|
||||||
const MOON_PAN_LIMIT = 1.8;
|
const MOON_PAN_LIMIT = 1.8;
|
||||||
const MOON_PLAYBACK_STEP_MINUTES = 5;
|
const MOON_PLAYBACK_STEP_MINUTES = 5;
|
||||||
const MOON_PLAYBACK_INTERVAL_MS = 180;
|
const MOON_PLAYBACK_INTERVAL_MS = 180;
|
||||||
@@ -521,6 +527,100 @@ function resetMoonView() {
|
|||||||
updateMoon();
|
updateMoon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchWithProgress(url, onProgress) {
|
||||||
|
const response = await fetch(url);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const contentLength = Number(response.headers.get('Content-Length') || 0);
|
||||||
|
const reader = response.body.getReader();
|
||||||
|
const chunks = [];
|
||||||
|
let received = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
chunks.push(value);
|
||||||
|
received += value.length;
|
||||||
|
if (contentLength > 0) {
|
||||||
|
onProgress(received / contentLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return URL.createObjectURL(new Blob(chunks));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadHdTextures() {
|
||||||
|
if (hdTexturesLoaded || hdTexturesLoading || !moonSceneState) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdTexturesLoading = true;
|
||||||
|
hdTextureBtn.disabled = true;
|
||||||
|
moonLoading.classList.remove('is-hidden', 'is-error');
|
||||||
|
setMoonLoadingProgress(0, 'HD-Texturen werden geladen... 0 %');
|
||||||
|
|
||||||
|
const textureLoader = new THREE.TextureLoader();
|
||||||
|
const objectUrls = [];
|
||||||
|
|
||||||
|
const loadTexture = (objectUrl, colorSpace) => new Promise((resolve, reject) => {
|
||||||
|
textureLoader.load(objectUrl, tex => {
|
||||||
|
tex.colorSpace = colorSpace;
|
||||||
|
tex.anisotropy = moonSceneState.renderer.capabilities.getMaxAnisotropy();
|
||||||
|
resolve(tex);
|
||||||
|
}, undefined, reject);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
let prog1 = 0;
|
||||||
|
let prog2 = 0;
|
||||||
|
|
||||||
|
const updateProgress = () => {
|
||||||
|
const combined = (prog1 + prog2) / 2;
|
||||||
|
setMoonLoadingProgress(combined, `HD-Texturen werden geladen... ${Math.round(combined * 100)} %`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const [url1, url2] = await Promise.all([
|
||||||
|
fetchWithProgress(MOON_TEXTURE_PATH_HD, p => { prog1 = p; updateProgress(); }),
|
||||||
|
fetchWithProgress(MOON_DISPLACEMENT_MAP_PATH_HD, p => { prog2 = p; updateProgress(); })
|
||||||
|
]);
|
||||||
|
|
||||||
|
objectUrls.push(url1, url2);
|
||||||
|
setMoonLoadingProgress(1, 'HD-Texturen werden verarbeitet...');
|
||||||
|
|
||||||
|
const [hdTex, hdDisp] = await Promise.all([
|
||||||
|
loadTexture(url1, THREE.SRGBColorSpace),
|
||||||
|
loadTexture(url2, THREE.NoColorSpace)
|
||||||
|
]);
|
||||||
|
|
||||||
|
moonSceneState.moonMesh.material.map = hdTex;
|
||||||
|
moonSceneState.moonMesh.material.displacementMap = hdDisp;
|
||||||
|
moonSceneState.moonMesh.material.bumpMap = hdDisp;
|
||||||
|
moonSceneState.moonMesh.material.needsUpdate = true;
|
||||||
|
|
||||||
|
hdTexturesLoaded = true;
|
||||||
|
hdTexturesLoading = false;
|
||||||
|
hdTextureBtn.textContent = 'HD!';
|
||||||
|
hdTextureBtn.classList.add('is-active');
|
||||||
|
hdTextureBtn.disabled = true;
|
||||||
|
|
||||||
|
moonLoadingText.textContent = 'HD-Texturen aktiv';
|
||||||
|
window.setTimeout(hideMoonLoading, 600);
|
||||||
|
updateMoon();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('HD-Textur-Ladefehler:', error);
|
||||||
|
hdTexturesLoading = false;
|
||||||
|
hdTextureBtn.disabled = false;
|
||||||
|
hdTextureBtn.textContent = 'HD fehlgeschl.';
|
||||||
|
hideMoonLoading();
|
||||||
|
} finally {
|
||||||
|
objectUrls.forEach(u => URL.revokeObjectURL(u));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function syncDatePickerWithDate(date) {
|
function syncDatePickerWithDate(date) {
|
||||||
const timezoneOffset = date.getTimezoneOffset() * 60000;
|
const timezoneOffset = date.getTimezoneOffset() * 60000;
|
||||||
datePicker.value = new Date(date.getTime() - timezoneOffset).toISOString().slice(0, 10);
|
datePicker.value = new Date(date.getTime() - timezoneOffset).toISOString().slice(0, 10);
|
||||||
@@ -712,127 +812,134 @@ async function fetchMoonPhaseData(date) {
|
|||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureMoonScene() {
|
let moonSceneInitPromise = null;
|
||||||
if (moonSceneState || typeof THREE === 'undefined') {
|
|
||||||
|
async function ensureMoonScene() {
|
||||||
|
if (moonSceneState) {
|
||||||
return moonSceneState;
|
return moonSceneState;
|
||||||
}
|
}
|
||||||
|
|
||||||
let loadedMoonAssets = 0;
|
if (moonSceneInitPromise) {
|
||||||
let moonTextureFailed = false;
|
return moonSceneInitPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
moonSceneInitPromise = (async () => {
|
||||||
|
moonLoading.classList.remove('is-hidden', 'is-error');
|
||||||
|
setMoonLoadingProgress(0, 'Lade Mondtexturen... 0 %');
|
||||||
|
|
||||||
|
const objectUrls = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
let prog1 = 0;
|
||||||
|
let prog2 = 0;
|
||||||
|
|
||||||
|
const updateProgress = () => {
|
||||||
|
const combined = (prog1 + prog2) / 2;
|
||||||
|
setMoonLoadingProgress(combined, `Lade Mondtexturen... ${Math.round(combined * 100)} %`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const [url1, url2] = await Promise.all([
|
||||||
|
fetchWithProgress(MOON_TEXTURE_PATH, p => { prog1 = p; updateProgress(); }),
|
||||||
|
fetchWithProgress(MOON_DISPLACEMENT_MAP_PATH, p => { prog2 = p; updateProgress(); })
|
||||||
|
]);
|
||||||
|
|
||||||
|
objectUrls.push(url1, url2);
|
||||||
|
setMoonLoadingProgress(1, 'Mondtexturen werden verarbeitet...');
|
||||||
|
|
||||||
|
const renderer = new THREE.WebGLRenderer({
|
||||||
|
canvas: moonCanvas,
|
||||||
|
antialias: true,
|
||||||
|
alpha: false,
|
||||||
|
powerPreference: 'high-performance'
|
||||||
|
});
|
||||||
|
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
||||||
|
renderer.setClearColor(0x010102, 1);
|
||||||
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 3));
|
||||||
|
renderer.shadowMap.enabled = true;
|
||||||
|
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||||
|
|
||||||
|
const scene = new THREE.Scene();
|
||||||
|
const camera = new THREE.PerspectiveCamera(28, 1, 0.1, 100);
|
||||||
|
camera.position.set(0, 0, MOON_CAMERA_BASE_Z);
|
||||||
|
|
||||||
|
const ambientLight = new THREE.AmbientLight(0x1b2230, 0.004);
|
||||||
|
scene.add(ambientLight);
|
||||||
|
|
||||||
|
const sunLight = new THREE.DirectionalLight(0xffffff, 2.9);
|
||||||
|
sunLight.castShadow = true;
|
||||||
|
sunLight.shadow.mapSize.width = 4096;
|
||||||
|
sunLight.shadow.mapSize.height = 4096;
|
||||||
|
sunLight.shadow.bias = -0.00015;
|
||||||
|
sunLight.shadow.normalBias = 0.02;
|
||||||
|
sunLight.shadow.camera.near = 1;
|
||||||
|
sunLight.shadow.camera.far = 20;
|
||||||
|
sunLight.shadow.camera.left = -3;
|
||||||
|
sunLight.shadow.camera.right = 3;
|
||||||
|
sunLight.shadow.camera.top = 3;
|
||||||
|
sunLight.shadow.camera.bottom = -3;
|
||||||
|
scene.add(sunLight);
|
||||||
|
|
||||||
|
const rimLight = new THREE.DirectionalLight(0x89a8ff, 0.015);
|
||||||
|
rimLight.position.set(-2.5, 1.2, 3.2);
|
||||||
|
scene.add(rimLight);
|
||||||
|
|
||||||
|
const textureLoader = new THREE.TextureLoader();
|
||||||
|
const maxAnisotropy = renderer.capabilities.getMaxAnisotropy();
|
||||||
|
|
||||||
|
const loadTex = (url, colorSpace) => new Promise((resolve, reject) => {
|
||||||
|
textureLoader.load(url, tex => {
|
||||||
|
tex.colorSpace = colorSpace;
|
||||||
|
tex.anisotropy = maxAnisotropy;
|
||||||
|
resolve(tex);
|
||||||
|
}, undefined, reject);
|
||||||
|
});
|
||||||
|
|
||||||
|
const [texture, displacementMap] = await Promise.all([
|
||||||
|
loadTex(url1, THREE.SRGBColorSpace),
|
||||||
|
loadTex(url2, THREE.NoColorSpace)
|
||||||
|
]);
|
||||||
|
|
||||||
|
const geometry = new THREE.SphereGeometry(1.6, 256, 256);
|
||||||
|
const material = new THREE.MeshStandardMaterial({
|
||||||
|
map: texture,
|
||||||
|
displacementMap,
|
||||||
|
displacementScale: MOON_DISPLACEMENT_SCALE,
|
||||||
|
displacementBias: MOON_DISPLACEMENT_BIAS,
|
||||||
|
bumpMap: displacementMap,
|
||||||
|
bumpScale: MOON_BUMP_SCALE,
|
||||||
|
roughness: 1,
|
||||||
|
metalness: 0
|
||||||
|
});
|
||||||
|
const moonMesh = new THREE.Mesh(geometry, material);
|
||||||
|
moonMesh.castShadow = true;
|
||||||
|
moonMesh.receiveShadow = true;
|
||||||
|
moonMesh.rotation.y = MOON_TEXTURE_BASE_ROTATION_Y;
|
||||||
|
scene.add(moonMesh);
|
||||||
|
|
||||||
|
moonSceneState = { renderer, scene, camera, moonMesh, sunLight, ambientLight, rimLight };
|
||||||
|
|
||||||
|
resizeMoonScene();
|
||||||
|
applyMoonZoom();
|
||||||
|
renderer.render(scene, camera);
|
||||||
|
|
||||||
const handleMoonAssetLoaded = () => {
|
|
||||||
loadedMoonAssets += 1;
|
|
||||||
setMoonLoadingProgress(loadedMoonAssets / MOON_TEXTURE_ASSET_COUNT);
|
|
||||||
if (loadedMoonAssets >= MOON_TEXTURE_ASSET_COUNT && !moonTextureFailed) {
|
|
||||||
moonLoadingText.textContent = 'Mondtexturen geladen';
|
moonLoadingText.textContent = 'Mondtexturen geladen';
|
||||||
window.setTimeout(hideMoonLoading, 350);
|
window.setTimeout(hideMoonLoading, 350);
|
||||||
|
|
||||||
|
return moonSceneState;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Textur-Ladefehler:', error);
|
||||||
|
moonLoading.classList.remove('is-hidden');
|
||||||
|
moonLoading.classList.add('is-error');
|
||||||
|
moonLoadingFill.style.width = '100%';
|
||||||
|
moonLoadingText.textContent = 'Texturen konnten nicht vollstaendig geladen werden';
|
||||||
|
moonSceneInitPromise = null;
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
objectUrls.forEach(u => URL.revokeObjectURL(u));
|
||||||
}
|
}
|
||||||
};
|
})();
|
||||||
|
|
||||||
const handleMoonAssetError = () => {
|
return moonSceneInitPromise;
|
||||||
moonTextureFailed = true;
|
|
||||||
moonLoading.classList.remove('is-hidden');
|
|
||||||
moonLoading.classList.add('is-error');
|
|
||||||
moonLoadingFill.style.width = '100%';
|
|
||||||
moonLoadingText.textContent = 'Texturen konnten nicht vollstaendig geladen werden';
|
|
||||||
};
|
|
||||||
|
|
||||||
moonLoading.classList.remove('is-hidden', 'is-error');
|
|
||||||
setMoonLoadingProgress(0);
|
|
||||||
|
|
||||||
const renderer = new THREE.WebGLRenderer({
|
|
||||||
canvas: moonCanvas,
|
|
||||||
antialias: true,
|
|
||||||
alpha: false,
|
|
||||||
powerPreference: 'high-performance'
|
|
||||||
});
|
|
||||||
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
|
||||||
renderer.setClearColor(0x010102, 1);
|
|
||||||
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 3));
|
|
||||||
renderer.shadowMap.enabled = true;
|
|
||||||
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
||||||
|
|
||||||
const scene = new THREE.Scene();
|
|
||||||
const camera = new THREE.PerspectiveCamera(28, 1, 0.1, 100);
|
|
||||||
camera.position.set(0, 0, MOON_CAMERA_BASE_Z);
|
|
||||||
|
|
||||||
const ambientLight = new THREE.AmbientLight(0x1b2230, 0.004);
|
|
||||||
scene.add(ambientLight);
|
|
||||||
|
|
||||||
const sunLight = new THREE.DirectionalLight(0xffffff, 2.9);
|
|
||||||
sunLight.castShadow = true;
|
|
||||||
sunLight.shadow.mapSize.width = 4096;
|
|
||||||
sunLight.shadow.mapSize.height = 4096;
|
|
||||||
sunLight.shadow.bias = -0.00015;
|
|
||||||
sunLight.shadow.normalBias = 0.02;
|
|
||||||
sunLight.shadow.camera.near = 1;
|
|
||||||
sunLight.shadow.camera.far = 20;
|
|
||||||
sunLight.shadow.camera.left = -3;
|
|
||||||
sunLight.shadow.camera.right = 3;
|
|
||||||
sunLight.shadow.camera.top = 3;
|
|
||||||
sunLight.shadow.camera.bottom = -3;
|
|
||||||
scene.add(sunLight);
|
|
||||||
|
|
||||||
const rimLight = new THREE.DirectionalLight(0x89a8ff, 0.015);
|
|
||||||
rimLight.position.set(-2.5, 1.2, 3.2);
|
|
||||||
scene.add(rimLight);
|
|
||||||
|
|
||||||
const textureLoader = new THREE.TextureLoader();
|
|
||||||
const texture = textureLoader.load(
|
|
||||||
MOON_TEXTURE_PATH,
|
|
||||||
() => {
|
|
||||||
handleMoonAssetLoaded();
|
|
||||||
resizeMoonScene();
|
|
||||||
renderer.render(scene, camera);
|
|
||||||
},
|
|
||||||
undefined,
|
|
||||||
handleMoonAssetError
|
|
||||||
);
|
|
||||||
texture.colorSpace = THREE.SRGBColorSpace;
|
|
||||||
texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
|
|
||||||
const displacementMap = textureLoader.load(
|
|
||||||
MOON_DISPLACEMENT_MAP_PATH,
|
|
||||||
() => {
|
|
||||||
handleMoonAssetLoaded();
|
|
||||||
resizeMoonScene();
|
|
||||||
renderer.render(scene, camera);
|
|
||||||
},
|
|
||||||
undefined,
|
|
||||||
handleMoonAssetError
|
|
||||||
);
|
|
||||||
displacementMap.colorSpace = THREE.NoColorSpace;
|
|
||||||
displacementMap.anisotropy = renderer.capabilities.getMaxAnisotropy();
|
|
||||||
|
|
||||||
const geometry = new THREE.SphereGeometry(1.6, 256, 256);
|
|
||||||
const material = new THREE.MeshStandardMaterial({
|
|
||||||
map: texture,
|
|
||||||
displacementMap,
|
|
||||||
displacementScale: MOON_DISPLACEMENT_SCALE,
|
|
||||||
displacementBias: MOON_DISPLACEMENT_BIAS,
|
|
||||||
bumpMap: displacementMap,
|
|
||||||
bumpScale: MOON_BUMP_SCALE,
|
|
||||||
roughness: 1,
|
|
||||||
metalness: 0
|
|
||||||
});
|
|
||||||
const moonMesh = new THREE.Mesh(geometry, material);
|
|
||||||
moonMesh.castShadow = true;
|
|
||||||
moonMesh.receiveShadow = true;
|
|
||||||
moonMesh.rotation.y = MOON_TEXTURE_BASE_ROTATION_Y;
|
|
||||||
scene.add(moonMesh);
|
|
||||||
|
|
||||||
moonSceneState = {
|
|
||||||
renderer,
|
|
||||||
scene,
|
|
||||||
camera,
|
|
||||||
moonMesh,
|
|
||||||
sunLight,
|
|
||||||
ambientLight,
|
|
||||||
rimLight
|
|
||||||
};
|
|
||||||
|
|
||||||
resizeMoonScene();
|
|
||||||
applyMoonZoom();
|
|
||||||
return moonSceneState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resizeMoonScene() {
|
function resizeMoonScene() {
|
||||||
@@ -847,8 +954,8 @@ function resizeMoonScene() {
|
|||||||
moonSceneState.camera.updateProjectionMatrix();
|
moonSceneState.camera.updateProjectionMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderMoon3D(phaseData, libration) {
|
async function renderMoon3D(phaseData, libration) {
|
||||||
const state = ensureMoonScene();
|
const state = await ensureMoonScene();
|
||||||
if (!state) {
|
if (!state) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1034,7 +1141,7 @@ async function renderMoon2DToBlob(phaseData, size, transparentBackground = false
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function renderMoon3DToBlob(phaseData, libration, size, transparentBackground = false) {
|
async function renderMoon3DToBlob(phaseData, libration, size, transparentBackground = false) {
|
||||||
const state = ensureMoonScene();
|
const state = await ensureMoonScene();
|
||||||
if (!state) {
|
if (!state) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -1129,8 +1236,8 @@ window.openMoonExportDialog = openMoonExportDialog;
|
|||||||
window.closeMoonExportDialog = closeMoonExportDialog;
|
window.closeMoonExportDialog = closeMoonExportDialog;
|
||||||
window.exportMoonPng = exportMoonPng;
|
window.exportMoonPng = exportMoonPng;
|
||||||
|
|
||||||
function renderMoon(phaseData, libration) {
|
async function renderMoon(phaseData, libration) {
|
||||||
if (renderMoon3D(phaseData, libration)) {
|
if (await renderMoon3D(phaseData, libration)) {
|
||||||
renderMoonCraterOverlay(phaseData, libration);
|
renderMoonCraterOverlay(phaseData, libration);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1449,7 +1556,7 @@ async function updateMoon() {
|
|||||||
const phaseData = moonData.phase;
|
const phaseData = moonData.phase;
|
||||||
const libration = moonData.libration;
|
const libration = moonData.libration;
|
||||||
|
|
||||||
renderMoon(phaseData, libration);
|
await renderMoon(phaseData, libration);
|
||||||
|
|
||||||
phaseName.textContent = phaseData.label;
|
phaseName.textContent = phaseData.label;
|
||||||
illuminationValue.textContent = (phaseData.illumination * 100).toFixed(1).replace('.', ',') + ' %';
|
illuminationValue.textContent = (phaseData.illumination * 100).toFixed(1).replace('.', ',') + ' %';
|
||||||
@@ -1565,6 +1672,7 @@ nowBtn.addEventListener('click', () => {
|
|||||||
updateMoon();
|
updateMoon();
|
||||||
});
|
});
|
||||||
resetViewBtn.addEventListener('click', resetMoonView);
|
resetViewBtn.addEventListener('click', resetMoonView);
|
||||||
|
hdTextureBtn.addEventListener('click', loadHdTextures);
|
||||||
freeCameraBtn.addEventListener('click', () => {
|
freeCameraBtn.addEventListener('click', () => {
|
||||||
freeCameraMode = !freeCameraMode;
|
freeCameraMode = !freeCameraMode;
|
||||||
freeCameraBtn.classList.toggle('is-active', freeCameraMode);
|
freeCameraBtn.classList.toggle('is-active', freeCameraMode);
|
||||||
|
|||||||
Reference in New Issue
Block a user