Я хочу добиться панорамирования объектов svg вдоль оси x и y и семантического масштабирования только вдоль оси x.
Пока объект d3.event.transform содержит вычисленные значения для масштабирования и панорамирования, всякий раз, когда я вызываю панорамирование и масштабирование одно за другим, вновь переведенные значения y неверны, потому что они игнорируют \ не игнорируют предыдущие противоположные действия.(zoom игнорирует d3.event.transform.y действий панорамирования, а pan не игнорирует d3.event.transform.y действий масштабирования)
Если вы масштабируете где-либо в области svg, круги должны только переводитьсякоордината x и координата y должны оставаться такими же, как и раньше (с учетом предыдущих сдвигов)
Теперь круги «прыгают» из-за неправильных значений y.
if (isZoom)
{//zoom
return "translate(" + t.apply(d)[0] + "," + (d[1]) +")"; //ignores previous panning-only values and positions to static initial value
}
//panning
return "translate(" + t.apply(d)[0] + "," + (t.y + d[1]) +")"; //how to ignore portion of t.y belonging to previous zooming?
Вы можетераскомментируйте эту строку кода, чтобы не допустить скачка окружностей, но при масштабировании у изменяется (что не должно)
//ignore isZoom and apply both for panning and zooming
return "translate(" + t.apply(d)[0] + "," + (t.y + d[1]) +")";
https://jsfiddle.net/197cz2vj/
Спасибо!
ОБНОВЛЕНИЕ
Наконец-то я нашел решение, похожее на взлом.Мне это не нравится, и я все еще ищу правильное решение (мне не нравится выбирать действие isZoom, а также решение deltaPanY. Это все возможно для будущих изменений в d3 libray).Вот оно:
Каждый раз, когда трансформация изменяется и изменение инициируется движением мыши (панорамирование), обновляйте переменную deltaPanY, сравнивая новое значение со старым запомненным значением преобразования.(Я также делаю копию tx и tk, но для моих целей нужен только ty и deltaPanY).
function copyLastTransform(t)
{
lastTransform =
{
x: t.x,
y: t.y,
k: t.k
};
};
Каждый раз, когда происходит преобразование, задайте переменные delta и сохраните последнее преобразование:
if (isZoom)
{
deltaZoomY += t.y - lastTransform.y;
}
else
{
deltaPanY += t.y - lastTransform.y;
}
copyLastTransform(t);
Функция перевода теперь выглядит следующим образом:
return "translate(" + t.apply(d)[0] + "," + (deltaPanY + d[1]) +")";
Разветвленная скрипка: https://jsfiddle.net/xpr364uo/