From a34128c6a26ebf0fb64a347c30d6a66c43949059 Mon Sep 17 00:00:00 2001 From: pubuzhixing8 Date: Sun, 17 Nov 2024 00:26:54 +0800 Subject: [PATCH] feat: support strokeStyle for mind node and link BREAK CHANGES: 1. It is planned to replace branchColor and branchWidth with strokeColor and strokeWidth. To maintain compatibility, branchColor and branchWidth will not be deleted. BranchColor and branchWidth will be applied first. 2. Both branchWidth and branchColor attributes are applied to the child node first and no longer rely on the attributes of the parent node. BranchShape remains dependent on the attributes of the parent node. --- .changeset/polite-ants-sell.md | 16 ++++++++++ packages/common/src/constants/index.ts | 1 + packages/common/src/constants/property.ts | 5 ++++ packages/common/src/utils/index.ts | 1 + packages/common/src/utils/stroke.ts | 12 ++++++++ packages/core/src/utils/drawing/line.ts | 1 - .../generators/geometry-shape.generator.ts | 9 +++--- .../draw/src/generators/table.generator.ts | 9 +++--- .../src/utils/arrow-line/arrow-line-basic.ts | 7 +++-- packages/draw/src/utils/style/stroke.ts | 13 +-------- packages/draw/src/utils/vector-line.ts | 7 +++-- packages/mind/src/constants/default.ts | 1 - packages/mind/src/interfaces/element.ts | 3 +- .../src/utils/draw/node-link/abstract-link.ts | 13 ++++++--- .../src/utils/draw/node-link/draw-link.ts | 10 ++++--- .../src/utils/draw/node-link/indented-link.ts | 19 +++++++----- .../src/utils/draw/node-link/logic-link.ts | 29 ++++++++++++------- packages/mind/src/utils/draw/node-shape.ts | 10 +++++-- packages/mind/src/utils/mind.ts | 2 +- packages/mind/src/utils/node-style/branch.ts | 14 ++++----- packages/mind/src/utils/node-style/shape.ts | 7 ++++- packages/mind/src/utils/node/create-node.ts | 2 ++ 22 files changed, 124 insertions(+), 67 deletions(-) create mode 100644 .changeset/polite-ants-sell.md create mode 100644 packages/common/src/constants/property.ts create mode 100644 packages/common/src/utils/stroke.ts diff --git a/.changeset/polite-ants-sell.md b/.changeset/polite-ants-sell.md new file mode 100644 index 000000000..5316a9335 --- /dev/null +++ b/.changeset/polite-ants-sell.md @@ -0,0 +1,16 @@ +--- +'@plait/mind': minor +--- + +support strokeStyle for mind node and link + +BREAK CHANGES: + +1. It is planned to replace branchColor and branchWidth with strokeColor and strokeWidth. To maintain compatibility, branchColor and branchWidth will not be deleted. BranchColor and branchWidth will be applied first. +2. Both branchWidth and branchColor attributes are applied to the child node first and no longer rely on the attributes of the parent node. BranchShape remains dependent on the attributes of the parent node. + + +破坏性更改: + +1. 计划用 strokeColor 和 strokeWidth 替换 branchColor 和 branchWidth,为保持兼容 branchColor 和 branchWidth 不删除,优先应用 branchColor 和 branchWidth。 +2. branchWidth 和 branchColor 属性都优先应用 child 节点,不再依赖父节点的属性,branchShape 保持依赖父节点属性 diff --git a/packages/common/src/constants/index.ts b/packages/common/src/constants/index.ts index 2b29c070b..c3b0e2de3 100644 --- a/packages/common/src/constants/index.ts +++ b/packages/common/src/constants/index.ts @@ -1,3 +1,4 @@ export * from './default'; export * from './media'; export * from './resize'; +export * from './property'; diff --git a/packages/common/src/constants/property.ts b/packages/common/src/constants/property.ts new file mode 100644 index 000000000..74c9b284a --- /dev/null +++ b/packages/common/src/constants/property.ts @@ -0,0 +1,5 @@ +export enum StrokeStyle { + solid = 'solid', + dashed = 'dashed', + dotted = 'dotted' +} diff --git a/packages/common/src/utils/index.ts b/packages/common/src/utils/index.ts index 75b4c9c77..783d6d725 100644 --- a/packages/common/src/utils/index.ts +++ b/packages/common/src/utils/index.ts @@ -14,3 +14,4 @@ export * from './drawing'; export * from './rotate'; export * from './elements'; export * from './animate'; +export * from './stroke'; diff --git a/packages/common/src/utils/stroke.ts b/packages/common/src/utils/stroke.ts new file mode 100644 index 000000000..2f27efb28 --- /dev/null +++ b/packages/common/src/utils/stroke.ts @@ -0,0 +1,12 @@ +import { StrokeStyle } from '../constants'; + +export const getStrokeLineDash = (strokeStyle: StrokeStyle, strokeWidth: number) => { + switch (strokeStyle) { + case StrokeStyle.dashed: + return [8, 8 + strokeWidth]; + case StrokeStyle.dotted: + return [2, 4 + strokeWidth]; + default: + return undefined; + } +}; diff --git a/packages/core/src/utils/drawing/line.ts b/packages/core/src/utils/drawing/line.ts index d8b923d5e..0b6461377 100644 --- a/packages/core/src/utils/drawing/line.ts +++ b/packages/core/src/utils/drawing/line.ts @@ -30,7 +30,6 @@ export function drawLinearPath(points: Point[], options?: Options, closePath?: b path.setAttribute('fill', `${options?.fill || 'none'}`); options?.strokeLineDash && path.setAttribute('stroke-dasharray', `${options.strokeLineDash}`); g.appendChild(path); - return g; } diff --git a/packages/draw/src/generators/geometry-shape.generator.ts b/packages/draw/src/generators/geometry-shape.generator.ts index cdc3ef002..a44ff2ce0 100644 --- a/packages/draw/src/generators/geometry-shape.generator.ts +++ b/packages/draw/src/generators/geometry-shape.generator.ts @@ -1,6 +1,6 @@ import { BasicShapes, PlaitGeometry } from '../interfaces'; -import { Generator } from '@plait/common'; -import { getFillByElement, getLineDashByElement, getStrokeColorByElement } from '../utils/style/stroke'; +import { Generator, getStrokeLineDash } from '@plait/common'; +import { getFillByElement, getStrokeColorByElement, getStrokeStyleByElement } from '../utils/style/stroke'; import { drawGeometry, getStrokeWidthByElement } from '../utils'; import { RectangleClient } from '@plait/core'; @@ -17,10 +17,11 @@ export class GeometryShapeGenerator extends Generator if (shape === BasicShapes.text) { return; } + const fill = getFillByElement(this.board, element); const strokeWidth = getStrokeWidthByElement(element); const strokeColor = getStrokeColorByElement(this.board, element); - const fill = getFillByElement(this.board, element); - const strokeLineDash = getLineDashByElement(element); + const strokeStyle = getStrokeStyleByElement(this.board, element); + const strokeLineDash = getStrokeLineDash(strokeStyle, strokeWidth); return drawGeometry(this.board, RectangleClient.inflate(rectangle, -strokeWidth), shape, { stroke: strokeColor, strokeWidth, diff --git a/packages/draw/src/generators/table.generator.ts b/packages/draw/src/generators/table.generator.ts index 27edcd9d8..cdb961d19 100644 --- a/packages/draw/src/generators/table.generator.ts +++ b/packages/draw/src/generators/table.generator.ts @@ -1,9 +1,9 @@ import { TableSymbols } from '../interfaces'; -import { Generator } from '@plait/common'; +import { Generator, getStrokeLineDash } from '@plait/common'; import { PlaitElement, RectangleClient } from '@plait/core'; import { PlaitBaseTable } from '../interfaces/table'; import { getEngine } from '../engines'; -import { getDrawDefaultStrokeColor, getFillByElement, getLineDashByElement, getStrokeColorByElement, getStrokeWidthByElement } from '../utils'; +import { getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement } from '../utils'; export interface TableData {} @@ -14,16 +14,17 @@ export class TableGenerator extends Gen draw(element: T, data: TableData) { const rectangle = RectangleClient.getRectangleByPoints(element.points!); - const strokeLineDash = getLineDashByElement(element); const strokeWidth = getStrokeWidthByElement(element); const strokeColor = getStrokeColorByElement(this.board, element); + const strokeStyle = getStrokeStyleByElement(this.board, element); + const strokeLineDash = getStrokeLineDash(strokeStyle, strokeWidth); return getEngine(TableSymbols.table).draw( this.board, rectangle, { strokeWidth, stroke: strokeColor, - strokeLineDash, + strokeLineDash }, { element: element diff --git a/packages/draw/src/utils/arrow-line/arrow-line-basic.ts b/packages/draw/src/utils/arrow-line/arrow-line-basic.ts index cd1c69e0f..c51210536 100644 --- a/packages/draw/src/utils/arrow-line/arrow-line-basic.ts +++ b/packages/draw/src/utils/arrow-line/arrow-line-basic.ts @@ -14,7 +14,7 @@ import { setStrokeLinecap } from '@plait/core'; import { pointsOnBezierCurves } from 'points-on-curve'; -import { getPointOnPolyline, getPointByVectorComponent, removeDuplicatePoints, getExtendPoint } from '@plait/common'; +import { getPointOnPolyline, getPointByVectorComponent, removeDuplicatePoints, getExtendPoint, getStrokeLineDash } from '@plait/common'; import { ArrowLineHandle, ArrowLineMarkerType, @@ -25,7 +25,7 @@ import { PlaitShapeElement, StrokeStyle } from '../../interfaces'; -import { getLineDashByElement, getStrokeColorByElement } from '../style/stroke'; +import { getStrokeColorByElement, getStrokeStyleByElement } from '../style/stroke'; import { getEngine } from '../../engines'; import { getElementShape } from '../shape'; import { DefaultLineStyle, LINE_TEXT_SPACE } from '../../constants/line'; @@ -115,7 +115,8 @@ export const getCurvePoints = (board: PlaitBoard, element: PlaitArrowLine) => { export const drawArrowLine = (board: PlaitBoard, element: PlaitArrowLine) => { const strokeWidth = getStrokeWidthByElement(element); const strokeColor = getStrokeColorByElement(board, element); - const strokeLineDash = getLineDashByElement(element); + const strokeStyle = getStrokeStyleByElement(board, element); + const strokeLineDash = getStrokeLineDash(strokeStyle, strokeWidth); const options = { stroke: strokeColor, strokeWidth, strokeLineDash }; const lineG = createG(); let points = getArrowLinePoints(board, element); diff --git a/packages/draw/src/utils/style/stroke.ts b/packages/draw/src/utils/style/stroke.ts index 248d647f4..78ea39677 100644 --- a/packages/draw/src/utils/style/stroke.ts +++ b/packages/draw/src/utils/style/stroke.ts @@ -19,17 +19,6 @@ export const getFillByElement = (board: PlaitBoard, element: PlaitElement) => { return fill; }; -export const getLineDashByElement = (element: PlaitElement) => { - switch (element.strokeStyle) { - case StrokeStyle.dashed: - return [8, 8 + getStrokeWidthByElement(element)]; - case StrokeStyle.dotted: - return [2, 4 + getStrokeWidthByElement(element)]; - default: - return undefined; - } -}; - -export const getStrokeStyleByElement = (element: PlaitElement) => { +export const getStrokeStyleByElement = (board: PlaitBoard, element: PlaitElement) => { return element.strokeStyle || StrokeStyle.solid; }; diff --git a/packages/draw/src/utils/vector-line.ts b/packages/draw/src/utils/vector-line.ts index 4599377eb..8071fd984 100644 --- a/packages/draw/src/utils/vector-line.ts +++ b/packages/draw/src/utils/vector-line.ts @@ -4,10 +4,10 @@ import { getLineMemorizedLatest } from './memorize'; import { DefaultLineStyle } from '../constants/line'; import { alignPoints } from './arrow-line'; import { getStrokeWidthByElement } from './common'; -import { getFillByElement, getLineDashByElement, getStrokeColorByElement } from './style'; +import { getFillByElement, getStrokeColorByElement, getStrokeStyleByElement } from './style'; import { VectorLineShapeGenerator } from '../generators/vector-line-generator'; import { pointsOnBezierCurves } from 'points-on-curve'; -import { removeDuplicatePoints } from '@plait/common'; +import { getStrokeLineDash } from '@plait/common'; export const isClosedVectorLine = (vectorLine: PlaitVectorLine) => { const points = vectorLine.points; @@ -74,7 +74,8 @@ export const vectorLineCreating = ( export const drawVectorLine = (board: PlaitBoard, element: PlaitVectorLine) => { const strokeWidth = getStrokeWidthByElement(element); const strokeColor = getStrokeColorByElement(board, element); - const strokeLineDash = getLineDashByElement(element); + const strokeStyle = getStrokeStyleByElement(board, element); + const strokeLineDash = getStrokeLineDash(strokeStyle, strokeWidth); const fill = getFillByElement(board, element); const options = { stroke: strokeColor, strokeWidth, strokeLineDash, fill }; const lineG = createG(); diff --git a/packages/mind/src/constants/default.ts b/packages/mind/src/constants/default.ts index 4737a0300..1c5f743f5 100644 --- a/packages/mind/src/constants/default.ts +++ b/packages/mind/src/constants/default.ts @@ -4,7 +4,6 @@ export const BASE = 4; export const PRIMARY_COLOR = '#6698FF'; export const GRAY_COLOR = '#AAAAAA'; export const STROKE_WIDTH = 3; -export const BRANCH_WIDTH = 3; export const EXTEND_OFFSET = 8; export const EXTEND_DIAMETER = 16; diff --git a/packages/mind/src/interfaces/element.ts b/packages/mind/src/interfaces/element.ts index 2da87a6f5..28a9f9605 100644 --- a/packages/mind/src/interfaces/element.ts +++ b/packages/mind/src/interfaces/element.ts @@ -3,7 +3,7 @@ import { isNullOrUndefined, NODE_TO_PARENT, Path, PlaitBoard, PlaitElement, Plai import { MindQueries } from '../queries'; import { ELEMENT_TO_NODE } from '../utils'; import { BaseData, EmojiData, ImageData } from './element-data'; -import { MindNodeComponent } from '../mind-node.component'; +import { StrokeStyle } from '@plait/common'; export interface MindElement extends PlaitElement { data: T; @@ -18,6 +18,7 @@ export interface MindElement extends PlaitElement { fill?: string; strokeColor?: string; strokeWidth?: number; + strokeStyle?: StrokeStyle; shape?: MindElementShape; // link style attributes diff --git a/packages/mind/src/utils/draw/node-link/abstract-link.ts b/packages/mind/src/utils/draw/node-link/abstract-link.ts index 6aff619e6..c57f379d1 100644 --- a/packages/mind/src/utils/draw/node-link/abstract-link.ts +++ b/packages/mind/src/utils/draw/node-link/abstract-link.ts @@ -1,15 +1,18 @@ -import { PlaitBoard, Point, createG, drawLinearPath, getRectangleByElements } from '@plait/core'; +import { PlaitBoard, createG, drawLinearPath, getRectangleByElements } from '@plait/core'; import { MindNode } from '../../../interfaces/node'; import { getRectangleByNode } from '../../position/node'; import { HorizontalPlacement, PointPlacement, VerticalPlacement } from '../../../interfaces/types'; import { getLayoutDirection, getPointByPlacement, getXDistanceBetweenPoint, moveXOfPoint, transformPlacement } from '../../point-placement'; import { getAbstractBranchColor, getAbstractBranchWidth, getBranchShapeByMindElement } from '../../node-style/branch'; import { BranchShape } from '../../../interfaces/element'; +import { getStrokeStyleByElement } from '../../node-style'; +import { getStrokeLineDash } from '@plait/common'; export function drawAbstractLink(board: PlaitBoard, node: MindNode, isHorizontal: boolean) { const linkPadding = 15; const branchWidth = getAbstractBranchWidth(board, node.origin); const branchColor = getAbstractBranchColor(board, node.origin); + const strokeStyle = getStrokeStyleByElement(board, node.origin); const parent = node.parent; const branchShape = getBranchShapeByMindElement(board, node.origin); const abstractRectangle = getRectangleByNode(node); @@ -36,7 +39,7 @@ export function drawAbstractLink(board: PlaitBoard, node: MindNode, isHorizontal bezierEndPoint = moveXOfPoint(bezierEndPoint, linkPadding, linkDirection); let c2 = moveXOfPoint(bezierEndPoint, curveDistance, linkDirection); let bezierConnectorPoint = moveXOfPoint(abstractConnectorPoint, -linkPadding, linkDirection); - + const strokeLineDash = getStrokeLineDash(strokeStyle, branchWidth); if (branchShape === BranchShape.polyline) { const g = createG(); const polyline = drawLinearPath([bezierBeginPoint, c1, bezierConnectorPoint, c2, bezierEndPoint], { @@ -45,7 +48,8 @@ export function drawAbstractLink(board: PlaitBoard, node: MindNode, isHorizontal }); const straightLine = drawLinearPath([abstractConnectorPoint, bezierConnectorPoint], { stroke: branchColor, - strokeWidth: branchWidth + strokeWidth: branchWidth, + strokeLineDash }); g.appendChild(polyline); @@ -58,7 +62,8 @@ export function drawAbstractLink(board: PlaitBoard, node: MindNode, isHorizontal `M${bezierBeginPoint[0]},${bezierBeginPoint[1]} Q${c1[0]},${c1[1]} ${bezierConnectorPoint[0]},${bezierConnectorPoint[1]} Q${c2[0]},${c2[1]} ${bezierEndPoint[0]},${bezierEndPoint[1]} M${abstractConnectorPoint[0]},${abstractConnectorPoint[1]} L${bezierConnectorPoint[0]},${bezierConnectorPoint[1]}`, { stroke: branchColor, - strokeWidth: branchWidth + strokeWidth: branchWidth, + strokeLineDash } ); return link; diff --git a/packages/mind/src/utils/draw/node-link/draw-link.ts b/packages/mind/src/utils/draw/node-link/draw-link.ts index 11704e414..af7039b2f 100644 --- a/packages/mind/src/utils/draw/node-link/draw-link.ts +++ b/packages/mind/src/utils/draw/node-link/draw-link.ts @@ -3,6 +3,7 @@ import { drawIndentedLink } from './indented-link'; import { drawLogicLink } from './logic-link'; import { MindElement } from '../../../interfaces/element'; import { MindNode } from '../../../interfaces/node'; +import { StrokeStyle } from '@plait/common'; export function drawLink( board: PlaitBoard, @@ -10,10 +11,11 @@ export function drawLink( node: MindNode, isHorizontal: boolean, needDrawUnderline?: boolean, - defaultStroke?: string, - defaultStrokeWidth?: number + defaultStrokeColor?: string, + defaultStrokeWidth?: number, + defaultStrokeStyle?: StrokeStyle ) { return MindElement.isIndentedLayout(parentNode.origin) - ? drawIndentedLink(board, parentNode, node, defaultStroke, needDrawUnderline, defaultStrokeWidth) - : drawLogicLink(board, parentNode, node, isHorizontal, defaultStroke, defaultStrokeWidth); + ? drawIndentedLink(board, parentNode, node, needDrawUnderline, defaultStrokeColor, defaultStrokeWidth, defaultStrokeStyle) + : drawLogicLink(board, parentNode, node, isHorizontal, defaultStrokeColor, defaultStrokeWidth, defaultStrokeStyle); } diff --git a/packages/mind/src/utils/draw/node-link/indented-link.ts b/packages/mind/src/utils/draw/node-link/indented-link.ts index 9f1522dfd..0b1a6e8d9 100644 --- a/packages/mind/src/utils/draw/node-link/indented-link.ts +++ b/packages/mind/src/utils/draw/node-link/indented-link.ts @@ -1,21 +1,24 @@ import { pointsOnBezierCurves } from 'points-on-curve'; import { MindNode } from '../../../interfaces/node'; import { PlaitBoard, Point, drawBezierPath, drawLinearPath } from '@plait/core'; -import { getShapeByElement, getRectangleByNode, isChildUp } from '../..'; +import { getShapeByElement, getRectangleByNode, isChildUp, getStrokeStyleByElement } from '../..'; import { getBranchColorByMindElement, getBranchShapeByMindElement, getBranchWidthByMindElement } from '../../node-style/branch'; import { BranchShape, MindElementShape } from '../../../interfaces/element'; +import { getStrokeLineDash, StrokeStyle } from '@plait/common'; export function drawIndentedLink( board: PlaitBoard, parent: MindNode, child: MindNode, - defaultStroke: string | null = null, needDrawUnderline = true, - defaultStrokeWidth?: number + defaultStrokeColor: string | null = null, + defaultStrokeWidth?: number, + defaultStrokeStyle?: StrokeStyle ) { const branchShape = getBranchShapeByMindElement(board, parent.origin); - const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, parent.origin); - const branchColor = defaultStroke || getBranchColorByMindElement(board, child.origin); + const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, child.origin); + const branchColor = defaultStrokeColor || getBranchColorByMindElement(board, child.origin); + const strokeStyle = defaultStrokeStyle || getStrokeStyleByElement(board, child.origin); const isUnderlineShape = (getShapeByElement(board, child.origin) as MindElementShape) === MindElementShape.underline; let beginX, @@ -46,7 +49,7 @@ export function drawIndentedLink( isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY], isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY] ]; - + const strokeLineDash = getStrokeLineDash(strokeStyle, branchWidth); if (branchShape === BranchShape.polyline) { const polylinePoints = [ [beginX, beginY], @@ -55,9 +58,9 @@ export function drawIndentedLink( isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY] ]; - return drawLinearPath(polylinePoints as Point[], { stroke: branchColor, strokeWidth: branchWidth }); + return drawLinearPath(polylinePoints as Point[], { stroke: branchColor, strokeWidth: branchWidth, strokeLineDash }); } const points = pointsOnBezierCurves(curve, 0.001); - return drawBezierPath(points as Point[], { stroke: branchColor, strokeWidth: branchWidth }); + return drawBezierPath(points as Point[], { stroke: branchColor, strokeWidth: branchWidth, strokeLineDash }); } diff --git a/packages/mind/src/utils/draw/node-link/logic-link.ts b/packages/mind/src/utils/draw/node-link/logic-link.ts index fb90d7538..adfb52040 100644 --- a/packages/mind/src/utils/draw/node-link/logic-link.ts +++ b/packages/mind/src/utils/draw/node-link/logic-link.ts @@ -1,23 +1,26 @@ import { pointsOnBezierCurves } from 'points-on-curve'; import { MindNode } from '../../../interfaces/node'; -import { PlaitBoard, Point, drawLinearPath } from '@plait/core'; -import { getRectangleByNode, getShapeByElement } from '../..'; +import { PlaitBoard, Point, drawLinearPath, setStrokeLinecap } from '@plait/core'; +import { getRectangleByNode, getShapeByElement, getStrokeStyleByElement } from '../..'; import { getLayoutDirection, getPointByPlacement, moveXOfPoint, transformPlacement } from '../../point-placement'; import { HorizontalPlacement, PointPlacement, VerticalPlacement } from '../../../interfaces/types'; import { getBranchColorByMindElement, getBranchShapeByMindElement, getBranchWidthByMindElement } from '../../node-style/branch'; import { BranchShape, MindElementShape } from '../../../interfaces/element'; +import { getStrokeLineDash, StrokeStyle } from '@plait/common'; export function drawLogicLink( board: PlaitBoard, parent: MindNode, node: MindNode, isHorizontal: boolean, - defaultStroke: string | null = null, - defaultStrokeWidth?: number + defaultStrokeColor: string | null = null, + defaultStrokeWidth?: number, + defaultStrokeStyle?: StrokeStyle ) { const branchShape = getBranchShapeByMindElement(board, parent.origin); - const branchColor = defaultStroke || getBranchColorByMindElement(board, node.origin); - const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, parent.origin); + const branchColor = defaultStrokeColor || getBranchColorByMindElement(board, node.origin); + const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, node.origin); + const strokeStyle = defaultStrokeStyle || getStrokeStyleByElement(board, node.origin); const hasStraightLine = branchShape === BranchShape.polyline ? true : !parent.origin.isRoot; const parentShape = getShapeByElement(board, parent.origin); const shape = getShapeByElement(board, node.origin); @@ -64,9 +67,10 @@ export function drawLogicLink( // ④ underline shape and horizontal const underlineEnd = moveXOfPoint(endPoint, nodeClient.width, linkDirection); const underline: Point[] = hasUnderlineShape && isHorizontal ? [underlineEnd, underlineEnd, underlineEnd] : []; - const points = pointsOnBezierCurves([...straightLine, ...curve, ...underline]); - + const strokeLineDash = getStrokeLineDash(strokeStyle, branchWidth); + console.log(`strokeStyle: ${strokeStyle}, strokeLineDash: `, strokeLineDash); + let linkG: SVGGElement; if (branchShape === BranchShape.polyline) { const buffer = 8; const movePoint = moveXOfPoint(beginPoint2, buffer, linkDirection); @@ -77,7 +81,12 @@ export function drawLogicLink( endPoint, ...underline ]; - return drawLinearPath(polylinePoints as Point[], { stroke: branchColor, strokeWidth: branchWidth }); + linkG = drawLinearPath(polylinePoints as Point[], { stroke: branchColor, strokeWidth: branchWidth, strokeLineDash }); + } else { + linkG = PlaitBoard.getRoughSVG(board).curve(points as any, { stroke: branchColor, strokeWidth: branchWidth, strokeLineDash }); + } + if (strokeStyle === StrokeStyle.dotted) { + setStrokeLinecap(linkG, 'round'); } - return PlaitBoard.getRoughSVG(board).curve(points as any, { stroke: branchColor, strokeWidth: branchWidth }); + return linkG; } diff --git a/packages/mind/src/utils/draw/node-shape.ts b/packages/mind/src/utils/draw/node-shape.ts index 8044bf5d2..ad2e07896 100644 --- a/packages/mind/src/utils/draw/node-shape.ts +++ b/packages/mind/src/utils/draw/node-shape.ts @@ -1,9 +1,10 @@ import { MindNode } from '../../interfaces/node'; import { getRectangleByNode } from '../position/node'; import { PlaitBoard, RectangleClient, drawRoundRectangle } from '@plait/core'; -import { getFillByElement, getStrokeByMindElement, getStrokeWidthByElement } from '../node-style/shape'; +import { getFillByElement, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement } from '../node-style/shape'; import { DefaultNodeStyle } from '../../constants/node-style'; import { MindElement } from '../../interfaces'; +import { getStrokeLineDash } from '@plait/common'; export function drawRoundRectangleByNode(board: PlaitBoard, node: MindNode) { const rectangle = getRectangleByNode(node); @@ -12,8 +13,10 @@ export function drawRoundRectangleByNode(board: PlaitBoard, node: MindNode) { export function drawRoundRectangleByElement(board: PlaitBoard, nodeRectangle: RectangleClient, element: MindElement) { const fill = getFillByElement(board, element); - const stroke = getStrokeByMindElement(board, element); + const stroke = getStrokeColorByElement(board, element); const strokeWidth = getStrokeWidthByElement(board, element); + const strokeStyle = getStrokeStyleByElement(board, element); + const strokeLineDash = getStrokeLineDash(strokeStyle, strokeWidth); const newNodeRectangle = RectangleClient.inflate(nodeRectangle, -strokeWidth); const nodeG = drawRoundRectangle( PlaitBoard.getRoughSVG(board), @@ -25,7 +28,8 @@ export function drawRoundRectangleByElement(board: PlaitBoard, nodeRectangle: Re stroke, strokeWidth, fill, - fillStyle: 'solid' + fillStyle: 'solid', + strokeLineDash }, false, DefaultNodeStyle.shape.rectangleRadius diff --git a/packages/mind/src/utils/mind.ts b/packages/mind/src/utils/mind.ts index c0db37c6e..5bc4416e9 100644 --- a/packages/mind/src/utils/mind.ts +++ b/packages/mind/src/utils/mind.ts @@ -1,4 +1,4 @@ -import { addSelectedElement, clearSelectedElement, getSelectedElements, idCreator, Path, PlaitBoard, Transforms } from '@plait/core'; +import { addSelectedElement, clearSelectedElement, idCreator, Path, PlaitBoard, Transforms } from '@plait/core'; import { MindElement, PlaitMind } from '../interfaces/element'; import { editTopic } from './node/common'; import { createMindElement, INHERIT_ATTRIBUTE_KEYS, InheritAttribute } from './node/create-node'; diff --git a/packages/mind/src/utils/node-style/branch.ts b/packages/mind/src/utils/node-style/branch.ts index 52c3c9705..512e09fb8 100644 --- a/packages/mind/src/utils/node-style/branch.ts +++ b/packages/mind/src/utils/node-style/branch.ts @@ -3,7 +3,7 @@ */ import { PlaitBoard, isNullOrUndefined } from '@plait/core'; import { BranchShape, MindElement } from '../../interfaces/element'; -import { BRANCH_WIDTH } from '../../constants/default'; +import { STROKE_WIDTH } from '../../constants/default'; import { DefaultAbstractNodeStyle } from '../../constants/node-style'; import { getAvailableProperty } from './common'; import { MindDefaultThemeColor, MindThemeColor } from '../../interfaces/theme-color'; @@ -15,7 +15,7 @@ export const getBranchColorByMindElement = (board: PlaitBoard, element: MindElem return getAbstractBranchColor(board, element); } - const branchColor = getAvailableProperty(board, element, 'branchColor'); + const branchColor = getAvailableProperty(board, element, 'branchColor') || getAvailableProperty(board, element, 'strokeColor'); return branchColor || getDefaultBranchColor(board, element); }; @@ -25,20 +25,20 @@ export const getBranchShapeByMindElement = (board: PlaitBoard, element: MindElem }; export const getBranchWidthByMindElement = (board: PlaitBoard, element: MindElement) => { - const branchWidth = getAvailableProperty(board, element, 'branchWidth'); - return branchWidth || BRANCH_WIDTH; + const branchWidth = getAvailableProperty(board, element, 'branchWidth') || getAvailableProperty(board, element, 'strokeWidth'); + return branchWidth || STROKE_WIDTH; }; export const getAbstractBranchWidth = (board: PlaitBoard, element: MindElement) => { if (!isNullOrUndefined(element.branchWidth)) { - return element.branchWidth; + return element.branchWidth as number; } return DefaultAbstractNodeStyle.branch.width; }; export const getAbstractBranchColor = (board: PlaitBoard, element: MindElement) => { - if (element.branchColor) { - return element.branchColor; + if (element.branchColor || element.strokeColor) { + return element.branchColor || element.strokeColor; } return DefaultAbstractNodeStyle.branch.color; }; diff --git a/packages/mind/src/utils/node-style/shape.ts b/packages/mind/src/utils/node-style/shape.ts index 1d0611070..2c291587c 100644 --- a/packages/mind/src/utils/node-style/shape.ts +++ b/packages/mind/src/utils/node-style/shape.ts @@ -5,8 +5,9 @@ import { getDefaultBranchColor, getMindThemeColor } from './branch'; import { AbstractNode } from '@plait/layouts'; import { isChildOfAbstract } from '../abstract/common'; import { DefaultAbstractNodeStyle, DefaultNodeStyle } from '../../constants/node-style'; +import { StrokeStyle } from '@plait/common'; -export const getStrokeByMindElement = (board: PlaitBoard, element: MindElement) => { +export const getStrokeColorByElement = (board: PlaitBoard, element: MindElement) => { if (PlaitMind.isMind(element)) { const defaultRootStroke = getMindThemeColor(board).rootFill; return element.strokeColor || defaultRootStroke; @@ -19,6 +20,10 @@ export const getStrokeByMindElement = (board: PlaitBoard, element: MindElement) return getAvailableProperty(board, element, 'strokeColor') || getDefaultBranchColor(board, element); }; +export const getStrokeStyleByElement = (board: PlaitBoard, element: MindElement) => { + return element.strokeStyle || StrokeStyle.solid; +}; + export const getStrokeWidthByElement = (board: PlaitBoard, element: MindElement) => { const strokeWidth = element.strokeWidth || diff --git a/packages/mind/src/utils/node/create-node.ts b/packages/mind/src/utils/node/create-node.ts index e5e607ebf..5b8724c9e 100644 --- a/packages/mind/src/utils/node/create-node.ts +++ b/packages/mind/src/utils/node/create-node.ts @@ -56,6 +56,7 @@ export interface InheritAttribute { fill?: string; strokeColor?: string; strokeWidth?: number; + strokeStyle?: number; shape?: MindElementShape; layout?: MindLayoutType; branchColor?: string; @@ -67,6 +68,7 @@ export const INHERIT_ATTRIBUTE_KEYS = [ 'fill', 'strokeColor', 'strokeWidth', + 'strokeStyle', 'shape', 'layout', 'branchColor',