From c114bd0b98215a44f870dfa136903e8d90d3f4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=C3=A1nchez?= Date: Thu, 18 Apr 2024 09:42:45 +0200 Subject: [PATCH] Strokes (#44) * strokes * adjust a few types * simplify --------- Co-authored-by: Jordi Sala Morales --- .../transformers/partials/transformStrokes.ts | 16 +++++-- plugin-src/translators/translateStrokes.ts | 47 ++++++++++++++++--- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/plugin-src/transformers/partials/transformStrokes.ts b/plugin-src/transformers/partials/transformStrokes.ts index cf9a371..05cc5e0 100644 --- a/plugin-src/transformers/partials/transformStrokes.ts +++ b/plugin-src/transformers/partials/transformStrokes.ts @@ -6,19 +6,25 @@ const isVectorLike = (node: GeometryMixin | VectorLikeMixin): node is VectorLike return 'vectorNetwork' in node; }; -const hasFillGeometry = (node: GeometryMixin | (GeometryMixin & VectorLikeMixin)): boolean => { +const isIndividualStrokes = ( + node: GeometryMixin | IndividualStrokesMixin +): node is IndividualStrokesMixin => { + return 'strokeTopWeight' in node; +}; + +const hasFillGeometry = (node: GeometryMixin): boolean => { return node.fillGeometry.length > 0; }; export const transformStrokes = ( - node: GeometryMixin | (GeometryMixin & VectorLikeMixin) + node: GeometryMixin | (GeometryMixin & IndividualStrokesMixin) ): Partial => { return { strokes: translateStrokes( - node.strokes, - node.strokeWeight, + node, hasFillGeometry(node), - isVectorLike(node) ? node.vectorNetwork : undefined + isVectorLike(node) ? node.vectorNetwork : undefined, + isIndividualStrokes(node) ? node : undefined ) }; }; diff --git a/plugin-src/translators/translateStrokes.ts b/plugin-src/translators/translateStrokes.ts index ebe3e75..e380213 100644 --- a/plugin-src/translators/translateStrokes.ts +++ b/plugin-src/translators/translateStrokes.ts @@ -1,19 +1,21 @@ import { translateFill } from '@plugin/translators/translateFills'; -import { Stroke, StrokeCaps } from '@ui/lib/types/utils/stroke'; +import { Stroke, StrokeAlignment, StrokeCaps } from '@ui/lib/types/utils/stroke'; export const translateStrokes = ( - paints: readonly Paint[], - strokeWeight: number | typeof figma.mixed, + nodeStrokes: MinimalStrokesMixin, hasFillGeometry?: boolean, - vectorNetwork?: VectorNetwork + vectorNetwork?: VectorNetwork, + individualStrokes?: IndividualStrokesMixin ): Stroke[] => { - return paints.map((paint, index) => { + return nodeStrokes.strokes.map((paint, index) => { const fill = translateFill(paint, 0, 0); const stroke: Stroke = { strokeColor: fill?.fillColor, strokeOpacity: fill?.fillOpacity, - strokeWidth: strokeWeight === figma.mixed ? 1 : strokeWeight + strokeWidth: translateStrokeWeight(nodeStrokes.strokeWeight, individualStrokes), + strokeAlignment: translateStrokeAlignment(nodeStrokes.strokeAlign), + strokeStyle: nodeStrokes.dashPattern.length ? 'dashed' : 'solid' }; if (!hasFillGeometry && index === 0 && vectorNetwork && vectorNetwork.vertices.length) { @@ -27,6 +29,39 @@ export const translateStrokes = ( }); }; +const translateStrokeWeight = ( + strokeWeight: number | typeof figma.mixed, + individualStrokes?: IndividualStrokesMixin +): number => { + if (strokeWeight !== figma.mixed) { + return strokeWeight; + } + + if (!individualStrokes) { + return 1; + } + + return Math.max( + individualStrokes.strokeTopWeight, + individualStrokes.strokeRightWeight, + individualStrokes.strokeBottomWeight, + individualStrokes.strokeLeftWeight + ); +}; + +const translateStrokeAlignment = ( + strokeAlign: 'CENTER' | 'INSIDE' | 'OUTSIDE' +): StrokeAlignment => { + switch (strokeAlign) { + case 'CENTER': + return 'center'; + case 'INSIDE': + return 'inner'; + case 'OUTSIDE': + return 'outer'; + } +}; + const translateStrokeCap = (vertex: VectorVertex): StrokeCaps | undefined => { switch (vertex.strokeCap as StrokeCap | ConnectorStrokeCap) { case 'NONE':