[fix] polygon bounds (#2378)
This PR fixes the bounds calculation for polygons. It solves the bug reported here: https://github.com/tldraw/tldraw/issues/2309 . Note that this may produce visual changes for hexagons and other shapes. ![Kapture 2023-12-24 at 10 35 13](https://github.com/tldraw/tldraw/assets/23072548/773e89ee-f8c3-4875-b942-30860b1cdf22) ### Change Type - [x] `patch` — Bug fix ### Test Plan 1. Create a hexagon shape with a label. 2. The label should be correctly centered. ### Release Notes - Fixed a bug with the bounds calculation for polygons.
This commit is contained in:
parent
e5232e3513
commit
3f90fbf5b0
2 changed files with 37 additions and 4 deletions
|
@ -314,8 +314,11 @@ export function getPolygonVertices(width: number, height: number, sides: number)
|
||||||
const cx = width / 2
|
const cx = width / 2
|
||||||
const cy = height / 2
|
const cy = height / 2
|
||||||
const pointsOnPerimeter: Vec2d[] = []
|
const pointsOnPerimeter: Vec2d[] = []
|
||||||
|
|
||||||
let minX = Infinity
|
let minX = Infinity
|
||||||
|
let maxX = -Infinity
|
||||||
let minY = Infinity
|
let minY = Infinity
|
||||||
|
let maxY = -Infinity
|
||||||
for (let i = 0; i < sides; i++) {
|
for (let i = 0; i < sides; i++) {
|
||||||
const step = PI2 / sides
|
const step = PI2 / sides
|
||||||
const t = -TAU + i * step
|
const t = -TAU + i * step
|
||||||
|
@ -323,14 +326,25 @@ export function getPolygonVertices(width: number, height: number, sides: number)
|
||||||
const y = cy + cy * Math.sin(t)
|
const y = cy + cy * Math.sin(t)
|
||||||
if (x < minX) minX = x
|
if (x < minX) minX = x
|
||||||
if (y < minY) minY = y
|
if (y < minY) minY = y
|
||||||
|
if (x > maxX) maxX = x
|
||||||
|
if (y > maxY) maxY = y
|
||||||
pointsOnPerimeter.push(new Vec2d(x, y))
|
pointsOnPerimeter.push(new Vec2d(x, y))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minX !== 0 || minY !== 0) {
|
// Bounds of calculated points
|
||||||
|
const w = maxX - minX
|
||||||
|
const h = maxY - minY
|
||||||
|
|
||||||
|
// Difference between input bounds and calculated bounds
|
||||||
|
const dx = width - w
|
||||||
|
const dy = height - h
|
||||||
|
|
||||||
|
// If there's a difference, scale the points to the input bounds
|
||||||
|
if (dx !== 0 || dy !== 0) {
|
||||||
for (let i = 0; i < pointsOnPerimeter.length; i++) {
|
for (let i = 0; i < pointsOnPerimeter.length; i++) {
|
||||||
const pt = pointsOnPerimeter[i]
|
const pt = pointsOnPerimeter[i]
|
||||||
pt.x -= minX
|
pt.x = ((pt.x - minX) / w) * width
|
||||||
pt.y -= minY
|
pt.y = ((pt.y - minY) / h) * height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {
|
||||||
TLOnResizeHandler,
|
TLOnResizeHandler,
|
||||||
TLShapeUtilCanvasSvgDef,
|
TLShapeUtilCanvasSvgDef,
|
||||||
Vec2d,
|
Vec2d,
|
||||||
|
VecLike,
|
||||||
geoShapeMigrations,
|
geoShapeMigrations,
|
||||||
geoShapeProps,
|
geoShapeProps,
|
||||||
getDefaultColorTheme,
|
getDefaultColorTheme,
|
||||||
|
@ -321,11 +322,13 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
|
||||||
|
|
||||||
const labelSize = getLabelSize(this.editor, shape)
|
const labelSize = getLabelSize(this.editor, shape)
|
||||||
const labelWidth = Math.min(w, Math.max(labelSize.w, Math.min(32, Math.max(1, w - 8))))
|
const labelWidth = Math.min(w, Math.max(labelSize.w, Math.min(32, Math.max(1, w - 8))))
|
||||||
const labelHeight = Math.min(h, Math.max(labelSize.h, Math.min(32, Math.max(1, w - 8))))
|
const labelHeight = Math.min(h, Math.max(labelSize.h, Math.min(32, Math.max(1, w - 8)))) // not sure if bug
|
||||||
|
|
||||||
const lines = getLines(shape.props, strokeWidth)
|
const lines = getLines(shape.props, strokeWidth)
|
||||||
const edges = lines ? lines.map((line) => new Polyline2d({ points: line })) : []
|
const edges = lines ? lines.map((line) => new Polyline2d({ points: line })) : []
|
||||||
|
|
||||||
|
// todo: use centroid for label position
|
||||||
|
|
||||||
return new Group2d({
|
return new Group2d({
|
||||||
children: [
|
children: [
|
||||||
body,
|
body,
|
||||||
|
@ -1151,3 +1154,19 @@ function getCheckBoxLines(w: number, h: number) {
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the centroid of a regular polygon.
|
||||||
|
* @param points - The points that make up the polygon.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export function getCentroidOfRegularPolygon(points: VecLike[]) {
|
||||||
|
const len = points.length
|
||||||
|
let x = 0
|
||||||
|
let y = 0
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
x += points[i].x
|
||||||
|
y += points[i].y
|
||||||
|
}
|
||||||
|
return new Vec2d(x / len, y / len)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue