mirror of
https://github.com/penpot/penpot-exporter-figma-plugin.git
synced 2024-12-22 13:43:03 -05:00
[WIP] Detect better when a shape is duplicated
This commit is contained in:
parent
477291758e
commit
74d26d80c5
3 changed files with 70 additions and 17 deletions
18
package-lock.json
generated
18
package-lock.json
generated
|
@ -15,6 +15,7 @@
|
||||||
"react-hook-form": "^7.51",
|
"react-hook-form": "^7.51",
|
||||||
"romans": "^2.0",
|
"romans": "^2.0",
|
||||||
"slugify": "^1.6",
|
"slugify": "^1.6",
|
||||||
|
"svg-path-commander": "^2.0.9",
|
||||||
"svg-path-parser": "^1.1",
|
"svg-path-parser": "^1.1",
|
||||||
"use-resize-observer": "^9.1"
|
"use-resize-observer": "^9.1"
|
||||||
},
|
},
|
||||||
|
@ -2454,6 +2455,11 @@
|
||||||
"@swc/counter": "^0.1.3"
|
"@swc/counter": "^0.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@thednp/dommatrix": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@thednp/dommatrix/-/dommatrix-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-DXQq4Rs/akYzeXYGkNy3KiJ4JoD8+SYr1QRWTXtAGoZ0+vJcyBt0aeqA1K4CxPaBaIfKdOTE+Te1HV9sAQ4I4A=="
|
||||||
|
},
|
||||||
"node_modules/@trivago/prettier-plugin-sort-imports": {
|
"node_modules/@trivago/prettier-plugin-sort-imports": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.0.tgz",
|
||||||
|
@ -8277,6 +8283,18 @@
|
||||||
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
|
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/svg-path-commander": {
|
||||||
|
"version": "2.0.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/svg-path-commander/-/svg-path-commander-2.0.9.tgz",
|
||||||
|
"integrity": "sha512-VfRLznHewlpQvuahtBK0MT/PlWAapbTx8RSytqgaVwD3US2keKcc3WYYlBBk4vIOR+jB3nQu/NAVlWHKlo0Fjw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@thednp/dommatrix": "^2.0.6"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16",
|
||||||
|
"pnpm": ">=8.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/svg-path-parser": {
|
"node_modules/svg-path-parser": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/svg-path-parser/-/svg-path-parser-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/svg-path-parser/-/svg-path-parser-1.1.0.tgz",
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
"react-hook-form": "^7.51",
|
"react-hook-form": "^7.51",
|
||||||
"romans": "^2.0",
|
"romans": "^2.0",
|
||||||
"slugify": "^1.6",
|
"slugify": "^1.6",
|
||||||
|
"svg-path-commander": "^2.0.9",
|
||||||
"svg-path-parser": "^1.1",
|
"svg-path-parser": "^1.1",
|
||||||
"use-resize-observer": "^9.1"
|
"use-resize-observer": "^9.1"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,24 +1,18 @@
|
||||||
|
import SVGPathCommander from 'svg-path-commander';
|
||||||
import { parseSVG } from 'svg-path-parser';
|
import { parseSVG } from 'svg-path-parser';
|
||||||
|
|
||||||
import {
|
|
||||||
transformBlend,
|
|
||||||
transformDimensionAndPositionFromVectorPath,
|
import { transformBlend, transformDimensionAndPositionFromVectorPath, transformEffects, transformProportion, transformSceneNode, transformStrokesFromVector } from '@plugin/transformers/partials';
|
||||||
transformEffects,
|
|
||||||
transformProportion,
|
|
||||||
transformSceneNode,
|
|
||||||
transformStrokesFromVector
|
|
||||||
} from '@plugin/transformers/partials';
|
|
||||||
import { translateFills } from '@plugin/translators/fills';
|
import { translateFills } from '@plugin/translators/fills';
|
||||||
import {
|
import { translateCommandsToSegments, translateLineNode, translateVectorPaths, translateWindingRule } from '@plugin/translators/vectors';
|
||||||
translateCommandsToSegments,
|
|
||||||
translateLineNode,
|
|
||||||
translateVectorPaths,
|
|
||||||
translateWindingRule
|
|
||||||
} from '@plugin/translators/vectors';
|
|
||||||
|
|
||||||
import { PathAttributes } from '@ui/lib/types/shapes/pathShape';
|
import { PathAttributes } from '@ui/lib/types/shapes/pathShape';
|
||||||
import { PathShape } from '@ui/lib/types/shapes/pathShape';
|
import { PathShape } from '@ui/lib/types/shapes/pathShape';
|
||||||
|
|
||||||
|
|
||||||
export const transformVectorPathsAsContent = (
|
export const transformVectorPathsAsContent = (
|
||||||
node: StarNode | LineNode | PolygonNode,
|
node: StarNode | LineNode | PolygonNode,
|
||||||
baseX: number,
|
baseX: number,
|
||||||
|
@ -59,9 +53,27 @@ export const transformVectorPaths = async (
|
||||||
node.fillGeometry
|
node.fillGeometry
|
||||||
.filter(
|
.filter(
|
||||||
geometry =>
|
geometry =>
|
||||||
!node.vectorPaths.find(
|
!node.vectorPaths.find(vectorPath => {
|
||||||
vectorPath => normalizePath(vectorPath.data) === normalizePath(geometry.data)
|
// console.log(vectorPath.data, geometry.data);
|
||||||
)
|
console.log(
|
||||||
|
SVGPathCommander.optimizePath(SVGPathCommander.normalizePath(vectorPath.data), 2),
|
||||||
|
SVGPathCommander.optimizePath(SVGPathCommander.normalizePath(geometry.data), 2),
|
||||||
|
new SVGPathCommander(vectorPath.data, { round: 'auto' }).optimize().toString() ===
|
||||||
|
new SVGPathCommander(geometry.data, { round: 'auto' }).optimize().toString(),
|
||||||
|
SVGPathCommander.normalizePath(vectorPath.data),
|
||||||
|
SVGPathCommander.normalizePath(geometry.data),
|
||||||
|
normalizePath(vectorPath.data) === normalizePath(geometry.data),
|
||||||
|
Math.abs(
|
||||||
|
SVGPathCommander.getTotalLength(vectorPath.data) -
|
||||||
|
SVGPathCommander.getTotalLength(geometry.data)
|
||||||
|
) <= 0.01
|
||||||
|
);
|
||||||
|
|
||||||
|
// compare vertexs of the path
|
||||||
|
|
||||||
|
|
||||||
|
return normalizePath(vectorPath.data) === normalizePath(geometry.data);
|
||||||
|
})
|
||||||
)
|
)
|
||||||
.map(geometry => transformVectorPath(node, geometry, undefined, baseX, baseY))
|
.map(geometry => transformVectorPath(node, geometry, undefined, baseX, baseY))
|
||||||
);
|
);
|
||||||
|
@ -69,6 +81,28 @@ export const transformVectorPaths = async (
|
||||||
return [...geometryShapes, ...pathShapes];
|
return [...geometryShapes, ...pathShapes];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const compareVertices = (vertices1: Vertex[], vertices2: Vertex[]): boolean => {
|
||||||
|
if (vertices1.length !== vertices2.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const set1 = new Set(vertices1.map(v => `${v.x},${v.y}`));
|
||||||
|
const set2 = new Set(vertices2.map(v => `${v.x},${v.y}`));
|
||||||
|
|
||||||
|
if (set1.size !== set2.size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const vertex of set1) {
|
||||||
|
if (!set2.has(vertex)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const getVectorPaths = (node: StarNode | LineNode | PolygonNode): VectorPaths => {
|
const getVectorPaths = (node: StarNode | LineNode | PolygonNode): VectorPaths => {
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
case 'STAR':
|
case 'STAR':
|
||||||
|
|
Loading…
Reference in a new issue