Add more control
This commit is contained in:
@@ -2,42 +2,134 @@ import { useEffect, useState } from "react";
|
||||
import type { ImageEditor } from "../handler/image-editor";
|
||||
import type { TracerOptions } from "../interface";
|
||||
import { NumericInputWithLabelTable } from "./numeric-labeld-input";
|
||||
import styled from "styled-components";
|
||||
import { Button } from "../styles";
|
||||
import { FaBezierCurve } from "react-icons/fa6";
|
||||
import { VerticalSlider } from "./vertical-slider";
|
||||
import { TRANSPARENCY_THRESHOLD_DEFAULT } from "../svg-tracer";
|
||||
import type { VectraceHandler } from "../handler/vectrace-handler";
|
||||
import { clamp } from "lodash";
|
||||
|
||||
const Table = styled.table`
|
||||
margin: 2px;
|
||||
padding-right: 4px;
|
||||
`;
|
||||
|
||||
const WrapperColumn = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const WrapperRow = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100px;
|
||||
`;
|
||||
|
||||
const LayerPanel = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100px;
|
||||
overflow: auto;
|
||||
height: 100px;
|
||||
`;
|
||||
|
||||
const ToggleButton = styled.button<{ $enabled: boolean }>`
|
||||
background-color: ${({ $enabled }) => $enabled ? "var(--secondary-color)" : "var(--primary-color)"};
|
||||
color: white;
|
||||
border: 1px solid white;
|
||||
&:hover {
|
||||
color: var(--secondary-color);
|
||||
background-color: white;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
export function SvgTracerOptions({ selected }: { selected: ImageEditor[] }) {
|
||||
|
||||
export function SvgTracerOptions({ selected, handler }: { selected: ImageEditor[], handler: VectraceHandler }) {
|
||||
const [options, setOptions] = useState(selected[0]?.tracerOptions ?? {});
|
||||
const [updated, setUpdated] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setOptions(selected[0]?.tracerOptions ?? {});
|
||||
}, [selected.map(e => e.id).join("")]);
|
||||
setUpdated(true);
|
||||
}, [selected.map(e => `${e.id}${JSON.stringify(e.svgData.options)}`).join("")]);
|
||||
|
||||
const setValue = (key: keyof TracerOptions, value: number) => {
|
||||
setOptions({ ...options, [key]: value });
|
||||
const redraw = () => {
|
||||
selected.forEach(e => {
|
||||
e.setTracerSvg({ ...options, [key]: value });
|
||||
e.setTracerSvg({ ...options });
|
||||
});
|
||||
setUpdated(true);
|
||||
};
|
||||
|
||||
return <tbody>
|
||||
<NumericInputWithLabelTable
|
||||
name="Ltres"
|
||||
value={options.ltres}
|
||||
onChange={value => setValue("ltres", value)}
|
||||
/>
|
||||
<NumericInputWithLabelTable
|
||||
name="Qtres"
|
||||
value={options.qtres}
|
||||
onChange={value => setValue("qtres", value)}
|
||||
/>
|
||||
<NumericInputWithLabelTable
|
||||
name="Path omit"
|
||||
value={options.pathomit}
|
||||
onChange={value => setValue("pathomit", value)}
|
||||
/>
|
||||
<NumericInputWithLabelTable
|
||||
name="Round corners"
|
||||
value={options.roundcoords}
|
||||
onChange={value => setValue("roundcoords", value)}
|
||||
/>
|
||||
</tbody>;
|
||||
const setValue = (key: keyof TracerOptions, value: any) => {
|
||||
setOptions({ ...options, [key]: value });
|
||||
setUpdated(false);
|
||||
};
|
||||
|
||||
return <WrapperRow>
|
||||
<VerticalSlider
|
||||
max={255}
|
||||
min={0}
|
||||
value={options.transparencyThreshold ?? TRANSPARENCY_THRESHOLD_DEFAULT}
|
||||
onLabelClick={async () => {
|
||||
const value = await handler.popup.prompt(
|
||||
"Transparency threshold",
|
||||
"Enter transparency threshold between 0-255",
|
||||
(options.transparencyThreshold ?? TRANSPARENCY_THRESHOLD_DEFAULT).toString());
|
||||
if (value) {
|
||||
const int = parseInt(value, 10);
|
||||
if (!isNaN(int)) {
|
||||
setValue("transparencyThreshold", clamp(int, 0, 255));
|
||||
}
|
||||
}
|
||||
}}
|
||||
onChange={value => {
|
||||
setValue("transparencyThreshold", value);
|
||||
}} />
|
||||
<WrapperColumn>
|
||||
<Button $active={!updated} title="Draw" onClick={() => { redraw(); }}><FaBezierCurve /></Button>
|
||||
<WrapperRow>
|
||||
<Table>
|
||||
<tbody>
|
||||
<NumericInputWithLabelTable
|
||||
name="Ltres"
|
||||
value={options.ltres}
|
||||
onChange={value => setValue("ltres", value)}
|
||||
/>
|
||||
<NumericInputWithLabelTable
|
||||
name="Qtres"
|
||||
value={options.qtres}
|
||||
onChange={value => setValue("qtres", value)}
|
||||
/>
|
||||
<NumericInputWithLabelTable
|
||||
name="Path omit"
|
||||
value={options.pathomit}
|
||||
onChange={value => setValue("pathomit", value)}
|
||||
/>
|
||||
<NumericInputWithLabelTable
|
||||
name="Round corners"
|
||||
value={options.roundcoords}
|
||||
onChange={value => setValue("roundcoords", value)}
|
||||
/>
|
||||
</tbody>
|
||||
</Table >
|
||||
<LayerPanel>
|
||||
{(options.allowedPaths || []).map((e, i) => {
|
||||
return <ToggleButton
|
||||
key={i}
|
||||
$enabled={e}
|
||||
onClick={() => {
|
||||
const array = options?.allowedPaths ? [...options.allowedPaths] : [];
|
||||
array[i] = !array[i];
|
||||
setValue("allowedPaths", array);
|
||||
}}
|
||||
>
|
||||
{`${i + 1} Layer`}
|
||||
</ToggleButton>;
|
||||
})}
|
||||
</LayerPanel>
|
||||
|
||||
</WrapperRow>
|
||||
</WrapperColumn></WrapperRow>;
|
||||
}
|
||||
Reference in New Issue
Block a user