Skip to content

Commit 97f6e72

Browse files
authored
Merge pull request #1034 from ChepteaCatalin/fix-1033
feat(matrix): allow rotating relative to a point different than the origin
2 parents ac1bc40 + 5e9add1 commit 97f6e72

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

src/core/matrix.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,12 @@ export function translate(out: MatrixArray, a: MatrixArray, v: VectorArray): Mat
7979
/**
8080
* 旋转变换
8181
*/
82-
export function rotate(out: MatrixArray, a: MatrixArray, rad: number): MatrixArray {
82+
export function rotate(
83+
out: MatrixArray,
84+
a: MatrixArray,
85+
rad: number,
86+
pivot: VectorArray = [0, 0]
87+
): MatrixArray {
8388
const aa = a[0];
8489
const ac = a[2];
8590
const atx = a[4];
@@ -93,8 +98,8 @@ export function rotate(out: MatrixArray, a: MatrixArray, rad: number): MatrixArr
9398
out[1] = -aa * st + ab * ct;
9499
out[2] = ac * ct + ad * st;
95100
out[3] = -ac * st + ct * ad;
96-
out[4] = ct * atx + st * aty;
97-
out[5] = ct * aty - st * atx;
101+
out[4] = ct * (atx - pivot[0]) + st * (aty - pivot[1]) + pivot[0];
102+
out[5] = ct * (aty - pivot[1]) - st * (atx - pivot[0]) + pivot[1];
98103
return out;
99104
}
100105

src/tool/parseSVG.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,10 @@ function parseTransformAttribute(xmlNode: SVGElement, node: Element): void {
845845
break;
846846
case 'rotate':
847847
// TODO: zrender use different hand in coordinate system.
848-
matrix.rotate(mt, mt, -parseFloat(valueArr[0]) * DEGREE_TO_ANGLE);
848+
matrix.rotate(mt, mt, -parseFloat(valueArr[0]) * DEGREE_TO_ANGLE, [
849+
parseFloat(valueArr[1] || '0'),
850+
parseFloat(valueArr[2] || '0')
851+
]);
849852
break;
850853
case 'skewX':
851854
const sx = Math.tan(parseFloat(valueArr[0]) * DEGREE_TO_ANGLE);

test/ut/spec/core/matrix.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { rotate } from '../../../../src/core/matrix';
2+
3+
describe('matrix', function () {
4+
it('should rotate relative to a pivot point', function () {
5+
const matrix = [
6+
0.9659258262890683, 0.25881904510252074, -0.25881904510252074, 0.9659258262890683,
7+
40.213201392710246, -26.96358986452364
8+
];
9+
const rad = -0.2617993877991494;
10+
const pivot = [122.511, 139.243];
11+
12+
const result = rotate(matrix, matrix, rad, pivot);
13+
14+
expect(result[0]).toBeCloseTo(0.8660254037844387, 5);
15+
expect(result[1]).toBeCloseTo(0.49999999999999994, 5);
16+
expect(result[2]).toBeCloseTo(-0.49999999999999994, 5);
17+
expect(result[3]).toBeCloseTo(0.8660254037844387, 5);
18+
expect(result[4]).toBeCloseTo(86.03486175696463, 5);
19+
expect(result[5]).toBeCloseTo(-42.600475299156585, 5);
20+
});
21+
});

0 commit comments

Comments
 (0)