Creates standard shape fallback for dashed / dotted rects, ellipses

This commit is contained in:
Steve Ruiz 2021-06-22 06:22:37 +01:00
parent fcd1a8276d
commit 03603b5190
3 changed files with 79 additions and 57 deletions

View file

@ -1,12 +1,16 @@
import { uniqueId } from 'utils/utils' import { uniqueId } from 'utils/utils'
import vec from 'utils/vec' import vec from 'utils/vec'
import { EllipseShape, ShapeType } from 'types' import { DashStyle, EllipseShape, ShapeType } from 'types'
import { getShapeUtils } from './index' import { getShapeUtils } from './index'
import { boundsContained, getRotatedEllipseBounds } from 'utils/bounds' import { boundsContained, getRotatedEllipseBounds } from 'utils/bounds'
import { intersectEllipseBounds } from 'utils/intersections' import { intersectEllipseBounds } from 'utils/intersections'
import { pointInEllipse } from 'utils/hitTests' import { pointInEllipse } from 'utils/hitTests'
import { ease, getSvgPathFromStroke, rng, translateBounds } from 'utils/utils' import { ease, getSvgPathFromStroke, rng, translateBounds } from 'utils/utils'
import { defaultStyle, getShapeStyle } from 'state/shape-styles' import {
defaultStyle,
getShapeStyle,
getStrokeDashArray,
} from 'state/shape-styles'
import getStroke from 'perfect-freehand' import getStroke from 'perfect-freehand'
import { registerShapeUtils } from './register' import { registerShapeUtils } from './register'
@ -40,35 +44,43 @@ const ellipse = registerShapeUtils<EllipseShape>({
const { id, radiusX, radiusY, style } = shape const { id, radiusX, radiusY, style } = shape
const styles = getShapeStyle(style) const styles = getShapeStyle(style)
if (!pathCache.has(shape)) { if (style.dash === DashStyle.Solid) {
renderPath(shape) if (!pathCache.has(shape)) {
renderPath(shape)
}
const path = pathCache.get(shape)
return (
<g id={id}>
<ellipse
id={id}
cx={radiusX}
cy={radiusY}
rx={Math.max(0, radiusX - +styles.strokeWidth / 2)}
ry={Math.max(0, radiusY - +styles.strokeWidth / 2)}
stroke="none"
/>
<path d={path} fill={styles.stroke} />
</g>
)
} }
const path = pathCache.get(shape)
return ( return (
<g id={id}> <ellipse
<ellipse id={id}
id={id} cx={radiusX}
cx={radiusX} cy={radiusY}
cy={radiusY} rx={Math.max(0, radiusX - +styles.strokeWidth / 2)}
rx={Math.max(0, radiusX - Number(styles.strokeWidth) / 2)} ry={Math.max(0, radiusY - +styles.strokeWidth / 2)}
ry={Math.max(0, radiusY - Number(styles.strokeWidth) / 2)} fill={styles.fill}
stroke="none" stroke={styles.stroke}
/> strokeDasharray={getStrokeDashArray(
<path d={path} fill={styles.stroke} /> style.dash,
</g> +styles.strokeWidth
).join(' ')}
/>
) )
// return (
// <ellipse
// id={id}
// cx={radiusX}
// cy={radiusY}
// rx={Math.max(0, radiusX - Number(styles.strokeWidth) / 2)}
// ry={Math.max(0, radiusY - Number(styles.strokeWidth) / 2)}
// />
// )
}, },
getBounds(shape) { getBounds(shape) {

View file

@ -1,10 +0,0 @@
# Shape Utils
## Text
- Click to create a shape, type to add its content
- Click to select
- Double click (long press?) to begin editing
- Deselect to confirm changes
- Escape to revert changes
- If confirmed changes and text is empty, delete shape

View file

@ -1,6 +1,6 @@
import { uniqueId } from 'utils/utils' import { uniqueId } from 'utils/utils'
import vec from 'utils/vec' import vec from 'utils/vec'
import { RectangleShape, ShapeType } from 'types' import { DashStyle, RectangleShape, ShapeType } from 'types'
import { import {
getSvgPathFromStroke, getSvgPathFromStroke,
translateBounds, translateBounds,
@ -8,7 +8,11 @@ import {
shuffleArr, shuffleArr,
pointsBetween, pointsBetween,
} from 'utils/utils' } from 'utils/utils'
import { defaultStyle, getShapeStyle } from 'state/shape-styles' import {
defaultStyle,
getShapeStyle,
getStrokeDashArray,
} from 'state/shape-styles'
import getStroke from 'perfect-freehand' import getStroke from 'perfect-freehand'
import { registerShapeUtils } from './register' import { registerShapeUtils } from './register'
@ -40,29 +44,45 @@ const rectangle = registerShapeUtils<RectangleShape>({
render(shape) { render(shape) {
const { id, size, radius, style } = shape const { id, size, radius, style } = shape
const styles = getShapeStyle(style) const styles = getShapeStyle(style)
if (!pathCache.has(shape.size)) { if (style.dash === DashStyle.Solid) {
renderPath(shape) if (!pathCache.has(shape.size)) {
renderPath(shape)
}
const path = pathCache.get(shape.size)
return (
<g id={id}>
<rect
rx={radius}
ry={radius}
x={+styles.strokeWidth / 2}
y={+styles.strokeWidth / 2}
width={Math.max(0, size[0] + -styles.strokeWidth)}
height={Math.max(0, size[1] + -styles.strokeWidth)}
strokeWidth={0}
fill={styles.fill}
/>
<path d={path} fill={styles.stroke} />
</g>
)
} }
const path = pathCache.get(shape.size)
return ( return (
<g id={id}> <rect
<rect id={id}
className="hi" width={size[0]}
rx={radius} height={size[1]}
ry={radius} fill={styles.fill}
x={+styles.strokeWidth / 2} stroke={styles.stroke}
y={+styles.strokeWidth / 2} strokeDasharray={getStrokeDashArray(
width={Math.max(0, size[0] + -styles.strokeWidth)} style.dash,
height={Math.max(0, size[1] + -styles.strokeWidth)} +styles.strokeWidth
strokeWidth={0} ).join(' ')}
fill={styles.fill} />
/>
<path d={path} fill={styles.stroke} />
</g>
) )
}, },