From 1ffb224cb5eae84ef975b1c577b4a5b475198e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=C3=A1nchez?= Date: Tue, 16 Apr 2024 17:11:46 +0200 Subject: [PATCH] lines & arrows draft --- plugin-src/transformers/index.ts | 1 + plugin-src/transformers/transformLineNode.ts | 21 ++++++++++ plugin-src/transformers/transformSceneNode.ts | 3 ++ .../transformers/transformVectorNode.ts | 2 +- plugin-src/translators/translateStrokes.ts | 39 +++++++++++++++++-- 5 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 plugin-src/transformers/transformLineNode.ts diff --git a/plugin-src/transformers/index.ts b/plugin-src/transformers/index.ts index 11ab8089..fd8f8bcc 100644 --- a/plugin-src/transformers/index.ts +++ b/plugin-src/transformers/index.ts @@ -3,6 +3,7 @@ export * from './transformEllipseNode'; export * from './transformFrameNode'; export * from './transformGroupNode'; export * from './transformImageNode'; +export * from './transformLineNode'; export * from './transformPageNode'; export * from './transformPolygonNode'; export * from './transformRectangleNode'; diff --git a/plugin-src/transformers/transformLineNode.ts b/plugin-src/transformers/transformLineNode.ts new file mode 100644 index 00000000..c976f05e --- /dev/null +++ b/plugin-src/transformers/transformLineNode.ts @@ -0,0 +1,21 @@ +import { + transformBlend, + transformDimensionAndPosition, + transformSceneNode +} from '@plugin/transformers/partials'; +import { translateFills, translateStrokes, translateVectorPaths } from '@plugin/translators'; + +import { PathShape } from '@ui/lib/types/path/pathShape'; + +export const transformLineNode = (node: LineNode, baseX: number, baseY: number): PathShape => { + return { + type: 'path', + name: node.name, + fills: node.fillGeometry.length ? translateFills(node.fills, node.width, node.height) : [], + content: translateVectorPaths(node.strokeGeometry, baseX + node.x, baseY + node.y), + strokes: translateStrokes(node), + ...transformDimensionAndPosition(node, baseX, baseY), + ...transformSceneNode(node), + ...transformBlend(node) + }; +}; diff --git a/plugin-src/transformers/transformSceneNode.ts b/plugin-src/transformers/transformSceneNode.ts index a7f03249..29fb92ae 100644 --- a/plugin-src/transformers/transformSceneNode.ts +++ b/plugin-src/transformers/transformSceneNode.ts @@ -7,6 +7,7 @@ import { transformFrameNode, transformGroupNode, transformImageNode, + transformLineNode, transformPolygonNode, transformRectangleNode, transformTextNode, @@ -47,6 +48,8 @@ export const transformSceneNode = async ( return transformPolygonNode(node, baseX, baseY); case 'VECTOR': return transformVectorNode(node, baseX, baseY); + case 'LINE': + return transformLineNode(node, baseX, baseY); } throw new Error(`Unsupported node type: ${node.type}`); diff --git a/plugin-src/transformers/transformVectorNode.ts b/plugin-src/transformers/transformVectorNode.ts index c82c160b..29c06196 100644 --- a/plugin-src/transformers/transformVectorNode.ts +++ b/plugin-src/transformers/transformVectorNode.ts @@ -13,7 +13,7 @@ export const transformVectorNode = (node: VectorNode, baseX: number, baseY: numb name: node.name, fills: node.fillGeometry.length ? translateFills(node.fills, node.width, node.height) : [], content: translateVectorPaths(node.vectorPaths, baseX + node.x, baseY + node.y), - strokes: translateStrokes(node), + strokes: translateStrokes(node, node.vectorNetwork), ...transformDimensionAndPosition(node, baseX, baseY), ...transformSceneNode(node), ...transformBlend(node) diff --git a/plugin-src/translators/translateStrokes.ts b/plugin-src/translators/translateStrokes.ts index 85574464..b25252e4 100644 --- a/plugin-src/translators/translateStrokes.ts +++ b/plugin-src/translators/translateStrokes.ts @@ -1,14 +1,45 @@ import { translateFill } from '@plugin/translators/translateFills'; -import { Stroke } from '@ui/lib/types/utils/stroke'; +import { Stroke, StrokeCaps } from '@ui/lib/types/utils/stroke'; -export const translateStrokes = (node: MinimalStrokesMixin): Stroke[] => { - return node.strokes.map(stroke => { +export const translateStrokes = ( + node: MinimalStrokesMixin, + vectorNetwork?: VectorNetwork +): Stroke[] => { + const strokes = node.strokes.map(stroke => { const fill = translateFill(stroke, 0, 0); return { strokeColor: fill?.fillColor, strokeOpacity: fill?.fillOpacity, strokeWidth: node.strokeWeight === figma.mixed ? 1 : node.strokeWeight - }; + } as Stroke; }); + + // if line check for arrow strokes + if (vectorNetwork && vectorNetwork.vertices.length === 2) { + strokes[0].strokeCapStart = translateStrokeCap(vectorNetwork.vertices[0]); + strokes[0].strokeCapEnd = translateStrokeCap(vectorNetwork.vertices[1]); + } + + return strokes; +}; + +const translateStrokeCap = (vertex: VectorVertex): StrokeCaps | undefined => { + switch (vertex.strokeCap as StrokeCap | ConnectorStrokeCap) { + case 'NONE': + return; + case 'ROUND': + return 'round'; + case 'ARROW_EQUILATERAL': + return 'triangle-arrow'; + case 'SQUARE': + return 'square'; + case 'CIRCLE_FILLED': + return 'circle-marker'; + case 'DIAMOND_FILLED': + return 'diamond-marker'; + case 'ARROW_LINES': + default: + return 'line-arrow'; + } };