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
118
119
120
|
// Map function
export function map (array, block) {
var i
var il = array.length
var result = []
for (i = 0; i < il; i++) {
result.push(block(array[i]))
}
return result
}
// Filter function
export function filter (array, block) {
var i
var il = array.length
var result = []
for (i = 0; i < il; i++) {
if (block(array[i])) {
result.push(array[i])
}
}
return result
}
// Degrees to radians
export function radians (d) {
return d % 360 * Math.PI / 180
}
// Radians to degrees
export function degrees (r) {
return r * 180 / Math.PI % 360
}
// Convert dash-separated-string to camelCase
export function camelCase (s) {
return s.toLowerCase().replace(/-(.)/g, function (m, g) {
return g.toUpperCase()
})
}
// Convert camel cased string to dash separated
export function unCamelCase (s) {
return s.replace(/([A-Z])/g, function (m, g) {
return '-' + g.toLowerCase()
})
}
// Capitalize first letter of a string
export function capitalize (s) {
return s.charAt(0).toUpperCase() + s.slice(1)
}
// Calculate proportional width and height values when necessary
export function proportionalSize (element, width, height, box) {
if (width == null || height == null) {
box = box || element.bbox()
if (width == null) {
width = box.width / box.height * height
} else if (height == null) {
height = box.height / box.width * width
}
}
return {
width: width,
height: height
}
}
/**
* This function adds support for string origins.
* It searches for an origin in o.origin o.ox and o.originX.
* This way, origin: {x: 'center', y: 50} can be passed as well as ox: 'center', oy: 50
**/
export function getOrigin (o, element) {
const origin = o.origin
// First check if origin is in ox or originX
let ox = o.ox != null ? o.ox
: o.originX != null ? o.originX
: 'center'
let oy = o.oy != null ? o.oy
: o.originY != null ? o.originY
: 'center'
// Then check if origin was used and overwrite in that case
if (origin != null) {
[ ox, oy ] = Array.isArray(origin) ? origin
: typeof origin === 'object' ? [ origin.x, origin.y ]
: [ origin, origin ]
}
// Make sure to only call bbox when actually needed
const condX = typeof ox === 'string'
const condY = typeof oy === 'string'
if (condX || condY) {
const { height, width, x, y } = element.bbox()
// And only overwrite if string was passed for this specific axis
if (condX) {
ox = ox.includes('left') ? x
: ox.includes('right') ? x + width
: x + width / 2
}
if (condY) {
oy = oy.includes('top') ? y
: oy.includes('bottom') ? y + height
: y + height / 2
}
}
// Return the origin as it is if it wasn't a string
return [ ox, oy ]
}
|