From 3da80b4c266cf21e3123f8bf8a80bf2318c48c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=C3=A1nchez?= Date: Thu, 14 Nov 2024 15:42:45 +0100 Subject: [PATCH] Fix transformed shapes (#236) * fix transformed shapes * minor fix --- .changeset/bright-roses-wave.md | 5 +++++ package.json | 2 +- .../partials/transformRotationAndPosition.ts | 11 +++++------ plugin-src/translators/vectors/translateCommands.ts | 6 ++---- plugin-src/utils/applyRotation.ts | 10 +++++++--- 5 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 .changeset/bright-roses-wave.md diff --git a/.changeset/bright-roses-wave.md b/.changeset/bright-roses-wave.md new file mode 100644 index 0000000..f21ad88 --- /dev/null +++ b/.changeset/bright-roses-wave.md @@ -0,0 +1,5 @@ +--- +'penpot-exporter': patch +--- + +Fixed transformed shapes when flipped horizontally/vertically diff --git a/package.json b/package.json index 95da11e..1b49715 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build:prod": "concurrently -n widget,iframe 'npm:build:main' 'npm:build:ui -- --mode production'", "build:main": "esbuild plugin-src/code.ts --bundle --outfile=dist/code.js --target=es2016 --minify", "build:ui": "vite build", - "build:watch": "concurrently -n widget,iframe 'npm:build:main -- --watch' 'npm:build:ui -- --watch'", + "build:watch": "concurrently -n widget,iframe 'npm:build:main -- --watch' 'npm:build:ui -- --watch --mode development'", "lint": "concurrently 'npm:lint:*'", "lint:eslint": "eslint .", "lint:stylelint": "stylelint ui-src/**.css", diff --git a/plugin-src/transformers/partials/transformRotationAndPosition.ts b/plugin-src/transformers/partials/transformRotationAndPosition.ts index 2520580..5511d8c 100644 --- a/plugin-src/transformers/partials/transformRotationAndPosition.ts +++ b/plugin-src/transformers/partials/transformRotationAndPosition.ts @@ -1,5 +1,5 @@ import { translateRotation, translateZeroRotation } from '@plugin/translators'; -import { applyInverseRotation, getRotation, hasRotation } from '@plugin/utils'; +import { applyInverseRotation, getRotation, isTransformed } from '@plugin/utils'; import { ShapeBaseAttributes, ShapeGeomAttributes } from '@ui/lib/types/shapes/shape'; @@ -8,10 +8,6 @@ export const transformRotation = ( ): Pick => { const rotation = getRotation(node.absoluteTransform); - if (!hasRotation(rotation)) { - return translateZeroRotation(); - } - return translateRotation(node.absoluteTransform, rotation); }; @@ -23,7 +19,10 @@ export const transformRotationAndPosition = ( const y = node.absoluteTransform[1][2]; const rotation = getRotation(node.absoluteTransform); - if (!hasRotation(rotation) || !node.absoluteBoundingBox) { + if ( + !node.absoluteBoundingBox || + !isTransformed(node.absoluteTransform, node.absoluteBoundingBox) + ) { return { x, y, diff --git a/plugin-src/translators/vectors/translateCommands.ts b/plugin-src/translators/vectors/translateCommands.ts index dbb696e..553653c 100644 --- a/plugin-src/translators/vectors/translateCommands.ts +++ b/plugin-src/translators/vectors/translateCommands.ts @@ -1,14 +1,12 @@ import { Command } from 'svg-path-parser'; -import { getRotation, hasRotation } from '@plugin/utils'; +import { isTransformed } from '@plugin/utils'; import { translateNonRotatedCommands } from '.'; import { translateRotatedCommands } from './translateRotatedCommands'; export const translateCommands = (node: LayoutMixin, commands: Command[]) => { - const rotation = getRotation(node.absoluteTransform); - - if (hasRotation(rotation) && node.absoluteBoundingBox) { + if (node.absoluteBoundingBox && isTransformed(node.absoluteTransform, node.absoluteBoundingBox)) { return translateRotatedCommands(commands, node.absoluteTransform, node.absoluteBoundingBox); } diff --git a/plugin-src/utils/applyRotation.ts b/plugin-src/utils/applyRotation.ts index 79748c7..e61a43e 100644 --- a/plugin-src/utils/applyRotation.ts +++ b/plugin-src/utils/applyRotation.ts @@ -1,8 +1,6 @@ import { ClosePath, CurveTo, Segment } from '@ui/lib/types/shapes/pathShape'; import { Point } from '@ui/lib/types/utils/point'; -const ROTATION_TOLERANCE = 0.000001; - export const applyRotation = (point: Point, transform: Transform, boundingBox: Rect): Point => { const centerPoint = calculateCenter(boundingBox); @@ -61,7 +59,13 @@ export const applyInverseRotation = ( export const getRotation = (transform: Transform): number => Math.acos(transform[0][0]) * (180 / Math.PI); -export const hasRotation = (rotation: number): boolean => rotation > ROTATION_TOLERANCE; +export const isTransformed = (transform: Transform, boundingBox: Rect | null): boolean => { + if (!boundingBox) { + return false; + } + + return transform[0][2] !== boundingBox.x || transform[1][2] !== boundingBox.y; +}; const inverseMatrix = (matrix: Transform): Transform => [ [matrix[0][0], matrix[1][0], matrix[0][2]],