JavaFX中的可缩放滚动窗格

时间:2019-10-14 08:54:51

标签: java javafx javafx-8 zoom scrollpane

我正在尝试实现可滚动的缩放窗格。我从这个例子开始: JavaFx 8 - Scaling / zooming ScrollPane relative to mouse position。但是,我有一个问题-线和其他对象的宽度也被缩放了,而我想达到要素无量纲的效果。因此,我从JavaFX How do I scale the coordinates of a Path without altering the line width?处使用PointScalers改进了解决方案,并设法获得以下结果:

这看起来不错,但是场景的缩放方式并没有使我单击的点在转换期间保持在原处。这是我的代码:

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);
    }

}

我了解为什么newHvaluenewVvalue的方程式不正确,但是我不知道如何纠正它们。我想我应该在视口坐标系中使用鼠标的位置,但是我可以看到鼠标位置在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]

0 个答案:

没有答案