0
Fork 0
mirror of https://github.com/penpot/penpot-exporter-figma-plugin.git synced 2024-12-22 13:43:03 -05:00

Add shadows to the export (#58)

This commit is contained in:
Jordi Sala Morales 2024-04-22 14:35:59 +02:00 committed by GitHub
parent c464ff9bda
commit e732887399
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 94 additions and 15 deletions

View file

@ -0,0 +1,5 @@
---
"penpot-exporter": minor
---
Shadows

View file

@ -2,6 +2,7 @@ export * from './transformBlend';
export * from './transformChildren';
export * from './transformCornerRadius';
export * from './transformDimensionAndPosition';
export * from './transformEffects';
export * from './transformFills';
export * from './transformProportion';
export * from './transformSceneNode';

View file

@ -0,0 +1,9 @@
import { translateShadowEffects } from '@plugin/translators';
import { ShapeAttributes } from '@ui/lib/types/shape/shapeAttributes';
export const transformEffects = (node: BlendMixin): Partial<ShapeAttributes> => {
return {
shadow: translateShadowEffects(node.effects)
};
};

View file

@ -1,6 +1,7 @@
import {
transformBlend,
transformDimensionAndPosition,
transformEffects,
transformFills,
transformProportion,
transformSceneNode,
@ -18,6 +19,7 @@ export const transformEllipseNode = (
type: 'circle',
name: node.name,
...transformFills(node),
...transformEffects(node),
...transformStrokes(node),
...transformDimensionAndPosition(node, baseX, baseY),
...transformSceneNode(node),

View file

@ -3,6 +3,7 @@ import {
transformChildren,
transformCornerRadius,
transformDimensionAndPosition,
transformEffects,
transformFills,
transformProportion,
transformSceneNode,
@ -20,25 +21,30 @@ export const transformFrameNode = async (
baseX: number,
baseY: number
): Promise<FrameShape> => {
let frameSpecificAttributes: Partial<FrameShape> = {};
if (!isSectionNode(node)) {
// Figma API does not expose strokes, blend modes, corner radius, or constraint proportions for sections,
// they plan to add it in the future. Refactor this when available.
frameSpecificAttributes = {
// @see: https://forum.figma.com/t/why-are-strokes-not-available-on-section-nodes/41658
...transformStrokes(node),
// @see: https://forum.figma.com/t/add-a-blendmode-property-for-sectionnode/58560
...transformBlend(node),
...transformProportion(node),
...transformCornerRadius(node),
...transformEffects(node)
};
}
return {
type: 'frame',
name: node.name,
showContent: isSectionNode(node) ? true : !node.clipsContent,
...transformFills(node),
// Figma API does not expose strokes for sections,
// they plan to add it in the future. Refactor this when available.
// @see: https://forum.figma.com/t/why-are-strokes-not-available-on-section-nodes/41658
...(isSectionNode(node) ? [] : transformStrokes(node)),
...frameSpecificAttributes,
...(await transformChildren(node, baseX + node.x, baseY + node.y)),
...transformDimensionAndPosition(node, baseX, baseY),
// Figma API does not expose blend modes for sections,
// they plan to add it in the future. Refactor this when available.
// @see: https://forum.figma.com/t/add-a-blendmode-property-for-sectionnode/58560
...(isSectionNode(node) ? [] : transformBlend(node)),
...transformSceneNode(node),
// Figma API does not expose constraints proportions for sections
...(isSectionNode(node) ? [] : transformProportion(node)),
// Figma API does not expose corner radius for sections
...(isSectionNode(node) ? [] : transformCornerRadius(node))
...transformSceneNode(node)
};
};

View file

@ -1,6 +1,7 @@
import {
transformBlend,
transformDimensionAndPosition,
transformEffects,
transformSceneNode
} from '@plugin/transformers/partials';
import { transformChildren } from '@plugin/transformers/partials';
@ -17,6 +18,7 @@ export const transformGroupNode = async (
name: node.name,
...(await transformChildren(node, baseX, baseY)),
...transformDimensionAndPosition(node, baseX, baseY),
...transformEffects(node),
...transformSceneNode(node),
...transformBlend(node)
};

View file

@ -1,6 +1,7 @@
import {
transformBlend,
transformDimensionAndPosition,
transformEffects,
transformFills,
transformProportion,
transformSceneNode,
@ -23,6 +24,7 @@ export const transformPathNode = (
name: node.name,
...(hasFillGeometry(node) ? transformFills(node) : []),
...transformStrokes(node),
...transformEffects(node),
...transformVectorPaths(node, baseX, baseY),
...transformDimensionAndPosition(node, baseX, baseY),
...transformSceneNode(node),

View file

@ -2,6 +2,7 @@ import {
transformBlend,
transformCornerRadius,
transformDimensionAndPosition,
transformEffects,
transformFills,
transformProportion,
transformSceneNode,
@ -19,6 +20,7 @@ export const transformRectangleNode = (
type: 'rect',
name: node.name,
...transformFills(node),
...transformEffects(node),
...transformStrokes(node),
...transformDimensionAndPosition(node, baseX, baseY),
...transformSceneNode(node),

View file

@ -1,6 +1,7 @@
import {
transformBlend,
transformDimensionAndPosition,
transformEffects,
transformFills,
transformProportion,
transformSceneNode,
@ -42,6 +43,7 @@ export const transformTextNode = (node: TextNode, baseX: number, baseY: number):
]
},
...transformDimensionAndPosition(node, baseX, baseY),
...transformEffects(node),
...transformSceneNode(node),
...transformBlend(node),
...transformProportion(node)

View file

@ -1,4 +1,5 @@
export * from './translateBlendMode';
export * from './translateShadowEffects';
export * from './translateFills';
export * from './translateStrokes';
export * from './translateStyledTextSegments';

View file

@ -0,0 +1,45 @@
import { rgbToHex } from '@plugin/utils';
import { Shadow, ShadowStyle } from '@ui/lib/types/utils/shadow';
export const translateShadowEffect = (effect: Effect): Shadow | undefined => {
if (effect.type !== 'DROP_SHADOW' && effect.type !== 'INNER_SHADOW') {
return;
}
return {
style: translateShadowType(effect),
offsetX: effect.offset.x,
offsetY: effect.offset.y,
blur: effect.radius,
spread: effect.spread ?? 0,
hidden: !effect.visible,
color: {
color: rgbToHex(effect.color),
opacity: effect.color.a
}
};
};
export const translateShadowEffects = (effects: readonly Effect[]): Shadow[] => {
const shadows: Shadow[] = [];
for (const effect of effects) {
const shadow = translateShadowEffect(effect);
if (shadow) {
// effects are applied in reverse order in Figma, that's why we unshift
shadows.unshift(shadow);
}
}
return shadows;
};
const translateShadowType = (effect: DropShadowEffect | InnerShadowEffect): ShadowStyle => {
switch (effect.type) {
case 'DROP_SHADOW':
return 'drop-shadow';
case 'INNER_SHADOW':
return 'inner-shadow';
}
};

View file

@ -12,6 +12,6 @@ export type Color = {
modifiedAt?: string; //@TODO: check this attribute in penpot
refId?: Uuid;
refFile?: Uuid;
gradient: Gradient;
gradient?: Gradient;
image?: ImageColor;
};

View file

@ -2,9 +2,11 @@ import { Color } from '@ui/lib/types/utils/color';
import { Uuid } from './uuid';
export type ShadowStyle = 'drop-shadow' | 'inner-shadow';
export type Shadow = {
id?: Uuid;
style: symbol; // 'drop-shadow' | 'inner-shadow'
style: ShadowStyle;
offsetX: number;
offsetY: number;
blur: number;