Проблема в контейнере для перетаскивания.Контейнер по умолчанию - this.parentNode
, где this
- это элемент, к которому применяется перетаскивание.Вы применяете перетаскивание к кругу, и его родительский узел - g
.В вашем событии перетаскивания вы вращаете родителя.Это важно, потому что:
- Контейнер устанавливает систему координат для события перетаскивания (см. Документы здесь ).
- Вращая g, вы изменяетесистема координат во время перетаскивания.
Что нам действительно нужно, так это фиксированная система координат для ссылки на событие перетаскивания, сам SVG будет в порядке или родительский элемент g
- что-то, что не меняетсяего трансформация каждого перетаскивания.Итак, давайте установим контейнер перетаскивания на что-то вроде родителя вращающегося g
.Родителем вращающегося g
является ваш svg со статической системой координат, поэтому давайте попробуем:
d3.drag()
.on('start', startRotation)
.on('drag', rotate)
.container(function() { return this.parentNode.parentNode; })
Это, кажется, позволяет избежать дрожания и дает нам плавный переход (обновлено fiddle )
Вот упрощенный фрагмент для демонстрации с той же функциональностью:
var svg = d3.select("svg");
var drag = d3.drag()
.on("drag", dragged)
// Set coordinate system to a frame of reference that doesn't move.
.container(function() { return this.parentNode.parentNode });
var contentG = svg.append("g")
.attr("transform","translate(100,100)"); // center of rotation
var rotatingG = contentG.append("g");
var circle = rotatingG.append("circle")
.attr("cx", 0)
.attr("cy", -75)
.attr("r", 10)
.call(drag);
var rect = rotatingG.append("rect")
.attr("width", 100)
.attr("height", 100)
.attr("x", -50)
.attr("y", -50);
function dragged() {
var x = d3.event.x, y = d3.event.y, angle;
if (x < 0) {
angle = 270 - (Math.atan(y / -x) * 180 / Math.PI);
} else {
angle = 90 + (Math.atan(y / x) * 180 / Math.PI);
}
rotatingG.attr("transform","rotate("+angle+")");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="500"></svg>
Во фрагменте я полагаюсь на this в качестве быстрого и простого примера получения угла от точки