JavaFx 8-相对于鼠标位置缩放/缩放ScrollPane

我需要在滚动窗格上相对于鼠标位置放大/缩小。

我目前通过将内容包装在一个组中并缩放组本身来实现缩放功能。我用自定义枢轴创建一个新的Scale对象。(枢轴设置为鼠标位置)

这在Group的初始比例为1.0的情况下非常适用,但是之后的缩放比例无法沿正确的方向缩放-我相信这是因为Group缩放后相对鼠标位置会发生变化。

我的代码:

@Override

public void initialize(URL location, ResourceBundle resources) {

Delta initial_mouse_pos = new Delta();

anchorpane.setOnScrollStarted(event -> {

initial_mouse_pos.x = event.getX();

initial_mouse_pos.y = event.getY();

});

anchorpane.setOnScroll(event -> {

double zoom_fac = 1.05;

double delta_y = event.getDeltaY();

if(delta_y < 0) {

zoom_fac = 2.0 - zoom_fac;

}

Scale newScale = new Scale();

newScale.setPivotX(initial_mouse_pos.x);

newScale.setPivotY(initial_mouse_pos.y);

newScale.setX( content_group.getScaleX() * zoom_fac );

newScale.setY( content_group.getScaleY() * zoom_fac );

content_group.getTransforms().add(newScale);

event.consume();

});

}

private class Delta { double x, y; }

如何在不同的缩放级别上获得正确的鼠标位置?有没有一种更简单的缩放ScrollPane的完全不同的方法?

回答:

这是一个 JavaFX ScrollPane:

import javafx.geometry.Bounds;

import javafx.geometry.Point2D;

import javafx.geometry.Pos;

import javafx.scene.Group;

import javafx.scene.Node;

import javafx.scene.control.ScrollPane;

import javafx.scene.layout.VBox;

public class ZoomableScrollPane extends ScrollPane {

private double scaleValue = 0.7;

private double zoomIntensity = 0.02;

private Node target;

private Node zoomNode;

public ZoomableScrollPane(Node target) {

super();

this.target = target;

this.zoomNode = new Group(target);

setContent(outerNode(zoomNode));

setPannable(true);

setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);

setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);

setFitToHeight(true); //center

setFitToWidth(true); //center

updateScale();

}

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 updateScale() {

target.setScaleX(scaleValue);

target.setScaleY(scaleValue);

}

private void onScroll(double wheelDelta, Point2D mousePoint) {

double zoomFactor = Math.exp(wheelDelta * zoomIntensity);

Bounds innerBounds = zoomNode.getLayoutBounds();

Bounds viewportBounds = getViewportBounds();

// calculate pixel offsets from [0, 1] range

double valX = this.getHvalue() * (innerBounds.getWidth() - viewportBounds.getWidth());

double valY = this.getVvalue() * (innerBounds.getHeight() - viewportBounds.getHeight());

scaleValue = scaleValue * zoomFactor;

updateScale();

this.layout(); // refresh ScrollPane scroll positions & target bounds

// convert target coordinates to zoomTarget coordinates

Point2D posInZoomTarget = target.parentToLocal(zoomNode.parentToLocal(mousePoint));

// calculate adjustment of scroll position (pixels)

Point2D adjustment = target.getLocalToParentTransform().deltaTransform(posInZoomTarget.multiply(zoomFactor - 1));

// convert back to [0, 1] range

// (too large/small values are automatically corrected by ScrollPane)

Bounds updatedInnerBounds = zoomNode.getBoundsInLocal();

this.setHvalue((valX + adjustment.getX()) / (updatedInnerBounds.getWidth() - viewportBounds.getWidth()));

this.setVvalue((valY + adjustment.getY()) / (updatedInnerBounds.getHeight() - viewportBounds.getHeight()));

}

}

以上是 JavaFx 8-相对于鼠标位置缩放/缩放ScrollPane 的全部内容, 来源链接: utcz.com/qa/405469.html

回到顶部