mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-26 02:39:41 +02:00
updated curved trapezoid shape
This commit is contained in:
@@ -1,38 +1,23 @@
|
|||||||
import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js';
|
import {
|
||||||
|
labelHelper,
|
||||||
|
updateNodeBounds,
|
||||||
|
getNodeClasses,
|
||||||
|
createPathFromPoints,
|
||||||
|
generateCirclePoints,
|
||||||
|
} from './util.js';
|
||||||
import intersect from '../intersect/index.js';
|
import intersect from '../intersect/index.js';
|
||||||
import type { Node } from '../../types.d.ts';
|
import type { Node } from '../../types.d.ts';
|
||||||
import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
|
import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
|
||||||
import rough from 'roughjs';
|
import rough from 'roughjs';
|
||||||
|
|
||||||
function createCurvedTrapezoidPathD(
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
totalWidth: number,
|
|
||||||
totalHeight: number,
|
|
||||||
radius: number
|
|
||||||
) {
|
|
||||||
const w = totalWidth - radius;
|
|
||||||
const tw = totalHeight / 4;
|
|
||||||
const points = [
|
|
||||||
{ x: x + w, y },
|
|
||||||
{ x: x + tw, y },
|
|
||||||
{ x: x, y: y + totalHeight / 2 },
|
|
||||||
{ x: x + tw, y: y + totalHeight },
|
|
||||||
{ x: x + w, y: y + totalHeight },
|
|
||||||
];
|
|
||||||
const rectPath = createPathFromPoints(points);
|
|
||||||
const arcPath = `M ${w},0 A ${totalHeight / 2} ${totalHeight / 2} 0 0 1 ${w} ${totalHeight}`;
|
|
||||||
const finalPath = `${rectPath} ${arcPath}`.replace('Z', '');
|
|
||||||
return finalPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const curvedTrapezoid = async (parent: SVGAElement, node: Node) => {
|
export const curvedTrapezoid = async (parent: SVGAElement, node: Node) => {
|
||||||
const { labelStyles, nodeStyles } = styles2String(node);
|
const { labelStyles, nodeStyles } = styles2String(node);
|
||||||
node.labelStyle = labelStyles;
|
node.labelStyle = labelStyles;
|
||||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||||
const widthMultiplier = bbox.width < 15 ? 2 : 1.25;
|
const minWidth = 80,
|
||||||
const w = (bbox.width + node.padding) * widthMultiplier;
|
minHeight = 20;
|
||||||
const h = bbox.height + node.padding;
|
const w = Math.max(minWidth, (bbox.width + (node.padding ?? 0) * 2) * 1.25, node?.width ?? 0);
|
||||||
|
const h = Math.max(minHeight, bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0);
|
||||||
const radius = h / 2;
|
const radius = h / 2;
|
||||||
|
|
||||||
const { cssStyles } = node;
|
const { cssStyles } = node;
|
||||||
@@ -45,7 +30,21 @@ export const curvedTrapezoid = async (parent: SVGAElement, node: Node) => {
|
|||||||
options.fillStyle = 'solid';
|
options.fillStyle = 'solid';
|
||||||
}
|
}
|
||||||
|
|
||||||
const pathData = createCurvedTrapezoidPathD(0, 0, w, h, radius);
|
const totalWidth = w,
|
||||||
|
totalHeight = h;
|
||||||
|
const rw = totalWidth - radius;
|
||||||
|
const tw = totalHeight / 4;
|
||||||
|
|
||||||
|
const points = [
|
||||||
|
{ 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 shapeNode = rc.path(pathData, options);
|
const shapeNode = rc.path(pathData, options);
|
||||||
|
|
||||||
const polygon = shapeSvg.insert(() => shapeNode, ':first-child');
|
const polygon = shapeSvg.insert(() => shapeNode, ':first-child');
|
||||||
@@ -64,29 +63,7 @@ export const curvedTrapezoid = async (parent: SVGAElement, node: Node) => {
|
|||||||
updateNodeBounds(node, polygon);
|
updateNodeBounds(node, polygon);
|
||||||
|
|
||||||
node.intersect = function (point) {
|
node.intersect = function (point) {
|
||||||
const pos = intersect.rect(node, point);
|
const pos = intersect.polygon(node, points, point);
|
||||||
const rx = h / 2;
|
|
||||||
const ry = h / 2;
|
|
||||||
const y = pos.y - (node.y ?? 0);
|
|
||||||
|
|
||||||
if (
|
|
||||||
ry != 0 &&
|
|
||||||
(Math.abs(y) < (node.height ?? 0) / 2 ||
|
|
||||||
(Math.abs(y) == (node.height ?? 0) / 2 &&
|
|
||||||
Math.abs(pos.x - (node.x ?? 0)) > (node.width ?? 0) / 2 - rx))
|
|
||||||
) {
|
|
||||||
let x = rx * rx * (1 - (y * y) / (ry * ry));
|
|
||||||
if (x != 0) {
|
|
||||||
x = Math.sqrt(x);
|
|
||||||
}
|
|
||||||
x = rx - x;
|
|
||||||
if (point.x - (node.x ?? 0) > 0) {
|
|
||||||
x = -x;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.x += x;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -163,3 +163,33 @@ export function generateFullSineWavePoints(x1, y1, x2, y2, amplitude, numCycles)
|
|||||||
|
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function generateCirclePoints(
|
||||||
|
centerX, // x-coordinate of center of circle
|
||||||
|
centerY, // x-coordinate of center of circle
|
||||||
|
radius, // radius of circle
|
||||||
|
numPoints, // total points required
|
||||||
|
startAngle, // angle where arc will start
|
||||||
|
endAngle // angle where arc will end
|
||||||
|
) {
|
||||||
|
const points = [];
|
||||||
|
|
||||||
|
// Convert angles to radians
|
||||||
|
const startAngleRad = (startAngle * Math.PI) / 180;
|
||||||
|
const endAngleRad = (endAngle * Math.PI) / 180;
|
||||||
|
|
||||||
|
// Calculate the angle range in radians
|
||||||
|
const angleRange = endAngleRad - startAngleRad;
|
||||||
|
|
||||||
|
// Calculate the angle step
|
||||||
|
const angleStep = angleRange / (numPoints - 1);
|
||||||
|
|
||||||
|
for (let i = 0; i < numPoints; i++) {
|
||||||
|
const angle = startAngleRad + i * angleStep;
|
||||||
|
const x = centerX + radius * Math.cos(angle);
|
||||||
|
const y = centerY + radius * Math.sin(angle);
|
||||||
|
points.push({ x: -x, y: -y });
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user