alignSelectedElements = (type, relativeTo) => {
  const selectedElements = svgCanvas.getSelectedElements()
  const bboxes = [] // angles = [];
  const len = selectedElements.length
  if (!len) {
    return
  }
  let minx = Number.MAX_VALUE
  let maxx = Number.MIN_VALUE
  let miny = Number.MAX_VALUE
  let maxy = Number.MIN_VALUE

  const isHorizontalAlign = (type) => ['l', 'c', 'r', 'left', 'center', 'right'].includes(type)
  const isVerticalAlign = (type) => ['t', 'm', 'b', 'top', 'middle', 'bottom'].includes(type)

  for (let i = 0; i < len; ++i) {
    if (!selectedElements[i]) {
      break
    }
    const elem = selectedElements[i]
    bboxes[i] = getStrokedBBoxDefaultVisible([elem])
  }

  // distribute horizontal and vertical align is not support smallest and largest
  if (['smallest', 'largest'].includes(relativeTo) && ['dh', 'distrib_horiz', 'dv', 'distrib_verti'].includes(type)) {
    relativeTo = 'selected'
  }

  switch (relativeTo) {
    case 'smallest':
      if (isHorizontalAlign(type) || isVerticalAlign(type)) {
        const sortedBboxes = bboxes.slice().sort((a, b) => a.width - b.width)
        const minBbox = sortedBboxes[0]
        minx = minBbox.x
        miny = minBbox.y
        maxx = minBbox.x + minBbox.width
        maxy = minBbox.y + minBbox.height
      }
      break
    case 'largest':
      if (isHorizontalAlign(type) || isVerticalAlign(type)) {
        const sortedBboxes = bboxes.slice().sort((a, b) => a.width - b.width)
        const maxBbox = sortedBboxes[bboxes.length - 1]
        minx = maxBbox.x
        miny = maxBbox.y
        maxx = maxBbox.x + maxBbox.width
        maxy = maxBbox.y + maxBbox.height
      }
      break
    case 'page':
      minx = 0
      miny = 0
      maxx = svgCanvas.getContentW()
      maxy = svgCanvas.getContentH()
      break
    default:
      // 'selected'
      minx = Math.min(...bboxes.map(box => box.x))
      miny = Math.min(...bboxes.map(box => box.y))
      maxx = Math.max(...bboxes.map(box => box.x + box.width))
      maxy = Math.max(...bboxes.map(box => box.y + box.height))
      break
  } // adjust min/max

  let dx = []
  let dy = []

  if (['dh', 'distrib_horiz'].includes(type)) { // distribute horizontal align
    [dx, dy] = _getDistributeHorizontalDistances(relativeTo, selectedElements, bboxes, minx, maxx, miny, maxy)
  } else if (['dv', 'distrib_verti'].includes(type)) { // distribute vertical align
    [dx, dy] = _getDistributeVerticalDistances(relativeTo, selectedElements, bboxes, minx, maxx, miny, maxy)
  } else { // normal align (top, left, right, ...)
    [dx, dy] = _getNormalDistances(type, selectedElements, bboxes, minx, maxx, miny, maxy)
  }

  moveSelectedElements(dx, dy)
}
Aligns selected elements.
@function module:selected-elem.SvgCanvas#alignSelectedElements
@param {string} type - String with single character indicating the alignment type
@param {"selected"|"largest"|"smallest"|"page"} relativeTo
@returns {void}