1
0
Fork 0

wip(lab): Work on xray mode

This commit is contained in:
Joost De Cock 2022-01-28 19:55:32 +01:00
parent c05d9dce23
commit ec2fd35208
9 changed files with 215 additions and 89 deletions

View file

@ -2,6 +2,7 @@ const defaultSettings = {
sa: 0, sa: 0,
saBool: false, saBool: false,
saMm: 10, saMm: 10,
scale: 1,
complete: true, complete: true,
paperless: false, paperless: false,
units: 'metric', units: 'metric',
@ -9,6 +10,8 @@ const defaultSettings = {
margin: 2, margin: 2,
renderer: 'react', renderer: 'react',
embed: true, embed: true,
debug: true,
xray: false,
} }
export default defaultSettings export default defaultSettings

View file

@ -18,7 +18,7 @@ const tabClasses = active => `
const Wrap = props => <div className="max-w-screen-xl m-auto">{props.children}</div> const Wrap = props => <div className="max-w-screen-xl m-auto">{props.children}</div>
const LabDraft = props => { const LabDraft = props => {
const { app, pattern, gist, updateGist } = props const { app, pattern, gist, updateGist, unsetGist } = props
const [tab, setTab] = useState(props.pattern.config.name) const [tab, setTab] = useState(props.pattern.config.name)
@ -71,12 +71,12 @@ const LabDraft = props => {
{Object.keys(patternProps.parts).map((name) => ( {Object.keys(patternProps.parts).map((name) => (
<Part <Part
key={name} key={name}
partName={name}
part={patternProps.parts[name]} part={patternProps.parts[name]}
locale={gist.locale}
paperless={gist.paperless}
units={gist.units}
name={name}
app={app} app={app}
gist={gist}
updateGist={updateGist}
unsetGist={unsetGist}
/> />
))} ))}
</g> </g>

View file

@ -3,13 +3,17 @@ import Point from '../point'
import Snippet from '../snippet' import Snippet from '../snippet'
import { getProps } from '../utils' 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 focusPoint = (point, i) => {
const p = props.part.points[point] const p = part.points[point]
const pathString = `M ${p.x} ${props.part.topLeft.y} ` const pathString = `M ${p.x} ${part.topLeft.y} `
+ `L ${p.x} ${props.part.bottomRight.y} ` + `L ${p.x} ${part.bottomRight.y} `
+ `M ${props.part.topLeft.x} ${p.y} ` + `M ${part.topLeft.x} ${p.y} `
+ `L ${props.part.bottomRight.x} ${p.y} ` + `L ${part.bottomRight.x} ${p.y} `
const classes = 'focus point c' + (i % 8) // Cycle through 8 colors const classes = 'focus point c' + (i % 8) // Cycle through 8 colors
return ( return (
<React.Fragment key={'fp' + point}> <React.Fragment key={'fp' + point}>
@ -20,8 +24,8 @@ const Part = (props) => {
r="5" r="5"
className="contrast" className="contrast"
onClick={() => onClick={() =>
props.raiseEvent('clearFocus', { raiseEvent('clearFocus', {
part: props.name, part: partName,
type: 'points', type: 'points',
name: point name: point
}) })
@ -32,10 +36,10 @@ const Part = (props) => {
} }
const focusCoords = (p, i) => { const focusCoords = (p, i) => {
let pathString = `M ${p.x} ${props.part.topLeft.y} ` let pathString = `M ${p.x} ${part.topLeft.y} `
pathString += `L ${p.x} ${props.part.bottomRight.y} ` pathString += `L ${p.x} ${part.bottomRight.y} `
pathString += `M ${props.part.topLeft.x} ${p.y} ` pathString += `M ${part.topLeft.x} ${p.y} `
pathString += `L ${props.part.bottomRight.x} ${p.y} ` pathString += `L ${part.bottomRight.x} ${p.y} `
let classes = 'focus coords c' + (i % 4) // Cycle through 4 CSS classes let classes = 'focus coords c' + (i % 4) // Cycle through 4 CSS classes
return ( return (
<React.Fragment key={'cp' + i}> <React.Fragment key={'cp' + i}>
@ -46,8 +50,8 @@ const Part = (props) => {
r="5" r="5"
className={classes} className={classes}
onClick={() => onClick={() =>
props.raiseEvent('clearFocus', { raiseEvent('clearFocus', {
part: props.name, partName: partName,
type: 'coords', type: 'coords',
data: p data: p
}) })
@ -57,79 +61,74 @@ const Part = (props) => {
) )
} }
let grid = props.paperless ? ( let grid = gist.paperless ? (
<rect <rect
x={props.part.topLeft.x} x={part.topLeft.x}
y={props.part.topLeft.y} y={part.topLeft.y}
width={props.part.width} width={part.width}
height={props.part.height} height={part.height}
className="grid" className="grid"
fill={'url(#grid-' + props.name + ')'} fill={'url(#grid-' + partName + ')'}
/> />
) : null ) : null
let focus = [] let focus = []
if (props.develop) { //if (gist.debug) {
if (props.focus && typeof props.focus[props.name] !== 'undefined') { // if (focus && typeof props.focus[props.name] !== 'undefined') {
for (let i in props.focus[props.name].points) // for (let i in props.focus[props.name].points)
focus.push(focusPoint(props.focus[props.name].points[i], i)) // focus.push(focusPoint(props.focus[props.name].points[i], i))
for (let i in props.focus[props.name].paths) { // for (let i in props.focus[props.name].paths) {
let name = props.focus[props.name].paths[i] // let name = props.focus[props.name].paths[i]
focus.push( // focus.push(
<path // <path
key={'fpa-' + name} // key={'fpa-' + name}
d={props.part.paths[name].asPathstring()} // d={props.part.paths[name].asPathstring()}
className={'focus path c' + (i % 4)} // className={'focus path c' + (i % 4)}
onClick={() => // onClick={() =>
props.raiseEvent('clearFocus', { // props.raiseEvent('clearFocus', {
part: props.name, // part: props.name,
type: 'paths', // type: 'paths',
name // name
}) // })
} // }
/> // />
) // )
} // }
for (let i in props.focus[props.name].coords) // for (let i in props.focus[props.name].coords)
focus.push(focusCoords(props.focus[props.name].coords[i], i)) // focus.push(focusCoords(props.focus[props.name].coords[i], i))
} // }
} //}
return ( return (
<g {...getProps(props.part)} id={`part-${props.name}`}> <g {...getProps(part)} id={`part-${partName}`}>
{grid} {grid}
{Object.keys(props.part.paths).map((name) => ( {Object.keys(part.paths).map((pathName) => (
<Path <Path
key={name} key={name}
name={name} pathName={pathName}
part={props.name} path={part.paths[pathName]}
locale={props.locale}
path={props.part.paths[name]}
focus={props.focus}
topLeft={props.part.topLeft} topLeft={props.part.topLeft}
bottomRight={props.part.bottomRight} bottomRight={props.part.bottomRight}
develop={props.develop} {...props}
raiseEvent={props.raiseEvent}
app={props.app}
/> />
))} ))}
{Object.keys(props.part.points).map((name) => ( {Object.keys(props.part.points).map((name) => (
<Point <Point
key={name} key={name}
name={name} pointName={name}
part={props.name}
locale={props.locale}
point={props.part.points[name]} point={props.part.points[name]}
focus={props.focus}
topLeft={props.part.topLeft} topLeft={props.part.topLeft}
bottomRight={props.part.bottomRight} bottomRight={props.part.bottomRight}
develop={props.develop} {...props}
raiseEvent={props.raiseEvent}
app={props.app}
/> />
))} ))}
{Object.keys(props.part.snippets).map((name) => ( {Object.keys(props.part.snippets).map((snippetName) => (
<Snippet key={name} name={name} snippet={props.part.snippets[name]} /> <Snippet
key={name}
snippetName={snippetName}
snippet={props.part.snippets[snippetName]}
{...props}
/>
))} ))}
{focus} {focus}
</g> </g>

View file

@ -1,15 +1,16 @@
import TextOnPath from '../text-on-path' import TextOnPath from '../text-on-path'
import { getProps } from '../utils' import { getProps } from '../utils'
const Path = (props) => { const Path = props => {
if (!props.path.render) return null const { path, part, name } = props
if (!path.render) return null
const output = [] const output = []
const pathId = 'path-' + props.part + '-' + props.name const pathId = 'path-' + part + '-' + name
output.push( 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')) if (path.attributes.get('data-text'))
output.push(<TextOnPath key={'text-on-path-' + props.name} pathId={pathId} {...props} />) output.push(<TextOnPath key={'text-on-path-' + name} pathId={pathId} {...props} />)
return output return output
} }

View file

@ -1,12 +1,35 @@
import Text from '../text' import Text from '../text'
import Circle from '../circle' 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 = [] const output = []
if (props.point.attributes && props.point.attributes.get('data-text')) if (props.gist.xray) output.push(<XrayPoint {...props} key={'xp-' + props.name} />)
output.push(<Text {...props} key={'point-' + props.name} />) if (point.attributes && point.attributes.get('data-text'))
if (props.point.attributes && props.point.attributes.get('data-circle')) output.push(<Text {...props} key={'point-' + name} />)
output.push(<Circle point={props.point} key={'circle-' + props.name} />) if (point.attributes && point.attributes.get('data-circle'))
output.push(<Circle point={point} key={'circle-' + name} />)
return output.length < 1 ? null : output return output.length < 1 ? null : output
} }

View file

@ -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

View file

@ -29,6 +29,11 @@ const settings = {
max: 25, max: 25,
dflt: 2, dflt: 2,
}, },
scale: {
min: 0.1,
max: 5,
dflt: 1,
},
renderer: { renderer: {
list: ['react', 'svg'], list: ['react', 'svg'],
titles: { titles: {
@ -39,6 +44,9 @@ const settings = {
debug: { debug: {
dflt: false, dflt: false,
}, },
xray: {
dflt: false,
},
} }
const CoreSettings = props => { const CoreSettings = props => {

View file

@ -4,6 +4,7 @@ import CountOption from 'shared/components/workbench/inputs/design-option-count'
import ListSetting from './core-setting-list' import ListSetting from './core-setting-list'
import OnlySetting from './core-setting-only' import OnlySetting from './core-setting-only'
import MmSetting from './core-setting-mm' import MmSetting from './core-setting-mm'
import NrSetting from './core-setting-nr'
import BoolSetting from './core-setting-bool.js' import BoolSetting from './core-setting-bool.js'
import SaBoolSetting from './core-setting-sa-bool.js' import SaBoolSetting from './core-setting-sa-bool.js'
import SaMmSetting from './core-setting-sa-mm.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 => { saMm: props => {
return ( return (
<span className="text-secondary" dangerouslySetInnerHTML={{ <span className="text-secondary" dangerouslySetInnerHTML={{
@ -85,6 +89,7 @@ const inputs = {
}))} }))}
/>, />,
margin: props => <MmSetting {...props} {...props.config} />, margin: props => <MmSetting {...props} {...props.config} />,
scale: props => <NrSetting {...props} {...props.config} />,
saMm: props => <SaMmSetting {...props} {...props.config} />, saMm: props => <SaMmSetting {...props} {...props.config} />,
renderer: props => <ListSetting renderer: props => <ListSetting
{...props} {...props}
@ -100,7 +105,7 @@ const Setting = props => {
if (props.setting === 'saBool') if (props.setting === 'saBool')
return <SaBoolSetting {...props} {...props.config} /> 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} /> return <BoolSetting {...props} {...props.config} />
const Input = inputs[props.setting] const Input = inputs[props.setting]

View file

@ -35,21 +35,37 @@
.fs-stroke-contrast { stroke: var(--pattern-contrast); } .fs-stroke-contrast { stroke: var(--pattern-contrast); }
.fs-stroke-note { stroke: var(--pattern-note); } .fs-stroke-note { stroke: var(--pattern-note); }
svg.freesewing.pattern path.fabric, 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 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 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 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 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 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 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 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-fabric { fill: var(--pattern-fabric); }
.fs-fill-lining { fill: var(--pattern-lining); } .fs-fill-lining { fill: var(--pattern-lining); }
.fs-fill-interfacing { fill: var(--pattern-interfacing); } .fs-fill-interfacing { fill: var(--pattern-interfacing); }
@ -95,6 +111,8 @@
.fs-fill-current { fill: currentColor; } .fs-fill-current { fill: currentColor; }
svg.freesewing.pattern .fill-bg { @apply fs-fill-bg } svg.freesewing.pattern .fill-bg { @apply fs-fill-bg }
svg.freesewing.pattern .fill-current { @apply fs-fill-current } 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 */ /* Override DaisyUI button text color */