color picker floating above viewer

This commit is contained in:
ochafik 2023-03-27 01:08:45 +01:00
commit 2ae038020b
9 changed files with 41 additions and 11 deletions

View file

@ -22,12 +22,14 @@ Licenses: see [LICENSES](./LICENSE).
## Roadmap ## Roadmap
- Add tests! - Add tests!
- Better names for downloads (matching source)
- Model /home fs in shared state. have two clear paths: /libraries for builtins, and /home for user data. State pointing to /libraries paths needs not store the data except if there's overrides (flagged as modifications in the file picker) - Model /home fs in shared state. have two clear paths: /libraries for builtins, and /home for user data. State pointing to /libraries paths needs not store the data except if there's overrides (flagged as modifications in the file picker)
- Setup [OPENSCADPATH](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Libraries#Setting_OPENSCADPATH) env var w/ Emscripten to ensure examples will run fine. - Setup [OPENSCADPATH](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Libraries#Setting_OPENSCADPATH) env var w/ Emscripten to ensure examples will run fine.
- Bundle some official demos and more examples from each library! - Bundle some official demos and more examples from each library!
- Ask users to contribute recipes to include more libraries, and cool examples that work in the environment - Ask users to contribute recipes to include more libraries, and cool examples that work in the environment
- Drag and drop of files (SCAD, STL, etc) and Zip archives. For assets, auto insert the corresponding import. - Drag and drop of files (SCAD, STL, etc) and Zip archives. For assets, auto insert the corresponding import.
- Proper PWA w/ File opening / association to *.scad files - Proper PWA w/ File opening / association to *.scad files
- Animation rendering (And other formats than STL)
- Compress URL fragment - Compress URL fragment
- Customizer support. Probably by adding --export-json or --export-format=customizer-json to OpenSCAD. - Customizer support. Probably by adding --export-json or --export-format=customizer-json to OpenSCAD.
- Mobile (iOS) editing support: switch to https://www.npmjs.com/package/react-codemirror ? - Mobile (iOS) editing support: switch to https://www.npmjs.com/package/react-codemirror ?

View file

@ -113,7 +113,7 @@ export default function Footer({style}: {style?: CSSProperties}) {
{state.output && ( {state.output && (
<Button icon='pi pi-download' <Button icon='pi pi-download'
title={`Download ${state.output.isPreview ? "preview.stl" : "render.stl"} (${state.output.formattedStlFileSize})`} title={`Download ${state.output.isPreview ? "preview.stl" : "render.stl"} (${state.output.formattedStlFileSize})\nGenerated in ${state.output.formattedElapsedMillis}`}
severity="secondary" severity="secondary"
text text
// label={state.output.isPreview ? "preview.stl" : "render.stl"} // label={state.output.isPreview ? "preview.stl" : "render.stl"}

View file

@ -64,7 +64,6 @@ export default function PanelSwitcher() {
} }
<SettingsMenu style={{ <SettingsMenu style={{
position: 'absolute', position: 'absolute',
marginTop: '5px',
right: 0, right: 0,
top: 0, top: 0,
}} /> }} />

View file

@ -3,6 +3,8 @@
import { CSSProperties, forwardRef, useContext, useEffect, useRef, useState } from 'react'; import { CSSProperties, forwardRef, useContext, useEffect, useRef, useState } from 'react';
import { ModelContext } from './contexts'; import { ModelContext } from './contexts';
import { StlViewer} from "react-stl-viewer"; import { StlViewer} from "react-stl-viewer";
import { ColorPicker } from 'primereact/colorpicker';
import { defaultModelColor } from '../state/initial-state';
export default function ViewerPanel({className, style}: {className?: string, style?: CSSProperties}) { export default function ViewerPanel({className, style}: {className?: string, style?: CSSProperties}) {
const model = useContext(ModelContext); const model = useContext(ModelContext);
@ -21,8 +23,10 @@ export default function ViewerPanel({className, style}: {className?: string, sty
}}> }}>
{state.output?.stlFileURL && {state.output?.stlFileURL &&
<StlViewer <StlViewer
className='absolute-fill'
style={{ style={{
flex: 1 zIndex: 0,
// flex: 1,
// width: '100%' // width: '100%'
}} }}
// ref={stlModelRef} // ref={stlModelRef}
@ -30,12 +34,22 @@ export default function ViewerPanel({className, style}: {className?: string, sty
orbitControls orbitControls
shadows={state.view.showShadows} shadows={state.view.showShadows}
modelProps={{ modelProps={{
color: '#f9d72c', color: model.state.view.color,
}} }}
url={state.output?.stlFileURL ?? ''} url={state.output?.stlFileURL ?? ''}
/> />}
}
<ColorPicker
className={`opacity-animated ${!model.isComponentFullyVisible('viewer') ? 'opacity-0' : ''}`}
value={model.state.view.color}
style={{
position: 'absolute',
top: '12px',
left: '12px',
// pointerEvents: model.isComponentFullyVisible('viewer') ? undefined : 'none',
}}
onChange={(e) => model.mutate(s => s.view.color = `#${e.value ?? defaultModelColor}`)} />
</div> </div>
) )

View file

@ -20,7 +20,8 @@ export interface State {
} | ({ } | ({
mode: 'multi', mode: 'multi',
} & { [K in MultiLayoutComponentId]: boolean }) } & { [K in MultiLayoutComponentId]: boolean })
color: string,
showAxes?: boolean, showAxes?: boolean,
showShadows?: boolean, showShadows?: boolean,
} }

View file

@ -2,6 +2,7 @@
import { State } from "./app-state"; import { State } from "./app-state";
import { validateArray, validateBoolean, validateString, validateStringEnum } from "../utils"; import { validateArray, validateBoolean, validateString, validateStringEnum } from "../utils";
import { defaultModelColor } from "./initial-state";
export function buildUrlForStateParams(state: State) {//partialState: {params: State['params'], view: State['view']}) { export function buildUrlForStateParams(state: State) {//partialState: {params: State['params'], view: State['view']}) {
return `${location.protocol}//${location.host}${location.pathname}#${encodeStateParamsAsFragment(state)}`; return `${location.protocol}//${location.host}${location.pathname}#${encodeStateParamsAsFragment(state)}`;
@ -33,6 +34,7 @@ export function readStateFromFragment(): State | null {
viewer: validateBoolean(view?.layout['viewer']), viewer: validateBoolean(view?.layout['viewer']),
customizer: validateBoolean(view?.layout['customizer']), customizer: validateBoolean(view?.layout['customizer']),
}, },
color: validateString(view?.color, () => defaultModelColor),
showAxes: validateBoolean(view?.layout?.showAxis), showAxes: validateBoolean(view?.layout?.showAxis),
showShadows: validateBoolean(view?.layout?.showShadow), showShadows: validateBoolean(view?.layout?.showShadow),
} }

View file

@ -4,6 +4,7 @@ import defaultScad from './default-scad';
import { State } from './app-state'; import { State } from './app-state';
export const defaultSourcePath = '/playground.scad'; export const defaultSourcePath = '/playground.scad';
export const defaultModelColor = '#f9d72c';
export const blankProjectState: State = { export const blankProjectState: State = {
params: { params: {
@ -12,6 +13,7 @@ export const blankProjectState: State = {
features: [], features: [],
}, },
view: { view: {
color: defaultModelColor,
layout: { layout: {
mode: 'single', mode: 'single',
focus: 'editor' focus: 'editor'
@ -37,7 +39,9 @@ export function createInitialState(fs: any, state: State | null) {
editor: true, editor: true,
viewer: true, viewer: true,
customizer: false, customizer: false,
} as any } as any,
color: defaultModelColor,
}, },
...(state ?? {}) ...(state ?? {})
}; };

View file

@ -51,6 +51,14 @@ export class Model {
this.mutate(s => s.view.logs = value); this.mutate(s => s.view.logs = value);
} }
isComponentFullyVisible(id: SingleLayoutComponentId) {
if (this.state.view.layout.mode === 'multi') {
return this.state.view.layout[id];
} else {
return this.state.view.layout.focus === id;
}
}
changeLayout(mode: 'multi' | 'single') { changeLayout(mode: 'multi' | 'single') {
if (this.state.view.layout.mode === mode) return; if (this.state.view.layout.mode === mode) return;
this.mutate(s => { this.mutate(s => {

View file

@ -83,7 +83,7 @@ export function formatBytes(n: number) {
export function formatMillis(n: number) { export function formatMillis(n: number) {
if (n < 1000) if (n < 1000)
return `${Math.floor(n)} millis`; return `${Math.floor(n)}ms`;
return `${Math.floor(n / 100) / 10} sec`; return `${Math.floor(n / 100) / 10}sec`;
} }