[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 cy = height / 2
|
||||
const pointsOnPerimeter: Vec2d[] = []
|
||||
|
||||
let minX = Infinity
|
||||
let maxX = -Infinity
|
||||
let minY = Infinity
|
||||
let maxY = -Infinity
|
||||
for (let i = 0; i < sides; i++) {
|
||||
const step = PI2 / sides
|
||||
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)
|
||||
if (x < minX) minX = x
|
||||
if (y < minY) minY = y
|
||||
if (x > maxX) maxX = x
|
||||
if (y > maxY) maxY = 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++) {
|
||||
const pt = pointsOnPerimeter[i]
|
||||
pt.x -= minX
|
||||
pt.y -= minY
|
||||
pt.x = ((pt.x - minX) / w) * width
|
||||
pt.y = ((pt.y - minY) / h) * height
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
TLOnResizeHandler,
|
||||
TLShapeUtilCanvasSvgDef,
|
||||
Vec2d,
|
||||
VecLike,
|
||||
geoShapeMigrations,
|
||||
geoShapeProps,
|
||||
getDefaultColorTheme,
|
||||
|
@ -321,11 +322,13 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
|
|||
|
||||
const labelSize = getLabelSize(this.editor, shape)
|
||||
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 edges = lines ? lines.map((line) => new Polyline2d({ points: line })) : []
|
||||
|
||||
// todo: use centroid for label position
|
||||
|
||||
return new Group2d({
|
||||
children: [
|
||||
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