updated imageSquare Shape

This commit is contained in:
omkarht
2024-09-18 21:55:12 +05:30
parent a52949318a
commit cb85d50f61
2 changed files with 74 additions and 70 deletions

View File

@@ -146,7 +146,7 @@ export const addVertex = function (
} }
if (doc?.icon) { if (doc?.icon) {
vertex.icon = doc?.icon; vertex.icon = doc?.icon;
if (!doc.label) { if (!doc.label?.trim() && vertex.text === id) {
vertex.text = ''; vertex.text = '';
} }
} }
@@ -158,7 +158,7 @@ export const addVertex = function (
} }
if (doc?.img) { if (doc?.img) {
vertex.img = doc?.img; vertex.img = doc?.img;
if (!doc.label) { if (!doc.label?.trim() && vertex.text === id) {
vertex.text = ''; vertex.text = '';
} }
} }

View File

@@ -1,15 +1,16 @@
import { log } from '../../../logger.js'; import { log } from '../../../logger.js';
import { labelHelper, updateNodeBounds } from './util.js'; import { labelHelper, updateNodeBounds } from './util.js';
import type { Node } from '../../types.js'; import type { Node, RenderOptions } from '../../types.d.ts';
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';
import intersect from '../intersect/index.js'; import intersect from '../intersect/index.js';
import { createPathFromPoints } from './util.js';
import { getConfig } from '../../../diagram-api/diagramAPI.js';
export const imageSquare = async (parent: SVG, node: Node) => { export const imageSquare = async (
//image dimensions parent: SVG,
node: Node,
{ config: { flowchart } }: RenderOptions
) => {
const img = new Image(); const img = new Image();
img.src = node?.img ?? ''; img.src = node?.img ?? '';
await img.decode(); await img.decode();
@@ -17,49 +18,26 @@ export const imageSquare = async (parent: SVG, node: Node) => {
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 defaultWidth = getConfig().flowchart?.wrappingWidth; const { labelStyles } = styles2String(node);
node.labelStyle = labelStyles;
const defaultWidth = flowchart?.wrappingWidth;
const imageWidth = Math.max( const imageWidth = Math.max(
node.label ? (defaultWidth ?? 0) : 0, node.label ? (defaultWidth ?? 0) : 0,
node?.assetWidth ?? imageNaturalWidth node?.assetWidth ?? imageNaturalWidth
); );
const imageHeight = node?.assetHeight ?? imageNaturalHeight; const imageHeight = node?.assetHeight ?? imageNaturalHeight;
node.width = Math.max(imageWidth, defaultWidth ?? 0);
const imagePoints = [
{ x: -imageWidth / 2, y: -imageHeight },
{ x: imageWidth / 2, y: -imageHeight },
{ x: imageWidth / 2, y: 0 },
{ x: -imageWidth / 2, y: 0 },
];
//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 defaultHeight = bbox.height;
// 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, 'image-shape default'); const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'image-shape default');
// const width = Math.max(bbox.width + (node.padding ?? 0), node?.width ?? 0); const topLabel = node.pos === 't';
const height = Math.max(bbox.height + (node.padding ?? 0), node?.height ?? 0);
const labelHeight = node.label ? height : 0;
const imagePosition = node?.pos ?? 'b'; const x = -imageWidth / 2;
const y = -imageHeight / 2;
const labelPoints = [ const labelPadding = node.label ? 8 : 0;
{ x: -labelWidth / 2, y: 0 },
{ x: labelWidth / 2, y: 0 },
{ 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);
@@ -70,18 +48,20 @@ export const imageSquare = async (parent: SVG, node: Node) => {
options.fillStyle = 'solid'; options.fillStyle = 'solid';
} }
const imagePath = createPathFromPoints(imagePoints); const imageNode = rc.rectangle(x, y, imageWidth, imageHeight, options);
const imagePathNode = rc.path(imagePath, options);
const linePath = createPathFromPoints(labelPoints); const outerWidth = Math.max(imageWidth, bbox.width);
const lineNode = rc.path(linePath, { ...options }); const outerHeight = imageHeight + bbox.height + labelPadding;
const imageShape = shapeSvg.insert(() => lineNode, ':first-child').attr('opacity', 0); const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, {
imageShape.insert(() => imagePathNode, ':first-child'); ...options,
fill: 'none',
stroke: 'none',
});
imageShape.attr('transform', `translate(${0},${(imageHeight - labelHeight) / 2})`); const iconShape = shapeSvg.insert(() => imageNode, ':first-child');
const outerShape = shapeSvg.insert(() => outerNode);
// Image operations
if (node.img) { if (node.img) {
const image = shapeSvg.append('image'); const image = shapeSvg.append('image');
@@ -91,34 +71,58 @@ export const imageSquare = async (parent: SVG, node: Node) => {
image.attr('height', imageHeight); image.attr('height', imageHeight);
image.attr('preserveAspectRatio', 'none'); image.attr('preserveAspectRatio', 'none');
const yPos = image.attr(
imagePosition === 'b' ? -imageHeight / 2 - labelHeight / 2 : (-imageHeight + labelHeight) / 2; 'transform',
image.attr('transform', `translate(${-imageWidth / 2}, ${yPos})`); `translate(${-imageWidth / 2},${topLabel ? outerHeight / 2 - imageHeight : -outerHeight / 2})`
);
} }
if (cssStyles && node.look !== 'handDrawn') { label.attr(
imageShape.selectAll('path').attr('style', cssStyles); 'transform',
} `translate(${-bbox.width / 2},${topLabel ? -imageHeight / 2 - bbox.height / 2 - labelPadding / 2 : imageHeight / 2 - bbox.height / 2 + labelPadding / 2})`
);
if (nodeStyles && node.look !== 'handDrawn') { iconShape.attr(
imageShape.selectAll('path').attr('style', nodeStyles); 'transform',
} `translate(${0},${topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2})`
);
const yPos = updateNodeBounds(node, outerShape);
imagePosition === 'b'
? (imageHeight + labelHeight) / 2 - bbox.height - (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})`);
updateNodeBounds(node, imageShape);
node.intersect = function (point) { node.intersect = function (point) {
log.info('imageSquare intersect', node, point); log.info('iconSquare intersect', node, point);
if (!node.label) {
return intersect.rect(node, point);
}
const dx = node.x ?? 0;
const dy = node.y ?? 0;
const nodeHeight = node.height ?? 0;
let points = [];
if (topLabel) {
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 + bbox.height + labelPadding },
{ x: dx + imageWidth / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
{ x: dx + imageWidth / 2, y: dy + nodeHeight / 2 },
{ x: dx - imageWidth / 2, y: dy + nodeHeight / 2 },
{ x: dx - imageWidth / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
{ x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
];
} else {
points = [
{ x: dx - imageWidth / 2, y: dy - nodeHeight / 2 },
{ x: dx + imageWidth / 2, y: dy - nodeHeight / 2 },
{ x: dx + imageWidth / 2, y: dy - nodeHeight / 2 + imageHeight },
{ x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + imageHeight },
{ 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 + imageHeight },
{ x: dx - imageWidth / 2, y: dy - nodeHeight / 2 + imageHeight },
];
}
const combinedPoints = [...imagePoints, ...labelPoints]; const pos = intersect.polygon(node, points, point);
const pos = intersect.polygon(node, combinedPoints, point);
return pos; return pos;
}; };