wip(lab): Work on xray mode
This commit is contained in:
parent
c05d9dce23
commit
ec2fd35208
9 changed files with 215 additions and 89 deletions
|
@ -2,6 +2,7 @@ const defaultSettings = {
|
|||
sa: 0,
|
||||
saBool: false,
|
||||
saMm: 10,
|
||||
scale: 1,
|
||||
complete: true,
|
||||
paperless: false,
|
||||
units: 'metric',
|
||||
|
@ -9,6 +10,8 @@ const defaultSettings = {
|
|||
margin: 2,
|
||||
renderer: 'react',
|
||||
embed: true,
|
||||
debug: true,
|
||||
xray: false,
|
||||
}
|
||||
|
||||
export default defaultSettings
|
||||
|
|
|
@ -18,7 +18,7 @@ const tabClasses = active => `
|
|||
const Wrap = props => <div className="max-w-screen-xl m-auto">{props.children}</div>
|
||||
|
||||
const LabDraft = props => {
|
||||
const { app, pattern, gist, updateGist } = props
|
||||
const { app, pattern, gist, updateGist, unsetGist } = props
|
||||
|
||||
const [tab, setTab] = useState(props.pattern.config.name)
|
||||
|
||||
|
@ -71,12 +71,12 @@ const LabDraft = props => {
|
|||
{Object.keys(patternProps.parts).map((name) => (
|
||||
<Part
|
||||
key={name}
|
||||
partName={name}
|
||||
part={patternProps.parts[name]}
|
||||
locale={gist.locale}
|
||||
paperless={gist.paperless}
|
||||
units={gist.units}
|
||||
name={name}
|
||||
app={app}
|
||||
gist={gist}
|
||||
updateGist={updateGist}
|
||||
unsetGist={unsetGist}
|
||||
/>
|
||||
))}
|
||||
</g>
|
||||
|
|
|
@ -3,13 +3,17 @@ import Point from '../point'
|
|||
import Snippet from '../snippet'
|
||||
import { getProps } from '../utils'
|
||||
|
||||
const Part = (props) => {
|
||||
const raiseEvent = (evt) => console.log('raiseEVent not implemtned', evt)
|
||||
|
||||
const Part = props => {
|
||||
const { partName, part, app, gist, updateGist } = props
|
||||
|
||||
const focusPoint = (point, i) => {
|
||||
const p = props.part.points[point]
|
||||
const pathString = `M ${p.x} ${props.part.topLeft.y} `
|
||||
+ `L ${p.x} ${props.part.bottomRight.y} `
|
||||
+ `M ${props.part.topLeft.x} ${p.y} `
|
||||
+ `L ${props.part.bottomRight.x} ${p.y} `
|
||||
const p = part.points[point]
|
||||
const pathString = `M ${p.x} ${part.topLeft.y} `
|
||||
+ `L ${p.x} ${part.bottomRight.y} `
|
||||
+ `M ${part.topLeft.x} ${p.y} `
|
||||
+ `L ${part.bottomRight.x} ${p.y} `
|
||||
const classes = 'focus point c' + (i % 8) // Cycle through 8 colors
|
||||
return (
|
||||
<React.Fragment key={'fp' + point}>
|
||||
|
@ -20,8 +24,8 @@ const Part = (props) => {
|
|||
r="5"
|
||||
className="contrast"
|
||||
onClick={() =>
|
||||
props.raiseEvent('clearFocus', {
|
||||
part: props.name,
|
||||
raiseEvent('clearFocus', {
|
||||
part: partName,
|
||||
type: 'points',
|
||||
name: point
|
||||
})
|
||||
|
@ -32,10 +36,10 @@ const Part = (props) => {
|
|||
}
|
||||
|
||||
const focusCoords = (p, i) => {
|
||||
let pathString = `M ${p.x} ${props.part.topLeft.y} `
|
||||
pathString += `L ${p.x} ${props.part.bottomRight.y} `
|
||||
pathString += `M ${props.part.topLeft.x} ${p.y} `
|
||||
pathString += `L ${props.part.bottomRight.x} ${p.y} `
|
||||
let pathString = `M ${p.x} ${part.topLeft.y} `
|
||||
pathString += `L ${p.x} ${part.bottomRight.y} `
|
||||
pathString += `M ${part.topLeft.x} ${p.y} `
|
||||
pathString += `L ${part.bottomRight.x} ${p.y} `
|
||||
let classes = 'focus coords c' + (i % 4) // Cycle through 4 CSS classes
|
||||
return (
|
||||
<React.Fragment key={'cp' + i}>
|
||||
|
@ -46,8 +50,8 @@ const Part = (props) => {
|
|||
r="5"
|
||||
className={classes}
|
||||
onClick={() =>
|
||||
props.raiseEvent('clearFocus', {
|
||||
part: props.name,
|
||||
raiseEvent('clearFocus', {
|
||||
partName: partName,
|
||||
type: 'coords',
|
||||
data: p
|
||||
})
|
||||
|
@ -57,79 +61,74 @@ const Part = (props) => {
|
|||
)
|
||||
}
|
||||
|
||||
let grid = props.paperless ? (
|
||||
let grid = gist.paperless ? (
|
||||
<rect
|
||||
x={props.part.topLeft.x}
|
||||
y={props.part.topLeft.y}
|
||||
width={props.part.width}
|
||||
height={props.part.height}
|
||||
x={part.topLeft.x}
|
||||
y={part.topLeft.y}
|
||||
width={part.width}
|
||||
height={part.height}
|
||||
className="grid"
|
||||
fill={'url(#grid-' + props.name + ')'}
|
||||
fill={'url(#grid-' + partName + ')'}
|
||||
/>
|
||||
) : null
|
||||
|
||||
let focus = []
|
||||
if (props.develop) {
|
||||
if (props.focus && typeof props.focus[props.name] !== 'undefined') {
|
||||
for (let i in props.focus[props.name].points)
|
||||
focus.push(focusPoint(props.focus[props.name].points[i], i))
|
||||
for (let i in props.focus[props.name].paths) {
|
||||
let name = props.focus[props.name].paths[i]
|
||||
focus.push(
|
||||
<path
|
||||
key={'fpa-' + name}
|
||||
d={props.part.paths[name].asPathstring()}
|
||||
className={'focus path c' + (i % 4)}
|
||||
onClick={() =>
|
||||
props.raiseEvent('clearFocus', {
|
||||
part: props.name,
|
||||
type: 'paths',
|
||||
name
|
||||
})
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
for (let i in props.focus[props.name].coords)
|
||||
focus.push(focusCoords(props.focus[props.name].coords[i], i))
|
||||
}
|
||||
}
|
||||
//if (gist.debug) {
|
||||
// if (focus && typeof props.focus[props.name] !== 'undefined') {
|
||||
// for (let i in props.focus[props.name].points)
|
||||
// focus.push(focusPoint(props.focus[props.name].points[i], i))
|
||||
// for (let i in props.focus[props.name].paths) {
|
||||
// let name = props.focus[props.name].paths[i]
|
||||
// focus.push(
|
||||
// <path
|
||||
// key={'fpa-' + name}
|
||||
// d={props.part.paths[name].asPathstring()}
|
||||
// className={'focus path c' + (i % 4)}
|
||||
// onClick={() =>
|
||||
// props.raiseEvent('clearFocus', {
|
||||
// part: props.name,
|
||||
// type: 'paths',
|
||||
// name
|
||||
// })
|
||||
// }
|
||||
// />
|
||||
// )
|
||||
// }
|
||||
// for (let i in props.focus[props.name].coords)
|
||||
// focus.push(focusCoords(props.focus[props.name].coords[i], i))
|
||||
// }
|
||||
//}
|
||||
|
||||
return (
|
||||
<g {...getProps(props.part)} id={`part-${props.name}`}>
|
||||
<g {...getProps(part)} id={`part-${partName}`}>
|
||||
{grid}
|
||||
{Object.keys(props.part.paths).map((name) => (
|
||||
{Object.keys(part.paths).map((pathName) => (
|
||||
<Path
|
||||
key={name}
|
||||
name={name}
|
||||
part={props.name}
|
||||
locale={props.locale}
|
||||
path={props.part.paths[name]}
|
||||
focus={props.focus}
|
||||
pathName={pathName}
|
||||
path={part.paths[pathName]}
|
||||
topLeft={props.part.topLeft}
|
||||
bottomRight={props.part.bottomRight}
|
||||
develop={props.develop}
|
||||
raiseEvent={props.raiseEvent}
|
||||
app={props.app}
|
||||
{...props}
|
||||
/>
|
||||
))}
|
||||
{Object.keys(props.part.points).map((name) => (
|
||||
<Point
|
||||
key={name}
|
||||
name={name}
|
||||
part={props.name}
|
||||
locale={props.locale}
|
||||
pointName={name}
|
||||
point={props.part.points[name]}
|
||||
focus={props.focus}
|
||||
topLeft={props.part.topLeft}
|
||||
bottomRight={props.part.bottomRight}
|
||||
develop={props.develop}
|
||||
raiseEvent={props.raiseEvent}
|
||||
app={props.app}
|
||||
{...props}
|
||||
/>
|
||||
))}
|
||||
{Object.keys(props.part.snippets).map((name) => (
|
||||
<Snippet key={name} name={name} snippet={props.part.snippets[name]} />
|
||||
{Object.keys(props.part.snippets).map((snippetName) => (
|
||||
<Snippet
|
||||
key={name}
|
||||
snippetName={snippetName}
|
||||
snippet={props.part.snippets[snippetName]}
|
||||
{...props}
|
||||
/>
|
||||
))}
|
||||
{focus}
|
||||
</g>
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import TextOnPath from '../text-on-path'
|
||||
import { getProps } from '../utils'
|
||||
|
||||
const Path = (props) => {
|
||||
if (!props.path.render) return null
|
||||
const Path = props => {
|
||||
const { path, part, name } = props
|
||||
if (!path.render) return null
|
||||
const output = []
|
||||
const pathId = 'path-' + props.part + '-' + props.name
|
||||
const pathId = 'path-' + part + '-' + name
|
||||
output.push(
|
||||
<path id={pathId} key={pathId} d={props.path.asPathstring()} {...getProps(props.path)} />
|
||||
<path id={pathId} key={pathId} d={path.asPathstring()} {...getProps(path)} />
|
||||
)
|
||||
if (props.path.attributes.get('data-text'))
|
||||
output.push(<TextOnPath key={'text-on-path-' + props.name} pathId={pathId} {...props} />)
|
||||
if (path.attributes.get('data-text'))
|
||||
output.push(<TextOnPath key={'text-on-path-' + name} pathId={pathId} {...props} />)
|
||||
|
||||
return output
|
||||
}
|
||||
|
|
|
@ -1,12 +1,35 @@
|
|||
import Text from '../text'
|
||||
import Circle from '../circle'
|
||||
|
||||
const Point = (props) => {
|
||||
const XrayPoint = props => (
|
||||
<g>
|
||||
<circle
|
||||
cx={props.point.x}
|
||||
cy={props.point.y}
|
||||
r={2 * props.gist.scale}
|
||||
className="stroke-sm stroke-lining fill-lining fill-opacity-25" />
|
||||
<circle
|
||||
cx={props.point.x}
|
||||
cy={props.point.y}
|
||||
r={7.5 * props.gist.scale}
|
||||
className="fillhovertrap"
|
||||
onClick={() => props.updateGist(
|
||||
['xray', parts, 'props.partName', 'points', props.name],
|
||||
props.point
|
||||
)}
|
||||
/>
|
||||
</g>
|
||||
)
|
||||
|
||||
|
||||
const Point = props => {
|
||||
const { point, name } = props
|
||||
const output = []
|
||||
if (props.point.attributes && props.point.attributes.get('data-text'))
|
||||
output.push(<Text {...props} key={'point-' + props.name} />)
|
||||
if (props.point.attributes && props.point.attributes.get('data-circle'))
|
||||
output.push(<Circle point={props.point} key={'circle-' + props.name} />)
|
||||
if (props.gist.xray) output.push(<XrayPoint {...props} key={'xp-' + props.name} />)
|
||||
if (point.attributes && point.attributes.get('data-text'))
|
||||
output.push(<Text {...props} key={'point-' + name} />)
|
||||
if (point.attributes && point.attributes.get('data-circle'))
|
||||
output.push(<Circle point={point} key={'circle-' + name} />)
|
||||
|
||||
return output.length < 1 ? null : output
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import { useState } from 'react'
|
||||
import ClearIcon from 'shared/components/icons/clear.js'
|
||||
import EditIcon from 'shared/components/icons/edit.js'
|
||||
|
||||
const CoreSettingNr = props => {
|
||||
const { dflt, min, max } = props
|
||||
const val = props.gist?.[props.setting]
|
||||
|
||||
const [value, setValue] = useState(val)
|
||||
|
||||
const handleChange = evt => {
|
||||
const newVal = parseFloat(evt.target.value)
|
||||
|
||||
if (newVal === dflt) reset()
|
||||
else {
|
||||
setValue(newVal)
|
||||
props.updateGist([props.setting], newVal)
|
||||
}
|
||||
}
|
||||
const reset = () => {
|
||||
setValue(props.dflt)
|
||||
props.updateGist([props.setting], props.dflt)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="py-4 mx-6 border-l-2 pl-2">
|
||||
<p className="m-0 p-0 px-2 mb-2 text-neutral-content opacity-60 italic">
|
||||
{props.app.t(`settings.${props.setting}.description`)}
|
||||
</p>
|
||||
<div className="flex flex-row justify-between">
|
||||
<span className="opacity-50">
|
||||
{min}
|
||||
</span>
|
||||
<span className={`font-bold ${val===dflt ? 'text-secondary' : 'text-accent'}`}>
|
||||
{val}
|
||||
</span>
|
||||
<span className="opacity-50">
|
||||
{max}
|
||||
</span>
|
||||
</div>
|
||||
<input
|
||||
type="range"
|
||||
max={max}
|
||||
min={min}
|
||||
step={0.1}
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
className={`
|
||||
range range-sm mt-1
|
||||
${val === dflt ? 'range-secondary' : 'range-accent'}
|
||||
`}
|
||||
/>
|
||||
<div className="flex flex-row justify-between">
|
||||
<span />
|
||||
<button
|
||||
title={props.app.t('app.reset')}
|
||||
className="btn btn-ghost btn-xs text-accent"
|
||||
disabled={val === dflt}
|
||||
onClick={reset}
|
||||
>
|
||||
<ClearIcon />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CoreSettingNr
|
|
@ -29,6 +29,11 @@ const settings = {
|
|||
max: 25,
|
||||
dflt: 2,
|
||||
},
|
||||
scale: {
|
||||
min: 0.1,
|
||||
max: 5,
|
||||
dflt: 1,
|
||||
},
|
||||
renderer: {
|
||||
list: ['react', 'svg'],
|
||||
titles: {
|
||||
|
@ -39,6 +44,9 @@ const settings = {
|
|||
debug: {
|
||||
dflt: false,
|
||||
},
|
||||
xray: {
|
||||
dflt: false,
|
||||
},
|
||||
}
|
||||
|
||||
const CoreSettings = props => {
|
||||
|
|
|
@ -4,6 +4,7 @@ import CountOption from 'shared/components/workbench/inputs/design-option-count'
|
|||
import ListSetting from './core-setting-list'
|
||||
import OnlySetting from './core-setting-only'
|
||||
import MmSetting from './core-setting-mm'
|
||||
import NrSetting from './core-setting-nr'
|
||||
import BoolSetting from './core-setting-bool.js'
|
||||
import SaBoolSetting from './core-setting-sa-bool.js'
|
||||
import SaMmSetting from './core-setting-sa-mm.js'
|
||||
|
@ -52,6 +53,9 @@ const settings = {
|
|||
}} />
|
||||
)
|
||||
},
|
||||
scale: props => props.gist.scale === 1
|
||||
? <span className="text-secondary">{props.gist.scale}</span>
|
||||
: <span className="text-accent">{props.gist.scale}</span>,
|
||||
saMm: props => {
|
||||
return (
|
||||
<span className="text-secondary" dangerouslySetInnerHTML={{
|
||||
|
@ -85,6 +89,7 @@ const inputs = {
|
|||
}))}
|
||||
/>,
|
||||
margin: props => <MmSetting {...props} {...props.config} />,
|
||||
scale: props => <NrSetting {...props} {...props.config} />,
|
||||
saMm: props => <SaMmSetting {...props} {...props.config} />,
|
||||
renderer: props => <ListSetting
|
||||
{...props}
|
||||
|
@ -100,7 +105,7 @@ const Setting = props => {
|
|||
|
||||
if (props.setting === 'saBool')
|
||||
return <SaBoolSetting {...props} {...props.config} />
|
||||
if (['paperless', 'complete', 'debug'].indexOf(props.setting) !== -1)
|
||||
if (['paperless', 'complete', 'debug', 'xray'].indexOf(props.setting) !== -1)
|
||||
return <BoolSetting {...props} {...props.config} />
|
||||
|
||||
const Input = inputs[props.setting]
|
||||
|
|
|
@ -35,21 +35,37 @@
|
|||
.fs-stroke-contrast { stroke: var(--pattern-contrast); }
|
||||
.fs-stroke-note { stroke: var(--pattern-note); }
|
||||
svg.freesewing.pattern path.fabric,
|
||||
svg.freesewing.pattern circle.fabric { @apply fs-stroke-fabric }
|
||||
svg.freesewing.pattern path.stroke-fabric,
|
||||
svg.freesewing.pattern circle.fabric,
|
||||
svg.freesewing.pattern circle.stroke-fabric { @apply fs-stroke-fabric }
|
||||
svg.freesewing.pattern path.lining,
|
||||
svg.freesewing.pattern circle.lining { @apply fs-stroke-lining }
|
||||
svg.freesewing.pattern path.stroke-lining,
|
||||
svg.freesewing.pattern circle.lining,
|
||||
svg.freesewing.pattern circle.stroke-lining { @apply fs-stroke-lining }
|
||||
svg.freesewing.pattern path.interfacing,
|
||||
svg.freesewing.pattern circle.interfacing { @apply fs-stroke-interfacing }
|
||||
svg.freesewing.pattern path.stroke-interfacing,
|
||||
svg.freesewing.pattern circle.interfacing,
|
||||
svg.freesewing.pattern circle.stroke-interfacing { @apply fs-stroke-interfacing }
|
||||
svg.freesewing.pattern path.canvas,
|
||||
svg.freesewing.pattern circle.canvas { @apply fs-stroke-canvas }
|
||||
svg.freesewing.pattern path.stroke-canvas,
|
||||
svg.freesewing.pattern circle.canvas,
|
||||
svg.freesewing.pattern circle.stroke-canvas { @apply fs-stroke-canvas }
|
||||
svg.freesewing.pattern path.various,
|
||||
svg.freesewing.pattern circle.various { @apply fs-stroke-various }
|
||||
svg.freesewing.pattern path.stroke-various,
|
||||
svg.freesewing.pattern circle.various,
|
||||
svg.freesewing.pattern circle.stroke-various { @apply fs-stroke-various }
|
||||
svg.freesewing.pattern path.mark,
|
||||
svg.freesewing.pattern circle.mark { @apply fs-stroke-mark }
|
||||
svg.freesewing.pattern path.stroke-mark,
|
||||
svg.freesewing.pattern circle.mark,
|
||||
svg.freesewing.pattern circle.stroke-mark { @apply fs-stroke-mark }
|
||||
svg.freesewing.pattern path.contrast,
|
||||
svg.freesewing.pattern circle.contrast { @apply fs-stroke-contrast }
|
||||
svg.freesewing.pattern path.stroke-contrast,
|
||||
svg.freesewing.pattern circle.contrast,
|
||||
svg.freesewing.pattern circle.stroke-contrast { @apply fs-stroke-contrast }
|
||||
svg.freesewing.pattern path.note,
|
||||
svg.freesewing.pattern circle.note { @apply fs-stroke-note }
|
||||
svg.freesewing.pattern path.stroke-note,
|
||||
svg.freesewing.pattern circle.note,
|
||||
svg.freesewing.pattern circle.stroke-note { @apply fs-stroke-note }
|
||||
.fs-fill-fabric { fill: var(--pattern-fabric); }
|
||||
.fs-fill-lining { fill: var(--pattern-lining); }
|
||||
.fs-fill-interfacing { fill: var(--pattern-interfacing); }
|
||||
|
@ -95,6 +111,8 @@
|
|||
.fs-fill-current { fill: currentColor; }
|
||||
svg.freesewing.pattern .fill-bg { @apply fs-fill-bg }
|
||||
svg.freesewing.pattern .fill-current { @apply fs-fill-current }
|
||||
.fill-opacity-25 { fill-opacity: 0.25; }
|
||||
.fill-opacity-50 { fill-opacity: 0.5; }
|
||||
}
|
||||
|
||||
/* Override DaisyUI button text color */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue