https://crashlaker.github.io/d3js-static/svg-zoom/index0.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="//d3js.org/d3.v5.min.js"></script>
<title>Document</title>
</head>
<body>
<script>
width = document.body.scrollWidth - 20
height = document.body.scrollHeight - 20
var svg = d3.select('body').append('svg')
.attr('width', `${width}px`)
.attr('height', `${height}px`)
//var g = svg.append('g')
var zoom = d3.zoom().on('zoom', zoomed)
svg.call(zoom)
var g
d3.xml('./rocket.svg').then(rs => {
// d3.xml('./icon-23.svg').then(rs => {
console.log(rs)
var svgNode = rs.getElementsByTagName('svg')[0]
console.log('svgnode', svgNode.innerHTML)
//svg.node().appendChild(svgNode)
svg.node().innerHTML = svgNode.innerHTML
g = svg.select('g')
ss = g.node().getBoundingClientRect()
toscale = Math.min(((90*width)/100)/ss.width,
((90*height)/100)/ss.height)
tow = 0
toh = 0
g.attr('transform', `translate(${tow}, ${toh}) scale(${toscale})`)
newss = g.node().getBoundingClientRect()
tow = (width/2) - (newss.width/2)
toh = (height/2) - (newss.height/2)
console.log(tow, toh, toscale)
svg.call(zoom.transform, d3.zoomIdentity.translate(tow, toh).scale(toscale))
})
function dragstarted(){
d3.select(this).raise()
g.attr('cursor', 'grabbing')
}
function dragended(){
g.attr('cursor', 'grab')
}
function zoomed() {
g.attr('transform', d3.event.transform)
}
</script>
</body>
</html>