mirror of
https://github.com/penpot/penpot-exporter-figma-plugin.git
synced 2025-01-18 05:22:28 -05:00
Merge branch 'dev' into feature/upgrade-penpot-2.0
This commit is contained in:
commit
5b65f5dc7e
8 changed files with 134 additions and 33 deletions
18
package-lock.json
generated
18
package-lock.json
generated
|
@ -9,7 +9,6 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "MPL2.0",
|
"license": "MPL2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@figma-plugin/helpers": "^0.15",
|
|
||||||
"react": "^18.2",
|
"react": "^18.2",
|
||||||
"react-dom": "^18.2",
|
"react-dom": "^18.2",
|
||||||
"slugify": "^1.6"
|
"slugify": "^1.6"
|
||||||
|
@ -1164,15 +1163,6 @@
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@figma-plugin/helpers": {
|
|
||||||
"version": "0.15.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@figma-plugin/helpers/-/helpers-0.15.2.tgz",
|
|
||||||
"integrity": "sha512-ggFxoefZKc0D/HJXFHqliLWCLQG3QTbByHqgiSpTK0D76qTDv2fpcF9bytjSMVnc4flD7Rq17tLNP/WmaJt3dA==",
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": "^4.17.15",
|
|
||||||
"matrix-inverse": "^1.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@figma/eslint-plugin-figma-plugins": {
|
"node_modules/@figma/eslint-plugin-figma-plugins": {
|
||||||
"version": "0.15.0",
|
"version": "0.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/@figma/eslint-plugin-figma-plugins/-/eslint-plugin-figma-plugins-0.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@figma/eslint-plugin-figma-plugins/-/eslint-plugin-figma-plugins-0.15.0.tgz",
|
||||||
|
@ -5098,7 +5088,8 @@
|
||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/lodash.merge": {
|
"node_modules/lodash.merge": {
|
||||||
"version": "4.6.2",
|
"version": "4.6.2",
|
||||||
|
@ -5154,11 +5145,6 @@
|
||||||
"url": "https://github.com/sponsors/wooorm"
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/matrix-inverse": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/matrix-inverse/-/matrix-inverse-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-ubaJ6vEJfpsRpOLYLJN3bCW3VbO2t0OtZIfausKiizsPNCvCXsWsLMR8jm4zmi8bSnodp3ht25iqdpSe0wIbxg=="
|
|
||||||
},
|
|
||||||
"node_modules/mdn-data": {
|
"node_modules/mdn-data": {
|
||||||
"version": "2.0.30",
|
"version": "2.0.30",
|
||||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
"build:ui": "vite build --minify esbuild --emptyOutDir=false",
|
"build:ui": "vite build --minify esbuild --emptyOutDir=false",
|
||||||
"build:watch": "concurrently -n widget,iframe \"npm run build:main -- --watch\" \"npm run build:ui -- --watch\"",
|
"build:watch": "concurrently -n widget,iframe \"npm run build:main -- --watch\" \"npm run build:ui -- --watch\"",
|
||||||
"dev": "concurrently -n tsc,build,vite 'npm:tsc:watch' 'npm:build:watch' 'vite'",
|
"dev": "concurrently -n tsc,build,vite 'npm:tsc:watch' 'npm:build:watch' 'vite'",
|
||||||
"watch": "webpack watch",
|
|
||||||
"lint": "concurrently \"npm:lint:*\"",
|
"lint": "concurrently \"npm:lint:*\"",
|
||||||
"lint:eslint": "eslint .",
|
"lint:eslint": "eslint .",
|
||||||
"lint:stylelint": "stylelint ui-src/**.css",
|
"lint:stylelint": "stylelint ui-src/**.css",
|
||||||
|
@ -24,7 +23,6 @@
|
||||||
"author": "Kaleidos",
|
"author": "Kaleidos",
|
||||||
"license": "MPL2.0",
|
"license": "MPL2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@figma-plugin/helpers": "^0.15",
|
|
||||||
"react": "^18.2",
|
"react": "^18.2",
|
||||||
"react-dom": "^18.2",
|
"react-dom": "^18.2",
|
||||||
"slugify": "^1.6"
|
"slugify": "^1.6"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export * from './translateFills';
|
export * from './translateFills';
|
||||||
// export * from './translateGradientLinearFill';
|
export * from './translateGradientLinearFill';
|
||||||
export * from './translateSolidFill';
|
export * from './translateSolidFill';
|
||||||
export * from './translateTextDecoration';
|
export * from './translateTextDecoration';
|
||||||
export * from './translateTextTransform';
|
export * from './translateTextTransform';
|
||||||
|
|
|
@ -1,21 +1,14 @@
|
||||||
import { Fill } from '@ui/lib/types/utils/fill';
|
import { Fill } from '@ui/lib/types/utils/fill';
|
||||||
|
|
||||||
// import { translateGradientLinearFill } from './translateGradientLinearFill';
|
import { translateGradientLinearFill } from './translateGradientLinearFill';
|
||||||
import { translateSolidFill } from './translateSolidFill';
|
import { translateSolidFill } from './translateSolidFill';
|
||||||
|
|
||||||
const translateFill = (
|
const translateFill = (fill: Paint, width: number, height: number): Fill | undefined => {
|
||||||
fill: Paint,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
width: number,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
height: number
|
|
||||||
): Fill | undefined => {
|
|
||||||
switch (fill.type) {
|
switch (fill.type) {
|
||||||
case 'SOLID':
|
case 'SOLID':
|
||||||
return translateSolidFill(fill);
|
return translateSolidFill(fill);
|
||||||
// @TODO: fix this
|
case 'GRADIENT_LINEAR':
|
||||||
// case 'GRADIENT_LINEAR':
|
return translateGradientLinearFill(fill, width, height);
|
||||||
// return translateGradientLinearFill(fill, width, height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error('Color type ' + fill.type + ' not supported yet');
|
console.error('Color type ' + fill.type + ' not supported yet');
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { extractLinearGradientParamsFromTransform } from '@figma-plugin/helpers';
|
|
||||||
|
|
||||||
import { rgbToHex } from '@plugin/utils';
|
import { rgbToHex } from '@plugin/utils';
|
||||||
|
import { calculateLinearGradient } from '@plugin/utils/calculateLinearGradient';
|
||||||
|
|
||||||
import { Fill } from '@ui/lib/types/utils/fill';
|
import { Fill } from '@ui/lib/types/utils/fill';
|
||||||
|
|
||||||
|
@ -9,7 +8,7 @@ export const translateGradientLinearFill = (
|
||||||
width: number,
|
width: number,
|
||||||
height: number
|
height: number
|
||||||
): Fill => {
|
): Fill => {
|
||||||
const points = extractLinearGradientParamsFromTransform(width, height, fill.gradientTransform);
|
const points = calculateLinearGradient(width, height, fill.gradientTransform);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fillColorGradient: {
|
fillColorGradient: {
|
||||||
|
|
6
plugin-src/utils/applyMatrixToPoint.ts
Normal file
6
plugin-src/utils/applyMatrixToPoint.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export const applyMatrixToPoint = (matrix: number[][], point: number[]) => {
|
||||||
|
return [
|
||||||
|
point[0] * matrix[0][0] + point[1] * matrix[0][1] + matrix[0][2],
|
||||||
|
point[0] * matrix[1][0] + point[1] * matrix[1][1] + matrix[1][2]
|
||||||
|
];
|
||||||
|
};
|
23
plugin-src/utils/calculateLinearGradient.ts
Normal file
23
plugin-src/utils/calculateLinearGradient.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { applyMatrixToPoint } from '@plugin/utils/applyMatrixToPoint';
|
||||||
|
import { matrixInvert } from '@plugin/utils/matrixInvert';
|
||||||
|
|
||||||
|
export const calculateLinearGradient = (shapeWidth: number, shapeHeight: number, t: Transform) => {
|
||||||
|
const transform = t.length === 2 ? [...t, [0, 0, 1]] : [...t];
|
||||||
|
const mxInv = matrixInvert(transform);
|
||||||
|
|
||||||
|
if (!mxInv) {
|
||||||
|
return {
|
||||||
|
start: [0, 0],
|
||||||
|
end: [0, 0]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const startEnd = [
|
||||||
|
[0, 0.5],
|
||||||
|
[1, 0.5]
|
||||||
|
].map(p => applyMatrixToPoint(mxInv, p));
|
||||||
|
return {
|
||||||
|
start: [startEnd[0][0] * shapeWidth, startEnd[0][1] * shapeHeight],
|
||||||
|
end: [startEnd[1][0] * shapeWidth, startEnd[1][1] * shapeHeight]
|
||||||
|
};
|
||||||
|
};
|
96
plugin-src/utils/matrixInvert.ts
Normal file
96
plugin-src/utils/matrixInvert.ts
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
export const matrixInvert = (M: number[][]): number[][] | undefined => {
|
||||||
|
// if the matrix isn't square: exit (error)
|
||||||
|
if (M.length !== M[0].length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the identity matrix (I), and a copy (C) of the original
|
||||||
|
const dim = M.length;
|
||||||
|
let i = 0,
|
||||||
|
ii = 0,
|
||||||
|
j = 0,
|
||||||
|
e = 0;
|
||||||
|
const I: number[][] = [],
|
||||||
|
C: number[][] = [];
|
||||||
|
for (i = 0; i < dim; i += 1) {
|
||||||
|
// Create the row
|
||||||
|
I[i] = [];
|
||||||
|
C[i] = [];
|
||||||
|
for (j = 0; j < dim; j += 1) {
|
||||||
|
// if we're on the diagonal, put a 1 (for identity)
|
||||||
|
if (i === j) {
|
||||||
|
I[i][j] = 1;
|
||||||
|
} else {
|
||||||
|
I[i][j] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also, make the copy of the original
|
||||||
|
C[i][j] = M[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform elementary row operations
|
||||||
|
for (i = 0; i < dim; i += 1) {
|
||||||
|
// get the element e on the diagonal
|
||||||
|
e = C[i][i];
|
||||||
|
|
||||||
|
// if we have a 0 on the diagonal (we'll need to swap with a lower row)
|
||||||
|
if (e === 0) {
|
||||||
|
// look through every row below the i'th row
|
||||||
|
for (ii = i + 1; ii < dim; ii += 1) {
|
||||||
|
// if the ii'th row has a non-0 in the i'th col
|
||||||
|
if (C[ii][i] !== 0) {
|
||||||
|
// it would make the diagonal have a non-0 so swap it
|
||||||
|
for (j = 0; j < dim; j++) {
|
||||||
|
e = C[i][j]; // temp store i'th row
|
||||||
|
C[i][j] = C[ii][j]; // replace i'th row by ii'th
|
||||||
|
C[ii][j] = e; // replace ii'th by temp
|
||||||
|
e = I[i][j]; // temp store i'th row
|
||||||
|
I[i][j] = I[ii][j]; // replace i'th row by ii'th
|
||||||
|
I[ii][j] = e; // replace ii'th by temp
|
||||||
|
}
|
||||||
|
// don't bother checking other rows since we've swapped
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// get the new diagonal
|
||||||
|
e = C[i][i];
|
||||||
|
// if it's still 0, not invertable (error)
|
||||||
|
if (e === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale this row down by e (so we have a 1 on the diagonal)
|
||||||
|
for (j = 0; j < dim; j++) {
|
||||||
|
C[i][j] = C[i][j] / e; // apply to original matrix
|
||||||
|
I[i][j] = I[i][j] / e; // apply to identity
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtract this row (scaled appropriately for each row) from ALL of
|
||||||
|
// the other rows so that there will be 0's in this column in the
|
||||||
|
// rows above and below this one
|
||||||
|
for (ii = 0; ii < dim; ii++) {
|
||||||
|
// Only apply to other rows (we want a 1 on the diagonal)
|
||||||
|
if (ii === i) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want to change this element to 0
|
||||||
|
e = C[ii][i];
|
||||||
|
|
||||||
|
// Subtract (the row above(or below) scaled by e) from (the
|
||||||
|
// current row) but start at the i'th column and assume all the
|
||||||
|
// stuff left of diagonal is 0 (which it should be if we made this
|
||||||
|
// algorithm correctly)
|
||||||
|
for (j = 0; j < dim; j++) {
|
||||||
|
C[ii][j] -= e * C[i][j]; // apply to original matrix
|
||||||
|
I[ii][j] -= e * I[i][j]; // apply to identity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we've done all operations, C should be the identity
|
||||||
|
// matrix I should be the inverse:
|
||||||
|
return I;
|
||||||
|
};
|
Loading…
Add table
Reference in a new issue