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:
parent
c464ff9bda
commit
e732887399
13 changed files with 94 additions and 15 deletions
5
.changeset/flat-balloons-exercise.md
Normal file
5
.changeset/flat-balloons-exercise.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"penpot-exporter": minor
|
||||
---
|
||||
|
||||
Shadows
|
|
@ -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';
|
||||
|
|
9
plugin-src/transformers/partials/transformEffects.ts
Normal file
9
plugin-src/transformers/partials/transformEffects.ts
Normal 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)
|
||||
};
|
||||
};
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export * from './translateBlendMode';
|
||||
export * from './translateShadowEffects';
|
||||
export * from './translateFills';
|
||||
export * from './translateStrokes';
|
||||
export * from './translateStyledTextSegments';
|
||||
|
|
45
plugin-src/translators/translateShadowEffects.ts
Normal file
45
plugin-src/translators/translateShadowEffects.ts
Normal 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';
|
||||
}
|
||||
};
|
2
ui-src/lib/types/utils/color.d.ts
vendored
2
ui-src/lib/types/utils/color.d.ts
vendored
|
@ -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;
|
||||
};
|
||||
|
|
4
ui-src/lib/types/utils/shadow.d.ts
vendored
4
ui-src/lib/types/utils/shadow.d.ts
vendored
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue