-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement rotation for vector lines (#160)
* Implement rotation for vector lines * wip * Improve rotations for lines * add changelog * add layout attributes to line
- Loading branch information
1 parent
b85a4f7
commit af81fc7
Showing
14 changed files
with
235 additions
and
138 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"penpot-exporter": minor | ||
--- | ||
|
||
Apply rotations to lines |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { | ||
transformBlend, | ||
transformConstraints, | ||
transformEffects, | ||
transformFigmaIds, | ||
transformLayoutAttributes, | ||
transformPosition, | ||
transformProportion, | ||
transformSceneNode, | ||
transformStrokes | ||
} from '@plugin/transformers/partials'; | ||
import { translateLineNode } from '@plugin/translators/vectors'; | ||
|
||
import { PathShape } from '@ui/lib/types/shapes/pathShape'; | ||
|
||
/** | ||
* In order to match the normal representation of a line in Penpot, we will assume that | ||
* the line is never rotated, so we calculate its normal position. | ||
* | ||
* To represent the line rotated we do take into account the rotation of the line, but only in its content. | ||
*/ | ||
export const transformLineNode = (node: LineNode, baseX: number, baseY: number): PathShape => { | ||
return { | ||
type: 'path', | ||
name: node.name, | ||
content: translateLineNode(node, baseX, baseY), | ||
...transformFigmaIds(node), | ||
...transformStrokes(node), | ||
...transformEffects(node), | ||
...transformPosition(node, baseX, baseY), | ||
...transformSceneNode(node), | ||
...transformBlend(node), | ||
...transformProportion(node), | ||
...transformLayoutAttributes(node), | ||
...transformConstraints(node) | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './translateCommandsToSegments'; | ||
export * from './translateLineNode'; | ||
export * from './translateVectorPaths'; | ||
export * from './translateWindingRule'; |
57 changes: 57 additions & 0 deletions
57
plugin-src/translators/vectors/translateCommandsToSegments.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { Command, CurveToCommand, LineToCommand, MoveToCommand } from 'svg-path-parser'; | ||
|
||
import { Segment } from '@ui/lib/types/shapes/pathShape'; | ||
|
||
export const translateCommandsToSegments = ( | ||
commands: Command[], | ||
baseX: number, | ||
baseY: number | ||
): Segment[] => { | ||
return commands.map(command => { | ||
switch (command.command) { | ||
case 'moveto': | ||
return translateMoveToCommand(command, baseX, baseY); | ||
case 'lineto': | ||
return translateLineToCommand(command, baseX, baseY); | ||
case 'curveto': | ||
return translateCurveToCommand(command, baseX, baseY); | ||
case 'closepath': | ||
default: | ||
return { | ||
command: 'close-path' | ||
}; | ||
} | ||
}); | ||
}; | ||
|
||
const translateMoveToCommand = (command: MoveToCommand, baseX: number, baseY: number): Segment => { | ||
return { | ||
command: 'move-to', | ||
params: { x: command.x + baseX, y: command.y + baseY } | ||
}; | ||
}; | ||
|
||
const translateLineToCommand = (command: LineToCommand, baseX: number, baseY: number): Segment => { | ||
return { | ||
command: 'line-to', | ||
params: { x: command.x + baseX, y: command.y + baseY } | ||
}; | ||
}; | ||
|
||
const translateCurveToCommand = ( | ||
command: CurveToCommand, | ||
baseX: number, | ||
baseY: number | ||
): Segment => { | ||
return { | ||
command: 'curve-to', | ||
params: { | ||
c1x: command.x1 + baseX, | ||
c1y: command.y1 + baseY, | ||
c2x: command.x2 + baseX, | ||
c2y: command.y2 + baseY, | ||
x: command.x + baseX, | ||
y: command.y + baseY | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,65 @@ | ||
export const translateLineNode = (node: LineNode): VectorPaths => { | ||
const commands = [ | ||
import { Command } from 'svg-path-parser'; | ||
|
||
import { applyInverseRotation, applyRotation, hasRotation } from '@plugin/utils'; | ||
|
||
import { Segment } from '@ui/lib/types/shapes/pathShape'; | ||
|
||
import { translateCommandsToSegments } from '.'; | ||
|
||
export const translateLineNode = (node: LineNode, baseX: number, baseY: number): Segment[] => { | ||
if (!hasRotation(node.rotation) || !node.absoluteBoundingBox) { | ||
return translateCommandsToSegments( | ||
[ | ||
{ | ||
x: 0, | ||
y: 0, | ||
command: 'moveto', | ||
code: 'M' | ||
}, | ||
{ | ||
x: node.width, | ||
y: 0, | ||
command: 'lineto', | ||
code: 'L' | ||
} | ||
], | ||
baseX + node.x, | ||
baseY + node.y | ||
); | ||
} | ||
|
||
const startPoint = applyRotation( | ||
{ x: 0, y: 0 }, | ||
node.absoluteTransform, | ||
node.absoluteBoundingBox | ||
); | ||
|
||
const endPoint = applyRotation( | ||
{ x: node.width, y: 0 }, | ||
node.absoluteTransform, | ||
node.absoluteBoundingBox | ||
); | ||
|
||
const commands: Command[] = [ | ||
{ | ||
x: startPoint.x, | ||
y: startPoint.y, | ||
command: 'moveto', | ||
code: 'M', | ||
x: 0, | ||
y: 0 | ||
code: 'M' | ||
}, | ||
{ | ||
x: endPoint.x, | ||
y: endPoint.y, | ||
command: 'lineto', | ||
code: 'L', | ||
x: node.width, | ||
y: node.height | ||
code: 'L' | ||
} | ||
]; | ||
|
||
return [ | ||
{ | ||
windingRule: 'NONE', | ||
data: commands.reduce((acc, { code, x, y }) => acc + `${code} ${x} ${y}`, '') | ||
} | ||
]; | ||
const referencePoint = applyInverseRotation( | ||
{ x: node.x, y: node.y }, | ||
node.absoluteTransform, | ||
node.absoluteBoundingBox | ||
); | ||
|
||
return translateCommandsToSegments(commands, baseX + referencePoint.x, baseY + referencePoint.y); | ||
}; |
Oops, something went wrong.