mirror of
https://github.com/penpot/penpot-exporter-figma-plugin.git
synced 2024-12-22 13:43:03 -05:00
Masked Groups (#114)
* masked groups * changeset * refactor * refactor * refactor * fixes * fixes * wip * try to fix * refactor * refactor for better undestanding of code * refactor * fix name --------- Co-authored-by: Jordi Sala Morales <jordism91@gmail.com>
This commit is contained in:
parent
36afc6da55
commit
761093564b
4 changed files with 58 additions and 5 deletions
5
.changeset/dull-donkeys-share.md
Normal file
5
.changeset/dull-donkeys-share.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"penpot-exporter": minor
|
||||
---
|
||||
|
||||
Added support for masked groups
|
|
@ -1,16 +1,22 @@
|
|||
import { transformSceneNode } from '@plugin/transformers';
|
||||
import { translateChildren, translateMaskChildren } from '@plugin/translators';
|
||||
|
||||
import { PenpotNode } from '@ui/lib/types/penpotNode';
|
||||
import { Children } from '@ui/lib/types/utils/children';
|
||||
|
||||
const nodeActsAsMask = (node: SceneNode): boolean => {
|
||||
return 'isMask' in node && node.isMask;
|
||||
};
|
||||
|
||||
export const transformChildren = async (
|
||||
node: ChildrenMixin,
|
||||
baseX: number = 0,
|
||||
baseY: number = 0
|
||||
): Promise<Children> => {
|
||||
const maskIndex = node.children.findIndex(nodeActsAsMask);
|
||||
const containsMask = maskIndex !== -1;
|
||||
|
||||
return {
|
||||
children: (
|
||||
await Promise.all(node.children.map(child => transformSceneNode(child, baseX, baseY)))
|
||||
).filter((child): child is PenpotNode => !!child)
|
||||
children: containsMask
|
||||
? await translateMaskChildren(node.children, maskIndex, baseX, baseY)
|
||||
: await translateChildren(node.children, baseX, baseY)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export * from './translateBlendMode';
|
||||
export * from './translateBlurEffects';
|
||||
export * from './translateBoolType';
|
||||
export * from './translateChildren';
|
||||
export * from './translateShadowEffects';
|
||||
export * from './translateStrokes';
|
||||
|
|
41
plugin-src/translators/translateChildren.ts
Normal file
41
plugin-src/translators/translateChildren.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { transformGroupNodeLike, transformSceneNode } from '@plugin/transformers';
|
||||
|
||||
import { PenpotNode } from '@ui/lib/types/penpotNode';
|
||||
|
||||
/**
|
||||
* Translates the children of a node that acts as a mask.
|
||||
* We need to split the children into two groups: the ones that are masked and the ones that are not.
|
||||
*
|
||||
* The masked children will be grouped together in a mask group.
|
||||
* The unmasked children will be returned as they are.
|
||||
*
|
||||
* @maskIndex The index of the mask node in the children array
|
||||
*/
|
||||
export const translateMaskChildren = async (
|
||||
children: readonly SceneNode[],
|
||||
maskIndex: number,
|
||||
baseX: number,
|
||||
baseY: number
|
||||
): Promise<PenpotNode[]> => {
|
||||
const maskChild = children[maskIndex];
|
||||
const unmaskedChildren = await translateChildren(children.slice(0, maskIndex), baseX, baseY);
|
||||
const maskedChildren = await translateChildren(children.slice(maskIndex), baseX, baseY);
|
||||
|
||||
const maskGroup = {
|
||||
...transformGroupNodeLike(maskChild, baseX, baseY),
|
||||
children: maskedChildren,
|
||||
maskedGroup: true
|
||||
};
|
||||
|
||||
return [...unmaskedChildren, maskGroup];
|
||||
};
|
||||
|
||||
export const translateChildren = async (
|
||||
children: readonly SceneNode[],
|
||||
baseX: number,
|
||||
baseY: number
|
||||
): Promise<PenpotNode[]> => {
|
||||
return (await Promise.all(children.map(child => transformSceneNode(child, baseX, baseY)))).filter(
|
||||
(child): child is PenpotNode => !!child
|
||||
);
|
||||
};
|
Loading…
Reference in a new issue