[英]JavaFX Canvas.setScaleX/Y(2) not scaling to twice the size
也許我誤解了一些基本的東西,但我正在試驗 JavaFX 並且很困惑為什么縮放 Canvas (使用.setScaleX/Y)的值為 2 不會導致 ZFCC790C72A861960DEZDC5 的兩倍寬
相關代碼是這樣的:(此時我沒有使用any.fxml)
public class Main extends Application {
@Override
public void start(Stage primaryStage){
AnchorPane pane = new AnchorPane();
Canvas canvas = new Canvas();
canvas.setWidth(100);
canvas.setHeight(100);
canvas.getGraphicsContext2D().setFill(Color.BLUE);
canvas.getGraphicsContext2D().fillRect(0,0,100,100);
canvas.setScaleX(2);
canvas.setScaleY(2);
pane.getChildren().add(canvas);
primaryStage.setScene(new Scene(pane, 200, 200));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
這導致 canvas 大約是 window 的 2/3(就寬度/高度而言,而不是面積)。 使用 3 的比例使它填滿整個 window(邊緣處有一個像素間隙),我不明白為什么。 我查看了文檔,但似乎 2 的比例因子應該導致兩倍的尺寸。
編輯:因此,根據下面的建議,將 canvas 翻譯為其寬度/高度的一半可以解決問題。 但是將它集中在 StackPane 中也是如此,所以我不明白為什么 AnchorPane 不會通過它的頂部/左邊緣來錨定它,如果它在縮放后真的是 200x200,就好像它通過它的 100x100 邊緣來錨定它一樣。 但是,如果 Canvas 是 100x100,那么如果只是在 StackPane 中居中,它是如何超出這些界限的呢?
EDIT2:通過一些實驗,我想我確認 AnchorPane 正在定位 Canvas “好像”它仍然是 100x100。 因此,通過將頂部和左側錨點設置為 50,我可以獲得與平移 50 或將其置於 StackPane 中一樣的結果。 但這意味着 Canvas 實際上是在“邊緣”之外“繪制”。 這肯定不對吧?
您在原始帖子中的編輯中添加的信息提供了該問題的大部分答案。
首先注意scaleX
和scaleY
圍繞其中心縮放節點。 來自文檔:“定義沿該節點的 X 軸圍繞 object 的中心縮放坐標的因子。”
其次,請注意,應用於節點的轉換不會在該節點的布局計算中考慮。 從布局文檔(參見“Visual Bounds vs Layout Bounds”部分):
因此,例如...如果使用
ScaleTransition
來脈沖按鈕的大小,則該脈沖 animation 不會干擾該按鈕周圍的布局。 如果應用程序希望將效果、剪輯或變換因素考慮到節點的布局中,則應將該節點包裝在Group
中。
文檔中引用的最后一句話是指Group
的布局邊界包括應用於該組的子級(但不應用於該組本身)的任何轉換這一事實。
要可視化正在發生的事情,請從 100x100 canvas 開始。 布局忽略縮放,因此您可以將其可視化為在應用縮放之前將 canvas 錨定到錨窗格的左上角。 然后 canvas 圍繞其中心進行縮放,將所有四個角在兩個維度上都推離中心 50 像素。 因此,錨窗格坐標系中 canvas 的邊界是從(-50, -50)
到(150, 150)
。 您可以通過添加來驗證這一點
System.out.println(canvas.getBoundsInParent());
舞台展示后。
有兩種解決方案。 一種是將 canvas 包裝在一個Group
中。 Group
的布局邊界將考慮 canvas 上的縮放:
public class Main extends Application {
@Override
public void start(Stage primaryStage){
AnchorPane pane = new AnchorPane();
Canvas canvas = new Canvas();
canvas.setWidth(100);
canvas.setHeight(100);
canvas.getGraphicsContext2D().setFill(Color.BLUE);
canvas.getGraphicsContext2D().fillRect(0,0,100,100);
canvas.setScaleX(2);
canvas.setScaleY(2);
Group group = new Group(canvas);
AnchorPane.setTopAnchor(group, 0.0);
AnchorPane.setLeftAnchor(group, 0.0);
pane.getChildren().add(group);
primaryStage.setScene(new Scene(pane, 200, 200));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
另一種解決方案是應用一個轉換,將 canvas 圍繞其左上角進行縮放:
public class Main extends Application {
@Override
public void start(Stage primaryStage){
AnchorPane pane = new AnchorPane();
Canvas canvas = new Canvas();
canvas.setWidth(100);
canvas.setHeight(100);
canvas.getGraphicsContext2D().setFill(Color.BLUE);
canvas.getGraphicsContext2D().fillRect(0,0,100,100);
Scale scale = new Scale(2,2);
scale.setPivotX(0);
scale.setPivotY(0);
canvas.getTransforms().add(scale);
pane.getChildren().add(canvas);
primaryStage.setScene(new Scene(pane, 200, 200));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
您已經將 canvas 添加到窗格中,嘗試在pane.getChildren().add(canvas)
之前 apply.setScaleX/Y 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.