viewport_and_canvas_transforms.rst 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. Viewport & Canvas Transforms
  2. ============================
  3. Introduction
  4. ------------
  5. This tutorial is created after a topic that is a little dark for most
  6. users, and explains all the 2D transforms going on for nodes from the
  7. moment they draw their content locally to the time they are drawn into
  8. the screen.
  9. Canvas Transform
  10. ----------------
  11. As mentioned in the previous tutorial [[Canvas Layers]], every
  12. CanvasItem node (remember that Node2D and Control based nodes use
  13. CanvasItem as their common root) will reside in a *Canvas Layer*. Every
  14. canvas layer has a transform (translation, rotation, scale, etc) that
  15. can be accessed as a
  16. `Matrix32 <https://github.com/okamstudio/godot/wiki/class_matrix32>`__.
  17. By default, nodes are drawn in Layer 0, in the built-in canvas. To put
  18. nodes in a different layer, a
  19. `CanvasLayer <https://github.com/okamstudio/godot/wiki/class_canvaslayer>`__
  20. node can be used. This was covered in the previous tutorial anyway, just
  21. refreshing.
  22. Global Canvas Transform
  23. -----------------------
  24. Viewports also have a Global Canvas transform (also a
  25. `Matrix32 <https://github.com/okamstudio/godot/wiki/class_matrix32>`__
  26. ). This is the master transform and affects all individual *Canvas
  27. Layer* transforms. Generally this transform is not of much use, but is
  28. used in the CanvasItem Editor in Godot's editor.
  29. Stretch Transform
  30. -----------------
  31. Finally, viewports have a *Stretch Transform*, which is used when
  32. resizing or stretching the screen. This transform is used internally by
  33. the [[Tutorial Multires]], but can also be requested to the viewport.
  34. Input events received in the
  35. `Node.\_input\_event(ev) <https://github.com/okamstudio/godot/wiki/class_node#_input_event>`__
  36. callback are multiplied by this transform, but lack the ones above. To
  37. convert InputEvent coordinates to local CanvasItem coordinates, the
  38. `CanvasItem.make\_input\_local(ev) <https://github.com/okamstudio/godot/wiki/class_canvasitem#make_input_local>`__
  39. function was added for convenience.
  40. Transform Order
  41. ---------------
  42. For a coordinate in CanvasItem local properties to become an actual
  43. screen coordinate, the following chain of transforms must be applied:
  44. .. image:: /img/viewport_transforms2.png
  45. Transform Functions
  46. -------------------
  47. Obtaining each transform can be achieved with the following functions:
  48. | \|Type: \| Transform\|
  49. | \|CanvasItem \|
  50. `CanvasItem.get\_global\_transform() <https://github.com/okamstudio/godot/wiki/class_canvasitem#get_global_transform>`__
  51. \|
  52. | \|CanvasLayer\|
  53. `CanvasItem.get\_canvas\_transform() <https://github.com/okamstudio/godot/wiki/class_canvasitem#get_canvas_transform>`__
  54. \|
  55. | \|CanvasLayer+GlobalCanvas+Stretch \|
  56. `CanvasItem.get\_viewport\_transform() <https://github.com/okamstudio/godot/wiki/class_canvasitem#get_viewport_transform>`__
  57. \|
  58. Finally then, to convert a CanvasItem local coordinates to screen
  59. coordinates, just multiply in the following order:
  60. ::
  61. var screen_coord = get_viewport_transform() + ( get_global_transform() + local_pos )
  62. Keep in mind, however, that it is generally not desired to work with
  63. screen coordinates. The recommended approach is to simply work in Canvas
  64. coordinates (CanvasItem.get\_global\_transform()), to allow automatic
  65. screen resolution resizing to work properly.
  66. Feeding Custom Input Events
  67. ---------------------------
  68. It is often desired to feed custom input events to the scene tree. With
  69. the above knowledge, to correctly do this, it must be done the following
  70. way:
  71. ::
  72. var local_pos = Vector2(10,20) # local to Control/Node2D
  73. var ie = InputEvent()
  74. ie.type=InputEvent.MOUSE_BUTTON
  75. ie.button_index=1 #left click
  76. ie.pos = get_viewport_transform() + ( get_global_transform() + local_pos )
  77. get_tree().input_event(ie)
  78. *Juan Linietsky, Ariel Manzur, Distributed under the terms of the `CC
  79. By <https://creativecommons.org/licenses/by/3.0/legalcode>`__ license.*