[READ-ONLY] Mirror of https://github.com/flo-bit/room. tiny 3d rooms saved locally or in your bluesky account, svelte/threlte flo-bit.dev/room/
0

Configure Feed

Select the types of activity you want to include in your feed.

small fixes, formatting

Florian (Mar 8, 2025, 11:29 PM +0100) 5e6401f0 6f94c56d

+81 -57
+1 -2
README.md
··· 13 13 - color picker from [svelte-color-select](https://github.com/CaptainCodeman/svelte-color-select) 14 14 - ui from my own [ui-kit](https://github.com/flo-bit/ui-kit) which is based on [bits-ui](https://bits-ui.com/) 15 15 - bluesky login made possible by [atcute](https://github.com/mary-ext/atcute) 16 - 17 16 - (old version: assets by [kenney](https://kenney.nl/assets/furniture-kit)) 18 17 19 18 ### todo ··· 32 31 ### bugs 33 32 34 33 - show error message when room is not found 35 - - fix moving with transform controls might select other object 34 + - fix moving with transform controls might select other object
+1 -1
package.json
··· 58 58 "three": "^0.174.0" 59 59 }, 60 60 "license": "MIT" 61 - } 61 + }
+11 -10
src/lib/Image.svelte
··· 30 30 } 31 31 return null; 32 32 }); 33 - 34 33 </script> 35 34 36 - <HTML transform bind:ref occlude="blending" scale={0.1} pointerEvents="none" {...props}> 37 - <div style="width: {size?.[0] ?? 270}px; height: {size?.[1] ?? 150}px;" class="bg-black"> 38 - {#await myImage then myImage} 39 - {#if myImage} 40 - <img src={myImage} alt="" class="h-full w-full object-cover select-none touch-none" /> 41 - {/if} 42 - {/await} 43 - </div> 44 - </HTML> 35 + {#if image} 36 + <HTML transform bind:ref occlude="blending" scale={0.1} pointerEvents="none" {...props}> 37 + <div style="width: {size?.[0] ?? 270}px; height: {size?.[1] ?? 150}px;" class="bg-black"> 38 + {#await myImage then myImage} 39 + {#if myImage} 40 + <img src={myImage} alt="" class="h-full w-full touch-none object-cover select-none" /> 41 + {/if} 42 + {/await} 43 + </div> 44 + </HTML> 45 + {/if}
+6 -1
src/lib/Room.svelte
··· 157 157 ); 158 158 }} 159 159 > 160 - <RoomObject kind={object.kind} colors={object.colors} placement={object.placement} image={object.image} /> 160 + <RoomObject 161 + kind={object.kind} 162 + colors={object.colors} 163 + placement={object.placement} 164 + image={object.image} 165 + /> 161 166 </TransformControls> 162 167 {:else if editorState.isEditing} 163 168 <T.Group
+4 -1
src/lib/Youtube.svelte
··· 21 21 </script> 22 22 23 23 <HTML transform bind:ref occlude="blending" scale={0.1} pointerEvents="none" {...props}> 24 - <div style="width: {size?.[0] ?? 270}px; height: {size?.[1] ?? 150}px;" class="select-none touch-none"> 24 + <div 25 + style="width: {size?.[0] ?? 270}px; height: {size?.[1] ?? 150}px;" 26 + class="touch-none select-none" 27 + > 25 28 <VideoPlayer id={videoId} bind:playPause /> 26 29 </div> 27 30 </HTML>
+1 -5
src/lib/models/kaykit-furniture-kit/chair_stool_wood.svelte
··· 47 47 {#await gltf} 48 48 {@render fallback?.()} 49 49 {:then gltf} 50 - <T.Mesh 51 - castShadow 52 - receiveShadow 53 - geometry={gltf.nodes.chair_stool_wood.geometry} 54 - > 50 + <T.Mesh castShadow receiveShadow geometry={gltf.nodes.chair_stool_wood.geometry}> 55 51 <RoomObjectMaterial index={0} {colors} {opacity} /> 56 52 </T.Mesh> 57 53 {:catch err}
+7 -1
src/lib/models/kaykit-furniture-kit/lamp_desk.svelte
··· 59 59 ><RoomObjectMaterial index={1} {colors} {opacity} /></T.Mesh 60 60 > 61 61 <T.Mesh geometry={gltf.nodes.Cylinder629_2.geometry} 62 - ><RoomObjectMaterial emissive={colors?.[2]} emissiveIntensity={1} index={2} {colors} {opacity} /></T.Mesh 62 + ><RoomObjectMaterial 63 + emissive={colors?.[2]} 64 + emissiveIntensity={1} 65 + index={2} 66 + {colors} 67 + {opacity} 68 + /></T.Mesh 63 69 > 64 70 <T.PointLight position={[0, 0.8, 0.45]} color={colors?.[2]} intensity={1} /> 65 71 </T.Group>
+15 -3
src/lib/models/kaykit-furniture-kit/lamp_standing.svelte
··· 55 55 {:then gltf} 56 56 <T.Group> 57 57 <T.Mesh castShadow receiveShadow geometry={gltf.nodes.Sphere002.geometry} 58 - ><RoomObjectMaterial index={0} {colors} opacity={0.95} emissive={colors?.[2]} emissiveIntensity={0.5} /></T.Mesh 58 + ><RoomObjectMaterial 59 + index={0} 60 + {colors} 61 + opacity={0.95} 62 + emissive={colors?.[2]} 63 + emissiveIntensity={0.5} 64 + /></T.Mesh 59 65 > 60 66 <T.Mesh castShadow receiveShadow geometry={gltf.nodes.Sphere002_1.geometry} 61 - ><RoomObjectMaterial index={1} {colors} {opacity} /></T.Mesh 67 + ><RoomObjectMaterial index={1} {colors} {opacity} /></T.Mesh 62 68 > 63 69 <T.Mesh geometry={gltf.nodes.Sphere002_2.geometry} 64 - ><RoomObjectMaterial emissive={colors?.[2]} emissiveIntensity={1} index={2} {colors} {opacity} /></T.Mesh 70 + ><RoomObjectMaterial 71 + emissive={colors?.[2]} 72 + emissiveIntensity={1} 73 + index={2} 74 + {colors} 75 + {opacity} 76 + /></T.Mesh 65 77 > 66 78 67 79 <T.PointLight position={[0, 2, 0.0]} color={colors?.[2]} intensity={1} />
+7 -1
src/lib/models/kaykit-furniture-kit/lamp_table.svelte
··· 65 65 ><RoomObjectMaterial index={1} {colors} {opacity} /></T.Mesh 66 66 > 67 67 <T.Mesh geometry={gltf.nodes.Sphere001_2.geometry} 68 - ><RoomObjectMaterial emissive={colors?.[2]} emissiveIntensity={1} index={2} {colors} {opacity} /></T.Mesh 68 + ><RoomObjectMaterial 69 + emissive={colors?.[2]} 70 + emissiveIntensity={1} 71 + index={2} 72 + {colors} 73 + {opacity} 74 + /></T.Mesh 69 75 > 70 76 71 77 <T.PointLight position={[0, 0.4, 0]} color={colors?.[2]} intensity={1} />
+1 -1
src/lib/models/kaykit-furniture-kit/pictureframe_large_a.svelte
··· 57 57 <T.Mesh castShadow receiveShadow geometry={gltf.nodes.Cube016.geometry} 58 58 ><RoomObjectMaterial index={0} {colors} {opacity} /></T.Mesh 59 59 > 60 - <Image image={image} position={[0, 0, 0.15]} size={[270 * 1.3, 150 * 2.6]} /> 60 + <Image {image} position={[0, 0, 0.15]} size={[270 * 1.3, 150 * 2.6]} /> 61 61 </T.Group> 62 62 {:catch err} 63 63 {@render error?.({ error: err })}
+1 -1
src/lib/models/kaykit-furniture-kit/pictureframe_large_b.svelte
··· 58 58 ><RoomObjectMaterial index={0} {colors} {opacity} /></T.Mesh 59 59 > 60 60 61 - <Image image={image} position={[0, 0, 0.15]} size={[270 * 2.65, 150 * 2.6]} /> 61 + <Image {image} position={[0, 0, 0.15]} size={[270 * 2.65, 150 * 2.6]} /> 62 62 </T.Group> 63 63 {:catch err} 64 64 {@render error?.({ error: err })}
+1 -2
src/lib/models/kaykit-furniture-kit/pictureframe_medium.svelte
··· 57 57 <T.Mesh castShadow receiveShadow geometry={gltf.nodes.Cube015.geometry} 58 58 ><RoomObjectMaterial index={0} {colors} {opacity} /></T.Mesh 59 59 > 60 - <Image image={image} position={[0, 0, 0.15]} size={[270 * 0.7, 150 * 1.8]} /> 61 - 60 + <Image {image} position={[0, 0, 0.15]} size={[270 * 0.7, 150 * 1.8]} /> 62 61 </T.Group> 63 62 {:catch err} 64 63 {@render error?.({ error: err })}
+1 -2
src/lib/models/kaykit-furniture-kit/pictureframe_small_a.svelte
··· 57 57 <T.Mesh castShadow receiveShadow geometry={gltf.nodes.Cube014.geometry} 58 58 ><RoomObjectMaterial index={0} {colors} {opacity} /></T.Mesh 59 59 > 60 - <Image image={image} position={[0, 0.0, 0.15]} size={[270 * 0.5, 150 * 1.1]} /> 61 - 60 + <Image {image} position={[0, 0.0, 0.15]} size={[270 * 0.5, 150 * 1.1]} /> 62 61 </T.Group> 63 62 {:catch err} 64 63 {@render error?.({ error: err })}
+1 -2
src/lib/models/kaykit-furniture-kit/pictureframe_small_b.svelte
··· 57 57 <T.Mesh castShadow receiveShadow geometry={gltf.nodes.Cube017.geometry} 58 58 ><RoomObjectMaterial index={0} {colors} {opacity} /></T.Mesh 59 59 > 60 - <Image image={image} position={[0, 0.0, 0.15]} size={[270 * 0.7, 150 * 0.6]} /> 61 - 60 + <Image {image} position={[0, 0.0, 0.15]} size={[270 * 0.7, 150 * 0.6]} /> 62 61 </T.Group> 63 62 {:catch err} 64 63 {@render error?.({ error: err })}
+1 -1
src/lib/models/kaykit-furniture-kit/pictureframe_small_c.svelte
··· 57 57 <T.Mesh castShadow receiveShadow geometry={gltf.nodes.Cube025.geometry} 58 58 ><RoomObjectMaterial index={0} {colors} {opacity} /></T.Mesh 59 59 > 60 - <Image image={image} position={[0, 0.0, 0.15]} size={[270 * 0.5, 270 * 0.5]} /> 60 + <Image {image} position={[0, 0.0, 0.15]} size={[270 * 0.5, 270 * 0.5]} /> 61 61 </T.Group> 62 62 {:catch err} 63 63 {@render error?.({ error: err })}
+1 -1
src/lib/models/kaykit-furniture-kit/pictureframe_standing_a.svelte
··· 57 57 <T.Mesh castShadow receiveShadow geometry={gltf.nodes.Cube024.geometry} 58 58 ><RoomObjectMaterial index={0} {colors} {opacity} /></T.Mesh 59 59 > 60 - <Image image={image} position={[0, 0.33, 0.05]} size={[270 * 0.5, 150 * 1.1]} rotation.x={-0.35} /> 60 + <Image {image} position={[0, 0.33, 0.05]} size={[270 * 0.5, 150 * 1.1]} rotation.x={-0.35} /> 61 61 </T.Group> 62 62 {:catch err} 63 63 {@render error?.({ error: err })}
+2 -2
src/lib/models/kaykit-furniture-kit/pictureframe_standing_b.svelte
··· 56 56 <T.Mesh castShadow receiveShadow geometry={gltf.nodes.Cube023.geometry} 57 57 ><RoomObjectMaterial index={0} {colors} {opacity} /></T.Mesh 58 58 > 59 - 60 - <Image image={image} position={[0, 0.25, 0.05]} size={[270 * 0.7, 150 * 0.6]} rotation.x={-0.35} /> 59 + 60 + <Image {image} position={[0, 0.25, 0.05]} size={[270 * 0.7, 150 * 0.6]} rotation.x={-0.35} /> 61 61 {:catch err} 62 62 {@render error?.({ error: err })} 63 63 {/await}
+1 -3
src/routes/PreviewUI.svelte
··· 56 56 </Button> 57 57 </div> 58 58 59 - 60 - 61 59 <Modal bind:open={modals.infoModalState} class="text-base-900 dark:text-base-50"> 62 60 <div> 63 61 This is an experimental web app for creating tiny 3d rooms (and sharing them on bluesky) built ··· 86 84 >bluesky</a 87 85 > (or tag me when sharing your room so I can admire your creation 😊) 88 86 </div> 89 - </Modal> 87 + </Modal>
+18 -17
src/routes/test/+page.svelte
··· 15 15 if (target.files) { 16 16 for (const file of target.files) { 17 17 const compressedFile = await compressImage(file); 18 - saveImage((new Date()).getTime().toString() + crypto.randomUUID(), compressedFile); 18 + saveImage(new Date().getTime().toString() + crypto.randomUUID(), compressedFile); 19 19 } 20 20 loadImages(); 21 21 } ··· 93 93 }); 94 94 } 95 95 96 - let images = $state<{ 97 - name: string; 98 - url: string; 99 - }[]>([]); 96 + let images = $state< 97 + { 98 + name: string; 99 + url: string; 100 + }[] 101 + >([]); 100 102 101 103 let inputRef = $state<HTMLInputElement | null>(null); 102 104 103 105 async function loadImages() { 104 106 const names = await getAllImageNames(); 105 107 console.log('Names:', names); 106 - images = (await Promise.all( 107 - names.map(async (name) => ({ 108 - name, 109 - url: await getImage(name) 110 - })) 111 - )).sort((a, b) => b.name.localeCompare(a.name)); 108 + images = ( 109 + await Promise.all( 110 + names.map(async (name) => ({ 111 + name, 112 + url: await getImage(name) 113 + })) 114 + ) 115 + ).sort((a, b) => b.name.localeCompare(a.name)); 112 116 } 113 117 114 118 function handleDragOver(event: DragEvent) { ··· 184 188 <div class="mt-4 grid grid-cols-3 gap-4"> 185 189 {#each images as image} 186 190 <div 187 - class="border-base-200 isolate dark:border-base-800 relative aspect-square rounded-2xl border object-cover" 191 + class="border-base-200 dark:border-base-800 relative isolate aspect-square rounded-2xl border object-cover" 188 192 > 189 193 <img 190 194 src={image.url} ··· 197 201 deleteImage(image.name); 198 202 loadImages(); 199 203 }} 200 - class="bg-accent-600/10 z-10 dark:bg-accent-400/10 text-accent-600 dark:text-accent-400 absolute -top-2 -left-2 flex size-6 cursor-pointer items-center justify-center rounded-full p-1 backdrop-blur-sm" 204 + class="bg-accent-600/10 dark:bg-accent-400/10 text-accent-600 dark:text-accent-400 absolute -top-2 -left-2 z-10 flex size-6 cursor-pointer items-center justify-center rounded-full p-1 backdrop-blur-sm" 201 205 > 202 206 <svg 203 207 xmlns="http://www.w3.org/2000/svg" ··· 213 217 <span class="sr-only">Delete</span> 214 218 </button> 215 219 216 - <button 217 - onclick={() => handleSelectImage(image)} 218 - class="absolute inset-0 cursor-pointer" 219 - > 220 + <button onclick={() => handleSelectImage(image)} class="absolute inset-0 cursor-pointer"> 220 221 <span class="sr-only">select image</span> 221 222 </button> 222 223 </div>