我有一个 SVG 形状(非常复杂,为了便于理解我将其变得简单),我需要对其进行转换。我的要求是,
- 当鼠标悬停时,该组应缩放至 2 倍
- 鼠标移开时,组应缩小至 1 倍
- 拖动时应保留组比例
到目前为止,除了一期外,我已经完成了所有部分。当我尝试将鼠标悬停在组上时拖动元素后,它会恢复到其原始位置。我不明白为什么会发生这种情况。这是一个工作fiddle 。谁能帮我吗?
index.html
<svg width="400" height="400" style="background-color: red">
<g id="op" class="operator" transform="translate(0,0)">
<circle class="head" cx="50" cy="50" r="20" style="fill: yellow"></circle>
<circle cx="40" cy="40" r="10" style="fill: blue"></circle>
<circle cx="60" cy="40" r="10" style="fill: blue"></circle>
</g>
</svg>
脚本.js
d3.selectAll('.operator')
.on('mouseenter', function () {
console.log('Mouse Enter');
var c = d3.select(this).select('.head');
var x = c.attr('cx');
var y = c.attr('cy');
var scale = 2;
var scaleX = -1 * x * (scale - 1);
var scaleY = -1 * y * (scale - 1);
d3.select(this).attr('transform', 'translate(' + scaleX + ',' + scaleY + ')' + 'scale(' + scale + ')');
})
.on('mouseleave', function () {
console.log('Mouse Leave');
var c = d3.select(this).select('.head');
var x = c.attr('cx');
var y = c.attr('cy');
var scale = 1;
var scaleX = -1 * x * (scale - 1);
var scaleY = -1 * y * (scale - 1);
d3.select(this).attr('transform', 'translate(' + scaleX + ',' + scaleY + ')' + 'scale(' + scale + ')');
})
.call(d3.behavior.drag()
.origin(function () {
var t = d3.select(this);
return {
x: d3.transform(t.attr("transform")).translate[0],
y: d3.transform(t.attr("transform")).translate[1]
};
})
.on('drag', function () {
var oldScale = d3.transform(d3.select(this).attr('transform')).scale;
d3.select(this).attr('transform', 'translate(' + d3.event.x + ',' + d3.event.y + ')scale(' + oldScale + ')');
}))
最佳答案
正如 @PhilAnderson 所说,您不应该混合 translate
和 cx/cy
。事实上,按照嵌套元素的方式,您应该只进行翻译。翻译 SVG 中的 g
,然后翻译 g
中的圆圈。纠正这个问题,事情就变得简单多了:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<svg width="400" height="400" style="background-color: red">
<g id="op" class="operator" transform="translate(50,50)">
<circle class="head" r="20" style="fill: yellow"></circle>
<circle transform="translate(-10,0)" r="10" style="fill: blue"></circle>
<circle transform="translate(10,0)" r="10" style="fill: blue"></circle>
</g>
</svg>
<script>
d3.select('.operator')
.on('mouseenter', function() {
console.log('Mouse Enter');
var self = d3.select(this),
xy = d3.transform(self.attr('transform')).translate,
scale = 2;
self.attr('transform', 'translate(' + xy[0] + ',' + xy[1] + ')' + 'scale(' + scale + ')');
})
.on('mouseleave', function() {
console.log('Mouse Leave');
var self = d3.select(this),
xy = d3.transform(self.attr('transform')).translate,
scale = 1;
self.attr('transform', 'translate(' + xy[0] + ',' + xy[1] + ')' + 'scale(' + scale + ')');
})
.call(d3.behavior.drag()
.on('drag', function() {
var self = d3.select(this),
oldScale = d3.transform(self.attr('transform')).scale;
self.attr('transform', 'translate(' + d3.event.x + ',' + d3.event.y + ')scale(' + oldScale + ')');
}))
</script>
</body>
</html>
关于javascript - 在 SVG 元素中保留变换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34772401/