godot-docs/tutorials/2d/viewport_and_canvas_transfo...

100 lines
4.2 KiB
ReStructuredText
Raw Normal View History

2016-02-08 23:45:57 +01:00
.. _doc_viewport_and_canvas_transforms:
Viewport and canvas transforms
==============================
2016-02-06 01:54:33 +01:00
Introduction
------------
This tutorial is created after a topic that is a little dark for most
users, and explains all the 2D transforms going on for nodes from the
moment they draw their content locally to the time they are drawn into
the screen.
2016-02-15 18:18:42 +01:00
Canvas transform
2016-02-06 01:54:33 +01:00
----------------
2016-02-08 23:45:57 +01:00
As mentioned in the previous tutorial :ref:`doc_canvas_layers`, every
2016-02-06 01:54:33 +01:00
CanvasItem node (remember that Node2D and Control based nodes use
CanvasItem as their common root) will reside in a *Canvas Layer*. Every
2016-02-15 18:18:42 +01:00
canvas layer has a transform (translation, rotation, scale, etc.) that
can be accessed as a :ref:`Matrix32 <class_Matrix32>`.
2016-02-06 01:54:33 +01:00
By default, nodes are drawn in Layer 0, in the built-in canvas. To put
2016-02-15 18:18:42 +01:00
nodes in a different layer, a :ref:`CanvasLayer <class_CanvasLayer>`
2016-02-06 01:54:33 +01:00
node can be used. This was covered in the previous tutorial anyway, just
refreshing.
2016-02-15 18:18:42 +01:00
Global canvas transform
2016-02-06 01:54:33 +01:00
-----------------------
Viewports also have a Global Canvas transform (also a
2016-02-15 18:18:42 +01:00
:ref:`Matrix32 <class_Matrix32>`). This is the master transform and
affects all individual *Canvas Layer* transforms. Generally this
transform is not of much use, but is used in the CanvasItem Editor
in Godot's editor.
2016-02-06 01:54:33 +01:00
2016-02-15 18:18:42 +01:00
Stretch transform
2016-02-06 01:54:33 +01:00
-----------------
Finally, viewports have a *Stretch Transform*, which is used when
resizing or stretching the screen. This transform is used internally by
2016-02-08 23:45:57 +01:00
the :ref:`doc_multiple_resolutions`, but can also be requested to the viewport.
2016-02-06 01:54:33 +01:00
2016-02-15 18:18:42 +01:00
Input events received in the :ref:`Node._input_event() <class_Node__input_event>`
2016-02-06 01:54:33 +01:00
callback are multiplied by this transform, but lack the ones above. To
convert InputEvent coordinates to local CanvasItem coordinates, the
:ref:`CanvasItem.make_input_local() <class_CanvasItem_make_input_local>`
2016-02-06 01:54:33 +01:00
function was added for convenience.
2016-02-15 18:18:42 +01:00
Transform order
2016-02-06 01:54:33 +01:00
---------------
For a coordinate in CanvasItem local properties to become an actual
screen coordinate, the following chain of transforms must be applied:
.. image:: /img/viewport_transforms2.png
2016-02-15 18:18:42 +01:00
Transform functions
2016-02-06 01:54:33 +01:00
-------------------
Obtaining each transform can be achieved with the following functions:
2016-02-15 18:18:42 +01:00
+----------------------------------+--------------------------------------------------------------------------------------+
| Type | Transform |
+==================================+======================================================================================+
| CanvasItem | :ref:`CanvasItem.get_global_transform() <class_CanvasItem_get_global_transform>` |
+----------------------------------+--------------------------------------------------------------------------------------+
| CanvasLayer | :ref:`CanvasItem.get_canvas_transform() <class_CanvasItem_get_canvas_transform>` |
+----------------------------------+--------------------------------------------------------------------------------------+
| CanvasLayer+GlobalCanvas+Stretch | :ref:`CanvasItem.get_viewport_transform() <class_CanvasItem_get_viewport_transform>` |
+----------------------------------+--------------------------------------------------------------------------------------+
2016-02-06 01:54:33 +01:00
Finally then, to convert a CanvasItem local coordinates to screen
coordinates, just multiply in the following order:
::
var screen_coord = get_viewport_transform() + ( get_global_transform() + local_pos )
Keep in mind, however, that it is generally not desired to work with
screen coordinates. The recommended approach is to simply work in Canvas
2016-02-15 18:18:42 +01:00
coordinates (``CanvasItem.get_global_transform()``), to allow automatic
2016-02-06 01:54:33 +01:00
screen resolution resizing to work properly.
2016-02-15 18:18:42 +01:00
Feeding custom input events
2016-02-06 01:54:33 +01:00
---------------------------
It is often desired to feed custom input events to the scene tree. With
the above knowledge, to correctly do this, it must be done the following
way:
::
var local_pos = Vector2(10,20) # local to Control/Node2D
var ie = InputEvent()
2016-02-15 18:18:42 +01:00
ie.type = InputEvent.MOUSE_BUTTON
ie.button_index = BUTTON_LEFT
ie.pos = get_viewport_transform() + (get_global_transform() + local_pos)
2016-02-06 01:54:33 +01:00
get_tree().input_event(ie)