Viewport and canvas transforms
Introduction
This is an overview of the 2D transforms going on for nodes from themoment they draw their content locally to the time they are drawn ontothe screen. This overview discusses very low-level details of the engine.
The goal of this tutorial is to teach a way for feeding input events to theInput with a position in the correct coordinate system.
A more extensive description of all coordinate systems and 2d transforms isavailable in2D coordinate systems and 2D transforms.
Canvas transform
As mentioned in the previous tutorial,Canvas layers, everyCanvasItem node (remember that Node2D and Control based nodes useCanvasItem as their common root) will reside in aCanvas Layer. Everycanvas layer has a transform (translation, rotation, scale, etc.) thatcan be accessed as aTransform2D.
Also covered in the previous tutorial, nodes are drawn by default in Layer 0,in the built-in canvas. To put nodes in a different layer, aCanvasLayer node can be used.
Global canvas transform
Viewports also have a Global Canvas transform (also aTransform2D). This is the master transform andaffects all individualCanvas Layer transforms. Generally, this is primarilyused in Godot's CanvasItem Editor.
Stretch transform
Finally, viewports have aStretch Transform, which is used whenresizing or stretching the screen. This transform is used internally (asdescribed inMultiple resolutions), but can also be manually seton each viewport.
Input events are multiplied by this transform, but lack the ones above. Toconvert InputEvent coordinates to local CanvasItem coordinates, theCanvasItem.make_input_local()function was added for convenience.
Window transform
The root viewport is aWindow. In order to scale andposition theWindow's content as described inMultiple resolutions,eachWindow contains awindow transform. It is forexample responsible for the black bars at theWindow's sides so that theViewport is displayed with a fixed aspect ratio.
Transform order
To convert a CanvasItem local coordinate to an actual screen coordinate,the following chain of transforms must be applied:

Transform functions
The above graphic shows some available transform functions. All transforms are directed from rightto left, this means multiplying a transform with a coordinate results in a coordinate systemfurther to the left, multiplying theaffine inverseof a transform results in a coordinate system further to the right:
# Called from a CanvasItem.canvas_pos=get_global_transform()*local_poslocal_pos=get_global_transform().affine_inverse()*canvas_pos
// Called from a CanvasItem.canvasPos=GetGlobalTransform()*localPos;localPos=GetGlobalTransform().AffineInverse()*canvasPos;
Finally, then, to convert a CanvasItem local coordinates to screen coordinates, just multiply inthe following order:
varscreen_coord=get_viewport().get_screen_transform()*get_global_transform_with_canvas()*local_pos
varscreenCoord=GetViewport().GetScreenTransform()*GetGlobalTransformWithCanvas()*localPos;
Keep in mind, however, that it is generally not desired to work with screen coordinates. Therecommended approach is to simply work in Canvas coordinates(CanvasItem.get_global_transform()
), to allow automatic screen resolution resizing to workproperly.
Feeding custom input events
It is often desired to feed custom input events to the game. With the above knowledge, to correctlydo this in the focused window, it must be done the following way:
varlocal_pos=Vector2(10,20)# Local to Control/Node2D.varie=InputEventMouseButton.new()ie.button_index=MOUSE_BUTTON_LEFTie.position=get_viewport().get_screen_transform()*get_global_transform_with_canvas()*local_posInput.parse_input_event(ie)
varlocalPos=newVector2(10,20);// Local to Control/Node2D.varie=newInputEventMouseButton(){ButtonIndex=MouseButton.Left,Position=GetViewport().GetScreenTransform()*GetGlobalTransformWithCanvas()*localPos,};Input.ParseInputEvent(ie);