Skip to content

Instantly share code, notes, and snippets.

@feketegy
Last active November 17, 2017 10:00
Show Gist options
  • Save feketegy/ce9ab2efa9439f3c59c381f567522dd3 to your computer and use it in GitHub Desktop.
Save feketegy/ce9ab2efa9439f3c59c381f567522dd3 to your computer and use it in GitHub Desktop.
d3 zoom pan problem
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.container {
height: 700px;
border: 1px solid #ff0000;
}
svg {
background: #eee;
}
</style>
</head>
<body>
<div class="container"></div>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript">
var svg = d3.select('.container')
.append('svg')
.attr( 'width', '100%' )
.attr( 'height', '100%' );
var outer = svg.append('g')
.attr('class', 'outer-group')
.attr('transform', 'translate(0,0)scale(1)');
outer.append('path')
.attr('d', 'M100,100 L140,140 L200,250 L100,250 Z')
.attr('fill', '#cccccc')
.attr('stroke', '#8191A2')
.attr('stroke-width', '2px');
outer.append('path')
.attr('d', 'M400,100 L450,100 L450,250 L400,250 Z')
.attr('fill', '#cccccc')
.attr('stroke', '#8191A2')
.attr('stroke-width', '2px');
outer.append('path')
.attr('d', 'M800,400 L1000,500 L1100,350 L800,400 Z')
.attr('fill', '#cccccc')
.attr('stroke', '#8191A2')
.attr('stroke-width', '2px');
outer.append('path')
.attr('d', 'M300,400 L400,500 L300,550 L200,400 Z')
.attr('fill', '#cccccc')
.attr('stroke', '#8191A2')
.attr('stroke-width', '2px');
var sameSizePos = outer.append('g')
.attr('class', 'same-size-position')
.attr('transform', 'translate(300,250)');
var sameSize = sameSizePos.append('g')
.attr('class', 'same-size')
.attr('transform', 'scale(1)');
sameSize.append('path')
.attr('d', 'M0,0 L50,0 L50,50 L0,50 Z')
.attr('fill', '#0000ff');
var zoom = d3.zoom()
.scaleExtent([0.2, 1.5])
.on('zoom', evtPanZoom);
svg.call(zoom);
function evtPanZoom() {
var ssp = d3.select('.same-size-position');
var delta = 1 / d3.event.transform.k;
// [ SOLUTION ]
var sameSizeElem = d3.select('.same-size');
var bbox = sameSizeElem.node().getBBox();
var cx = bbox.x + (bbox.width / 2);
var cy = bbox.y + (bbox.height / 2);
var zx = cx - delta * cx;
var zy = cy - delta * cy;
sameSizeElem
.attr('transform', 'matrix(' + delta + ', 0, 0, ' + delta + ', ' + zx + ', ' + zy + ')');
d3.select('.outer-group')
.attr('transform',
'translate('
+ d3.event.transform.x
+ ','
+ d3.event.transform.y
+ ')scale('
+ d3.event.transform.k
+ ')');
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment