DOMMouseScrollEvent = (e) => {
  const zoom = svgCanvas.getZoom()
  const { $id } = svgCanvas
  if (!e.shiftKey) { return }

  e.preventDefault()

  svgCanvas.setRootSctm($id('svgcontent').querySelector('g').getScreenCTM().inverse())

  const workarea = document.getElementById('workarea')
  const scrbar = 15
  const rulerwidth = svgCanvas.getCurConfig().showRulers ? 16 : 0

  // mouse relative to content area in content pixels
  const pt = transformPoint(e.clientX, e.clientY, svgCanvas.getrootSctm())

  // full work area width in screen pixels
  const editorFullW = parseFloat(getComputedStyle(workarea, null).width.replace('px', ''))
  const editorFullH = parseFloat(getComputedStyle(workarea, null).height.replace('px', ''))

  // work area width minus scroll and ruler in screen pixels
  const editorW = editorFullW - scrbar - rulerwidth
  const editorH = editorFullH - scrbar - rulerwidth

  // work area width in content pixels
  const workareaViewW = editorW * svgCanvas.getrootSctm().a
  const workareaViewH = editorH * svgCanvas.getrootSctm().d

  // content offset from canvas in screen pixels
  const wOffset = findPos(workarea)
  const wOffsetLeft = wOffset.left + rulerwidth
  const wOffsetTop = wOffset.top + rulerwidth

  const delta = (e.wheelDelta) ? e.wheelDelta : (e.detail) ? -e.detail : 0
  if (!delta) { return }

  let factor = Math.max(3 / 4, Math.min(4 / 3, (delta)))

  let wZoom; let hZoom
  if (factor > 1) {
    wZoom = Math.ceil(editorW / workareaViewW * factor * 100) / 100
    hZoom = Math.ceil(editorH / workareaViewH * factor * 100) / 100
  } else {
    wZoom = Math.floor(editorW / workareaViewW * factor * 100) / 100
    hZoom = Math.floor(editorH / workareaViewH * factor * 100) / 100
  }
  let zoomlevel = Math.min(wZoom, hZoom)
  zoomlevel = Math.min(10, Math.max(0.01, zoomlevel))
  if (zoomlevel === zoom) {
    return
  }
  factor = zoomlevel / zoom

  // top left of workarea in content pixels before zoom
  const topLeftOld = transformPoint(wOffsetLeft, wOffsetTop, svgCanvas.getrootSctm())

  // top left of workarea in content pixels after zoom
  const topLeftNew = {
    x: pt.x - (pt.x - topLeftOld.x) / factor,
    y: pt.y - (pt.y - topLeftOld.y) / factor
  }

  // top left of workarea in canvas pixels relative to content after zoom
  const topLeftNewCanvas = {
    x: topLeftNew.x * zoomlevel,
    y: topLeftNew.y * zoomlevel
  }

  // new center in canvas pixels
  const newCtr = {
    x: topLeftNewCanvas.x - rulerwidth + editorFullW / 2,
    y: topLeftNewCanvas.y - rulerwidth + editorFullH / 2
  }

  svgCanvas.setZoom(zoomlevel)
  document.getElementById('zoom').value = ((zoomlevel * 100).toFixed(1))

  svgCanvas.call('updateCanvas', { center: false, newCtr })
  svgCanvas.call('zoomDone')
}
@param {Event} e
@fires module:event.SvgCanvas#event:updateCanvas
@fires module:event.SvgCanvas#event:zoomDone
@returns {void}