logo

G

  • Tutorials
  • API
  • Examples
  • Plugins
  • Productsantv logo arrow
  • 6.1.26
  • Canvas
    • Introduction
    • Options
    • Built-in objects
    • Coordinate system
    • Scenegraph & Lifecycle
    • Event
    • OffscreenCanvas & Server-side Rendering
    • CustomElementRegistry
    • Frequently Asked Questions
  • Renderer
    • Introduction
    • Canvas Renderer
    • Canvaskit Renderer
    • SVG Renderer
    • WebGL Renderer
    • WebGPU Renderer
    • Custom Renderer
  • Camera
    • Introduction
    • Camera Parameters
    • Camera action
    • Camera animation
  • Event
    • Introduction
    • Event Object
    • Gesture & Drag'n'Drop
    • Frequently Asked Questions
  • Animation
    • Web Animations API
    • Lottie
  • Basic Shapes
    • Basic Concepts
    • DisplayObject
    • Group
    • Text
    • Circle
    • Ellipse
    • Rect
    • Image
    • Line
    • Polygon
    • Polyline
    • Path
    • HTML
  • Style System
    • Introduction
    • CSS Typed OM
    • Inheritance
    • CSS Properties & Values API
    • CSS Layout API
    • Pattern
    • Gradient
  • 3D
    • 材质
    • 几何
    • Mesh
    • 光源
    • 雾
    • 交互
  • Built-in Objects
    • EventTarget
    • Node
    • Element
    • Document
    • MutationObserver
    • Utils
  • GPGPU
    • Introduction
    • Programming Model
    • Kernel API
    • Principles of classical GPGPU implementation
    • webgpu-graph
  • Declarative programming
    • 使用 Web Components
  • Devtools
    • G 开发者工具
    • 内置的渲染统计信息
    • 第三方开发调试工具

Basic Concepts

Previous
Lottie
Next
DisplayObject

Resource

Ant Design
Galacea Effects
Umi-React Application Framework
Dumi-Component doc generator
ahooks-React Hooks Library

Community

Ant Financial Experience Tech
seeconfSEE Conf-Experience Tech Conference

Help

GitHub
StackOverflow

more productsMore Productions

Ant DesignAnt Design-Enterprise UI design language
yuqueYuque-Knowledge creation and Sharing tool
EggEgg-Enterprise-class Node development framework
kitchenKitchen-Sketch Tool set
GalaceanGalacean-Interactive solution
xtechLiven Experience technology
© Copyright 2025 Ant Group Co., Ltd..备案号:京ICP备15032932号-38

Loading...

First, you need to clarify some concepts, such as bounding boxes, coordinates, anchor points, transform centers, etc. Understanding them helps to better use the specific API. Understanding them helps to better use the specific API.

Hierarchy

In scene graph we learned that it is possible to construct parent-child relationships between graphs, and that such parent-child relationships can sometimes be counter-intuitive, for example adding a child node text (Text) to a line (Line).

line.appendChild(text);

But essentially this hierarchy just defines a parent-child relationship that is taken into account when computing the transformation. For example, we don't need to move the line and the text separately anymore, based on this parent-child relationship, we can just move the line and the text will follow it. During the transformation, the position of the text relative to the line remains unchanged, i.e., the coordinates of the text in the local coordinate system of the parent line remain unchanged.

Bounding Box

To simplify the calculation, we need to wrap the figure in a regular geometry, usually using [axis-aligned bounding boxes](https://developer.mozilla.org/zh-CN/docs/Games/Techniques/3D_collision_detection#axis- aligned_bounding_boxes%EF%BC%88aabb%E5%8C%85%E5%9B%B4%E7%9B%92%EF%BC%89) (Axis Aligned Bounding Box), which is a non-rotating cube, and the following figure from

https://developer.mozilla.org/zh-CN/docs/Games/Techniques/3D_collision_detection#axis-aligned_bounding_boxes%EF%BC%88aabb%E5%8C%85%E5%9B%B4%E7%9B%92%EF%BC%89

AABB

We use the following definitions.

interface AABB {
center: [number, number, number]; // 中心坐标
halfExtents: [number, number, number]; // 长宽高的一半
min: [number, number, number]; // 左上角坐标
max: [number, number, number]; // 右下角坐标
}

AABB boxes have different meanings in different situations. Let's first look at what a wraparound box represents for a single figure. The figure below shows a circle with a radius of 100 and a border width of 20. For better illustration we have set the border to be translucent and it also has a shadow effect.

For the user, it is often desirable to use the geometric definition of the shape, e.g. the size of the circle is 100 * 100, and we don't want the circle to be picked up even if the mouse slides over the shaded area.

And for rendering pipelines, these style properties obviously need to be taken into account, e.g.

  • Correctly erasing the drawn area in the dirty rectangle rendering will result in a poorly erased "shadow" once the increase in the size of the enclosing box due to the shadow is not taken into account
  • Culling plug-ins also needs to be considered, for example a drawing should not be rejected even if only the shaded part appears in the viewport

It is easy to define geometric enclosing boxes based on different types of graphs.

  • Geometry Bounds。Determined only by the geometric definition of the figure, disregard most of the drawing properties(like radius of Circle , width/height of Rect, path definition of Path) and transformation. We can use getGeometryBounds to get them.

Once a node has child nodes, it should be considered in the calculation of the enclosing box. For example, if we want to rotate it as a whole, we need to find the center of the enclosing box as the center of rotation. Therefore, the following enclosing boxes are considered for the hierarchy.

  • Bounds。It is calculated in the world coordinate system and obtained by merging the Geometry Bounds of itself and all its children. Users usually use this wrapping box most often. We can use getBounds to get them.
  • Local Bounds。The only difference with Bounds is that it is calculated in the local coordinate system of the parent node. We can use getLocalBounds to get them.
  • Render Bounds。Calculated in the world coordinate system, based on Bounds, influenced by some rendering properties, such as border width, shadows, some filters, etc., while merging the Render Bounds of all child nodes. We can use getRenderBounds to get them.

In the figure below, ul1 has two word nodes, li1 and li2, which are not considered in the calculation of its own Geometry Bounds, but are needed in the calculation of Bounds. Since ul1 also has shadows, its Render Bounds are one turn larger.

bounds

Anchor

How should the anchor point (origin) of a graph be defined? We can define it based on Geometry Bounds, with the value range [0, 0] ~ [1, 1], where [0, 0] represents the upper left corner of Geometry Bounds and [1, 1] represents the lower right corner. And the default anchor points for different shapes due to different geometry definitions are as follows.

  • The center of Circle and Ellipse is [0.5, 0.5]
  • The top left corner of Rect, Image, Line, Polyline, Polygon and Path is [0, 0].
  • We should always use textBaseline and textAlign to set the anchor of Text.
  • Since Group has no geometry bounds, so its anchor is [0, 0].

Sometimes we want to change the definition of the origin of a base graph, for example by defining the anchor of Rect as the center instead of the top left corner, example:

rect.style.anchor = [0.5, 0.5];
anchor

Does that anchor point change affect the coordinates of the drawing in the local/world coordinate system? The answer is no. We just put the origin of the graph in these coordinates, and no matter how the definition of the origin is changed, the "location" coordinates remain unchanged.

rect.getPosition(); // [200, 200]
rect.style.anchor = [0.5, 0.5];
rect.getPosition(); // [200, 200]

Transform Origin

When scaling or rotating a drawing, you need to specify a transformation center. For example, if you use scale(2) as the center of a circle, you will get a completely different result than if you use the upper left corner of the Geometry Bounds of a circle as the center of the transformation. In a library like gl-matrix, the RTS transformation matrix is usually obtained by specifying the transformation center.

mat4.fromRotationTranslationScaleOrigin();

In some scenarios, it is easier to use some literal or percentage definitions. CSS, for example, provides the transform-origin property, which is defined exactly relative to Bounds. The image below is from: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin.

transform origin

When we want to achieve "rotation around the center", we only need to use literal amounts or percentages, so that we can avoid having to do Bounds fetching.

group.style.transformOrigin = 'center';
group.style.transformOrigin = 'center center';
group.style.transformOrigin = '50% 50%';