缩放和平移 javaFX - 更改滚动

Zooming and Panning javaFX - change scroll

我有 .fxml 文件和 Controller.java。

我有这个结构:AnchorPane -> BorderPane -> ImageView;

在这个 ImageView 中,我可以缩放和平移图像(我使用了来自 Whosebug 的代码:))。但是,不幸的是,我不太了解所有这些几何和公式,所以我需要交换滚动(现在当我滚动时放大工作) - 我想在我滚动时放大。

你能帮我吗?

private void setImage(int imageId) {
    Image selectedImage = new ImageService().getObjectByID(DBResource.Image.SELECT_BY_ID,
            imageId);

    ImageView imageView = setImageView(selectedImage);

    //zoom
    double width = imageView.getImage().getWidth();
    double height = imageView.getImage().getHeight();

    imageView.setPreserveRatio(true);
    reset(imageView, width, height);

    ObjectProperty<Point2D> mouseDown = new SimpleObjectProperty<>();

    imageView.setOnMousePressed(e -> {

        Point2D mousePress = imageViewToImage(imageView, new Point2D(e.getX(), e.getY()));
        mouseDown.set(mousePress);
    });

    imageView.setOnMouseDragged(e -> {
        Point2D dragPoint = imageViewToImage(imageView, new Point2D(e.getX(), e.getY()));
        shift(imageView, dragPoint.subtract(mouseDown.get()));
        mouseDown.set(imageViewToImage(imageView, new Point2D(e.getX(), e.getY())));
    });

    imageView.setOnScroll(e -> {
        double delta = e.getDeltaY();
        Rectangle2D viewport = imageView.getViewport();

        double scale = clamp(Math.pow(1.01, delta),

                // don't scale so we're zoomed in to fewer than MIN_PIXELS in any direction:
                Math.min(MIN_PIXELS / viewport.getWidth(), MIN_PIXELS / viewport.getHeight()),

                // don't scale so that we're bigger than image dimensions:
                Math.max(width / viewport.getWidth(), height / viewport.getHeight())

        );

        Point2D mouse = imageViewToImage(imageView, new Point2D(e.getX(), e.getY()));

        double newWidth = viewport.getWidth() * scale;
        double newHeight = viewport.getHeight() * scale;

        // To keep the visual point under the mouse from moving, we need
        // (x - newViewportMinX) / (x - currentViewportMinX) = scale
        // where x is the mouse X coordinate in the image

        // solving this for newViewportMinX gives

        // newViewportMinX = x - (x - currentViewportMinX) * scale

        // we then clamp this value so the image never scrolls out
        // of the imageview:

        double newMinX = clamp(mouse.getX() - (mouse.getX() - viewport.getMinX()) * scale,
                0, width - newWidth);
        double newMinY = clamp(mouse.getY() - (mouse.getY() - viewport.getMinY()) * scale,
                0, height - newHeight);

        imageView.setViewport(new Rectangle2D(newMinX, newMinY, newWidth, newHeight));
    });

    imageView.setOnMouseClicked(e -> {
        if (e.getClickCount() == 2) {
            reset(imageView, width, height);
        }
    });

    imageView.setPreserveRatio(true);
    borderPane.setCenter(imageView);

    imageView.fitWidthProperty().bind(pane.widthProperty());
    imageView.fitHeightProperty().bind(pane.heightProperty());
}

// reset to the top left:
private void reset(ImageView imageView, double width, double height) {
    imageView.setViewport(new Rectangle2D(0, 0, width, height));
}

// shift the viewport of the imageView by the specified delta, clamping so
// the viewport does not move off the actual image:
private void shift(ImageView imageView, Point2D delta) {
    Rectangle2D viewport = imageView.getViewport();

    double width = imageView.getImage().getWidth() ;
    double height = imageView.getImage().getHeight() ;

    double maxX = width - viewport.getWidth();
    double maxY = height - viewport.getHeight();

    double minX = clamp(viewport.getMinX() - delta.getX(), 0, maxX);
    double minY = clamp(viewport.getMinY() - delta.getY(), 0, maxY);

    imageView.setViewport(new Rectangle2D(minX, minY, viewport.getWidth(), viewport.getHeight()));
}

private double clamp(double value, double min, double max) {

    if (value < min)
        return min;
    if (value > max)
        return max;
    return value;
}

// convert mouse coordinates in the imageView to coordinates in the actual image:
private Point2D imageViewToImage(ImageView imageView, Point2D imageViewCoordinates) {
    double xProportion = imageViewCoordinates.getX() / imageView.getBoundsInLocal().getWidth();
    double yProportion = imageViewCoordinates.getY() / imageView.getBoundsInLocal().getHeight();

    Rectangle2D viewport = imageView.getViewport();
    return new Point2D(
            viewport.getMinX() + xProportion * viewport.getWidth(),
            viewport.getMinY() + yProportion * viewport.getHeight());
}

private ImageView setImageView(Image image) {

    ImageView imageView = new ImageView();
    imageView.setImage(new javafx.scene.image.Image("file:" + image.getAbsPathI()));

    double w;
    double h;

    double ratioX = imageView.getFitWidth() / imageView.getImage().getWidth();
    double ratioY = imageView.getFitHeight() / imageView.getImage().getHeight();

    double reducCoeff;
    if(ratioX >= ratioY) {
        reducCoeff = ratioY;
    } else {
        reducCoeff = ratioX;
    }

    w = imageView.getImage().getWidth() * reducCoeff;
    h = imageView.getImage().getHeight() * reducCoeff;

    imageView.setX((imageView.getFitWidth() - w) / 2);
    imageView.setY((imageView.getFitHeight() - h) / 2);

    return imageView;
}

正如我在示例中看到的(并且不要忘记归功于 James_D as this is his example)此行控制缩放:

double delta = e.getDeltaY();

因此,如果您将其设置为...

double delta = -e.getDeltaY();

...缩放in/out 将被切换。