#6097 Implemented calcIntersect for the first round of shapes

This commit is contained in:
Knut Sveidqvist
2024-11-30 10:54:18 +01:00
parent 33d8b1a78d
commit 0c28593ea5
9 changed files with 122 additions and 52 deletions

View File

@@ -120,9 +120,20 @@ export async function bowTieRect<T extends SVGGraphicsElement>(parent: D3Selecti
updateNodeBounds(node, bowTieRectShape); updateNodeBounds(node, bowTieRectShape);
node.calcIntersect = function (bounds: Bounds, point: Point) { node.calcIntersect = function (bounds: Bounds, point: Point) {
// TODO: Implement intersect for this shape const w = bounds.width;
const radius = bounds.width / 2; const h = bounds.height;
return intersect.circle(bounds, radius, point);
const ry = h / 2;
const rx = ry / (2.5 + h / 50);
const points = [
{ x: w / 2, y: -h / 2 },
{ x: -w / 2, y: -h / 2 },
...generateArcPoints(-w / 2, -h / 2, -w / 2, h / 2, rx, ry, false),
{ x: w / 2, y: h / 2 },
...generateArcPoints(w / 2, h / 2, w / 2, -h / 2, rx, ry, true),
];
return intersect.polygon(bounds, points, point);
}; };
node.intersect = function (point) { node.intersect = function (point) {
const pos = intersect.polygon(node, points, point); const pos = intersect.polygon(node, points, point);

View File

@@ -57,9 +57,22 @@ export async function card<T extends SVGGraphicsElement>(parent: D3Selection<T>,
updateNodeBounds(node, polygon); updateNodeBounds(node, polygon);
node.calcIntersect = function (bounds: Bounds, point: Point) { node.calcIntersect = function (bounds: Bounds, point: Point) {
// TODO: Implement intersect for this shape const h = bounds.height;
const radius = bounds.width / 2; const padding = 12;
return intersect.circle(bounds, radius, point); const w = bounds.width;
const left = 0;
const right = w;
const top = -h;
const bottom = 0;
const points = [
{ x: left + padding, y: top },
{ x: right, y: top },
{ x: right, y: bottom },
{ x: left, y: bottom },
{ x: left, y: top + padding },
{ x: left + padding, y: top },
];
return intersect.polygon(bounds, points, point);
}; };
node.intersect = function (point) { node.intersect = function (point) {

View File

@@ -49,9 +49,15 @@ export function choice<T extends SVGGraphicsElement>(parent: D3Selection<T>, nod
node.height = 28; node.height = 28;
node.calcIntersect = function (bounds: Bounds, point: Point) { node.calcIntersect = function (bounds: Bounds, point: Point) {
// TODO: Implement intersect for this shape const s = Math.max(28, bounds.width ?? 0);
const radius = bounds.width / 2;
return intersect.circle(bounds, radius, point); const points = [
{ x: 0, y: s / 2 },
{ x: s / 2, y: 0 },
{ x: 0, y: -s / 2 },
{ x: -s / 2, y: 0 },
];
return intersect.circle(bounds, points, point);
}; };
node.intersect = function (point) { node.intersect = function (point) {

View File

@@ -201,9 +201,7 @@ export async function classBox<T extends SVGGraphicsElement>(parent: D3Selection
updateNodeBounds(node, rect); updateNodeBounds(node, rect);
node.calcIntersect = function (bounds: Bounds, point: Point) { node.calcIntersect = function (bounds: Bounds, point: Point) {
// TODO: Implement intersect for this shape return intersect.rect(bounds, point);
const radius = bounds.width / 2;
return intersect.circle(bounds, radius, point);
}; };
node.intersect = function (point) { node.intersect = function (point) {
return intersect.rect(node, point); return intersect.rect(node, point);

View File

@@ -59,8 +59,7 @@ export function crossedCircle<T extends SVGGraphicsElement>(parent: D3Selection<
updateNodeBounds(node, crossedCircle); updateNodeBounds(node, crossedCircle);
node.calcIntersect = function (bounds: Bounds, point: Point) { node.calcIntersect = function (bounds: Bounds, point: Point) {
// TODO: Implement intersect for this shape const radius = Math.max(30, bounds?.width ?? 0);
const radius = bounds.width / 2;
return intersect.circle(bounds, radius, point); return intersect.circle(bounds, radius, point);
}; };

View File

@@ -107,9 +107,23 @@ export async function curlyBraceLeft<T extends SVGGraphicsElement>(
updateNodeBounds(node, curlyBraceLeftShape); updateNodeBounds(node, curlyBraceLeftShape);
node.calcIntersect = function (bounds: Bounds, point: Point) { node.calcIntersect = function (bounds: Bounds, point: Point) {
// TODO: Implement intersect for this shape const w = bounds.width;
const radius = bounds.width / 2; const h = bounds.height;
return intersect.circle(bounds, radius, point); const radius = Math.max(5, h * 0.1);
const rectPoints = [
{ x: w / 2, y: -h / 2 - radius },
{ x: -w / 2, y: -h / 2 - radius },
...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0),
{ x: -w / 2 - radius, y: -radius },
...generateCirclePoints(w / 2 + w * 0.1, -radius, radius, 20, -180, -270),
...generateCirclePoints(w / 2 + w * 0.1, radius, radius, 20, -90, -180),
{ x: -w / 2 - radius, y: h / 2 },
...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90),
{ x: -w / 2, y: h / 2 + radius },
{ x: w / 2, y: h / 2 + radius },
];
return intersect.polygon(bounds, rectPoints, point);
}; };
node.intersect = function (point) { node.intersect = function (point) {

View File

@@ -107,9 +107,23 @@ export async function curlyBraceRight<T extends SVGGraphicsElement>(
updateNodeBounds(node, curlyBraceRightShape); updateNodeBounds(node, curlyBraceRightShape);
node.calcIntersect = function (bounds: Bounds, point: Point) { node.calcIntersect = function (bounds: Bounds, point: Point) {
// TODO: Implement intersect for this shape const w = bounds.width;
const radius = bounds.width / 2; const h = bounds.height;
return intersect.circle(bounds, radius, point); const radius = Math.max(5, h * 0.1);
const rectPoints = [
{ x: -w / 2, y: -h / 2 - radius },
{ x: w / 2, y: -h / 2 - radius },
...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0),
{ x: w / 2 + radius, y: -radius },
...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270),
...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180),
{ x: w / 2 + radius, y: h / 2 },
...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90),
{ x: w / 2, y: h / 2 + radius },
{ x: -w / 2, y: h / 2 + radius },
];
return intersect.polygon(bounds, rectPoints, point);
}; };
node.intersect = function (point) { node.intersect = function (point) {

View File

@@ -36,6 +36,25 @@ function generateCirclePoints(
return points; return points;
} }
const getRectPoints = (w: number, h: number, radius: number) => [
{ x: w / 2, y: -h / 2 - radius },
{ x: -w / 2, y: -h / 2 - radius },
...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0),
{ x: -w / 2 - radius, y: -radius },
...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270),
...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180),
{ x: -w / 2 - radius, y: h / 2 },
...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90),
{ x: -w / 2, y: h / 2 + radius },
{ x: w / 2 - radius - radius / 2, y: h / 2 + radius },
...generateCirclePoints(-w / 2 + radius + radius / 2, -h / 2, radius, 20, -90, -180),
{ x: w / 2 - radius / 2, y: radius },
...generateCirclePoints(-w / 2 - radius / 2, -radius, radius, 20, 0, 90),
...generateCirclePoints(-w / 2 - radius / 2, radius, radius, 20, -90, 0),
{ x: w / 2 - radius / 2, y: -radius },
...generateCirclePoints(-w / 2 + radius + radius / 2, h / 2, radius, 30, -180, -270),
];
export async function curlyBraces<T extends SVGGraphicsElement>( export async function curlyBraces<T extends SVGGraphicsElement>(
parent: D3Selection<T>, parent: D3Selection<T>,
node: Node node: Node
@@ -67,24 +86,7 @@ export async function curlyBraces<T extends SVGGraphicsElement>(
...generateCirclePoints(-w / 2 + radius + radius / 2, h / 2, radius, 30, -180, -270), ...generateCirclePoints(-w / 2 + radius + radius / 2, h / 2, radius, 30, -180, -270),
]; ];
const rectPoints = [ const rectPoints = getRectPoints(w, h, radius);
{ x: w / 2, y: -h / 2 - radius },
{ x: -w / 2, y: -h / 2 - radius },
...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0),
{ x: -w / 2 - radius, y: -radius },
...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270),
...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180),
{ x: -w / 2 - radius, y: h / 2 },
...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90),
{ x: -w / 2, y: h / 2 + radius },
{ x: w / 2 - radius - radius / 2, y: h / 2 + radius },
...generateCirclePoints(-w / 2 + radius + radius / 2, -h / 2, radius, 20, -90, -180),
{ x: w / 2 - radius / 2, y: radius },
...generateCirclePoints(-w / 2 - radius / 2, -radius, radius, 20, 0, 90),
...generateCirclePoints(-w / 2 - radius / 2, radius, radius, 20, -90, 0),
{ x: w / 2 - radius / 2, y: -radius },
...generateCirclePoints(-w / 2 + radius + radius / 2, h / 2, radius, 30, -180, -270),
];
// @ts-expect-error -- Passing a D3.Selection seems to work for some reason // @ts-expect-error -- Passing a D3.Selection seems to work for some reason
const rc = rough.svg(shapeSvg); const rc = rough.svg(shapeSvg);
@@ -126,9 +128,12 @@ export async function curlyBraces<T extends SVGGraphicsElement>(
updateNodeBounds(node, curlyBracesShape); updateNodeBounds(node, curlyBracesShape);
node.calcIntersect = function (bounds: Bounds, point: Point) { node.calcIntersect = function (bounds: Bounds, point: Point) {
// TODO: Implement intersect for this shape const w = bounds.width;
const radius = bounds.width / 2; const h = bounds.height;
return intersect.circle(bounds, radius, point); const radius = Math.max(5, h * 0.1);
const rectPoints = getRectPoints(w, h, radius);
return intersect.polygon(bounds, rectPoints, point);
}; };
node.intersect = function (point) { node.intersect = function (point) {

View File

@@ -12,6 +12,15 @@ import rough from 'roughjs';
import type { D3Selection } from '../../../types.js'; import type { D3Selection } from '../../../types.js';
import type { Bounds, Point } from '../../../types.js'; import type { Bounds, Point } from '../../../types.js';
const getTrapezoidPoints = (rw: number, tw: number, totalHeight: number, radius: number) => [
{ x: rw, y: 0 },
{ x: tw, y: 0 },
{ x: 0, y: totalHeight / 2 },
{ x: tw, y: totalHeight },
{ x: rw, y: totalHeight },
...generateCirclePoints(-rw, -totalHeight / 2, radius, 50, 270, 90),
];
export async function curvedTrapezoid<T extends SVGGraphicsElement>( export async function curvedTrapezoid<T extends SVGGraphicsElement>(
parent: D3Selection<T>, parent: D3Selection<T>,
node: Node node: Node
@@ -40,14 +49,7 @@ export async function curvedTrapezoid<T extends SVGGraphicsElement>(
const rw = totalWidth - radius; const rw = totalWidth - radius;
const tw = totalHeight / 4; const tw = totalHeight / 4;
const points = [ const points = getTrapezoidPoints(rw, tw, totalHeight, radius);
{ x: rw, y: 0 },
{ x: tw, y: 0 },
{ x: 0, y: totalHeight / 2 },
{ x: tw, y: totalHeight },
{ x: rw, y: totalHeight },
...generateCirclePoints(-rw, -totalHeight / 2, radius, 50, 270, 90),
];
const pathData = createPathFromPoints(points); const pathData = createPathFromPoints(points);
const shapeNode = rc.path(pathData, options); const shapeNode = rc.path(pathData, options);
@@ -68,9 +70,17 @@ export async function curvedTrapezoid<T extends SVGGraphicsElement>(
updateNodeBounds(node, polygon); updateNodeBounds(node, polygon);
node.calcIntersect = function (bounds: Bounds, point: Point) { node.calcIntersect = function (bounds: Bounds, point: Point) {
// TODO: Implement intersect for this shape const w = bounds.width;
const radius = bounds.width / 2; const h = bounds.height;
return intersect.circle(bounds, radius, point); const radius = h / 2;
const totalWidth = w,
totalHeight = h;
const rw = totalWidth - radius;
const tw = totalHeight / 4;
const points = getTrapezoidPoints(rw, tw, totalHeight, radius);
return intersect.polygon(bounds, points, point);
}; };
node.intersect = function (point) { node.intersect = function (point) {