I am struggling to write my own zoom + pan function, that zooms into the center of my SVG graphic when I use my mousewheel. To be more specific I don't translate + zoom the whole SVG element but rather just one group (that accounts for almost the whole image anyway.) So far I tried using SVG Matrices but end up jumping around in my SVG instead of smoothling zooming to the center of the screen. Here is what I have so far:
panAfterZooming : (zoomLevel, position) =>
$svg = @$el.find("#process-graph")
svgRoot = $svg[0]
midX = $svg.width() / 2
midY = $svg.height() / 2
groupElement = @graph.graphContainer[0][0]
transformationMatrix = groupElement.getCTM()
p = svgRoot.createSVGPoint()
p.x = midX
p.y = midY
p = p.matrixTransform(transformationMatrix.inverse())
panNZoomMatrix = svgRoot.createSVGMatrix().translate(p.x, p.y).scale(zoomLevel).translate(-p.x, -p.y)
transformationMatrix = transformationMatrix.multiply(panNZoomMatrix)
newTransformation = @decomposeMatrix(transformationMatrix)
@panTo(newTransformation.translateX, newTransformation.translateY, newTransformation.scaleX)
panTo : (x, y, zoom) =>
transformation = d3.transform(@graph.graphContainer.attr("transform"))
transformation.translate = [x, y]
transformation.scale = zoom || app.view.process.zoom
@graph.graphContainer.attr("transform", transformation.toString())
app.trigger "behavior:panning"
decomposeMatrix : (matrix) ->
return {
translateX: matrix.e
translateY: matrix.f
scaleX: Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b)
scaleY: Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d)
}