Skip to content

Commit

Permalink
Declare Path.transform and Path.toSVG and their tests
Browse files Browse the repository at this point in the history
  • Loading branch information
baku89 committed Nov 28, 2023
1 parent 6a6a686 commit 274ccd3
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
20 changes: 20 additions & 0 deletions src/Path.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import '../jest.setup'

import {Path} from './Path'

describe('Path', () => {
it('should compute `toSVG` correctly', () => {
const path: Path = [
['M', [0, 0]],
['L', [1, 1]],
['L', [2, 2]],
['Q', [3, 3], [4, 4]],
['A', [1, 1], 1, false, true, [5, 5]],
['Z'],
]

expect(Path.toSVG(path)).toEqual(
'M 0,0 L 1,1 L 2,2 Q 3,3 4,4 A 1,1 1 0 1 5,5 Z'
)
})
})
57 changes: 55 additions & 2 deletions src/Path.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {vec2} from 'linearly'
import {mat2d, vec2} from 'linearly'

import {toFixedSimple} from './utils'

// Line commands
export type CommandM = ['M', end: vec2]
Expand Down Expand Up @@ -37,4 +39,55 @@ export type Command =

export type Path = Command[]

export namespace Path {}
export namespace Path {
export function transform(path: Path, matrix: mat2d): Path {
return path.map(([command, ...points]) => {
switch (command) {
case 'M':
case 'L':
case 'Q':
case 'T':
case 'C':
case 'S':
return [
command,
...(points as vec2[]).map(p => vec2.transformMat2d(p, matrix)),
]
case 'H':
return [
command,
vec2.transformMat2d([points[0] as number, 0], matrix)[0],
]
case 'V':
return [
command,
vec2.transformMat2d([0, points[0] as number], matrix)[0],
]
case 'A':
throw new Error('Not implemented')
case 'Z':
return ['Z']
}
}) as Path
}

export function toSVG(path: Path, fractionDigits = 2): string {
return path
.map(([command, ...ps]) => {
const strs = ps.map(p => {
if (typeof p === 'number') {
return toFixedSimple(p, fractionDigits)
} else if (typeof p === 'boolean') {
return p ? '1' : '0'
} else {
const x = toFixedSimple(p[0], fractionDigits)
const y = toFixedSimple(p[1], fractionDigits)
return `${x},${y}`
}
})

return [command, ...strs].join(' ')
})
.join(' ')
}
}

0 comments on commit 274ccd3

Please sign in to comment.