【问题标题】:JavaFX Scaling Shape without moving the originJavaFX 缩放形状而不移动原点
【发布时间】:2014-11-17 22:02:56
【问题描述】:

我的形状的缩放能力有问题。我想使用我自己绘制的坐标系,它包含一些形状。这些形状需要缩放功能。缩放形状后,它们会移动,因为缩放发生在每个形状的中心。为了对这个运动做出反应,我重新计算了原点。但是,如果我缩放多次,形状仍然会远离原点。我不知道为什么。谁能解释这种行为? 此外,我尝试重新计算笔画宽度以保持 1px。

谢谢!

我的代码:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polyline;
import javafx.stage.Stage;

public class ScaleTest extends Application {

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

    @Override
    public void start(Stage stage) throws Exception {
        Pane root = new Pane();
        Scene scene = new Scene(root, 800, 600, Color.WHITE);
        stage.setScene(scene);

        Polyline line1 = new Polyline(new double[] { 50, 50, 50, 150, 150, 150,
                150, 50, 50, 50 });
        line1.setStrokeWidth(1);

        Group polylines = new Group();
        polylines.getChildren().add(line1);

        Line xAxis = new Line(0, 50, 800, 50);
        Line yAxis = new Line(50, 0, 50, 800);

        root.setScaleY(-1);
        root.getChildren().addAll(xAxis, yAxis);
        root.getChildren().add(polylines);

        scene.setOnScroll(new EventHandler<ScrollEvent>() {

            @Override
            public void handle(ScrollEvent event) {
                double scale = 0;
                if (event.getDeltaY() < 0) {
                    scale = -0.1;
                } else {
                    scale = 0.1;
                }

                Bounds beforeScaling = polylines.getBoundsInParent();
                polylines.setScaleX(polylines.getScaleX() + scale);
                polylines.setScaleY(polylines.getScaleY() + scale);
                Bounds afterScaling = polylines.getBoundsInParent();
                polylines.setTranslateX(polylines.getTranslateX()
                        + beforeScaling.getMinX() - afterScaling.getMinX());
                polylines.setTranslateY(polylines.getTranslateY()
                        + beforeScaling.getMinY() - afterScaling.getMinY());

                //optional
                line1.setStrokeWidth(1/polylines.getScaleX());
            }

        });

        stage.show();
    }
}

【问题讨论】:

    标签: javafx javafx-2 scaling shape pane


    【解决方案1】:

    我不确定它为什么会“漂移”——可能只是在累积舍入误差。无论如何,一种更简单的方法是使用Scale 转换。有了它,您可以指定缩放发生的“枢轴”点。

    import javafx.application.Application;
    import javafx.event.EventHandler;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.input.ScrollEvent;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Line;
    import javafx.scene.shape.Polyline;
    import javafx.scene.transform.Scale;
    import javafx.stage.Stage;
    
    public class ScaleTest extends Application {
    
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage stage) throws Exception {
            Pane root = new Pane();
            Scene scene = new Scene(root, 800, 600, Color.WHITE);
            stage.setScene(scene);
    
            Polyline line1 = new Polyline(new double[] { 50, 50, 50, 150, 150, 150,
                    150, 50, 50, 50 });
            line1.setStrokeWidth(1);
    
            Group polylines = new Group();
            polylines.getChildren().add(line1);
    
            Line xAxis = new Line(0, 50, 800, 50);
            Line yAxis = new Line(50, 0, 50, 800);
    
            root.setScaleY(-1);
            root.getChildren().addAll(xAxis, yAxis);
            root.getChildren().add(polylines);
    
            Scale scale = new Scale();
            scale.setPivotX(50);
            scale.setPivotY(50);
            polylines.getTransforms().add(scale);
    
            scene.setOnScroll(new EventHandler<ScrollEvent>() {
    
                @Override
                public void handle(ScrollEvent event) {
                    double scaleDelta = 0;
                    if (event.getDeltaY() < 0) {
                        scaleDelta = -0.1;
                    } else {
                        scaleDelta = 0.1;
                    }
                    scale.setX(scale.getX() + scaleDelta);
                    scale.setY(scale.getY() + scaleDelta);
                    //optional
                    line1.setStrokeWidth(1/scale.getX());
                }
    
            });
    
            stage.show();
        }
    }
    

    【讨论】:

    • 天哪,非常感谢。我花了好几天才摆脱它!效果很好!
    • FWIW,我认为出现“漂移”是因为线条笔划(非零宽度)以形状边界为中心。所以如果你有一条 1px 宽的线,你的边界计算就会偏离 0.5 像素。当您缩放时,这种差异也会被缩放。但这很学术,只需使用变换方法即可。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多