Skip to content

Commit 8518b7a

Browse files
authored
✨Css transform (#30)
* ✨ feat: Add matrix parsing
1 parent 952feab commit 8518b7a

File tree

5 files changed

+63
-3
lines changed

5 files changed

+63
-3
lines changed

src/model/Base/BaseLayer.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,15 @@ abstract class BaseLayer {
148148
this.frame.left = left;
149149
}
150150

151+
get rotation() {
152+
return this.frame.rotation;
153+
}
154+
155+
set rotation(deg) {
156+
console.log(deg);
157+
this.frame.rotation = deg;
158+
}
159+
151160
setFixedWidthAndHeight() {
152161
this.setResizingConstraint(
153162
ResizingConstraint.Width,

src/model/Base/Frame.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ class Frame {
2424

2525
height: number = 0;
2626

27+
/**
28+
* 旋转角度
29+
*/
30+
rotation: number = 0;
31+
2732
get right() {
2833
return this.x + this.width;
2934
}

src/model/Layer/Rectangle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class Rectangle extends BaseLayer {
7373
layerListExpandedType: 0,
7474
nameIsFixed: false,
7575
resizingType: 0,
76-
rotation: 0,
76+
rotation: this.rotation,
7777
shouldBreakMaskChain: false,
7878
clippingMaskMode: 0,
7979
isLocked: false,

src/parser/pseudoShape.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Rectangle, Frame } from '../model';
22
import { parseToShape } from './shape';
33
import { isVisibleShape } from '../utils/visibility';
4+
import { matrixToRotation } from '../utils/matrix';
45

56
/**
67
* 解析图形类伪类
@@ -25,6 +26,9 @@ export const parsePseudoToShape = async (
2526
if (pseudoEl.position === 'absolute') {
2627
x += parseFloat(pseudoEl.left);
2728
y += parseFloat(pseudoEl.top);
29+
const { borderTopWidth, borderLeftWidth } = getComputedStyle(node);
30+
x += parseFloat(borderLeftWidth);
31+
y += parseFloat(borderTopWidth);
2832
}
2933

3034
rect.frame = new Frame({
@@ -38,12 +42,24 @@ export const parsePseudoToShape = async (
3842

3943
const { transform } = pseudoEl;
4044
if (transform !== 'none') {
41-
// TODO 如何使用 将 transform 转换到 对象的 frame 上 ?
4245
// transform: rotate(45deg) scale(1) translate(-50%, -50%);
4346
// ↓↓↓
4447
// matrix(0.707107, 0.707107, -0.707107, 0.707107, 1.41421, -4.94975)
4548
// ↓↓↓
46-
// ???
49+
const params = /matrix\((.*)\)/.exec(transform)?.[1].split(',');
50+
51+
// 将 transform 转换到对象的 frame 上
52+
if (params) {
53+
const [a, b, c, d, e, f] = params.map(parseFloat);
54+
// 偏移 X 和 Y
55+
rect.x += e;
56+
rect.y += f;
57+
// 解析旋转角度
58+
const rotation = matrixToRotation(a, b, c, d);
59+
// TODO 有待研究
60+
// 很奇怪 这里需要用负才能转成正的值
61+
rect.rotation = -rotation;
62+
}
4763
}
4864

4965
if (isVisibleShape(<Rectangle>rect)) return rect;

src/utils/matrix.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* 解析matrix矩阵,0°-360°,返回旋转角度
3+
* 当a=b||-a=b,0<=deg<=180
4+
* 当-a+b=180,180<=deg<=270
5+
* 当a+b=180,270<=deg<=360
6+
*
7+
* 当0<=deg<=180,deg=d;
8+
* 当180<deg<=270,deg=180+c;
9+
* 当270<deg<=360,deg=360-(c||d);
10+
* */
11+
export const matrixToRotation = (
12+
a: number,
13+
b: number,
14+
c: number,
15+
d: number,
16+
) => {
17+
const aa = Math.round((180 * Math.asin(a)) / Math.PI);
18+
const bb = Math.round((180 * Math.acos(b)) / Math.PI);
19+
const cc = Math.round((180 * Math.asin(c)) / Math.PI);
20+
const dd = Math.round((180 * Math.acos(d)) / Math.PI);
21+
let deg = 0;
22+
if (aa === bb || -aa === bb) {
23+
deg = dd;
24+
} else if (-aa + bb === 180) {
25+
deg = 180 + cc;
26+
} else if (aa + bb === 180) {
27+
deg = 360 - cc || 360 - dd;
28+
}
29+
return deg >= 360 ? 0 : deg;
30+
};

0 commit comments

Comments
 (0)