在 javavfx 中创建一个椭圆,其中缩放是从左上角(如矩形)而不是中心

Create an Ellipse in javavfx where the scaling is from the top left (like a Rectangle) rather than center

我有一个生成 canvas 的 javafx 程序,用户可以在其中绘制椭圆。我正在使用鼠标的按下、拖动和释放技术。 但是,我希望能够从形状的左上角(很像缩放矩形)而不是它的中心来缩放形状的大小。对我如何实现这一点有什么建议吗?

@Override
public void start(Stage ellipseStage) {

    //Create ellipse
    ellipsePane = new Pane();
    ellipsePane.setMinSize(600,600);

    ellipsePane.setOnMousePressed(e -> {
        if (e.getButton() == MouseButton.PRIMARY) {
            ellipse = new Ellipse();
            ellipse.setCenterX(e.getX());
            ellipse.setCenterY(e.getY());
            ellipse.setStroke(Color.ORANGE);
            ellipse.setFill(Color.BLACK);
            ellipsePane.getChildren().add(ellipse);
        }
        //if we double click
        if (e.getClickCount() == 2) {
            ellipse = null;
        }
    });

    //When the mouse is dragged the ellipse expands
    ellipsePane.setOnMouseDragged(e -> {
        if (ellipse != null) {
            ellipse.setRadiusX(e.getX() - ellipse.getCenterX());
            ellipse.setRadiusY(e.getY() - ellipse.getCenterY());
        }
    });

    Scene scene = new Scene(ellipsePane);
    ellipseStage.setScene(scene);
    ellipseStage.show();
}

public static void main(String[] args) {
    launch(args);
}}

一个选项是跟踪原始鼠标按下的位置,然后将 Ellipse 的中心 X/Y 属性设置为始终是原点和鼠标所在位置之间的中点当前(即它被拖动的位置)。半径也将是原点和当前位置之间距离的一半。这是一个例子:

import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Ellipse;
import javafx.stage.Stage;

public class Main extends Application {

    private Pane pane;
    private Point2D origin;
    private Ellipse ellipse;

    @Override
    public void start(Stage primaryStage) {
        pane = new Pane();
        pane.setOnMousePressed(this::handleMousePressed);
        pane.setOnMouseDragged(this::handleMouseDragged);
        pane.setOnMouseReleased(this::handleMouseReleased);

        primaryStage.setScene(new Scene(pane, 600.0, 400.0));
        primaryStage.show();
    }

    private void handleMousePressed(MouseEvent event) {
        event.consume();

        origin = new Point2D(event.getX(), event.getY());
        ellipse = new Ellipse(event.getX(), event.getY(), 0.0, 0.0);
        pane.getChildren().add(ellipse);
    }

    private void handleMouseDragged(MouseEvent event) {
        event.consume();

        ellipse.setCenterX((origin.getX() + event.getX()) / 2.0);
        ellipse.setCenterY((origin.getY() + event.getY()) / 2.0);
        ellipse.setRadiusX(Math.abs(event.getX() - origin.getX()) / 2.0);
        ellipse.setRadiusY(Math.abs(event.getY() - origin.getY()) / 2.0);
    }

    private void handleMouseReleased(MouseEvent event) {
        event.consume();

        ellipse = null;
        origin = null;
    }

}

所以我推测你的意思是当你拖动椭圆时,边缘位置会改变,但你希望边缘位置保持不变,中心移动。

ellipsePane.setOnMouseDragged(e -> {
    if (ellipse != null) {

        double x0 = ellipse.getCenterX() - ellipse.getRadiusX();
        double y0 = ellipse.getCenterY() - ellipse.getRadiusY();

        //the new radii
        double rxp = e.getX() - x0;
        double ryp = e.getY() - y0;

        //the new center positions. to keep the origin the same.
        double cx = x0 + rxp;
        double cy = y0 + ryp;

        ellipse.setRadiusX(rxp);
        ellipse.setRadiusY(ryp);
        ellipse.setCenterX(cx);
        ellipse.setCenterY(cy);

    }
});