Coordinates and units
Drawings and 3D scenes put the origin in the middle and point Y up; images, the UI and the window start at the top-left and point Y down. Each part of the API works in one of these spaces, in its own unit.
Which way is up
| Space | Origin | Y | Unit |
|---|---|---|---|
| Canvas | the canvas's center | up | canvas pixels |
| Scene | the scene's origin | up | world units |
| Image | the top-left pixel | down | image pixels |
| UI | the top-left of your content area | down | UI px |
| Window | the window's top-left | down | the window's logical pixels |
Which parts of the API use which space:
- Canvas:
datumhue.drawshapes, and their physics bodies. - Scene:
datumhue.scenenodes, and their physics bodies. - Image:
datumhue.imagepixels, andImage:cursor. - UI: widget sizes and positions,
UiElement.boundsanddatumhue..input. app_ mouse_ position - Window:
datumhue.input.mouse_positionanddatumhue.input.touches.
A shape at vec2(0, 0) sits in the middle of its canvas, and a larger y
moves it up. A pixel at (0, 0) is an image's top-left corner, and a
larger y moves it down. To carry a point from a Y-up space to a Y-down
one, flip its y. On a canvas, DrawCanvas:screen_to_world and
DrawCanvas:world_to_screen do the whole conversion, pan, zoom and
letterboxing included.
Depth. A shape's depth is the z of its pos: give it a vec3, and a
larger z draws in front. Shapes made without a z stack in the order you
made them, the newest on top.
Physics works in the space of what a body is attached to: a shape's
body moves in canvas pixels, a scene node's in world units. There is
nothing to convert. Gravity, datumhue.physics.gravity, points down the
Y axis until you change it.
Angles
Angles are in radians. A 2D rotation, such as DrawPrimitive.rotation,
is a number of radians about the z axis, counterclockwise as Y points up.
A 3D orientation, such as SceneNode.rotation, is a Quat. The one
angle in degrees is a color's hue, in color.hsl and color.oklch, as
in CSS.
UI px
Your UI is measured in UI px: the window's logical pixels divided by
the zoom (datumhue.screen.zoom), the comfort setting the person using
the workstation picks. At 100% a UI px is one CSS pixel in a browser and
one logical pixel natively; at 125% a 100 UI px button spans 125 logical
pixels. Under a design resolution, a UI px is a pixel of the design
canvas as scaled to fit the window, times the zoom. The display's own
scale is always applied on top.
These are in UI px, from the top-left of your content area:
- every size and position you give a widget, and
UiElement.bounds; datumhue.screen.widthanddatumhue.screen.height;datumhue.and the positions theinput. app_ mouse_ position datumhue.debug.inputcalls take;UiElement:mouse_position, measured from the element's own top-left.
They agree with each other at every zoom and stretch mode, so a pointer
position compared with bounds is always right. What you draw agrees
too: Image:cursor, a chart's cursor, hover, pan, zoom and brush, and a
shader's pointer input all land on what is drawn under the pointer.
The window's own logical pixels stay unscaled by the zoom:
datumhue.input.mouse_position, datumhue.input.touches and the
window_resized event. To follow your own size in UI px, use
UiElement:on_resize on datumhue.ui.root.
Fit any window size shows the knobs that set
the window, the design resolution and the zoom.
Lengths in the UI
A UI length (a size, a position, a gap, padding, a margin or a border) is a number or a string:
| Form | Means |
|---|---|
24 | 24 UI px |
"auto" | sized by the layout |
"24px" | 24 UI px |
"50%" | 50% of the parent's size |
"10vw" | 10% of the viewport's width |
"10vh" | 10% of the viewport's height |
"5vmin" | 5% of the viewport's smaller side |
"5vmax" | 5% of the viewport's larger side |
See also
Reference used on this page: datumhue.draw datumhue.scene datumhue.image Image:cursor UiElement.bounds datumhue.input.app_mouse_position datumhue.input.mouse_position datumhue.input.touches DrawCanvas:screen_to_world DrawCanvas:world_to_screen datumhue.physics.gravity DrawPrimitive.rotation SceneNode.rotation datumhue.color.hsl datumhue.color.oklch datumhue.screen.zoom datumhue.screen.width datumhue.screen.height datumhue.debug.input UiElement:mouse_position UiElement:on_resize datumhue.ui.root