feat(react-components): Added PatternXray component
This commit is contained in:
parent
c527ccd702
commit
6da48ce4aa
5 changed files with 149 additions and 2 deletions
|
@ -1,4 +1,5 @@
|
||||||
// Components
|
// Components
|
||||||
|
// Pattern
|
||||||
import { Pattern as PatternComponent } from './pattern/index.mjs'
|
import { Pattern as PatternComponent } from './pattern/index.mjs'
|
||||||
import { Svg as SvgComponent } from './pattern/svg.mjs'
|
import { Svg as SvgComponent } from './pattern/svg.mjs'
|
||||||
import { Defs as DefsComponent } from './pattern/defs.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'
|
import { Text as TextComponent, TextOnPath as TextOnPathComponent } from './pattern/text.mjs'
|
||||||
// Pattern Utils
|
// Pattern Utils
|
||||||
import { getProps, withinPartBounds, getId, translateStrings } from './pattern/utils.mjs'
|
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
|
* Export all components as named exports
|
||||||
|
@ -28,6 +31,7 @@ export const Snippet = SnippetComponent
|
||||||
export const Grid = GridComponent
|
export const Grid = GridComponent
|
||||||
export const Text = TextComponent
|
export const Text = TextComponent
|
||||||
export const TextOnPath = TextOnPathComponent
|
export const TextOnPath = TextOnPathComponent
|
||||||
|
export const PatternXray = PatternXrayComponent
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Export pattern utils
|
* Export pattern utils
|
||||||
|
|
71
packages/react-components/src/pattern-xray/index.mjs
Normal file
71
packages/react-components/src/pattern-xray/index.mjs
Normal 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'
|
53
packages/react-components/src/pattern-xray/path.mjs
Normal file
53
packages/react-components/src/pattern-xray/path.mjs
Normal 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 }} />
|
||||||
|
</>
|
||||||
|
)
|
19
packages/react-components/src/pattern-xray/point.mjs
Normal file
19
packages/react-components/src/pattern-xray/point.mjs
Normal 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"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ import { Circle as DefaultCircle } from './circle.mjs'
|
||||||
/*
|
/*
|
||||||
* Allow people to swizzle these components
|
* Allow people to swizzle these components
|
||||||
*/
|
*/
|
||||||
const defaultComponents = {
|
export const defaultPatternComponents = {
|
||||||
Svg: DefaultSvg,
|
Svg: DefaultSvg,
|
||||||
Defs: DefaultDefs,
|
Defs: DefaultDefs,
|
||||||
Group: DefaultGroup,
|
Group: DefaultGroup,
|
||||||
|
@ -46,7 +46,7 @@ export const Pattern = forwardRef(
|
||||||
|
|
||||||
// Merge default and swizzled components
|
// Merge default and swizzled components
|
||||||
components = {
|
components = {
|
||||||
...defaultComponents,
|
...defaultPatternComponents,
|
||||||
...components,
|
...components,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue