137 lines
3.2 KiB
JavaScript
137 lines
3.2 KiB
JavaScript
// Map function
|
|
export function map(array, block) {
|
|
let i
|
|
const il = array.length
|
|
const result = []
|
|
|
|
for (i = 0; i < il; i++) {
|
|
result.push(block(array[i]))
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// Filter function
|
|
export function filter(array, block) {
|
|
let i
|
|
const il = array.length
|
|
const 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 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]
|
|
}
|
|
|
|
const descriptiveElements = new Set(['desc', 'metadata', 'title'])
|
|
export const isDescriptive = (element) =>
|
|
descriptiveElements.has(element.nodeName)
|
|
|
|
export const writeDataToDom = (element, data, defaults = {}) => {
|
|
const cloned = { ...data }
|
|
|
|
for (const key in cloned) {
|
|
if (cloned[key].valueOf() === defaults[key]) {
|
|
delete cloned[key]
|
|
}
|
|
}
|
|
|
|
if (Object.keys(cloned).length) {
|
|
element.node.setAttribute('data-svgjs', JSON.stringify(cloned)) // see #428
|
|
} else {
|
|
element.node.removeAttribute('data-svgjs')
|
|
element.node.removeAttribute('svgjs:data')
|
|
}
|
|
}
|