1
0
Fork 0

feat(react-components): Added PatternXray component

This commit is contained in:
joostdecock 2023-06-17 13:19:09 +02:00
parent c527ccd702
commit 6da48ce4aa
5 changed files with 149 additions and 2 deletions

View file

@ -1,4 +1,5 @@
// Components
// Pattern
import { Pattern as PatternComponent } from './pattern/index.mjs'
import { Svg as SvgComponent } from './pattern/svg.mjs'
import { Defs as DefsComponent } from './pattern/defs.mjs'
@ -12,6 +13,8 @@ import { Grid as GridComponent } from './pattern/grid.mjs'
import { Text as TextComponent, TextOnPath as TextOnPathComponent } from './pattern/text.mjs'
// Pattern Utils
import { getProps, withinPartBounds, getId, translateStrings } from './pattern/utils.mjs'
// PatternXray
import { PatternXray as PatternXrayComponent } from './pattern-xray/index.mjs'
/*
* Export all components as named exports
@ -28,6 +31,7 @@ export const Snippet = SnippetComponent
export const Grid = GridComponent
export const Text = TextComponent
export const TextOnPath = TextOnPathComponent
export const PatternXray = PatternXrayComponent
/*
* Export pattern utils

View file

@ -0,0 +1,71 @@
// eslint-disable-next-line no-unused-vars
import React, { forwardRef } from 'react'
import { defaultPatternComponents } from '../pattern/index.mjs'
// Components that can be swizzled
import { PointXray } from './point.mjs'
import { PathXray } from './path.mjs'
/*
* Allow people to swizzle these components
*/
export const defaultPatternXrayComponents = {
...defaultPatternComponents,
Point: PointXray,
Path: PathXray,
}
export const PatternXray = forwardRef(
(
{
renderProps = false,
t = (string) => string,
components = {},
children = false,
className = 'freesewing pattern',
},
ref
) => {
if (!renderProps) return null
// Merge default and swizzled components
components = {
...defaultPatternXrayComponents,
...components,
}
const { Svg, Defs, Stack, Group } = components
const optionalProps = {}
if (className) optionalProps.className = className
return (
<Svg
viewBox={`0 0 ${renderProps.width} ${renderProps.height}`}
embed={renderProps.settings.embed}
{...renderProps}
{...optionalProps}
ref={ref}
>
<Defs {...renderProps} />
<style>{`:root { --pattern-scale: ${renderProps.settings.scale || 1}} ${
renderProps.svg.style
}`}</style>
<Group>
{children
? children
: Object.keys(renderProps.stacks).map((stackName) => (
<Stack
key={stackName}
stackName={stackName}
stack={renderProps.stacks[stackName]}
settings={renderProps.settings}
components={components}
t={t}
/>
))}
</Group>
</Svg>
)
}
)
PatternXray.displayName = 'PatternXray'

View file

@ -0,0 +1,53 @@
// Components
import { Path } from '../pattern/path.mjs'
import { getProps, getId } from '../pattern/utils.mjs'
const coords = (point) => `${point.x},${point.y}`
const Cp = ({ at }) => (
<circle cx={at.x} cy={at.y} r={0.75} className="stroke-md opacity-50 text-warning" />
)
const Xray = ({ stackName, pathName, path, t, inspector }) => {
const output = []
let prev
let i = 0
for (const op of path.ops) {
if (op.type === 'curve') {
output.push(
<Cp at={op.cp1} key={`${i}-cp1`} />,
<Cp at={op.cp2} key={`${i}-cp2`} />,
<path
key={i}
d={`M ${coords(prev.to)} L ${coords(op.cp1)} M ${coords(op.to)} L ${coords(op.cp2)}`}
className={`text-warning stroke-sm dashed opacity-50`}
markerStart="none"
markerEnd="none"
/>
)
}
prev = op
i++
}
output.push(
<path key="path" d={path.d} {...getProps(path)} markerStart="none" markerEnd="none" />
)
return output
}
export const PathXray = ({
stackName,
pathName,
part,
path,
settings,
components,
t,
inspector,
}) => (
<>
<Xray {...{ stackName, pathName, path, part, settings, t, inspector }} />
<Path {...{ stackName, pathName, path, part, settings, components, t }} />
</>
)

View file

@ -0,0 +1,19 @@
// Components
import { Point } from '../pattern/point.mjs'
import { withinPartBounds } from '../pattern/utils.mjs'
export const PointXray = ({ stackName, pointName, part, point, settings, components, t }) => {
// Don't include parts outside the part bounding box
if (!withinPartBounds(point, part)) return null
return (
<>
<Point {...{ stackName, pointName, part, point, settings, components, t }} />
<circle
cx={point.x}
cy={point.y}
r={1.5 * (settings.scale || 1)}
className="stroke-md opacity-70"
/>
</>
)
}

View file

@ -16,7 +16,7 @@ import { Circle as DefaultCircle } from './circle.mjs'
/*
* Allow people to swizzle these components
*/
const defaultComponents = {
export const defaultPatternComponents = {
Svg: DefaultSvg,
Defs: DefaultDefs,
Group: DefaultGroup,
@ -46,7 +46,7 @@ export const Pattern = forwardRef(
// Merge default and swizzled components
components = {
...defaultComponents,
...defaultPatternComponents,
...components,
}