auto-git:
[change] src/app/App.tsx [change] src/app/editor-store.ts [change] src/document/migrate-scene-document.ts [change] src/document/scene-document.ts [change] src/viewport-three/ViewportCanvas.tsx [change] src/viewport-three/viewport-host.ts
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useEffect, useRef, useState, type ChangeEvent } from "react";
|
||||
|
||||
import { createSetSceneNameCommand } from "../commands/set-scene-name-command";
|
||||
import type { EditorSelection } from "../core/selection";
|
||||
import { Panel } from "../shared-ui/Panel";
|
||||
import { ViewportCanvas } from "../viewport-three/ViewportCanvas";
|
||||
import type { EditorStore } from "./editor-store";
|
||||
@@ -10,7 +11,7 @@ interface AppProps {
|
||||
store: EditorStore;
|
||||
}
|
||||
|
||||
function describeSelection(selectionKind: string): string {
|
||||
function describeSelection(selectionKind: EditorSelection["kind"]): string {
|
||||
switch (selectionKind) {
|
||||
case "none":
|
||||
return "No authored selection yet";
|
||||
@@ -87,7 +88,7 @@ export function App({ store }: AppProps) {
|
||||
importInputRef.current?.click();
|
||||
};
|
||||
|
||||
const handleImportChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const handleImportChange = async (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const file = event.currentTarget.files?.[0];
|
||||
|
||||
if (file === undefined) {
|
||||
|
||||
@@ -123,6 +123,7 @@ export class EditorStore {
|
||||
replaceDocument(document: SceneDocument, resetHistory = true) {
|
||||
this.document = document;
|
||||
this.selection = { kind: "none" };
|
||||
this.toolMode = "select";
|
||||
|
||||
if (resetHistory) {
|
||||
this.history.clear();
|
||||
|
||||
@@ -30,6 +30,14 @@ function expectHexColor(value: unknown, label: string): string {
|
||||
return normalizedValue;
|
||||
}
|
||||
|
||||
function expectLiteralString<T extends string>(value: unknown, expectedValue: T, label: string): T {
|
||||
if (value !== expectedValue) {
|
||||
throw new Error(`${label} must be ${expectedValue}.`);
|
||||
}
|
||||
|
||||
return expectedValue;
|
||||
}
|
||||
|
||||
function expectEmptyCollection(value: unknown, label: string): Record<string, never> {
|
||||
if (!isRecord(value)) {
|
||||
throw new Error(`${label} must be a record.`);
|
||||
@@ -71,7 +79,7 @@ function readWorldSettings(value: unknown): WorldSettings {
|
||||
|
||||
return {
|
||||
background: {
|
||||
mode: "solid",
|
||||
mode: expectLiteralString(background.mode, "solid", "world.background.mode"),
|
||||
colorHex: expectHexColor(background.colorHex, "world.background.colorHex")
|
||||
},
|
||||
ambientLight: {
|
||||
|
||||
@@ -50,7 +50,9 @@ export function createDefaultWorldSettings(): WorldSettings {
|
||||
sunLight: {
|
||||
colorHex: "#fff1d5",
|
||||
intensity: 1.75,
|
||||
direction: DEFAULT_SUN_DIRECTION
|
||||
direction: {
|
||||
...DEFAULT_SUN_DIRECTION
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ export function ViewportCanvas({ world }: ViewportCanvasProps) {
|
||||
|
||||
const viewportHost = new ViewportHost();
|
||||
hostRef.current = viewportHost;
|
||||
viewportHost.mount(container, world);
|
||||
viewportHost.mount(container);
|
||||
viewportHost.updateWorld(world);
|
||||
|
||||
return () => {
|
||||
viewportHost.dispose();
|
||||
|
||||
@@ -36,10 +36,9 @@ export class ViewportHost {
|
||||
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
||||
}
|
||||
|
||||
mount(container: HTMLElement, world: WorldSettings) {
|
||||
mount(container: HTMLElement) {
|
||||
this.container = container;
|
||||
container.appendChild(this.renderer.domElement);
|
||||
this.updateWorld(world);
|
||||
this.resize();
|
||||
|
||||
this.resizeObserver = new ResizeObserver(() => {
|
||||
|
||||
Reference in New Issue
Block a user