Skip to content

Commit 99d1947

Browse files
authored
Merge pull request #79 from armano2/fix/correct-skew-x-y
fix: correct skew functions to use tan for angle calculations
2 parents 995b48e + 9c583f0 commit 99d1947

File tree

3 files changed

+53
-16
lines changed

3 files changed

+53
-16
lines changed

src/SVGPathDataTransformer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,12 +571,12 @@ function SCALE(dX: number, dY = dX) {
571571

572572
function SKEW_X(a: number) {
573573
assertNumbers(a);
574-
return MATRIX(1, 0, Math.atan(a), 1, 0, 0);
574+
return MATRIX(1, 0, Math.tan(a), 1, 0, 0);
575575
}
576576

577577
function SKEW_Y(a: number) {
578578
assertNumbers(a);
579-
return MATRIX(1, Math.atan(a), 0, 1, 0, 0);
579+
return MATRIX(1, Math.tan(a), 0, 1, 0, 0);
580580
}
581581

582582
function X_AXIS_SYMMETRY(xOffset = 0) {

src/tests/arc.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,13 @@ describe('Transforming elliptical arc commands', () => {
278278
);
279279
});
280280

281-
test('should skew', () => {
281+
test('should skew by -45deg', () => {
282+
function degToRad(deg: number): number {
283+
return deg * (Math.PI / 180);
284+
}
285+
282286
assertDeepCloseTo(
283-
new SVGPathData('M 0,0 A 50,100 0 0 1 50,100z').skewX(Math.tan(-1))
287+
new SVGPathData('M 0,0 A 50,100 0 0 1 50,100z').skewX(degToRad(-45))
284288
.commands,
285289
new SVGPathData('M 0,0 A 34.2,146.0 48.6 0 1 -50,100 Z').commands,
286290
0.1,

src/tests/skew.test.ts

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import { describe, test, expect } from '@jest/globals';
22
import { SVGPathData } from '../index.js';
33
import { assertThrows } from './testUtils.js';
44

5+
function degToRad(deg: number): number {
6+
return deg * (Math.PI / 180);
7+
}
8+
59
describe('X axis skew', () => {
610
test('should fail with bad args', () => {
711
assertThrows(
@@ -15,21 +19,36 @@ describe('X axis skew', () => {
1519
);
1620
});
1721

18-
test('should work with relative path', () => {
22+
test('should work with relative path | 90deg', () => {
23+
expect(
24+
new SVGPathData('m100 75l-50 -45l0 90z').skewX(degToRad(90)).encode(),
25+
).toEqual(
26+
'm1224842951489652700 75l-734905770893791600 -45l1469811541787583200 90z',
27+
);
28+
});
29+
30+
test('should work with absolute path | 90deg', () => {
1931
expect(
20-
new SVGPathData('m100 75l-50 -45l0 90z').skewX(Math.PI / 2).encode(),
32+
new SVGPathData('M 100,75 50,30 50,120 z').skewX(degToRad(90)).encode(),
2133
).toEqual(
22-
'm175.29136163904155 75l-95.17481698342493 -45l90.34963396684985 90z',
34+
'M1224842951489652700 75L489937180595861200 30L1959748722383444500 120z',
2335
);
2436
});
2537

26-
test('should work with absolute path', () => {
38+
test('should work with relative path | 30deg', () => {
2739
expect(
28-
new SVGPathData('M 100,75 50,30 50,120 z').skewX(Math.PI / 2).encode(),
40+
new SVGPathData('m100 75l-50 -45l0 90z').skewX(degToRad(30)).encode(),
2941
).toEqual(
30-
'M175.29136163904155 75L80.11654465561662 30L170.46617862246646 120z',
42+
'm143.30127018922192 75l-75.98076211353316 -45l51.96152422706631 90z',
3143
);
3244
});
45+
test('should work with absolute path | 30deg', () => {
46+
expect(
47+
new SVGPathData('M 100,75 50,30 50,120 z').skewX(degToRad(30)).encode(),
48+
).toEqual(
49+
'M143.30127018922192 75L67.32050807568876 30L119.28203230275508 120z',
50+
);
51+
})
3352
});
3453

3554
describe('Y axis skew', () => {
@@ -45,17 +64,31 @@ describe('Y axis skew', () => {
4564
);
4665
});
4766

48-
test('should work with relative path', () => {
67+
test('should work with relative path | 90deg', () => {
4968
expect(
50-
new SVGPathData('m100 75l-50 -45l0 90z').skewY(Math.PI / 2).encode(),
51-
).toEqual('m100 175.3884821853887l-50 -95.19424109269436l0 90z');
69+
new SVGPathData('m100 75l-50 -45l0 90z').skewY(degToRad(90)).encode(),
70+
).toEqual('m100 1633123935319537000l-50 -816561967659768400l0 90z');
5271
});
5372

54-
test('should work with absolute path', () => {
73+
test('should work with absolute path | 90deg', () => {
5574
expect(
56-
new SVGPathData('M 100,75 50,30 50,120 z').skewY(Math.PI / 2).encode(),
75+
new SVGPathData('M 100,75 50,30 50,120 z').skewY(degToRad(90)).encode(),
5776
).toEqual(
58-
'M100 175.3884821853887L50 80.19424109269436L50 170.19424109269437z',
77+
'M100 1633123935319537000L50 816561967659768400L50 816561967659768600z',
5978
);
6079
});
80+
81+
test('should work with relative path | 30deg', () => {
82+
expect(
83+
new SVGPathData('m100 75l-50 -45l0 90z').skewY(degToRad(30)).encode(),
84+
).toEqual('m100 132.73502691896257l-50 -73.86751345948129l0 90z');
85+
});
86+
87+
test('should work with absolute path | 30deg', () => {
88+
expect(
89+
new SVGPathData('M 100,75 50,30 50,120 z').skewY(degToRad(30)).encode(),
90+
).toEqual(
91+
'M100 132.73502691896257L50 58.86751345948129L50 148.8675134594813z',
92+
);
93+
})
6194
});

0 commit comments

Comments
 (0)