mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
updated ImageSqaure shape
This commit is contained in:
parent
01bf7af360
commit
9421f63775
@ -1,6 +1,6 @@
|
|||||||
import { log } from '../../../logger.js';
|
import { log } from '../../../logger.js';
|
||||||
import { getNodeClasses, labelHelper, updateNodeBounds } from './util.js';
|
import { getNodeClasses, labelHelper, updateNodeBounds } from './util.js';
|
||||||
import type { Node } from '../../types.d.ts';
|
import type { Node } from '../../types.js';
|
||||||
import type { SVG } from '../../../diagram-api/types.js';
|
import type { SVG } from '../../../diagram-api/types.js';
|
||||||
import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
|
import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
|
||||||
import rough from 'roughjs';
|
import rough from 'roughjs';
|
||||||
@ -9,70 +9,98 @@ import { createPathFromPoints } from './util.js';
|
|||||||
import { getConfig } from '../../../diagram-api/diagramAPI.js';
|
import { getConfig } from '../../../diagram-api/diagramAPI.js';
|
||||||
|
|
||||||
export const imageSquare = async (parent: SVG, node: Node) => {
|
export const imageSquare = async (parent: SVG, node: Node) => {
|
||||||
const { labelStyles, nodeStyles } = styles2String(node);
|
//image dimensions
|
||||||
node.labelStyle = labelStyles;
|
|
||||||
|
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.src = node?.img ?? '';
|
img.src = node?.img ?? '';
|
||||||
|
|
||||||
await img.decode();
|
await img.decode();
|
||||||
|
|
||||||
const imageNaturalWidth = Number(img.naturalWidth.toString().replace('px', ''));
|
const imageNaturalWidth = Number(img.naturalWidth.toString().replace('px', ''));
|
||||||
const imageNaturalHeight = Number(img.naturalHeight.toString().replace('px', ''));
|
const imageNaturalHeight = Number(img.naturalHeight.toString().replace('px', ''));
|
||||||
|
|
||||||
const imageWidth = node?.assetWidth ?? imageNaturalWidth;
|
|
||||||
const imageHeight = node?.assetHeight ?? imageNaturalHeight;
|
|
||||||
const defaultWidth = getConfig().flowchart?.wrappingWidth;
|
const defaultWidth = getConfig().flowchart?.wrappingWidth;
|
||||||
|
const imageWidth = Math.max(
|
||||||
|
node.label ? (defaultWidth ?? 0) : 0,
|
||||||
|
node?.assetWidth ?? imageNaturalWidth
|
||||||
|
);
|
||||||
|
const imageHeight = node?.assetHeight ?? imageNaturalHeight;
|
||||||
// const htmlLabels = getConfig().flowchart?.htmlLabels
|
// const htmlLabels = getConfig().flowchart?.htmlLabels
|
||||||
|
|
||||||
node.width = Math.max(node.width ?? 0, node.label ? (defaultWidth ?? 0) : 0, imageWidth);
|
const imagePoints = [
|
||||||
|
{ x: -imageWidth / 2, y: -imageHeight },
|
||||||
|
{ x: imageWidth / 2, y: -imageHeight },
|
||||||
|
{ x: imageWidth / 2, y: 0 },
|
||||||
|
{ x: -imageWidth / 2, y: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node));
|
//label dimensions
|
||||||
|
const { labelStyles, nodeStyles } = styles2String(node);
|
||||||
|
node.labelStyle = labelStyles;
|
||||||
|
|
||||||
|
// const { shapeSvg, bbox, halfPadding, label } = await labelHelper(
|
||||||
|
// parent,
|
||||||
|
// node,
|
||||||
|
// 'icon-shape default'
|
||||||
|
// );
|
||||||
|
|
||||||
const { cssStyles } = node;
|
const { cssStyles } = node;
|
||||||
const defaultHeight = bbox.height;
|
// const defaultHeight = bbox.height;
|
||||||
node.height = Math.max(node.height ?? 0, node.label ? (defaultHeight ?? 0) : 0, imageHeight);
|
// node.height = Math.max(node.height ?? 0, node.label ? (defaultHeight ?? 0) : 0, imageHeight);
|
||||||
|
const labelWidth = Math.max(node.width ?? 0, node.label ? (defaultWidth ?? 0) : 0, imageWidth);
|
||||||
|
node.width = node.label ? labelWidth : 0;
|
||||||
|
const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node));
|
||||||
|
|
||||||
const width = Math.max(bbox.width + (node.padding ?? 0), imageWidth, node?.width ?? 0);
|
// const width = Math.max(bbox.width + (node.padding ?? 0), node?.width ?? 0);
|
||||||
const height = Math.max(bbox.height + (node.padding ?? 0), imageHeight, node?.height ?? 0);
|
const height = Math.max(bbox.height + (node.padding ?? 0), node?.height ?? 0);
|
||||||
|
const labelHeight = node.label ? height : 0;
|
||||||
const skeletonWidth = width + (node?.padding ?? 0) / 2;
|
|
||||||
const skeletonHeight = height + bbox.height;
|
|
||||||
|
|
||||||
const imagePosition = node?.pos ?? 'b';
|
const imagePosition = node?.pos ?? 'b';
|
||||||
const points = [
|
|
||||||
{ x: 0, y: 0 },
|
const labelPoints = [
|
||||||
{ x: skeletonWidth, y: 0 },
|
{ x: -labelWidth / 2, y: 0 },
|
||||||
{ x: skeletonWidth, y: skeletonHeight },
|
{ x: labelWidth / 2, y: 0 },
|
||||||
{ x: 0, y: skeletonHeight },
|
{ x: labelWidth / 2, y: labelHeight },
|
||||||
|
{ x: -labelWidth / 2, y: labelHeight },
|
||||||
];
|
];
|
||||||
|
|
||||||
// @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, {});
|
const options = userNodeOverrides(node, {});
|
||||||
|
// const options = userNodeOverrides(node, { stroke: stylesMap.get('fill') || mainBkg });
|
||||||
|
|
||||||
if (node.look !== 'handDrawn') {
|
if (node.look !== 'handDrawn') {
|
||||||
options.roughness = 0;
|
options.roughness = 0;
|
||||||
options.fillStyle = 'solid';
|
options.fillStyle = 'solid';
|
||||||
}
|
}
|
||||||
|
|
||||||
const linePath = createPathFromPoints(points);
|
const imagePath = createPathFromPoints(imagePoints);
|
||||||
const lineNode = rc.path(linePath, options);
|
const imagePathNode = rc.path(imagePath, options);
|
||||||
|
|
||||||
|
const linePath = createPathFromPoints(labelPoints);
|
||||||
|
const lineNode = rc.path(linePath, { ...options });
|
||||||
|
|
||||||
const imageShape = shapeSvg.insert(() => lineNode, ':first-child').attr('opacity', 0);
|
const imageShape = shapeSvg.insert(() => lineNode, ':first-child').attr('opacity', 0);
|
||||||
|
imageShape.insert(() => imagePathNode, ':first-child');
|
||||||
|
|
||||||
|
imageShape.attr('transform', `translate(${0},${(imageHeight - labelHeight) / 2})`);
|
||||||
|
|
||||||
|
// Image operations
|
||||||
if (node.img) {
|
if (node.img) {
|
||||||
const image = shapeSvg.append('image');
|
const image = shapeSvg.append('image');
|
||||||
|
|
||||||
// Set the image attributes
|
// Set the image attributes
|
||||||
image.attr('href', node.img);
|
image.attr('href', node.img);
|
||||||
image.attr('width', node.width);
|
image.attr('width', imageWidth);
|
||||||
image.attr('height', node.height);
|
image.attr('height', imageHeight);
|
||||||
image.attr('preserveAspectRatio', 'none');
|
image.attr('preserveAspectRatio', 'none');
|
||||||
|
|
||||||
|
// const yPos =
|
||||||
|
// imagePosition === 'b'
|
||||||
|
// ? -(imageHeight / 2)
|
||||||
|
// : labelHeight / 2 - height + (bbox.y + (bbox.top ?? 0)) * 2;
|
||||||
|
// image.attr('transform', `translate(${-imageWidth / 2}, ${-imageHeight/2 -labelHeight/2})`);
|
||||||
const yPos =
|
const yPos =
|
||||||
imagePosition === 'b'
|
imagePosition === 'b' ? -imageHeight / 2 - labelHeight / 2 : (-imageHeight + labelHeight) / 2;
|
||||||
? -(skeletonHeight / 2)
|
image.attr('transform', `translate(${-imageWidth / 2}, ${yPos})`);
|
||||||
: skeletonHeight / 2 - height + (bbox.y + (bbox.top ?? 0)) * 2;
|
|
||||||
image.attr('transform', `translate(${-node.width / 2}, ${yPos})`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cssStyles && node.look !== 'handDrawn') {
|
if (cssStyles && node.look !== 'handDrawn') {
|
||||||
@ -83,20 +111,23 @@ export const imageSquare = async (parent: SVG, node: Node) => {
|
|||||||
imageShape.selectAll('path').attr('style', nodeStyles);
|
imageShape.selectAll('path').attr('style', nodeStyles);
|
||||||
}
|
}
|
||||||
|
|
||||||
imageShape.attr('transform', `translate(${-skeletonWidth / 2},${-skeletonHeight / 2})`);
|
|
||||||
|
|
||||||
const yPos =
|
const yPos =
|
||||||
imagePosition === 'b'
|
imagePosition === 'b'
|
||||||
? skeletonHeight / 2 - bbox.height - (bbox.y - (bbox.top ?? 0))
|
? (imageHeight + labelHeight) / 2 - bbox.height - (bbox.y - (bbox.top ?? 0))
|
||||||
: -skeletonHeight / 2 + (node?.padding ?? 0) / 2 - (bbox.y - (bbox.top ?? 0));
|
: -(imageHeight + labelHeight) / 2 + (node?.padding ?? 0) / 2 - (bbox.y - (bbox.top ?? 0));
|
||||||
|
|
||||||
label.attr('transform', `translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))},${yPos})`);
|
label.attr('transform', `translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))},${yPos})`);
|
||||||
|
|
||||||
updateNodeBounds(node, imageShape);
|
updateNodeBounds(node, imageShape);
|
||||||
|
|
||||||
node.intersect = function (point) {
|
node.intersect = function (point) {
|
||||||
log.info('iconSquare intersect', node, point);
|
log.info('imageSquare intersect', node, point);
|
||||||
const pos = intersect.polygon(node, points, point);
|
|
||||||
|
// Combine image and label points into a single shape
|
||||||
|
const combinedPoints = [...imagePoints, ...labelPoints];
|
||||||
|
|
||||||
|
// Use the polygon intersection with the translated points
|
||||||
|
const pos = intersect.polygon(node, combinedPoints, point);
|
||||||
return pos;
|
return pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user