improves hit testing for draw shapes
This commit is contained in:
parent
c52c8f4c76
commit
c51c6631e1
1 changed files with 32 additions and 25 deletions
|
@ -3,16 +3,19 @@ import * as vec from 'utils/vec'
|
||||||
import { DashStyle, DrawShape, ShapeStyles, ShapeType } from 'types'
|
import { DashStyle, DrawShape, ShapeStyles, ShapeType } from 'types'
|
||||||
import { registerShapeUtils } from './index'
|
import { registerShapeUtils } from './index'
|
||||||
import { intersectPolylineBounds } from 'utils/intersections'
|
import { intersectPolylineBounds } from 'utils/intersections'
|
||||||
import { boundsContainPolygon } from 'utils/bounds'
|
import { boundsContain, boundsContainPolygon } from 'utils/bounds'
|
||||||
import getStroke from 'perfect-freehand'
|
import getStroke from 'perfect-freehand'
|
||||||
import {
|
import {
|
||||||
getBoundsCenter,
|
getBoundsCenter,
|
||||||
getBoundsFromPoints,
|
getBoundsFromPoints,
|
||||||
|
getRotatedCorners,
|
||||||
getSvgPathFromStroke,
|
getSvgPathFromStroke,
|
||||||
|
rotateBounds,
|
||||||
translateBounds,
|
translateBounds,
|
||||||
} from 'utils/utils'
|
} from 'utils/utils'
|
||||||
import { defaultStyle, getShapeStyle } from 'lib/shape-styles'
|
import { defaultStyle, getShapeStyle } from 'lib/shape-styles'
|
||||||
|
|
||||||
|
const rotatedCache = new WeakMap<DrawShape, number[][]>([])
|
||||||
const pathCache = new WeakMap<DrawShape['points'], string>([])
|
const pathCache = new WeakMap<DrawShape['points'], string>([])
|
||||||
|
|
||||||
const draw = registerShapeUtils<DrawShape>({
|
const draw = registerShapeUtils<DrawShape>({
|
||||||
|
@ -69,20 +72,16 @@ const draw = registerShapeUtils<DrawShape>({
|
||||||
},
|
},
|
||||||
|
|
||||||
getRotatedBounds(shape) {
|
getRotatedBounds(shape) {
|
||||||
const bounds =
|
const rBounds = translateBounds(
|
||||||
this.boundsCache.get(shape) || getBoundsFromPoints(shape.points)
|
getBoundsFromPoints(shape.points, shape.rotation),
|
||||||
|
|
||||||
const center = getBoundsCenter(bounds)
|
|
||||||
|
|
||||||
const rotatedPts = shape.points.map((pt) =>
|
|
||||||
vec.rotWith(pt, center, shape.rotation)
|
|
||||||
)
|
|
||||||
const rotatedBounds = translateBounds(
|
|
||||||
getBoundsFromPoints(rotatedPts),
|
|
||||||
shape.point
|
shape.point
|
||||||
)
|
)
|
||||||
|
|
||||||
return rotatedBounds
|
const bounds = this.getBounds(shape)
|
||||||
|
|
||||||
|
const delta = vec.sub(getBoundsCenter(bounds), getBoundsCenter(rBounds))
|
||||||
|
|
||||||
|
return translateBounds(rBounds, delta)
|
||||||
},
|
},
|
||||||
|
|
||||||
getCenter(shape) {
|
getCenter(shape) {
|
||||||
|
@ -100,22 +99,30 @@ const draw = registerShapeUtils<DrawShape>({
|
||||||
},
|
},
|
||||||
|
|
||||||
hitTestBounds(this, shape, brushBounds) {
|
hitTestBounds(this, shape, brushBounds) {
|
||||||
const b = this.getBounds(shape)
|
// Test axis-aligned shape
|
||||||
const center = [b.minX + b.width / 2, b.minY + b.height / 2]
|
if (shape.rotation === 0) {
|
||||||
|
return (
|
||||||
|
boundsContain(brushBounds, this.getBounds(shape)) ||
|
||||||
|
intersectPolylineBounds(shape.points, brushBounds).length > 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const rotatedCorners = [
|
// Test rotated shape
|
||||||
[b.minX, b.minY],
|
const rBounds = this.getRotatedBounds(shape)
|
||||||
[b.maxX, b.minY],
|
|
||||||
[b.maxX, b.maxY],
|
if (!rotatedCache.has(shape)) {
|
||||||
[b.minX, b.maxY],
|
const c = getBoundsCenter(rBounds)
|
||||||
].map((point) => vec.rotWith(point, center, shape.rotation))
|
rotatedCache.set(
|
||||||
|
shape,
|
||||||
|
shape.points.map((pt) =>
|
||||||
|
vec.rotWith(vec.add(pt, shape.point), c, shape.rotation)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
boundsContainPolygon(brushBounds, rotatedCorners) ||
|
boundsContain(brushBounds, rBounds) ||
|
||||||
intersectPolylineBounds(
|
intersectPolylineBounds(rotatedCache.get(shape), brushBounds).length > 0
|
||||||
shape.points.map((point) => vec.add(point, shape.point)),
|
|
||||||
brushBounds
|
|
||||||
).length > 0
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue