diff --git a/web/src/pages/app/app.css b/web/src/pages/app/app.css index b37c51c..f14e735 100644 --- a/web/src/pages/app/app.css +++ b/web/src/pages/app/app.css @@ -131,7 +131,8 @@ .thumb { position: relative; - min-height: 150px; + aspect-ratio: 4 / 3; + min-height: 0; display: grid; place-items: center; /* background: @@ -179,6 +180,7 @@ } .thumb img { + display: block; width: 100%; height: 100%; object-fit: contain; diff --git a/web/src/pages/app/modules/preview.ts b/web/src/pages/app/modules/preview.ts index a02a2fa..8a9b282 100644 --- a/web/src/pages/app/modules/preview.ts +++ b/web/src/pages/app/modules/preview.ts @@ -125,6 +125,8 @@ const zeroBasePoint: PreviewResolvedBasePoint = { const RAD_TO_DEG = 180 / Math.PI; const DEG_TO_RAD = Math.PI / 180; const BASE_POINT_DECIMAL_PLACES = 3; +const THUMBNAIL_WIDTH = 512; +const THUMBNAIL_HEIGHT = 384; const previewEnvironmentUrl = "/DayCityOutdoor.exr"; const DEFAULT_PREVIEW_FRAME_INTERVAL_MS = 20; @@ -599,15 +601,31 @@ async function screenshotModel(modelId: number, onThumbnailSaved?: () => Promise controls.update(); const oldBackground = scene.background; const oldClearAlpha = renderer.getClearAlpha(); - if (transparent) { - scene.background = null; - renderer.setClearColor(0x000000, 0); - } - renderer.render(scene, camera); - const thumbnail = renderer.domElement.toDataURL("image/png"); - if (transparent) { - scene.background = oldBackground; - renderer.setClearAlpha(oldClearAlpha); + const oldPixelRatio = renderer.getPixelRatio(); + const oldWidth = renderer.domElement.width / oldPixelRatio; + const oldHeight = renderer.domElement.height / oldPixelRatio; + const oldAspect = camera.aspect; + let thumbnail = ""; + try { + if (transparent) { + scene.background = null; + renderer.setClearColor(0x000000, 0); + } + renderer.setPixelRatio(1); + renderer.setSize(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, false); + camera.aspect = THUMBNAIL_WIDTH / THUMBNAIL_HEIGHT; + camera.updateProjectionMatrix(); + renderer.render(scene, camera); + thumbnail = renderer.domElement.toDataURL("image/png"); + } finally { + camera.aspect = oldAspect; + camera.updateProjectionMatrix(); + renderer.setPixelRatio(oldPixelRatio); + renderer.setSize(oldWidth, oldHeight, false); + if (transparent) { + scene.background = oldBackground; + renderer.setClearAlpha(oldClearAlpha); + } renderer.render(scene, camera); } await api(`/api/models/${modelId}/thumbnail`, {