diff --git a/package-lock.json b/package-lock.json index 1a36c18..165ad49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "react-hook-form": "^7.51", "romans": "^2.0", "slugify": "^1.6", + "svg-path-commander": "^2.0.9", "svg-path-parser": "^1.1", "use-resize-observer": "^9.1" }, @@ -2454,6 +2455,11 @@ "@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": { "version": "4.3.0", "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==", "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": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/svg-path-parser/-/svg-path-parser-1.1.0.tgz", diff --git a/package.json b/package.json index 24a1f14..46a862e 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "react-hook-form": "^7.51", "romans": "^2.0", "slugify": "^1.6", + "svg-path-commander": "^2.0.9", "svg-path-parser": "^1.1", "use-resize-observer": "^9.1" }, diff --git a/plugin-src/transformers/partials/transformVectorPaths.ts b/plugin-src/transformers/partials/transformVectorPaths.ts index f5c15e0..5ed7d65 100644 --- a/plugin-src/transformers/partials/transformVectorPaths.ts +++ b/plugin-src/transformers/partials/transformVectorPaths.ts @@ -1,24 +1,18 @@ +import SVGPathCommander from 'svg-path-commander'; import { parseSVG } from 'svg-path-parser'; -import { - transformBlend, - transformDimensionAndPositionFromVectorPath, - transformEffects, - transformProportion, - transformSceneNode, - transformStrokesFromVector -} from '@plugin/transformers/partials'; + + +import { transformBlend, transformDimensionAndPositionFromVectorPath, transformEffects, transformProportion, transformSceneNode, transformStrokesFromVector } from '@plugin/transformers/partials'; import { translateFills } from '@plugin/translators/fills'; -import { - translateCommandsToSegments, - translateLineNode, - translateVectorPaths, - translateWindingRule -} from '@plugin/translators/vectors'; +import { translateCommandsToSegments, translateLineNode, translateVectorPaths, translateWindingRule } from '@plugin/translators/vectors'; + + import { PathAttributes } from '@ui/lib/types/shapes/pathShape'; import { PathShape } from '@ui/lib/types/shapes/pathShape'; + export const transformVectorPathsAsContent = ( node: StarNode | LineNode | PolygonNode, baseX: number, @@ -59,9 +53,27 @@ export const transformVectorPaths = async ( node.fillGeometry .filter( geometry => - !node.vectorPaths.find( - vectorPath => normalizePath(vectorPath.data) === normalizePath(geometry.data) - ) + !node.vectorPaths.find(vectorPath => { + // 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)) ); @@ -69,6 +81,28 @@ export const transformVectorPaths = async ( 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 => { switch (node.type) { case 'STAR':