mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-12 03:49:43 +02:00
resolved edge intersection calculation issue for square and rounded form of icon shape
This commit is contained in:
@@ -15,31 +15,42 @@ export const iconRounded = async (
|
|||||||
) => {
|
) => {
|
||||||
const { labelStyles } = styles2String(node);
|
const { labelStyles } = styles2String(node);
|
||||||
node.labelStyle = labelStyles;
|
node.labelStyle = labelStyles;
|
||||||
|
const defaultWidth = flowchart?.wrappingWidth;
|
||||||
|
const labelPadding = node.label ? 8 : 0;
|
||||||
|
const padding = node.height ? node.height * 0.05 : 15;
|
||||||
const assetHeight = node.assetHeight ?? 48;
|
const assetHeight = node.assetHeight ?? 48;
|
||||||
const assetWidth = node.assetWidth ?? 48;
|
const assetWidth = node.assetWidth ?? 48;
|
||||||
const iconSize = Math.max(assetHeight, assetWidth);
|
let iconSize = Math.max(assetHeight, assetWidth);
|
||||||
const defaultWidth = flowchart?.wrappingWidth;
|
let height = iconSize + padding * 2;
|
||||||
node.width = Math.max(iconSize, defaultWidth ?? 0);
|
let width = iconSize + padding * 2;
|
||||||
const { shapeSvg, bbox, halfPadding, label } = await labelHelper(
|
|
||||||
parent,
|
|
||||||
node,
|
|
||||||
'icon-shape default'
|
|
||||||
);
|
|
||||||
|
|
||||||
|
let adjustDimensions = false;
|
||||||
|
if (node.width || node.height) {
|
||||||
|
adjustDimensions = true;
|
||||||
|
node.width = (node?.width ?? 10) - labelPadding * 2;
|
||||||
|
node.height = (node?.height ?? 10) - labelPadding * 2;
|
||||||
|
width = node.width;
|
||||||
|
height = node.height;
|
||||||
|
} else {
|
||||||
|
node.width = Math.max(width, defaultWidth ?? 0);
|
||||||
|
}
|
||||||
|
const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'icon-shape default');
|
||||||
const topLabel = node.pos === 't';
|
const topLabel = node.pos === 't';
|
||||||
|
|
||||||
const padding = node.look === 'neo' ? halfPadding * 2 : halfPadding;
|
if (adjustDimensions) {
|
||||||
|
node.width = node.width + labelPadding * 2;
|
||||||
|
node.height = (node.height ?? 10) + labelPadding * 2;
|
||||||
|
width = node.width;
|
||||||
|
height = node.height;
|
||||||
|
iconSize = Math.max(node.width - padding * 2, node.height - padding * 2);
|
||||||
|
}
|
||||||
|
|
||||||
const height = iconSize + padding * 2;
|
|
||||||
const width = iconSize + padding * 2;
|
|
||||||
const { nodeBorder, mainBkg } = themeVariables;
|
const { nodeBorder, mainBkg } = themeVariables;
|
||||||
const { stylesMap } = compileStyles(node);
|
const { stylesMap } = compileStyles(node);
|
||||||
|
|
||||||
const x = -width / 2;
|
const x = -width / 2;
|
||||||
const y = -height / 2;
|
const y = -height / 2;
|
||||||
|
|
||||||
const labelPadding = node.label ? 8 : 0;
|
|
||||||
|
|
||||||
// @ts-ignore - rough is not typed
|
// @ts-ignore - rough is not typed
|
||||||
const rc = rough.svg(shapeSvg);
|
const rc = rough.svg(shapeSvg);
|
||||||
const options = userNodeOverrides(node, { stroke: stylesMap.get('fill') ?? mainBkg });
|
const options = userNodeOverrides(node, { stroke: stylesMap.get('fill') ?? mainBkg });
|
||||||
@@ -66,18 +77,13 @@ export const iconRounded = async (
|
|||||||
|
|
||||||
if (node.icon) {
|
if (node.icon) {
|
||||||
iconElem.html(
|
iconElem.html(
|
||||||
`<g>${await getIconSVG(node.icon, { height: iconSize, width: iconSize, fallbackPrefix: '' })}</g>`
|
`<g>${await getIconSVG(node.icon, { height: iconSize, fallbackPrefix: '' })}</g>`
|
||||||
);
|
);
|
||||||
const iconBBox = iconElem.node().getBBox();
|
const iconBBox = iconElem.node().getBBox();
|
||||||
const iconWidth = iconBBox.width;
|
const iconWidth = iconBBox.width;
|
||||||
// const iconHeight = iconBBox.height;
|
// const iconHeight = iconBBox.height;
|
||||||
const iconX = iconBBox.x;
|
const iconX = iconBBox.x;
|
||||||
// const iconY = iconBBox.y;
|
// const iconY = iconBBox.y;
|
||||||
|
|
||||||
// iconElem.attr(
|
|
||||||
// 'transform',
|
|
||||||
// `translate(${-iconWidth / 2 - iconX},${topLabel ? outerHeight / 2 - iconHeight - iconY - padding : outerHeight / 2 - iconHeight - iconY - padding - bbox.height - labelPadding})`
|
|
||||||
// );
|
|
||||||
iconElem.attr(
|
iconElem.attr(
|
||||||
'transform',
|
'transform',
|
||||||
`translate(${-iconWidth / 2 - iconX},${topLabel ? -iconSize / 2 : -iconSize / 2})`
|
`translate(${-iconWidth / 2 - iconX},${topLabel ? -iconSize / 2 : -iconSize / 2})`
|
||||||
|
@@ -14,31 +14,46 @@ export const iconSquare = async (
|
|||||||
) => {
|
) => {
|
||||||
const { labelStyles } = styles2String(node);
|
const { labelStyles } = styles2String(node);
|
||||||
node.labelStyle = labelStyles;
|
node.labelStyle = labelStyles;
|
||||||
|
const defaultWidth = flowchart?.wrappingWidth;
|
||||||
|
const labelPadding = node.label ? 8 : 0;
|
||||||
|
const padding = node.height ? node.height * 0.05 : 15;
|
||||||
const assetHeight = node.assetHeight ?? 48;
|
const assetHeight = node.assetHeight ?? 48;
|
||||||
const assetWidth = node.assetWidth ?? 48;
|
const assetWidth = node.assetWidth ?? 48;
|
||||||
const iconSize = Math.max(assetHeight, assetWidth);
|
let iconSize = Math.max(assetHeight, assetWidth);
|
||||||
const defaultWidth = flowchart?.wrappingWidth;
|
let height = iconSize + padding * 2;
|
||||||
node.width = Math.max(iconSize, defaultWidth ?? 0);
|
let width = iconSize + padding * 2;
|
||||||
const { shapeSvg, bbox, halfPadding, label } = await labelHelper(
|
|
||||||
parent,
|
|
||||||
node,
|
|
||||||
'icon-shape default'
|
|
||||||
);
|
|
||||||
|
|
||||||
|
let adjustDimensions = false;
|
||||||
|
if (node.width || node.height) {
|
||||||
|
adjustDimensions = true;
|
||||||
|
node.width = (node?.width ?? 10) - labelPadding * 2;
|
||||||
|
node.height = (node?.height ?? 10) - labelPadding * 2;
|
||||||
|
width = node.width;
|
||||||
|
height = node.height;
|
||||||
|
} else {
|
||||||
|
node.width = Math.max(width, defaultWidth ?? 0);
|
||||||
|
}
|
||||||
|
const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'icon-shape default');
|
||||||
const topLabel = node.pos === 't';
|
const topLabel = node.pos === 't';
|
||||||
|
|
||||||
const padding = node.look === 'neo' ? halfPadding * 2 : halfPadding;
|
// node.width = Math.max(iconSize, defaultWidth ?? 0);
|
||||||
|
|
||||||
const height = iconSize + padding * 2;
|
if (adjustDimensions) {
|
||||||
const width = iconSize + padding * 2;
|
node.width = node.width + labelPadding * 2;
|
||||||
|
node.height = (node.height ?? 10) + labelPadding * 2;
|
||||||
|
width = node.width;
|
||||||
|
height = node.height;
|
||||||
|
iconSize = Math.max(node.width - padding * 2, node.height - padding * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//const height = iconSize + padding * 2;
|
||||||
|
//const width = iconSize + padding * 2;
|
||||||
const { nodeBorder, mainBkg } = themeVariables;
|
const { nodeBorder, mainBkg } = themeVariables;
|
||||||
const { stylesMap } = compileStyles(node);
|
const { stylesMap } = compileStyles(node);
|
||||||
|
|
||||||
const x = -width / 2;
|
const x = -width / 2;
|
||||||
const y = -height / 2;
|
const y = -height / 2;
|
||||||
|
|
||||||
const labelPadding = node.label ? 8 : 0;
|
|
||||||
|
|
||||||
// @ts-ignore - rough is not typed
|
// @ts-ignore - rough is not typed
|
||||||
const rc = rough.svg(shapeSvg);
|
const rc = rough.svg(shapeSvg);
|
||||||
const options = userNodeOverrides(node, { stroke: stylesMap.get('fill') ?? mainBkg });
|
const options = userNodeOverrides(node, { stroke: stylesMap.get('fill') ?? mainBkg });
|
||||||
@@ -50,31 +65,30 @@ export const iconSquare = async (
|
|||||||
|
|
||||||
const iconNode = rc.rectangle(x, y, width, height, options);
|
const iconNode = rc.rectangle(x, y, width, height, options);
|
||||||
|
|
||||||
const outerWidth = Math.max(width, bbox.width);
|
// const outerWidth = Math.max(width, bbox.width);
|
||||||
const outerHeight = height + bbox.height + labelPadding;
|
// const outerHeight = height + bbox.height + labelPadding;
|
||||||
|
|
||||||
const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, {
|
// const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, {
|
||||||
...options,
|
// ...options,
|
||||||
fill: 'transparent',
|
// fill: 'transparent',
|
||||||
stroke: 'none',
|
// stroke: 'none',
|
||||||
});
|
// });
|
||||||
|
|
||||||
const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
|
// const outerShape = shapeSvg.insert(() => outerNode);
|
||||||
const outerShape = shapeSvg.insert(() => outerNode);
|
|
||||||
const iconElem = shapeSvg.append('g');
|
const iconElem = shapeSvg.append('g');
|
||||||
|
|
||||||
if (node.icon) {
|
if (node.icon) {
|
||||||
iconElem.html(
|
iconElem.html(
|
||||||
`<g>${await getIconSVG(node.icon, { height: iconSize, width: iconSize, fallbackPrefix: '' })}</g>`
|
`<g>${await getIconSVG(node.icon, { height: iconSize, fallbackPrefix: '' })}</g>`
|
||||||
);
|
);
|
||||||
const iconBBox = iconElem.node().getBBox();
|
const iconBBox = iconElem.node().getBBox();
|
||||||
const iconWidth = iconBBox.width;
|
const iconWidth = iconBBox.width;
|
||||||
const iconHeight = iconBBox.height;
|
// const iconHeight = iconBBox.height;
|
||||||
const iconX = iconBBox.x;
|
const iconX = iconBBox.x;
|
||||||
const iconY = iconBBox.y;
|
// const iconY = iconBBox.y;
|
||||||
iconElem.attr(
|
iconElem.attr(
|
||||||
'transform',
|
'transform',
|
||||||
`translate(${-iconWidth / 2 - iconX},${topLabel ? outerHeight / 2 - iconHeight - iconY - padding : outerHeight / 2 - iconHeight - iconY - padding - bbox.height - labelPadding})`
|
`translate(${-iconWidth / 2 - iconX},${topLabel ? -iconSize / 2 : -iconSize / 2})`
|
||||||
);
|
);
|
||||||
iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') ?? nodeBorder);
|
iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') ?? nodeBorder);
|
||||||
iconElem.attr('class', 'icon');
|
iconElem.attr('class', 'icon');
|
||||||
@@ -82,14 +96,23 @@ export const iconSquare = async (
|
|||||||
|
|
||||||
label.attr(
|
label.attr(
|
||||||
'transform',
|
'transform',
|
||||||
`translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))},${topLabel ? -outerHeight / 2 : outerHeight / 2 - bbox.height})`
|
`translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))},${topLabel ? -height / 2 - bbox.height - labelPadding : height / 2 + labelPadding})`
|
||||||
);
|
);
|
||||||
|
|
||||||
iconShape.attr(
|
const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
|
||||||
'transform',
|
// iconShape.attr(
|
||||||
`translate(${0},${topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2})`
|
// 'transform',
|
||||||
);
|
// `translate(${0},${topLabel ? bbox.height / 2 - labelPadding : -bbox.height / 2 + labelPadding })`
|
||||||
|
// );
|
||||||
|
|
||||||
|
// iconShape.attr(
|
||||||
|
// 'transform',
|
||||||
|
// `translate(${-width/2},${topLabel ? -width / 2 : -width / 2 })`
|
||||||
|
// );
|
||||||
|
// rect.attr(
|
||||||
|
// 'transform',
|
||||||
|
// `translate(${-width/2},${topLabel ? -width / 2 + labelPadding/2 : -width / 2 + labelPadding/2})`
|
||||||
|
// );
|
||||||
if (stylesMap.get('stroke')) {
|
if (stylesMap.get('stroke')) {
|
||||||
iconElem.selectAll('path').attr('style', `fill: ${stylesMap.get('stroke')}`);
|
iconElem.selectAll('path').attr('style', `fill: ${stylesMap.get('stroke')}`);
|
||||||
}
|
}
|
||||||
@@ -98,43 +121,43 @@ export const iconSquare = async (
|
|||||||
iconShape.selectAll('path').attr('style', `stroke: ${stylesMap.get('fill')}`);
|
iconShape.selectAll('path').attr('style', `stroke: ${stylesMap.get('fill')}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNodeBounds(node, outerShape);
|
updateNodeBounds(node, iconShape);
|
||||||
|
|
||||||
node.intersect = function (point) {
|
node.intersect = function (point) {
|
||||||
log.info('iconSquare intersect', node, point);
|
log.info('iconSquare intersect', node, point);
|
||||||
if (!node.label) {
|
// if (!node.label) {
|
||||||
return intersect.rect(node, point);
|
return intersect.rect(node, point);
|
||||||
}
|
// }
|
||||||
const dx = node.x ?? 0;
|
// const dx = node.x ?? 0;
|
||||||
const dy = node.y ?? 0;
|
// const dy = node.y ?? 0;
|
||||||
const nodeHeight = node.height ?? 0;
|
// const nodeHeight = node.height ?? 0;
|
||||||
let points = [];
|
// let points = [];
|
||||||
if (topLabel) {
|
// if (topLabel) {
|
||||||
points = [
|
// points = [
|
||||||
{ x: dx - bbox.width / 2, y: dy - nodeHeight / 2 },
|
// { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 },
|
||||||
{ x: dx + bbox.width / 2, y: dy - nodeHeight / 2 },
|
// { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 },
|
||||||
{ x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
|
// { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
|
||||||
{ x: dx + width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
|
// { x: dx + width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
|
||||||
{ x: dx + width / 2, y: dy + nodeHeight / 2 },
|
// { x: dx + width / 2, y: dy + nodeHeight / 2 },
|
||||||
{ x: dx - width / 2, y: dy + nodeHeight / 2 },
|
// { x: dx - width / 2, y: dy + nodeHeight / 2 },
|
||||||
{ x: dx - width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
|
// { x: dx - width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
|
||||||
{ x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
|
// { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
|
||||||
];
|
// ];
|
||||||
} else {
|
// } else {
|
||||||
points = [
|
// points = [
|
||||||
{ x: dx - width / 2, y: dy - nodeHeight / 2 },
|
// { x: dx - width / 2, y: dy - nodeHeight / 2 },
|
||||||
{ x: dx + width / 2, y: dy - nodeHeight / 2 },
|
// { x: dx + width / 2, y: dy - nodeHeight / 2 },
|
||||||
{ x: dx + width / 2, y: dy - nodeHeight / 2 + height },
|
// { x: dx + width / 2, y: dy - nodeHeight / 2 + height },
|
||||||
{ x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + height },
|
// { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + height },
|
||||||
{ x: dx + bbox.width / 2 / 2, y: dy + nodeHeight / 2 },
|
// { x: dx + bbox.width / 2 / 2, y: dy + nodeHeight / 2 },
|
||||||
{ x: dx - bbox.width / 2, y: dy + nodeHeight / 2 },
|
// { x: dx - bbox.width / 2, y: dy + nodeHeight / 2 },
|
||||||
{ x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + height },
|
// { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + height },
|
||||||
{ x: dx - width / 2, y: dy - nodeHeight / 2 + height },
|
// { x: dx - width / 2, y: dy - nodeHeight / 2 + height },
|
||||||
];
|
// ];
|
||||||
}
|
// }
|
||||||
|
|
||||||
const pos = intersect.polygon(node, points, point);
|
// const pos = intersect.polygon(node, points, point);
|
||||||
return pos;
|
// return pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
|
Reference in New Issue
Block a user