javafx – 在已经缩放的节点上的枢轴点进行缩放

前端之家收集整理的这篇文章主要介绍了javafx – 在已经缩放的节点上的枢轴点进行缩放前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用可缩放/可绘制的画布创建应用程序.

特征:

>使用鼠标滚轮放大/缩小转动点
>使用鼠标左键在画布上拖动节点
>用鼠标右键拖动整个画布

只要您在比例尺1开始缩放,就可以在枢轴点进行缩放.将鼠标放在网格点上并滚动鼠标滚轮.枢轴点将保持开始缩放的位置.

问题:

当您放大时,将鼠标移动到另一点并再次放大,然后在初始鼠标位置,枢轴点移动,缩放不再发生.

例:

以下是代码

  1. import javafx.application.Application;
  2. import javafx.event.EventHandler;
  3. import javafx.scene.Group;
  4. import javafx.scene.Node;
  5. import javafx.scene.Scene;
  6. import javafx.scene.canvas.Canvas;
  7. import javafx.scene.canvas.GraphicsContext;
  8. import javafx.scene.control.Label;
  9. import javafx.scene.input.MouseEvent;
  10. import javafx.scene.input.ScrollEvent;
  11. import javafx.scene.layout.Pane;
  12. import javafx.scene.paint.Color;
  13. import javafx.scene.shape.Circle;
  14. import javafx.scene.shape.Rectangle;
  15. import javafx.scene.transform.Scale;
  16. import javafx.stage.Stage;
  17.  
  18. /**
  19. * The canvas which holds all of the nodes of the application.
  20. */
  21. class PannableCanvas extends Pane {
  22.  
  23. Scale scaleTransform;
  24.  
  25. public PannableCanvas() {
  26.  
  27. setPrefSize(600,600);
  28. setStyle("-fx-background-color: lightgrey; -fx-border-color: blue;");
  29.  
  30. // add scale transform
  31. scaleTransform = new Scale( 1.0,1.0);
  32. getTransforms().add( scaleTransform);
  33.  
  34. // logging
  35. addEventFilter(MouseEvent.MOUSE_PRESSED,event -> {
  36. System.out.println(
  37. "canvas event: " + ( ((event.getSceneX() - getBoundsInParent().getMinX()) / getScale()) + ",scale: " + getScale())
  38. );
  39. System.out.println( "canvas bounds: " + getBoundsInParent());
  40. });
  41.  
  42. }
  43.  
  44. /**
  45. * Add a grid to the canvas,send it to back
  46. */
  47. public void addGrid() {
  48.  
  49. double w = getBoundsInLocal().getWidth();
  50. double h = getBoundsInLocal().getHeight();
  51.  
  52. // add grid
  53. Canvas grid = new Canvas(w,h);
  54.  
  55. // don't catch mouse events
  56. grid.setMouseTransparent(true);
  57.  
  58. GraphicsContext gc = grid.getGraphicsContext2D();
  59.  
  60. gc.setStroke(Color.GRAY);
  61. gc.setLineWidth(1);
  62.  
  63. // draw grid lines
  64. double offset = 50;
  65. for( double i=offset; i < w; i+=offset) {
  66. // vertical
  67. gc.strokeLine( i,i,h);
  68. // horizontal
  69. gc.strokeLine( 0,w,i);
  70. }
  71.  
  72. getChildren().add( grid);
  73.  
  74. grid.toBack();
  75. }
  76.  
  77. public Scale getScaleTransform() {
  78. return scaleTransform;
  79. }
  80.  
  81. public double getScale() {
  82. return scaleTransform.getY();
  83. }
  84.  
  85. /**
  86. * Set x/y scale
  87. * @param scale
  88. */
  89. public void setScale( double scale) {
  90. scaleTransform.setX(scale);
  91. scaleTransform.setY(scale);
  92. }
  93.  
  94. /**
  95. * Set x/y pivot points
  96. * @param x
  97. * @param y
  98. */
  99. public void setPivot( double x,double y) {
  100. scaleTransform.setPivotX(x);
  101. scaleTransform.setPivotY(y);
  102. }
  103. }
  104.  
  105.  
  106. /**
  107. * Mouse drag context used for scene and nodes.
  108. */
  109. class DragContext {
  110.  
  111. double mouseAnchorX;
  112. double mouseAnchorY;
  113.  
  114. double translateAnchorX;
  115. double translateAnchorY;
  116.  
  117. }
  118.  
  119. /**
  120. * Listeners for making the nodes draggable via left mouse button. Considers if parent is zoomed.
  121. */
  122. class NodeGestures {
  123.  
  124. private DragContext nodeDragContext = new DragContext();
  125.  
  126. PannableCanvas canvas;
  127.  
  128. public NodeGestures( PannableCanvas canvas) {
  129. this.canvas = canvas;
  130.  
  131. }
  132.  
  133. public EventHandler<MouseEvent> getOnMousePressedEventHandler() {
  134. return onMousePressedEventHandler;
  135. }
  136.  
  137. public EventHandler<MouseEvent> getOnMouseDraggedEventHandler() {
  138. return onMouseDraggedEventHandler;
  139. }
  140.  
  141. private EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
  142.  
  143. public void handle(MouseEvent event) {
  144.  
  145. // left mouse button => dragging
  146. if( !event.isPrimaryButtonDown())
  147. return;
  148.  
  149. nodeDragContext.mouseAnchorX = event.getSceneX();
  150. nodeDragContext.mouseAnchorY = event.getSceneY();
  151.  
  152. Node node = (Node) event.getSource();
  153.  
  154. nodeDragContext.translateAnchorX = node.getTranslateX();
  155. nodeDragContext.translateAnchorY = node.getTranslateY();
  156.  
  157. }
  158.  
  159. };
  160.  
  161. private EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
  162. public void handle(MouseEvent event) {
  163.  
  164. // left mouse button => dragging
  165. if( !event.isPrimaryButtonDown())
  166. return;
  167.  
  168. double scale = canvas.getScale();
  169.  
  170. Node node = (Node) event.getSource();
  171.  
  172. node.setTranslateX(nodeDragContext.translateAnchorX + (( event.getSceneX() - nodeDragContext.mouseAnchorX) / scale));
  173. node.setTranslateY(nodeDragContext.translateAnchorY + (( event.getSceneY() - nodeDragContext.mouseAnchorY) / scale));
  174.  
  175. event.consume();
  176.  
  177. }
  178. };
  179. }
  180.  
  181. /**
  182. * Listeners for making the scene's canvas draggable and zoomable
  183. */
  184. class SceneGestures {
  185.  
  186. private static final double MAX_SCALE = 10.0d;
  187. private static final double MIN_SCALE = .1d;
  188.  
  189. private DragContext sceneDragContext = new DragContext();
  190.  
  191. PannableCanvas canvas;
  192.  
  193. public SceneGestures( PannableCanvas canvas) {
  194. this.canvas = canvas;
  195. }
  196.  
  197. public EventHandler<MouseEvent> getOnMousePressedEventHandler() {
  198. return onMousePressedEventHandler;
  199. }
  200.  
  201. public EventHandler<MouseEvent> getOnMouseDraggedEventHandler() {
  202. return onMouseDraggedEventHandler;
  203. }
  204.  
  205. public EventHandler<ScrollEvent> getOnScrollEventHandler() {
  206. return onScrollEventHandler;
  207. }
  208.  
  209. private EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
  210.  
  211. public void handle(MouseEvent event) {
  212.  
  213. // right mouse button => panning
  214. if( !event.isSecondaryButtonDown())
  215. return;
  216.  
  217. sceneDragContext.mouseAnchorX = event.getSceneX();
  218. sceneDragContext.mouseAnchorY = event.getSceneY();
  219.  
  220. sceneDragContext.translateAnchorX = canvas.getTranslateX();
  221. sceneDragContext.translateAnchorY = canvas.getTranslateY();
  222.  
  223. }
  224.  
  225. };
  226.  
  227. private EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
  228. public void handle(MouseEvent event) {
  229.  
  230. // right mouse button => panning
  231. if( !event.isSecondaryButtonDown())
  232. return;
  233.  
  234. canvas.setTranslateX(sceneDragContext.translateAnchorX + event.getSceneX() - sceneDragContext.mouseAnchorX);
  235. canvas.setTranslateY(sceneDragContext.translateAnchorY + event.getSceneY() - sceneDragContext.mouseAnchorY);
  236.  
  237. event.consume();
  238. }
  239. };
  240.  
  241. /**
  242. * Mouse wheel handler: zoom to pivot point
  243. */
  244. private EventHandler<ScrollEvent> onScrollEventHandler = new EventHandler<ScrollEvent>() {
  245.  
  246. @Override
  247. public void handle(ScrollEvent event) {
  248.  
  249. double delta = 1;
  250.  
  251. double scale = canvas.getScale(); // currently we only use Y,same value is used for X
  252. double oldScale = scale;
  253.  
  254. if (event.getDeltaY() < 0)
  255. scale -= delta;
  256. else
  257. scale += delta;
  258.  
  259. if (scale <= MIN_SCALE) {
  260. scale = MIN_SCALE;
  261. } else if (scale >= MAX_SCALE) {
  262. scale = MAX_SCALE;
  263. }
  264.  
  265. // pivot value must be untransformed,i. e. without scaling
  266. canvas.setPivot(
  267. ((event.getSceneX() - canvas.getBoundsInParent().getMinX()) / oldScale),((event.getSceneY() - canvas.getBoundsInParent().getMinY()) / oldScale)
  268. );
  269.  
  270. canvas.setScale( scale);
  271.  
  272. System.out.println( "new pivot x: " + canvas.scaleTransform.getPivotX() + "/" + canvas.scaleTransform.getPivotY() + ",new scale: " + scale);
  273. System.out.println( "bounds: " + canvas.getBoundsInParent());
  274.  
  275. event.consume();
  276.  
  277. }
  278.  
  279. };
  280.  
  281.  
  282. }
  283.  
  284. /**
  285. * An application with a zoomable and pannable canvas.
  286. */
  287. public class ScrollApplication extends Application {
  288. public static void main(String[] args) {
  289. launch(args);
  290. }
  291.  
  292. @Override
  293. public void start(Stage stage) {
  294.  
  295. Group group = new Group();
  296.  
  297. // create canvas
  298. PannableCanvas canvas = new PannableCanvas();
  299.  
  300. // we don't want the canvas on the top/left in this example => just
  301. // translate it a bit
  302. canvas.setTranslateX(100);
  303. canvas.setTranslateY(100);
  304.  
  305. // create sample nodes which can be dragged
  306. NodeGestures nodeGestures = new NodeGestures( canvas);
  307.  
  308. Label label1 = new Label("Draggable node 1");
  309. label1.setTranslateX(10);
  310. label1.setTranslateY(10);
  311. label1.addEventFilter( MouseEvent.MOUSE_PRESSED,nodeGestures.getOnMousePressedEventHandler());
  312. label1.addEventFilter( MouseEvent.MOUSE_DRAGGED,nodeGestures.getOnMouseDraggedEventHandler());
  313.  
  314. Label label2 = new Label("Draggable node 2");
  315. label2.setTranslateX(100);
  316. label2.setTranslateY(100);
  317. label2.addEventFilter( MouseEvent.MOUSE_PRESSED,nodeGestures.getOnMousePressedEventHandler());
  318. label2.addEventFilter( MouseEvent.MOUSE_DRAGGED,nodeGestures.getOnMouseDraggedEventHandler());
  319.  
  320. Label label3 = new Label("Draggable node 3");
  321. label3.setTranslateX(200);
  322. label3.setTranslateY(200);
  323. label3.addEventFilter( MouseEvent.MOUSE_PRESSED,nodeGestures.getOnMousePressedEventHandler());
  324. label3.addEventFilter( MouseEvent.MOUSE_DRAGGED,nodeGestures.getOnMouseDraggedEventHandler());
  325.  
  326. Circle circle1 = new Circle( 300,300,50);
  327. circle1.setStroke(Color.ORANGE);
  328. circle1.setFill(Color.ORANGE.deriveColor(1,1,0.5));
  329. circle1.addEventFilter( MouseEvent.MOUSE_PRESSED,nodeGestures.getOnMousePressedEventHandler());
  330. circle1.addEventFilter( MouseEvent.MOUSE_DRAGGED,nodeGestures.getOnMouseDraggedEventHandler());
  331.  
  332. Rectangle rect1 = new Rectangle(100,100);
  333. rect1.setTranslateX(450);
  334. rect1.setTranslateY(450);
  335. rect1.setStroke(Color.BLUE);
  336. rect1.setFill(Color.BLUE.deriveColor(1,0.5));
  337. rect1.addEventFilter( MouseEvent.MOUSE_PRESSED,nodeGestures.getOnMousePressedEventHandler());
  338. rect1.addEventFilter( MouseEvent.MOUSE_DRAGGED,nodeGestures.getOnMouseDraggedEventHandler());
  339.  
  340. canvas.getChildren().addAll(label1,label2,label3,circle1,rect1);
  341.  
  342. group.getChildren().add(canvas);
  343.  
  344. // create scene which can be dragged and zoomed
  345. Scene scene = new Scene(group,1024,768);
  346.  
  347. SceneGestures sceneGestures = new SceneGestures(canvas);
  348. scene.addEventFilter( MouseEvent.MOUSE_PRESSED,sceneGestures.getOnMousePressedEventHandler());
  349. scene.addEventFilter( MouseEvent.MOUSE_DRAGGED,sceneGestures.getOnMouseDraggedEventHandler());
  350. scene.addEventFilter( ScrollEvent.ANY,sceneGestures.getOnScrollEventHandler());
  351.  
  352. stage.setScene(scene);
  353. stage.show();
  354.  
  355. canvas.addGrid();
  356.  
  357. }
  358. }

显然,枢轴点计算有问题,但我无法弄清楚它是什么,以及如何解决它.

非常感谢你!

解决方法

首先,我建议不要按直线步长进行分级,还可以通过因素来平滑缩放:
  1. double delta = 1.2;
  2. if (event.getDeltaY() < 0)
  3. scale /= delta;
  4. else
  5. scale *= delta;

…而且以某种方式老板,我推荐大括号作为一个很好的风格;-):

  1. double delta = 1.2;
  2. if (event.getDeltaY() < 0) {
  3. scale /= delta;
  4. } else {
  5. scale *= delta;
  6. }

…并使用鼠标滚动值更好的质量:

  1. double delta = 1.2;
  2. if (event.getDeltaY() < 0) {
  3. scale /= Math.pow(delta,-event.getDeltaY()/20);
  4. } else {
  5. scale *= Math.pow(delta,event.getDeltaY()/20);
  6. }

…那最终是一样的:

  1. scale *= Math.pow(1.01,event.getDeltaY());

第二,我建议使用画布翻译和缩放属性而不是转换:

  1. public class ZoomApplication extends Application {
  2. static public class PannableCanvas extends Pane {
  3.  
  4. DoubleProperty myScale = new SimpleDoubleProperty(1.0);
  5.  
  6. public PannableCanvas() {
  7.  
  8. setPrefSize(600,600);
  9. setStyle("-fx-background-color: lightgrey; -fx-border-color: blue;");
  10.  
  11. // add scale transform
  12. scaleXProperty().bind(myScale);
  13. scaleYProperty().bind(myScale);
  14.  
  15. // logging
  16. addEventFilter(MouseEvent.MOUSE_PRESSED,event -> {
  17. System.out.println(
  18. "canvas event: " + ( ((event.getSceneX() - getBoundsInParent().getMinX()) / getScale()) + ",scale: " + getScale())
  19. );
  20. System.out.println( "canvas bounds: " + getBoundsInParent());
  21. });
  22.  
  23. }
  24.  
  25. /**
  26. * Add a grid to the canvas,send it to back
  27. */
  28. public void addGrid() {
  29.  
  30. double w = getBoundsInLocal().getWidth();
  31. double h = getBoundsInLocal().getHeight();
  32.  
  33. // add grid
  34. Canvas grid = new Canvas(w,h);
  35.  
  36. // don't catch mouse events
  37. grid.setMouseTransparent(true);
  38.  
  39. GraphicsContext gc = grid.getGraphicsContext2D();
  40.  
  41. gc.setStroke(Color.GRAY);
  42. gc.setLineWidth(1);
  43.  
  44. // draw grid lines
  45. double offset = 50;
  46. for( double i=offset; i < w; i+=offset) {
  47. // vertical
  48. gc.strokeLine( i,h);
  49. // horizontal
  50. gc.strokeLine( 0,i);
  51. }
  52.  
  53. getChildren().add( grid);
  54.  
  55. grid.toBack();
  56. }
  57.  
  58. public double getScale() {
  59. return myScale.get();
  60. }
  61.  
  62. /**
  63. * Set x/y scale
  64. * @param myScale
  65. */
  66. public void setScale( double scale) {
  67. myScale.set(scale);
  68. }
  69.  
  70. /**
  71. * Set x/y pivot points
  72. * @param x
  73. * @param y
  74. */
  75. public void setPivot( double x,double y) {
  76. setTranslateX(getTranslateX()-x);
  77. setTranslateY(getTranslateY()-y);
  78. }
  79. }
  80.  
  81.  
  82. /**
  83. * Mouse drag context used for scene and nodes.
  84. */
  85. class DragContext {
  86.  
  87. double mouseAnchorX;
  88. double mouseAnchorY;
  89.  
  90. double translateAnchorX;
  91. double translateAnchorY;
  92.  
  93. }
  94.  
  95. /**
  96. * Listeners for making the nodes draggable via left mouse button. Considers if parent is zoomed.
  97. */
  98. class NodeGestures {
  99.  
  100. private DragContext nodeDragContext = new DragContext();
  101.  
  102. PannableCanvas canvas;
  103.  
  104. public NodeGestures( PannableCanvas canvas) {
  105. this.canvas = canvas;
  106.  
  107. }
  108.  
  109. public EventHandler<MouseEvent> getOnMousePressedEventHandler() {
  110. return onMousePressedEventHandler;
  111. }
  112.  
  113. public EventHandler<MouseEvent> getOnMouseDraggedEventHandler() {
  114. return onMouseDraggedEventHandler;
  115. }
  116.  
  117. private EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
  118.  
  119. public void handle(MouseEvent event) {
  120.  
  121. // left mouse button => dragging
  122. if( !event.isPrimaryButtonDown())
  123. return;
  124.  
  125. nodeDragContext.mouseAnchorX = event.getSceneX();
  126. nodeDragContext.mouseAnchorY = event.getSceneY();
  127.  
  128. Node node = (Node) event.getSource();
  129.  
  130. nodeDragContext.translateAnchorX = node.getTranslateX();
  131. nodeDragContext.translateAnchorY = node.getTranslateY();
  132.  
  133. }
  134.  
  135. };
  136.  
  137. private EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
  138. public void handle(MouseEvent event) {
  139.  
  140. // left mouse button => dragging
  141. if( !event.isPrimaryButtonDown())
  142. return;
  143.  
  144. double scale = canvas.getScale();
  145.  
  146. Node node = (Node) event.getSource();
  147.  
  148. node.setTranslateX(nodeDragContext.translateAnchorX + (( event.getSceneX() - nodeDragContext.mouseAnchorX) / scale));
  149. node.setTranslateY(nodeDragContext.translateAnchorY + (( event.getSceneY() - nodeDragContext.mouseAnchorY) / scale));
  150.  
  151. event.consume();
  152.  
  153. }
  154. };
  155. }
  156.  
  157. /**
  158. * Listeners for making the scene's canvas draggable and zoomable
  159. */
  160. class SceneGestures {
  161.  
  162. private static final double MAX_SCALE = 10.0d;
  163. private static final double MIN_SCALE = .1d;
  164.  
  165. private DragContext sceneDragContext = new DragContext();
  166.  
  167. PannableCanvas canvas;
  168.  
  169. public SceneGestures( PannableCanvas canvas) {
  170. this.canvas = canvas;
  171. }
  172.  
  173. public EventHandler<MouseEvent> getOnMousePressedEventHandler() {
  174. return onMousePressedEventHandler;
  175. }
  176.  
  177. public EventHandler<MouseEvent> getOnMouseDraggedEventHandler() {
  178. return onMouseDraggedEventHandler;
  179. }
  180.  
  181. public EventHandler<ScrollEvent> getOnScrollEventHandler() {
  182. return onScrollEventHandler;
  183. }
  184.  
  185. private EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
  186.  
  187. public void handle(MouseEvent event) {
  188.  
  189. // right mouse button => panning
  190. if( !event.isSecondaryButtonDown())
  191. return;
  192.  
  193. sceneDragContext.mouseAnchorX = event.getSceneX();
  194. sceneDragContext.mouseAnchorY = event.getSceneY();
  195.  
  196. sceneDragContext.translateAnchorX = canvas.getTranslateX();
  197. sceneDragContext.translateAnchorY = canvas.getTranslateY();
  198.  
  199. }
  200.  
  201. };
  202.  
  203. private EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
  204. public void handle(MouseEvent event) {
  205.  
  206. // right mouse button => panning
  207. if( !event.isSecondaryButtonDown())
  208. return;
  209.  
  210. canvas.setTranslateX(sceneDragContext.translateAnchorX + event.getSceneX() - sceneDragContext.mouseAnchorX);
  211. canvas.setTranslateY(sceneDragContext.translateAnchorY + event.getSceneY() - sceneDragContext.mouseAnchorY);
  212.  
  213. event.consume();
  214. }
  215. };
  216.  
  217. /**
  218. * Mouse wheel handler: zoom to pivot point
  219. */
  220. private EventHandler<ScrollEvent> onScrollEventHandler = new EventHandler<ScrollEvent>() {
  221.  
  222. @Override
  223. public void handle(ScrollEvent event) {
  224.  
  225.  
  226. double scale = canvas.getScale(); // currently we only use Y,same value is used for X
  227. double oldScale = scale;
  228.  
  229. scale *= Math.pow(1.01,event.getDeltaY());
  230.  
  231. if (scale <= MIN_SCALE) {
  232. scale = MIN_SCALE;
  233. } else if (scale >= MAX_SCALE) {
  234. scale = MAX_SCALE;
  235. }
  236.  
  237. double f = (scale / oldScale)-1;
  238.  
  239. double dx = (event.getSceneX() - (canvas.getBoundsInParent().getWidth()/2 + canvas.getBoundsInParent().getMinX()));
  240. double dy = (event.getSceneY() - (canvas.getBoundsInParent().getHeight()/2 + canvas.getBoundsInParent().getMinY()));
  241.  
  242.  
  243. canvas.setScale( scale);
  244. canvas.setPivot(f*dx,f*dy);
  245.  
  246. event.consume();
  247.  
  248. }
  249.  
  250. };
  251.  
  252.  
  253. }
  254.  
  255. public static void main(String[] args) {
  256. launch(args);
  257. }
  258.  
  259. @Override
  260. public void start(Stage stage) {
  261.  
  262. Group group = new Group();
  263.  
  264. // create canvas
  265. PannableCanvas canvas = new PannableCanvas();
  266.  
  267. // we don't want the canvas on the top/left in this example => just
  268. // translate it a bit
  269. canvas.setTranslateX(100);
  270. canvas.setTranslateY(100);
  271.  
  272. // create sample nodes which can be dragged
  273. NodeGestures nodeGestures = new NodeGestures( canvas);
  274.  
  275. Label label1 = new Label("Draggable node 1");
  276. label1.setTranslateX(10);
  277. label1.setTranslateY(10);
  278. label1.addEventFilter( MouseEvent.MOUSE_PRESSED,sceneGestures.getOnScrollEventHandler());
  279.  
  280. stage.setScene(scene);
  281. stage.show();
  282.  
  283. canvas.addGrid();
  284.  
  285. }
  286. }

经过一些关于缩放的想法,我得出结论,这将是一个好主意

>编写一个独立的缩放辅助方法来简化缩放功能
>也可以使用相同的方法支持捏合到缩放手势

所以我写了以下帮助方法

  1. /** Allow to zoom/scale any node with pivot at scene (x,y) coordinates.
  2. *
  3. * @param node
  4. * @param delta
  5. * @param x
  6. * @param y
  7. */
  8. public static void zoom(Node node,double factor,double x,double y) {
  9. double oldScale = node.getScaleX();
  10. double scale = oldScale * factor;
  11. if (scale < 0.05) scale = 0.05;
  12. if (scale > 50) scale = 50;
  13. node.setScaleX(scale);
  14. node.setScaleY(scale);
  15.  
  16. double f = (scale / oldScale)-1;
  17. Bounds bounds = node.localToScene(node.getBoundsInLocal());
  18. double dx = (x - (bounds.getWidth()/2 + bounds.getMinX()));
  19. double dy = (y - (bounds.getHeight()/2 + bounds.getMinY()));
  20.  
  21. node.setTranslateX(node.getTranslateX()-f*dx);
  22. node.setTranslateY(node.getTranslateY()-f*dy);
  23. }
  24.  
  25. public static void zoom(Node node,ScrollEvent event) {
  26. zoom(node,Math.pow(1.01,event.getDeltaY()),event.getSceneX(),event.getSceneY());
  27. }
  28. public static void zoom(Node node,ZoomEvent event) {
  29. zoom(node,event.getZoomFactor(),event.getSceneY());
  30. }

允许我在任何节点上注册缩放功能,如:

  1. myView.setOnScroll(event -> GUITools.zoom(myView,event)); // mouse scroll wheel zoom
  2. myView.setOnZoom(event -> GUITools.zoom(myView,event)); // pinch to zoom

并做了…

猜你在找的Java相关文章