From 054cf0249d2c3e95cf1033baaf5e7e81ea617ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Goszczy=C5=84ski?= Date: Wed, 19 Mar 2025 19:56:00 +0100 Subject: [PATCH] add ticket scaling based on resolution --- apps/www/components/LaunchWeek/14/Header.tsx | 2 +- .../components/LaunchWeek/14/TicketLayout.tsx | 2 +- .../LaunchWeek/14/scenes/TicketScene.ts | 72 +++++++++++++++++-- 3 files changed, 70 insertions(+), 6 deletions(-) diff --git a/apps/www/components/LaunchWeek/14/Header.tsx b/apps/www/components/LaunchWeek/14/Header.tsx index 962c0aa8ab7..bfe0eb4a7b5 100644 --- a/apps/www/components/LaunchWeek/14/Header.tsx +++ b/apps/www/components/LaunchWeek/14/Header.tsx @@ -4,7 +4,7 @@ import SectionContainerWithCn from '~/components/Layouts/SectionContainerWithCn' export const TicketHeader = ({ children }: { children: ReactNode }) => { return ( - + {children} ) diff --git a/apps/www/components/LaunchWeek/14/TicketLayout.tsx b/apps/www/components/LaunchWeek/14/TicketLayout.tsx index 15978dbe665..a680d89c23b 100644 --- a/apps/www/components/LaunchWeek/14/TicketLayout.tsx +++ b/apps/www/components/LaunchWeek/14/TicketLayout.tsx @@ -3,7 +3,7 @@ import { cn } from 'ui' import SectionContainerWithCn from '~/components/Layouts/SectionContainerWithCn' export const TicketLayout = ({ children }: { children: ReactNode }) => { - return {children} + return {children} } const TicketLayoutCanvasCorner = ({ className }: { className?: string }) => { diff --git a/apps/www/components/LaunchWeek/14/scenes/TicketScene.ts b/apps/www/components/LaunchWeek/14/scenes/TicketScene.ts index 13c8a9136bd..42a0534e308 100644 --- a/apps/www/components/LaunchWeek/14/scenes/TicketScene.ts +++ b/apps/www/components/LaunchWeek/14/scenes/TicketScene.ts @@ -186,9 +186,27 @@ class TicketScene implements BaseScene { state: TicketSceneState + resolutions = { + 0: { + ticketPosition: new Vector3(0, 0, -1), + ticketScale: new Vector3(0.8, 0.8, 0.8), + }, + + 424: { + ticketPosition: new Vector3(0, 0, -0.6), + ticketScale: new Vector3(1, 1, 1), + }, + + 1024: { + ticketPosition: new Vector3(0, 0, -0.5), + ticketScale: new Vector3(1, 1, 1), + }, + } + private _internalState = { naturalRotation: new Vector3(0, 0, Math.PI), naturalPosition: new Vector3(0, 0, -0.5), + naturalScale: new Vector3(1, 1, 1), fontsLoaded: false, loadedTextureType: null as 'basic' | 'secret' | 'platinum' | null, @@ -267,6 +285,20 @@ class TicketScene implements BaseScene { await this._loadFonts() await this._preloadAllTextureSets() + const resolutionDescriptor = this.getResolutionDescriptor(window.innerWidth) + + this._internalState.naturalPosition.set( + resolutionDescriptor.ticketPosition.x, + resolutionDescriptor.ticketPosition.y, + resolutionDescriptor.ticketPosition.z + ) + + this._internalState.naturalScale.set( + resolutionDescriptor.ticketScale.x, + resolutionDescriptor.ticketScale.y, + resolutionDescriptor.ticketScale.z + ) + const gltf = await loadGLTFModel(this.sceneUrl) this._ticket = gltf.scene.getObjectByName('Plane') as unknown as Scene @@ -331,7 +363,8 @@ class TicketScene implements BaseScene { const mainRenderPass = context.composer.passes[0] if (mainRenderPass instanceof RenderPass) { this._updateNaturalPosition() - this._updateTicketSize(time) + this._updateTicketSize() + this._updateTicketPosition() if (this._ticket) this._updateTicketToFollowMouse(this._ticket, time) this._updatePasses(time) } @@ -340,6 +373,20 @@ class TicketScene implements BaseScene { cleanup(): void {} resize(_ev: UIEvent): void { + const resolutionDescriptor = this.getResolutionDescriptor(window.innerWidth) + + this._internalState.naturalPosition.set( + resolutionDescriptor.ticketPosition.x, + resolutionDescriptor.ticketPosition.y, + resolutionDescriptor.ticketPosition.z + ) + + this._internalState.naturalScale.set( + resolutionDescriptor.ticketScale.x, + resolutionDescriptor.ticketScale.y, + resolutionDescriptor.ticketScale.z + ) + return } @@ -584,12 +631,11 @@ class TicketScene implements BaseScene { } } - _visibleScaleVector = new Vector3(1, 1, 1) _invisibleScaleVector = new Vector3(0, 0, 0) - private _updateTicketSize(time?: number) { + private _updateTicketSize() { if (this.state.visible) { - this._ticket?.scale.lerp(this._visibleScaleVector, 0.01) + this._ticket?.scale.lerp(this._internalState.naturalScale, 0.01) } else { this._ticket?.scale.lerp(this._invisibleScaleVector, 0.01) } @@ -601,6 +647,13 @@ class TicketScene implements BaseScene { this._updateMeshBoundingBoxes() } + private _updateTicketPosition() { + this._ticket?.position.lerp( + this._internalState.naturalPosition, + 0.01 + ) + } + private _updateMeshBoundingBoxes() { // Update bounding boxes for all named meshes for (const meshName in this._namedMeshes) { @@ -999,6 +1052,17 @@ class TicketScene implements BaseScene { await Promise.all(promises) } + + private getResolutionDescriptor(resolution: number) { + const resolutions = Object.keys(this.resolutions).map(Number) + const closestResolution = resolutions.reduce((prev, curr) => + resolution - curr >= 0 && resolution - curr < resolution - prev ? curr : prev + ) as keyof typeof this.resolutions + + console.log('Closest resolution:', closestResolution) + + return this.resolutions[closestResolution] + } } export default TicketScene