Я пытаюсь реализовать прокручиваемую панель зума. Я начал с этого примера: JavaFx 8 - масштабирование / масштабирование ScrollPane относительно положения мыши . Однако у меня есть одна проблема - ширина линий и других объектов также увеличена, в то время как я хотел бы добиться эффекта безразмерности объектов. Поэтому я улучшил решение с помощью PointScalers здесь: JavaFX Как масштабировать координаты пути без изменения ширины линии? и мне удалось получить следующий результат: .
Это выглядит нормально, но сцена не масштабируется таким образом, чтобы точка, где я щелкаю, оставалась на месте во время преобразования. Вот мой код:
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import java.util.List;
public class ZoomableScrollPane extends ScrollPane {
private final List<PointScaler> scalers;
private final Node targetNode, outerNode;
private final double zoomIntensity = 0.1;
private double scaleValue = 1.0;
public ZoomableScrollPane(SignFeaturesPresenter signGroupPresenter) {
super();
this.scalers = signGroupPresenter.getScalers();
this.targetNode = signGroupPresenter.getFeaturesGroup();
this.outerNode = outerNode(this.targetNode);
setContent(this.outerNode);
setPannable(true);
}
private Node outerNode(Node node) {
Node outerNode = centeredNode(node);
outerNode.setOnScroll(e -> {
e.consume();
onScroll(e.getTextDeltaY(), new Point2D(e.getX(), e.getY()));
});
return outerNode;
}
private Node centeredNode(Node node) {
VBox vBox = new VBox(node);
vBox.setAlignment(Pos.CENTER);
return vBox;
}
private void onScroll(double wheelDelta, Point2D mousePoint) {
Bounds outerBounds = outerNode.getLayoutBounds();
double zoomFactor = Math.exp(wheelDelta * zoomIntensity);
scaleValue = scaleValue * zoomFactor;
for (PointScaler scaler : scalers) {
scaler.setScale(scaleValue);
}
this.layout();
double newHvalue = mousePoint.getX()/outerBounds.getWidth();
double newVvalue = mousePoint.getY()/outerBounds.getHeight();
this.setHvalue(newHvalue);
this.setVvalue(newVvalue);
}
}
Я понимаю, почему уравнения для newHvalue
и newVvalue
не верны, но я не знаю, как их исправить. Я полагаю, что я должен использовать положение мыши в системе координат области просмотра, но я вижу, что позиция мыши находится в системе координат outerNode
, которая многократно расширяет область просмотра. Кроме того, я не понимаю, что означает отрицательные значения для границ minX, minY, maxX, maxY, возвращаемых методом:
Bounds viewportBounds = getViewportBounds();
Например:
BoundingBox [minX:-3231.0, minY:-130.0, minZ:0.0, width:585.0, height:538.0, depth:0.0, maxX:-2646.0, maxY:408.0, maxZ:0.0]