moveSelectedElements = (dx, dy, undoable = true) => {
  const selectedElements = svgCanvas.getSelectedElements()
  const zoom = svgCanvas.getZoom()
  // if undoable is not sent, default to true
  // if single values, scale them to the zoom
  if (!Array.isArray(dx)) {
    dx /= zoom
    dy /= zoom
  }

  const batchCmd = new BatchCommand('position')
  selectedElements.forEach((selected, i) => {
    if (selected) {
      const xform = svgCanvas.getSvgRoot().createSVGTransform()
      const tlist = getTransformList(selected)

      // dx and dy could be arrays
      if (Array.isArray(dx)) {
        xform.setTranslate(dx[i], dy[i])
      } else {
        xform.setTranslate(dx, dy)
      }

      if (tlist.numberOfItems) {
        tlist.insertItemBefore(xform, 0)
      } else {
        tlist.appendItem(xform)
      }

      const cmd = recalculateDimensions(selected)
      if (cmd) {
        batchCmd.addSubCommand(cmd)
      }

      svgCanvas
        .gettingSelectorManager()
        .requestSelector(selected)
        .resize()
    }
  })
  if (!batchCmd.isEmpty()) {
    if (undoable) {
      svgCanvas.addCommandToHistory(batchCmd)
    }
    svgCanvas.call('changed', selectedElements)
    return batchCmd
  }
  return undefined
}
Moves selected elements on the X/Y axis.
@function module:selected-elem.SvgCanvas#moveSelectedElements
@param {Float} dx - Float with the distance to move on the x-axis
@param {Float} dy - Float with the distance to move on the y-axis
@param {boolean} undoable - Boolean indicating whether or not the action should be undoable
@fires module:selected-elem.SvgCanvas#event:changed
@returns {BatchCommand|void} Batch command for the move