1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
import { delimiter } from '../modules/core/regex.js'
import SVGArray from './SVGArray.js'
import Box from './Box.js'
import Matrix from './Matrix.js'
export default class PointArray extends SVGArray {
// Convert array to string
toString () {
// convert to a poly point string
for (var i = 0, il = this.length, array = []; i < il; i++) {
array.push(this[i].join(','))
}
return array.join(' ')
}
// Convert array to line object
toLine () {
return {
x1: this[0][0],
y1: this[0][1],
x2: this[1][0],
y2: this[1][1]
}
}
// Parse point string and flat array
parse (array = [ 0, 0 ]) {
var points = []
// if it is an array, we flatten it and therefore clone it to 1 depths
if (array instanceof Array) {
array = Array.prototype.concat.apply([], array)
} else { // Else, it is considered as a string
// parse points
array = array.trim().split(delimiter).map(parseFloat)
}
// validate points - https://svgwg.org/svg2-draft/shapes.html#DataTypePoints
// Odd number of coordinates is an error. In such cases, drop the last odd coordinate.
if (array.length % 2 !== 0) array.pop()
// wrap points in two-tuples
for (var i = 0, len = array.length; i < len; i = i + 2) {
points.push([ array[i], array[i + 1] ])
}
return points
}
transform (m) {
return this.clone().transformO(m)
}
// transform points with matrix (similar to Point.transform)
transformO (m) {
if (!Matrix.isMatrixLike(m)) {
m = new Matrix(m)
}
for (let i = this.length; i--;) {
// Perform the matrix multiplication
const [ x, y ] = this[i]
this[i][0] = m.a * x + m.c * y + m.e
this[i][1] = m.b * x + m.d * y + m.f
}
return this
}
// Move point string
move (x, y) {
var box = this.bbox()
// get relative offset
x -= box.x
y -= box.y
// move every point
if (!isNaN(x) && !isNaN(y)) {
for (var i = this.length - 1; i >= 0; i--) {
this[i] = [ this[i][0] + x, this[i][1] + y ]
}
}
return this
}
// Resize poly string
size (width, height) {
var i
var box = this.bbox()
// recalculate position of all points according to new size
for (i = this.length - 1; i >= 0; i--) {
if (box.width) this[i][0] = ((this[i][0] - box.x) * width) / box.width + box.x
if (box.height) this[i][1] = ((this[i][1] - box.y) * height) / box.height + box.y
}
return this
}
// Get bounding box of points
bbox () {
var maxX = -Infinity
var maxY = -Infinity
var minX = Infinity
var minY = Infinity
this.forEach(function (el) {
maxX = Math.max(el[0], maxX)
maxY = Math.max(el[1], maxY)
minX = Math.min(el[0], minX)
minY = Math.min(el[1], minY)
})
return new Box(minX, minY, maxX - minX, maxY - minY)
}
}
|