diff --git a/apps/www/next-env.d.ts b/apps/www/next-env.d.ts
index 9bc3dd46b..4f11a03dc 100644
--- a/apps/www/next-env.d.ts
+++ b/apps/www/next-env.d.ts
@@ -1,5 +1,4 @@
///
-///
///
// NOTE: This file should not be edited
diff --git a/packages/core/src/TLShapeUtil/TLShapeUtil.tsx b/packages/core/src/TLShapeUtil/TLShapeUtil.tsx
index 99fee77d7..95c57ca86 100644
--- a/packages/core/src/TLShapeUtil/TLShapeUtil.tsx
+++ b/packages/core/src/TLShapeUtil/TLShapeUtil.tsx
@@ -39,17 +39,7 @@ export abstract class TLShapeUtil {
const shapeBounds = this.getBounds(shape)
-
- if (!shape.rotation) {
- return (
- Utils.boundsContain(bounds, shapeBounds) ||
- Utils.boundsContain(shapeBounds, bounds) ||
- Utils.boundsCollide(shapeBounds, bounds)
- )
- }
-
const corners = Utils.getRotatedCorners(shapeBounds, shape.rotation)
-
return (
corners.every((point) => Utils.pointInBounds(point, bounds)) ||
intersectPolylineBounds(corners, bounds).length > 0
diff --git a/packages/core/src/hooks/useStyle.tsx b/packages/core/src/hooks/useStyle.tsx
index 01f63e004..6267f369c 100644
--- a/packages/core/src/hooks/useStyle.tsx
+++ b/packages/core/src/hooks/useStyle.tsx
@@ -218,6 +218,26 @@ const tlcss = css`
contain: layout style size;
}
+ .tl-stroke-hitarea {
+ cursor: pointer;
+ fill: none;
+ stroke: transparent;
+ stroke-width: calc(24px * var(--tl-scale));
+ pointer-events: stroke;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ }
+
+ .tl-fill-hitarea {
+ cursor: pointer;
+ fill: transparent;
+ stroke: transparent;
+ stroke-width: calc(24px * var(--tl-scale));
+ pointer-events: all;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ }
+
.tl-counter-scaled {
transform: scale(var(--tl-scale));
}
@@ -354,6 +374,7 @@ const tlcss = css`
.tl-handle {
pointer-events: all;
+ cursor: grab;
}
.tl-handle:hover .tl-handle-bg {
@@ -365,6 +386,7 @@ const tlcss = css`
}
.tl-handle:active .tl-handle-bg {
+ cursor: grabbing;
fill: var(--tl-selectFill);
}
@@ -389,6 +411,7 @@ const tlcss = css`
stroke-width: calc(3px * var(--tl-scale));
fill: var(--tl-selectFill);
stroke: var(--tl-selected);
+ pointer-events: none;
}
.tl-centered-g {
diff --git a/packages/tldraw/src/state/sessions/BrushSession/BrushSession.spec.ts b/packages/tldraw/src/state/sessions/BrushSession/BrushSession.spec.ts
index 196bb49c2..434be1b8a 100644
--- a/packages/tldraw/src/state/sessions/BrushSession/BrushSession.spec.ts
+++ b/packages/tldraw/src/state/sessions/BrushSession/BrushSession.spec.ts
@@ -6,9 +6,9 @@ describe('Brush session', () => {
const app = new TldrawTestApp()
.loadDocument(mockDocument)
.selectNone()
- .movePointer([-10, -10])
+ .movePointer([-48, -48])
.startSession(SessionType.Brush)
- .movePointer([10, 10])
+ .movePointer([48, 48])
.completeSession()
expect(app.status).toBe(TDStatus.Idle)
expect(app.selectedIds.length).toBe(1)
diff --git a/packages/tldraw/src/state/shapes/ArrowUtil/ArrowUtil.tsx b/packages/tldraw/src/state/shapes/ArrowUtil/ArrowUtil.tsx
index 78450649f..684a19d8b 100644
--- a/packages/tldraw/src/state/shapes/ArrowUtil/ArrowUtil.tsx
+++ b/packages/tldraw/src/state/shapes/ArrowUtil/ArrowUtil.tsx
@@ -144,16 +144,7 @@ export class ArrowUtil extends TDShapeUtil {
shaftPath =
arrowDist > 2 ? (
<>
-
+
{
// Curved arrow path
shaftPath = (
<>
-
+
{
strokeDashoffset={strokeDashoffset}
strokeLinecap="round"
strokeLinejoin="round"
- pointerEvents="stroke"
+ pointerEvents="none"
/>
>
)
@@ -238,30 +219,38 @@ export class ArrowUtil extends TDShapeUtil {
{shaftPath}
{startArrowHead && (
-
+ <>
+
+
+ >
)}
{endArrowHead && (
-
+ <>
+
+
+ >
)}
diff --git a/packages/tldraw/src/state/shapes/DrawUtil/DrawUtil.tsx b/packages/tldraw/src/state/shapes/DrawUtil/DrawUtil.tsx
index 3ebde7129..1952264fe 100644
--- a/packages/tldraw/src/state/shapes/DrawUtil/DrawUtil.tsx
+++ b/packages/tldraw/src/state/shapes/DrawUtil/DrawUtil.tsx
@@ -51,121 +51,131 @@ export class DrawUtil extends TDShapeUtil {
)
}
- Component = TDShapeUtil.Component(({ shape, meta, isGhost, events }, ref) => {
- const { points, style, isComplete } = shape
+ Component = TDShapeUtil.Component(
+ ({ shape, meta, isSelected, isGhost, events }, ref) => {
+ const { points, style, isComplete } = shape
- const polygonPathTDSnapshot = React.useMemo(() => {
- return getFillPath(shape)
- }, [points, style.size])
+ const polygonPathTDSnapshot = React.useMemo(() => {
+ return getFillPath(shape)
+ }, [points, style.size])
- const pathTDSnapshot = React.useMemo(() => {
- return style.dash === DashStyle.Draw
- ? getDrawStrokePathTDSnapshot(shape)
- : getSolidStrokePathTDSnapshot(shape)
- }, [points, style.size, style.dash, isComplete])
+ const pathTDSnapshot = React.useMemo(() => {
+ return style.dash === DashStyle.Draw
+ ? getDrawStrokePathTDSnapshot(shape)
+ : getSolidStrokePathTDSnapshot(shape)
+ }, [points, style.size, style.dash, isComplete])
- const styles = getShapeStyle(style, meta.isDarkMode)
- const { stroke, fill, strokeWidth } = styles
+ const styles = getShapeStyle(style, meta.isDarkMode)
+ const { stroke, fill, strokeWidth } = styles
- // For very short lines, draw a point instead of a line
- const bounds = this.getBounds(shape)
+ // For very short lines, draw a point instead of a line
+ const bounds = this.getBounds(shape)
- const verySmall = bounds.width <= strokeWidth / 2 && bounds.height <= strokeWidth / 2
+ const verySmall = bounds.width <= strokeWidth / 2 && bounds.height <= strokeWidth / 2
- if (verySmall) {
- const sw = 1 + strokeWidth
+ if (verySmall) {
+ const sw = 1 + strokeWidth
- return (
-
-
-
- )
- }
+ return (
+
+
+
+ )
+ }
- const shouldFill =
- style.isFilled &&
- points.length > 3 &&
- Vec.dist(points[0], points[points.length - 1]) < strokeWidth * 2
+ const shouldFill =
+ style.isFilled &&
+ points.length > 3 &&
+ Vec.dist(points[0], points[points.length - 1]) < strokeWidth * 2
+
+ if (shape.style.dash === DashStyle.Draw) {
+ return (
+
+
+
+ {shouldFill && (
+
+ )}
+
+
+
+ )
+ }
+
+ // For solid, dash and dotted lines, draw a regular stroke path
+
+ const strokeDasharray = {
+ [DashStyle.Draw]: 'none',
+ [DashStyle.Solid]: `none`,
+ [DashStyle.Dotted]: `0.1 ${strokeWidth * 4}`,
+ [DashStyle.Dashed]: `${strokeWidth * 4} ${strokeWidth * 4}`,
+ }[style.dash]
+
+ const strokeDashoffset = {
+ [DashStyle.Draw]: 'none',
+ [DashStyle.Solid]: `none`,
+ [DashStyle.Dotted]: `0`,
+ [DashStyle.Dashed]: `0`,
+ }[style.dash]
+
+ const sw = 1 + strokeWidth * 1.5
- if (shape.style.dash === DashStyle.Draw) {
return (
- {shouldFill && (
-
- )}
+
+
)
}
-
- // For solid, dash and dotted lines, draw a regular stroke path
-
- const strokeDasharray = {
- [DashStyle.Draw]: 'none',
- [DashStyle.Solid]: `none`,
- [DashStyle.Dotted]: `0.1 ${strokeWidth * 4}`,
- [DashStyle.Dashed]: `${strokeWidth * 4} ${strokeWidth * 4}`,
- }[style.dash]
-
- const strokeDashoffset = {
- [DashStyle.Draw]: 'none',
- [DashStyle.Solid]: `none`,
- [DashStyle.Dotted]: `0`,
- [DashStyle.Dashed]: `0`,
- }[style.dash]
-
- const sw = 1 + strokeWidth * 1.5
-
- return (
-
-
-
-
-
-
- )
- })
+ )
Indicator = TDShapeUtil.Indicator(({ shape }) => {
const { points } = shape
diff --git a/packages/tldraw/src/state/shapes/EllipseUtil/EllipseUtil.tsx b/packages/tldraw/src/state/shapes/EllipseUtil/EllipseUtil.tsx
index d86711907..62fe7588a 100644
--- a/packages/tldraw/src/state/shapes/EllipseUtil/EllipseUtil.tsx
+++ b/packages/tldraw/src/state/shapes/EllipseUtil/EllipseUtil.tsx
@@ -39,7 +39,7 @@ export class EllipseUtil extends TDShapeUtil {
}
Component = TDShapeUtil.Component(
- ({ shape, isGhost, isBinding, meta, events }, ref) => {
+ ({ shape, isGhost, isSelected, isBinding, meta, events }, ref) => {
const {
radius: [radiusX, radiusY],
style,
@@ -68,18 +68,25 @@ export class EllipseUtil extends TDShapeUtil {
ry={ry + 2}
/>
)}
+
{
/>
)}
+
@@ -130,7 +144,16 @@ export class EllipseUtil extends TDShapeUtil {
)
Indicator = TDShapeUtil.Indicator(({ shape }) => {
- return
+ const {
+ radius: [radiusX, radiusY],
+ style: { dash },
+ } = shape
+
+ return dash === DashStyle.Draw ? (
+
+ ) : (
+
+ )
})
hitTestPoint = (shape: T, point: number[]): boolean => {
diff --git a/packages/tldraw/src/state/shapes/RectangleUtil/RectangleUtil.tsx b/packages/tldraw/src/state/shapes/RectangleUtil/RectangleUtil.tsx
index 4f52f211d..6bf88e425 100644
--- a/packages/tldraw/src/state/shapes/RectangleUtil/RectangleUtil.tsx
+++ b/packages/tldraw/src/state/shapes/RectangleUtil/RectangleUtil.tsx
@@ -41,7 +41,7 @@ export class RectangleUtil extends TDShapeUtil {
}
Component = TDShapeUtil.Component(
- ({ shape, isBinding, isGhost, meta, events }, ref) => {
+ ({ shape, isBinding, isSelected, isGhost, meta, events }, ref) => {
const { id, size, style } = shape
const styles = getShapeStyle(style, meta.isDarkMode)
@@ -50,6 +50,7 @@ export class RectangleUtil extends TDShapeUtil {
if (style.dash === DashStyle.Draw) {
const pathTDSnapshot = getRectanglePath(shape)
+ const indicatorPath = getRectangleIndicatorPathTDSnapshot(shape)
return (
@@ -63,18 +64,20 @@ export class RectangleUtil extends TDShapeUtil {
/>
)}
+
@@ -107,9 +110,6 @@ export class RectangleUtil extends TDShapeUtil {
y1={start[1]}
x2={end[0]}
y2={end[1]}
- stroke={styles.stroke}
- strokeWidth={sw}
- strokeLinecap="round"
strokeDasharray={strokeDasharray}
strokeDashoffset={strokeDashoffset}
/>
@@ -118,26 +118,37 @@ export class RectangleUtil extends TDShapeUtil {
return (
- {isBinding && (
+
+ {isBinding && (
+
+ )}
- )}
-
- {paths}
+ {style.isFilled && (
+
+ )}
+
+ {paths}
+
+
)
}