Skip to content

Commit

Permalink
Allow rotation for Ellipses, Rectangles and Texts
Browse files Browse the repository at this point in the history
  • Loading branch information
jordisala1991 committed May 29, 2024
1 parent fa1d25a commit ea425a6
Show file tree
Hide file tree
Showing 17 changed files with 108 additions and 23 deletions.
1 change: 1 addition & 0 deletions plugin-src/transformers/partials/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './transformDimensionAndPosition';
export * from './transformEffects';
export * from './transformFills';
export * from './transformProportion';
export * from './transformRotationAndPosition';
export * from './transformSceneNode';
export * from './transformStrokes';
export * from './transformText';
Expand Down
2 changes: 1 addition & 1 deletion plugin-src/transformers/partials/transformBlend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ShapeAttributes } from '@ui/lib/types/shapes/shape';

export const transformBlend = (
node: SceneNodeMixin & MinimalBlendMixin
): Partial<ShapeAttributes> => {
): Pick<ShapeAttributes, 'blendMode' | 'opacity'> => {
return {
blendMode: translateBlendMode(node.blendMode),
opacity: !node.visible ? 0 : node.opacity // @TODO: check this. If we use the property hidden and it's hidden, it won't export
Expand Down
2 changes: 1 addition & 1 deletion plugin-src/transformers/partials/transformCornerRadius.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const isRectangleCornerMixin = (

export const transformCornerRadius = (
node: CornerMixin | (CornerMixin & RectangleCornerMixin)
): Partial<ShapeAttributes> | undefined => {
): Pick<ShapeAttributes, 'r1' | 'r2' | 'r3' | 'r4'> | Pick<ShapeAttributes, 'rx'> | undefined => {
if (isRectangleCornerMixin(node)) {
return {
r1: node.topLeftRadius,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ import { getBoundingBox } from '@plugin/utils';

import { ShapeGeomAttributes } from '@ui/lib/types/shapes/shape';

export const transformDimension = (
node: DimensionAndPositionMixin
): Pick<ShapeGeomAttributes, 'width' | 'height'> => {
return {
width: node.width,
height: node.height
};
};

export const transformDimensionAndPosition = (
node: DimensionAndPositionMixin,
baseX: number,
Expand Down
2 changes: 1 addition & 1 deletion plugin-src/transformers/partials/transformEffects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { translateBlurEffects, translateShadowEffects } from '@plugin/translator

import { ShapeAttributes } from '@ui/lib/types/shapes/shape';

export const transformEffects = (node: BlendMixin): Partial<ShapeAttributes> => {
export const transformEffects = (node: BlendMixin): Pick<ShapeAttributes, 'shadow' | 'blur'> => {
return {
shadow: translateShadowEffects(node.effects),
blur: translateBlurEffects(node.effects)
Expand Down
2 changes: 1 addition & 1 deletion plugin-src/transformers/partials/transformFills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ShapeAttributes } from '@ui/lib/types/shapes/shape';

export const transformFills = async (
node: MinimalFillsMixin & DimensionAndPositionMixin
): Promise<Partial<ShapeAttributes>> => {
): Promise<Pick<ShapeAttributes, 'fills'>> => {
return {
fills: await translateFills(node.fills)
};
Expand Down
2 changes: 1 addition & 1 deletion plugin-src/transformers/partials/transformProportion.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ShapeAttributes } from '@ui/lib/types/shapes/shape';

export const transformProportion = (node: LayoutMixin): Partial<ShapeAttributes> => {
export const transformProportion = (node: LayoutMixin): Pick<ShapeAttributes, 'proportionLock'> => {
return {
proportionLock: node.constrainProportions
};
Expand Down
68 changes: 68 additions & 0 deletions plugin-src/transformers/partials/transformRotationAndPosition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { ShapeBaseAttributes, ShapeGeomAttributes } from '@ui/lib/types/shapes/shape';
import { Point } from '@ui/lib/types/utils/point';

export const transformRotationAndPosition = (
node: LayoutMixin,
baseX: number,
baseY: number
): Pick<ShapeBaseAttributes, 'transform' | 'transformInverse' | 'rotation'> &
Pick<ShapeGeomAttributes, 'x' | 'y'> => {
const rotation = node.rotation;
const x = node.x + baseX;
const y = node.y + baseY;

if (rotation === 0 || !node.absoluteBoundingBox) {
return {
x,
y,
rotation,
transform: undefined,
transformInverse: undefined
};
}

const point = getRotatedPoint({ x, y }, node.absoluteTransform, node.absoluteBoundingBox);

return {
...point,
rotation: -rotation < 0 ? -rotation + 360 : -rotation,
transform: {
a: node.absoluteTransform[0][0],
b: node.absoluteTransform[1][0],
c: node.absoluteTransform[0][1],
d: node.absoluteTransform[1][1],
e: 0,
f: 0
},
transformInverse: {
a: node.absoluteTransform[0][0],
b: node.absoluteTransform[0][1],
c: node.absoluteTransform[1][0],
d: node.absoluteTransform[1][1],
e: 0,
f: 0
}
};
};

const getRotatedPoint = (point: Point, transform: Transform, boundingBox: Rect): Point => {
const centerPoint = {
x: boundingBox.x + boundingBox.width / 2,
y: boundingBox.y + boundingBox.height / 2
};

const relativePoint = {
x: point.x - centerPoint.x,
y: point.y - centerPoint.y
};

const rotatedPoint = {
x: relativePoint.x * transform[0][0] + relativePoint.y * transform[1][0],
y: relativePoint.x * transform[0][1] + relativePoint.y * transform[1][1]
};

return {
x: centerPoint.x + rotatedPoint.x,
y: centerPoint.y + rotatedPoint.y
};
};
4 changes: 3 additions & 1 deletion plugin-src/transformers/partials/transformSceneNode.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ShapeAttributes } from '@ui/lib/types/shapes/shape';

export const transformSceneNode = (node: SceneNodeMixin): Partial<ShapeAttributes> => {
export const transformSceneNode = (
node: SceneNodeMixin
): Pick<ShapeAttributes, 'blocked' | 'hidden'> => {
return {
blocked: node.locked,
hidden: false // @TODO: check this. it won't export if we hide it
Expand Down
4 changes: 2 additions & 2 deletions plugin-src/transformers/partials/transformStrokes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const hasFillGeometry = (node: GeometryMixin): boolean => {

export const transformStrokes = async (
node: GeometryMixin | (GeometryMixin & IndividualStrokesMixin)
): Promise<Partial<ShapeAttributes>> => {
): Promise<Pick<ShapeAttributes, 'strokes'>> => {
const vectorNetwork = isVectorLike(node) ? node.vectorNetwork : undefined;

const strokeCaps = (stroke: Stroke) => {
Expand All @@ -38,7 +38,7 @@ export const transformStrokesFromVector = async (
node: VectorNode,
vector: Command[],
vectorRegion: VectorRegion | undefined
): Promise<Partial<ShapeAttributes>> => {
): Promise<Pick<ShapeAttributes, 'strokes'>> => {
const strokeCaps = (stroke: Stroke) => {
if (vectorRegion !== undefined) return stroke;

Expand Down
6 changes: 4 additions & 2 deletions plugin-src/transformers/partials/transformText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import { transformFills } from '@plugin/transformers/partials';
import { transformTextStyle, translateStyleTextSegments } from '@plugin/translators/text';
import { translateGrowType, translateVerticalAlign } from '@plugin/translators/text/properties';

import { TextShape } from '@ui/lib/types/shapes/textShape';
import { TextAttributes, TextShape } from '@ui/lib/types/shapes/textShape';

export const transformText = async (node: TextNode): Promise<Partial<TextShape>> => {
export const transformText = async (
node: TextNode
): Promise<TextAttributes & Pick<TextShape, 'growType'>> => {
const styledTextSegments = node.getStyledTextSegments([
'fontName',
'fontSize',
Expand Down
6 changes: 4 additions & 2 deletions plugin-src/transformers/transformEllipseNode.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {
transformBlend,
transformDimensionAndPosition,
transformDimension,
transformEffects,
transformFills,
transformProportion,
transformRotationAndPosition,
transformSceneNode,
transformStrokes
} from '@plugin/transformers/partials';
Expand All @@ -21,7 +22,8 @@ export const transformEllipseNode = async (
...(await transformFills(node)),
...transformEffects(node),
...(await transformStrokes(node)),
...transformDimensionAndPosition(node, baseX, baseY),
...transformDimension(node),
...transformRotationAndPosition(node, baseX, baseY),
...transformSceneNode(node),
...transformBlend(node),
...transformProportion(node)
Expand Down
6 changes: 4 additions & 2 deletions plugin-src/transformers/transformRectangleNode.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {
transformBlend,
transformCornerRadius,
transformDimensionAndPosition,
transformDimension,
transformEffects,
transformFills,
transformProportion,
transformRotationAndPosition,
transformSceneNode,
transformStrokes
} from '@plugin/transformers/partials';
Expand All @@ -22,7 +23,8 @@ export const transformRectangleNode = async (
...(await transformFills(node)),
...transformEffects(node),
...(await transformStrokes(node)),
...transformDimensionAndPosition(node, baseX, baseY),
...transformDimension(node),
...transformRotationAndPosition(node, baseX, baseY),
...transformSceneNode(node),
...transformBlend(node),
...transformProportion(node),
Expand Down
6 changes: 4 additions & 2 deletions plugin-src/transformers/transformTextNode.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {
transformBlend,
transformDimensionAndPosition,
transformDimension,
transformEffects,
transformProportion,
transformRotationAndPosition,
transformSceneNode,
transformStrokes,
transformText
Expand All @@ -19,7 +20,8 @@ export const transformTextNode = async (
type: 'text',
name: node.name,
...(await transformText(node)),
...transformDimensionAndPosition(node, baseX, baseY),
...transformDimension(node),
...transformRotationAndPosition(node, baseX, baseY),
...transformEffects(node),
...transformSceneNode(node),
...transformBlend(node),
Expand Down
5 changes: 1 addition & 4 deletions plugin-src/translators/text/translateStyleTextSegments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ export const translateStyleTextSegments = async (
return translateParagraphProperties(node, partials);
};

export const transformTextStyle = (
node: TextNode,
segment: StyleTextSegment
): Partial<TextStyle> => {
export const transformTextStyle = (node: TextNode, segment: StyleTextSegment): TextStyle => {
return {
...translateFontId(segment.fontName, segment.fontWeight),
fontFamily: segment.fontName.family,
Expand Down
4 changes: 2 additions & 2 deletions plugin-src/translators/translateStrokes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const translateStrokes = async (
node: MinimalStrokesMixin | (MinimalStrokesMixin & IndividualStrokesMixin),
strokeCaps: (stroke: Stroke) => Stroke = stroke => stroke
): Promise<Stroke[]> => {
const sharedStrokeProperties: Partial<Stroke> = {
const sharedStrokeProperties: Stroke = {
strokeWidth: translateStrokeWeight(node),
strokeAlignment: translateStrokeAlignment(node.strokeAlign),
strokeStyle: node.dashPattern.length ? 'dashed' : 'solid'
Expand All @@ -22,7 +22,7 @@ export const translateStrokes = async (

export const translateStroke = async (
paint: Paint,
sharedStrokeProperties: Partial<Stroke>,
sharedStrokeProperties: Stroke,
strokeCaps: (stroke: Stroke) => Stroke,
firstStroke: boolean
): Promise<Stroke> => {
Expand Down
2 changes: 1 addition & 1 deletion ui-src/lib/types/shapes/textShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type TextShape = ShapeBaseAttributes &
TextAttributes &
LayoutChildAttributes;

type TextAttributes = {
export type TextAttributes = {
type?: 'text';
content?: TextContent;
};
Expand Down

0 comments on commit ea425a6

Please sign in to comment.