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 开发者工具
    • 内置的渲染统计信息
    • 第三方开发调试工具

DisplayObject

Previous
Basic Concepts
Next
Group

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...

DisplayObject is the base class of all graph like Group, Circle, Text etc.

We tried to make it as compatible as possible with DOM Element, which in addition to reducing learning costs, allows us to take advantage of the existing Web ecosystem by disguising ourselves as a DOM Element, e.g.

  • Using CSS selectors for advanced queries.
  • Using Hammer.js for gesture
  • Using Interact.js for Drag'n'Drop and Resize
  • Taking over D3's rendering implementation
  • Taking over Observable Plot's rendering implementation

Inherited from

Element

id

https://developer.mozilla.org/en-US/docs/Web/API/Element/id

Globally unique identifier, can be queried by [getElementById](/en/api/display-object#advanced query).

const circle = new Circle({
id: 'my-circle-id',
style: {
r: 10,
},
});
circle.id; // 'my-circle-id'
canvas.getElementById('my-circle-id'); // circle

name

https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByName

Graph name, not required to be globally unique, can be queried by [getElementsByName](/en/api/display-object#advanced query).

const circle = new Circle({
name: 'my-circle-name',
style: {
r: 10,
},
});
circle.name; // 'my-circle-name'
canvas.getElementsByName('my-circle-name'); // [circle]

className

https://developer.mozilla.org/en-US/docs/Web/API/Element/className

The class name owned by the graphic, which can be used to get/set the class name of the graphic. It can be queried later using [getElementsByClassName](/en/api/display-object#advanced query).

const circle = new Circle({
className: 'my-circle-classname',
style: {
r: 10,
},
});
circle.className; // 'my-circle-classname'
canvas.getElementsByClassName('my-circle-classname'); // [circle]

You can use spaces to separate multiple class names, and then use classList read-only attribute to get a list of class names.

circle.className = 'c1 c2';
circle.classList; // ['c1', 'c2']

Not specifying a class name will return the empty string.

const group = new Group();
group.className; // ''

Finally, you can also use class as an alias when setting.

const group = new Group({
class: 'my-classname',
// className: 'my-classname'
});
group.setAttribute('class', 'my-classname');
// wrong, class is the kept keywords
group.class;

interactive

Whether to support responding to events, default is true. Can be turned off on some graphics that do not need to support interaction.

For example, we don't want the following circle to respond to the mouse mouseenter/leave event, example

const circle = new Circle({
interactive: false,
style: {
r: 100,
},
});
// or
circle.interactive = false;

It is recommended to use the pointerEvents attribute, so the above prohibited interactions are equivalent to

circle.style.pointerEvents = 'none';

Drawing Properties

The drawing properties are set by style and usually contain generic properties such as fill color, transparency, etc. Different types of shapes also have their own additional properties, for example, in the following rounded rectangle, the fill color fill and stroke color stroke are generic properties, while the top-left vertex position (x, y), the size width/height and the radius radius of the rectangle are additional properties.

const rect = new Rect({
style: {
// or using attrs
x: 200,
y: 100,
fill: '#1890FF',
stroke: '#F04864',
lineWidth: 4,
width: 300,
height: 200,
radius: 8,
},
});

Property names can also be hyphenated, so the following writeups are fully equivalent, see get/set property values for full usage.

const rect = new Rect({
'line-width': 4,
// lineWidth: 4,
});
rect.style.lineWidth = 4;
rect.style['line-width'] = 4;
rect.style.setProperty('lineWidth', 4);
rect.style.setProperty('line-width', 4);

Position

The initial position of the drawing in the local coordinate system is described by different properties depending on the type of drawing, and can be reset later by setLocalPosition.

const circle = new Cirle({
style: {
cx: 100,
cy: 100,
r: 100,
},
});
circle.getLocalPosition(); // [0, 0]

transform

We provide shortcuts for transformations in local coordinate systems, while keeping in line with CSS Transform, supporting the following transform-function transformations function.

  • Scaling
    • scale(x, y)
    • scaleX(x)
    • scaleY(x)
    • scaleZ(z)
    • scale3d(x, y, z)
  • Translation, 0 can be used without units, unitless is treated as px, the percentage is relative to the current graph bounding box
    • translate(0, 0) translate(0, 30px) translate(100%, 100%)
    • translateX(0)
    • translateY(0)
    • translateZ(0)
    • translate3d(0, 0, 0)
  • Rotation, support for deg rad turn, these angular units
    • rotate(0.5turn) rotate(30deg) rotate(1rad)
  • Stretch, support deg rad turn these angular units
    • skew(ax, ay)
    • skewX(a)
    • skewY(a)
  • Matrix
    • matrix()
    • matrix3d()
  • none
Initial valueApplicable elementsInheritableAnimatableComputed value
'none'allnoyes<transform>

Since the transformation is performed in a local coordinate system, the following write-ups are visually consistent.

// Using transform
const circle = new Circle({
style: {
transform: 'translate(100px, 100px)',
r: 100,
},
});
// or set cx/cy directly
const circle = new Circle({
style: {
cx: 100,
cy: 100,
r: 100,
},
});
// or using transform functions
const circle = new Circle({
style: {
r: 100,
},
});
circle.translateLocal(100, 100);

transformOrigin

Rotation and scaling centers, also called transform origin, are defined relative to Bounds.

Similar to CSS transform-origin, the following string writing is supported, separated by spaces.

  • One value
    • Length in px, e.g. 10px
    • Length in %, e.g. 50%
    • The keywords left, center, right, top, bottom are expressed as percentages, e.g. left equals 0%, center equals 50%.
  • Two values
    • The first is the length in px or %, or one of the left, center, or right keywords
    • The second is the length in px or %, or one of the top, center, or bottom keywords

Therefore the following write-ups are equivalent.

// r = 100
circle.style.transformOrigin = 'left';
circle.style.transformOrigin = 'left center'; // AABB horizontal left edge, vertical midpoint
circle.style.transformOrigin = '0 50%'; // The distance to the left edge of the AABB is 0 horizontally and 50% height from the top vertically
circle.style.transformOrigin = '0 100px'; // The distance to the left edge of the AABB is 0 horizontally and 100px vertically from the top

⚠️ Writing with three values is not supported at the moment.

Initial valueApplicable elementsInheritableAnimatableComputed value
-allnono<transform-origin>

Fill

opacity

The overall transparency of the graph, with values in the range [0, 1], supports both number and string types, so the following two ways of writing it are equivalent.

circle.style.opacity = 0.5;
circle.style.opacity = '0.5';
Initial valueApplicable elementsInheritableAnimatableComputed value
'1'allnoyes<number>

fillOpacity

The fill color transparency, in the range [0, 1], supports both number and string types, so the following two ways of writing are equivalent.

circle.style.fillOpacity = 0.5;
circle.style.fillOpacity = '0.5';
Initial valueApplicable elementsInheritableAnimatableComputed
'1'allyesyes<number>

fill

Fill color, supports string type, see <paint>:

circle.style.fill = 'red';
circle.style.fill = 'rgb(255, 0, 0)';
Initial valueApplicable elementsInheritableAnimatableComputed value
'none'allnoyes<paint>

fillRule

This attribute is a presentation attribute defining the algorithm to use to determine the inside part of a shape.

  • 'nonzero' Default https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule#nonzero
  • 'evenodd' https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule#evenodd

This example shows the fill effects of 'nonzero' and 'evenodd' in order.

fill rule

Stroke

strokeOpacity

Stroke transparency, which takes values in the range [0, 1], supports both number and string types, so the following two ways of writing it are equivalent.

circle.style.strokeOpacity = 0.5;
circle.style.strokeOpacity = '0.5';
Initial valueApplicable elementsInheritableAnimatableComputed value
'1'allyesyes<number>

stroke

Stroke color, supports string type, see <paint>:

circle.style.stroke = 'red';
circle.style.stroke = 'rgb(255, 0, 0)';
Initial valueApplicable elementsInheritableAnimatableComputed value
'none'allnoyes<paint>

lineWidth

The width of the stroke. Unlike the familiar CSS box model, half of the width of the border is inside the graphic and half is outside the graphic. For example, the width of the enclosing box for the circle below is: r + lineWidth / 2 = 110

supports number and string types, the former defaulting to length values in px, with the following writing equivalents.

circle.style.lineWidth = 1;
circle.style.lineWidth = '1';
circle.style.lineWidth = '1px';
Initial valueApplicable elementsInheritableAnimatableComputed value
'1'allyesyes<percentage> <length>

lineCap

Endpoint style, supporting the following values.

  • 'butt' Default value. The end of the line segment ends in a square.
  • 'round' The line segment ends in a circle.
  • 'square' The line segment ends in a square, but adds a rectangular area with the same width as the line segment and half the height of the line segment's thickness.

https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/lineCap

lineJoin

Supporting the following values.

  • 'miter' Default. An additional diamond-shaped area is formed by extending the outer edges of the connected sections so that they intersect at a point. The effect of this setting can be seen with the miterLimit property.
  • 'round' Draws the shape of the corner by filling an additional, circular sector with the center of the circle at the end of the connected section. The radius of the rounded corner is the width of the line segment.
  • 'bevel' An additional triangular-base area is filled in at the end of the connected sections, each with its own separate rectangular corner.

https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/lineJoin

miterLimit

The default value for SVG and Canvas2D is different, the former is 4 and the latter is 10. We set Path Polyline Polygon to 4 and the rest to 10. api/basic/polygon) These three graphs are set to 4, and the rest are set to 10.

https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/miterLimit

lineDash

Use number[] to describe the alternate line segments and spacing. Reference can be made to: https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/setLineDash

Currently only the form [dash, gap] is supported, if there is only one element in the array, i.e. [dash] is equivalent to [dash, dash].

Applying animation to it can achieve handwriting animation effect.

stroke animation
Initial valueApplicable elementsInheritableAnimatableComputed value
-allyesyes

lineDashOffset

Dashed line offset, type number, transform it to achieve marching ants animation

marching ants animation
Initial valueApplicable elementsInheritableAnimatableComputed value
'0'allyesyes<percentage> <length>

Shadow

Add shadow effect at the bottom of the shape, support configuring shadow color, blur radius and horizontal/vertical offset distance. example.

Shadows do not affect the graph's Geometry Bounds, e.g. in the following figure, after adding a shadow to a circle with a radius of 100, the geometry wrapping box size remains the same.

circle.getBounds(); // { halfExtents: [100, 100] }
circle.style.shadowBlur = 20;
circle.getBounds(); // { halfExtents: [100, 100] }
outer shadow

Of course outer shadows increase the Render Bounds, inner shadows do not.

Finally, shadows can have a very big impact on rendering performance.

shadowType

We currently support two kinds of shadow.

  • 'outer' Outer Shading, which is also the default value for this property. The shadow appears on the outside of the drawing fill or stroke.
  • 'inner' Internal shading. As the name implies the shadows are inside the graph, as shown in the figure below.
inner shadow

shadowColor

Shade color, supports string type, for example '#1890FF'. Gradient or pattern writing is not supported.

Initial valueApplicable elementsInheritableAnimatableComputed value
-allnoyes<color>

shadowBlur

The blurring degree of the shading effect, number type, negative numbers are not allowed. Larger means more blurred, 0 means no blurring effect.

Initial valueApplicable elementsInheritableAnimatableComputed value
-allnoyes<number>

shadowOffsetX

Horizontal offset, supports number or string types, e.g. negative numbers move shadows to the left, positive numbers to the right.

Initial valueApplicable elementsInheritableAnimatableComputed value
-allnoyes<percentage> <length>

shadowOffsetY

Vertical offset, e.g. a negative number moves the shadow up, a positive number down.

Initial valueApplicable elementsInheritableAnimatableComputed value
-allnoyes<percentage> <length>

Filter

Filters can perform some processing on the generated image, such as blurring, highlighting, boosting contrast, etc. The following implementations are available on the web side.

  • CSS Filter: https://developer.mozilla.org/en-US/docs/Web/CSS/filter
  • Canvas Filter: https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/filter
  • SVG Filter: https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/filter
  • Post Processing in WebGL.

Referring to the CSS Filter syntax, we support applying one or more filter effects to a shape, example.

circle.style.filter = 'blur(5px)';
circle.style.filter = 'blur(5px) brightness(0.4)'; // Stackable
filters

Filters can currently be used in the g-canvas/svg/webgl renderer with the following caveats.

  • Due to poor Canvas Filter support, mainly Safari does not support, filters are not displayed properly in Safari using g-canvas
  • g-canvas and g-svg differ slightly in some filter effects
  • Can be applied to all base graphs and Groups
  • This property does not support animation at this time

blur

Applies a Gaussian blur to the input image. where radius defines the standard deviation value of the Gaussian function, or how many pixels on the screen blend into each other so that larger values will produce more blur, with a default value of 0. This parameter can be specified as a CSS length, but does not accept percentage values.

As with shadows, blurring also does not affect the size of the geometry bounds for graphics.

circle.style.filter = 'blur(5px)';

The following figure shows the blurring effect of 2px 4px and 10px in order, example.

blur filter

brightness

Applies a linear multiplier to the input image to make it lighter or darker, with a default value of 1. A value of 0% will create an all-black image. A value of 100% will leave the input unchanged. Other values are linear multipliers of the effect. Values greater than 100% provide brighter results.

circle.style.filter = 'brightness(2)';
circle.style.filter = 'brightness(200%)';

The following figure shows the bright effects of 0 100% and 200% in order, example.

brightness filter

drop-shadow

To display the shadows under the image, you can set the shadow color, offset and blur effect by passing in the following parameters in order.

  • offset-x Describes the horizontal offset distance of the shadow in px
  • offset-y Describes the vertical offset distance of the shadow in px
  • blur-radius The larger the value, the more ambiguous it is, in px, no negative numbers allowed
  • color

The shading does not affect the size of the geometry bounding box of the graph.

circle.style.filter = 'drop-shadow(16px 16px 10px black)';

The following figure shows the effect of the above configuration in turn, example.

drop-shadow filter

contrast

Adjusts the contrast of the image. When the value is 0%, the image becomes completely black. When the value is 100%, the image does not change at all.

circle.style.filter = 'contrast(2)';
circle.style.filter = 'contrast(200%)';

The following figure shows the contrast effect of 0, 1 and 10 in order,example.

contrast filter

grayscale

Converts the image to a gray picture. When the value is 100%, the image turns completely gray. When the value is 0%, the image does not change at all.

circle.style.filter = 'grayscale(1)';
circle.style.filter = 'grayscale(100%)';

The following figure shows the grayscale effect of 0 50% and 100% in order, example.

grayscale filter

saturate

Saturation is applied to the image. When the value is 0%, the image is not saturated at all. When the value is 100%, there is no change in the image.

circle.style.filter = 'saturate(1)';
circle.style.filter = 'saturate(100%)';

The following figure shows the saturation effect at 0 50% and 100% in order, example.

saturate filter

sepia

Applies sepia processing to the image (nostalgic style). When the value is 100%, the image becomes completely sepia. When the value is 0%, the image does not change at all.

circle.style.filter = 'sepia(1)';
circle.style.filter = 'sepia(100%)';

The following figure shows the results of 0 50% and 100% processing in order, example.

saturate filter

hue-rotate

Applying hue rotation to the input image sets the value of the color ring angle at which the image will be adjusted. The image does not change when the value is 0deg.

circle.style.filter = 'hue-rotate(30deg)';
circle.style.filter = 'hue-rotate(180deg)';

The following figure shows the effect of 0, 90deg and 180deg processing in turn, example.

saturate filter

invert

Inverts the color of the input image. amount defines the percentage of conversion, 100% means complete inversion, 0% means no change in the image.

circle.style.filter = 'invert(1)';
circle.style.filter = 'invert(100%)';

The following figure shows in turn the effect of 0, 50% and 100% inversions, example.

saturate filter

zIndex

Similar to CSS's z-index property, used to control the rendering order, it needs to be noted that

  1. Only affects the rendering order, and does not change the node structure in the scene graph.
  2. Effective only in the current context.
  3. The default display order is the order in which the scenes are added, with those added later on top of the previously added elements.
Initial valueApplicable elementsInheritableAnimatableComputed value
'0'allnono<number>

For example, in the scene below, li2 is displayed on top of li1 by default because li2 was added to the canvas after li1. If you want to change this display order, you can modify the zIndex of li1:

// ul1 -> li1
// -> li2
// ul2 -> li3
li1.style.zIndex = 1; // li1 在 li2 之上

For example, even though li2 has a much larger zIndex than ul2, it can only be under ul2 because ul1 is smaller than ul2, example

z-index

For compatibility with older versions, we also provide the following methods:

nameparametersreturn valueremarks
setZIndexnumber--
toFront---
toBack---
const group = new Group();
group.setZIndex(100);
// or group.setAttribute('zIndex', 100);
// or group.style.zIndex = 100;

visibility

To control the visibility of the graph, see. https://developer.mozilla.org/en-US/docs/Web/CSS/visibility

For compatibility with older versions, the following methods are also provided.

nameparametersreturn valueremarks
hide---
show---

Therefore the following write-ups are equivalent.

const group = new Group();
group.style.visibility = 'hidden';
// or group.setAttribute('visibility', 'hidden');
// or group.hide();
group.style.visibility = 'visible';
// or group.setAttribute('visibility', 'visible');
// or group.show();
Initial valueApplicable elementsInheritableAnimatableComputed value
'visible'allyesno<keywords>

There are two points to note about visibility.

  1. Hidden graphics can still be picked up, so use pointerEvents
  2. Hidden elements still need to participate in enclosing box operations, i.e. they still occupy space. If you want to remove the element completely, you should use removeChild

clipPath

Use clipping to create a displayable region of an element, with the parts inside the region shown and the parts outside the region hidden. See CSS's clip-path. The value of this property can be any shape, such as Circle, Rect, etc. The same clipping region can be shared by multiple shapes. Finally, the crop region also affects the pickup area of the shapes, example.

For example, if we want to create a picture that is cropped into a circle, so that the cropping area is just in the center of the picture (size 200 * 200), we can set the world coordinates of the circle in the cropping area to [100, 100]. example.

const image = new Image({
style: {
x: 0,
y: 0,
width: 200,
height: 200,
clipPath: new Circle({
style: {
cx: 100,
cy: 100,
r: 50,
},
}),
},
});

It is also possible to set the cropping area after creating the drawing, so the above writeup is equivalent to:

const image = new Image({
style: {
//...
},
});
image.style.clipPath = new Circle({
style: {
cx: 100,
cy: 100,
r: 50,
},
});
// or
image.setClip(
new Circle({
style: {
cx: 100,
cy: 100,
r: 50,
},
}),
);

When we want to clear the cropping area, we can set it to null.

image.style.clipPath = null;
// or
image.setClip(null);

Caveats

The crop area graphic itself is also supported to modify the property, and affected by it, the cropped graphic will be redrawn immediately. For example, with animation system we can transform the cropped area graphic to achieve the following effect, example.

// Apply animation to clipped areas
clipPathCircle.animate(
[{ transform: 'scale(1)' }, { transform: 'scale(1.2)' }],
{
duration: 1500,
iterations: Infinity,
},
);

We do not yet support composite clipped areas, such as custom graphics and Group.

Offset Path

In path-animation, we can use offsetPath to specify the trajectory of a drawing, applying a transformation to the offsetDistance property.

const circle = new Circle({
style: {
offsetPath: new Line({
style: {
// There is no need to set other drawing properties that are not related to trajectories
x1: 100,
y1: 100,
x2: 300,
y2: 100,
},
}),
r: 10,
},
});
const animation = circle.animate(
[{ offsetDistance: 0 }, { offsetDistance: 1 }],
{
duration: 3000,
easing: 'ease-in-out',
iterations: Infinity,
},
);

offsetPath

Specify path trajectory, currently support Line Path and Polyline these three graphics.

offsetDistance

The distance to travel from the start of the path, in the range of [0-1], where 0 is the start of the path and 1 is the end.

Initial valueApplicable elementsInheritableAnimatableComputed value
'0'allnoyes<number>

Cursor style

We can change the style of a graphic when the mouse hovers over it, by modifying the CSS style of the container.

The values supported by the cursor property can be found at https://developer.mozilla.org/zh-CN/docs/Web/CSS/cursor

const circle = new Circle({
style: {
//...
cursor: 'pointer',
},
});

Responding to interaction events

We can set how the graph responds to interaction events, such as displaying the mouse style when hitting a pickup, or increasing the pickup area.

pointerEvents

To set how the graph responds to interaction events, see. https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events

简而言之,fill stroke 和 visibility 都可以独立或组合影响拾取判定行为。目前支持以下关键词:

  • 'auto' Default value, equivalent to 'visiblepainted'.
  • 'none' Will never be the target of a response event.
  • 'visiblepainted' The following conditions are met before the event is responded to.
    • visibility takes 'visible' which means the graph is visible.
    • Trigger while fill takes a value other than 'none' in the graphics fill area. Or stroke takes a value other than 'none' when triggered in the drawing stroke area.
  • 'visiblefill' The following conditions are met before the event is responded to.
    • visibility takes 'visible' which means the graph is visible an not affected by the value of fill.
  • 'visiblestroke' The following conditions are met before the event is responded to.
    • visibility takes 'visible' which means the graph is visible an not affected by the value of stroke.
  • 'visible' The following conditions are met before the event is responded to.
    • visibility takes 'visible'.
    • Triggered in drawing fill or stroke area, not affected by fill and stroke values.
  • 'painted' The following conditions are met before the event is responded to.
    • Trigger while fill takes a value other than 'none' in the graphics fill area. Or stroke takes a value other than 'none' when the drawing stroke area is triggered. Not affected by the value of visibility.
  • 'fill' The following conditions are met before the event is responded to.
    • Triggered in graphics fill area, not affected by fill and visibility values.
  • 'stroke' The following conditions are met before the event is responded to.
    • Triggered in graphics fill area, not affected by stroke and visibility values.
  • 'all' The events are responded to whenever the fill and stroke areas of the drawing are entered. So it will not be affected by fill stroke [visibility](/en/api/ basic/display-object#visibility) is affected by the value of

In this example, we set the property to stroke, so the filled area will not respond to events.

pointer-events stroke

In this example, we can easily control the interactivity based on the inheritance mechanism.

// The entire canvas does not respond to interaction events
canvas.document.documentElement.style.pointerEvents = 'none';
Initial valueApplicable elementsInheritableAnimatableComputed value
'auto'allyesno<keywords>

increasedLineWidthForHitTesting

When lineWidth is small, the interactable area becomes smaller, sometimes we want to increase this area to make the "thin line" easier to be picked up. Note that this property does not affect the rendering effect.

In the example below, we set this property to 50, so that the line width is equal to 50 + the original line width when picking up, making it easier to pick up when close:

line.style.increasedLineWidthForHitTesting = 50;

Also like lineWidth, this property also extends to the sides, and in the image below the unfilled Path internal pickup area has been enlarged.

Initial valueApplicable elementsInheritableAnimatableComputed value
'0'allnono<percentage> <length>

Transformation operations

We offer a range of transformation methods.

Translation

For translation operations, we provide APIs for moving absolute/relative distances in local/world coordinate systems.

method nameparametersreturn valueremarks
translate[number, number] or number, number or number-Move relative to current position in world coordinate system
translateLocal[number, number] or number, number or number-Move relative to current position in local coordinate system
setPosition[number, number] or number, number or number-Sets the position in the world coordinate system.
setLocalPosition[number, number] or number, numberor number-Set the position under the local coordinate system
getPosition-[number, number]Get the position in the world coordinate system
getLocalPosition-[number, number]Get the position in the local coordinate system

translate/translateLocal/setPosition/setLocalPosition supports the following input forms, where if you want to modify only the X-axis direction, you can pass only one number.

circle.translate([100, 0]); // [number, number]
circle.translate(100, 0); // number, number
circle.translate(100); // number

Scaling

Unlike panning, we can't provide a method like setScale to set scaling in the world coordinate system, so scaling in the global coordinate system is read-only, which in Unity is called lossyScale。

method nameparametersreturn valueremarks
scaleLocal[number, number] or number, number ornumber-Continued scaling with respect to the current scale in local coordinate system
setLocalScale[number, number] or number, number or number-Set the scaling in local coordinate system
getScale-[number, number]Get the scaling in world coordinate system
getLocalScale-[number, number]Get the scaling in local coordinate system

scaleLocal/setLocalScale supports the following input forms, where only one number can be passed if the horizontal/vertical scaling is equal.

circle.scaleLocal([2, 2]); // [number, number]
circle.scaleLocal(2, 2); // number, number
circle.scaleLocal(2); // number

If you want to flip along the X / Y axis, you can pass in a negative value, e.g. flip along the Y axis.

circle.setLocalScale(-1, 1);

Rotation

In 3D scenes, rotations can be represented by matrices, axis angles, Euler angles and quaternions, which are interconvertible with each other. Although, considering future scalability, we use quaternions in the G internal implementation.

method nameparametersreturn valueremarks
rotateLocalnumber-In the local coordinate system, rotate by a certain Eulerian angle, clockwise positive, in degree
rotatenumber-In world coordinate system, rotate by a certain Eulerian angle
setEulerAnglesnumber-In world coordinate system, rotate by a certain Eulerian angle
setLocalEulerAnglesnumber-Set the Euler angles in the local coordinate system.
setLocalRotationquat-Sets the number of quaternions in the local coordinate system.
setRotationquat-Sets the number of quaternions in the world coordinate system.
getEulerAngles-numberGet the Euler angles in world coordinate system
getLocalEulerAngles-numberGet the Euler angles in local coordinate system
getLocalRotation-quatGet the quaternion in local coordinate system
getRotation-quatGet the quaternion in world coordinate system

Skew

In 2D scenes, stretching can be performed to distort each point on an element in a certain direction at a certain angle. See CSS eponymous transform function.

method nameparametersreturn valuesremarks
setLocalSkewvec2-The angle in rad that distorts the element along the horizontal/vertical coordinates in the local coordinate system.
getLocalSkew-vec2Gets the distortion angle in rad under the local coordinate system.

Set the scaling and rotation center

Using the transformOrigin property, you can also use setOrigin.

method nameparametersreturn valueremarks
setOrigin[number, number] or [number, number, number] or number, number or number, number, number-Set the scaling and rotation center in the local coordinate system.
getOrigin[number, number, number]-Get the scaling and rotation center in the local coordinate system.

Set the center of scaling and rotation in the local coordinate system, example.

The default value is [0, 0].

In the following example, we have placed a circle with a radius of 100 at [100, 100].

const circle = new Circle({
style: {
cx: 100,
cy: 100,
r: 100,
},
});

If we want the circle to be scaled with the center of the circle as the center of transformation, and it is the enclosing box that changes.

circle.setOrigin(100, 100);
circle.scale(0.5);
circle.getBounds(); // { center: [100, 100], halfExtents: [50, 50] }

But if we want the circle to be scaled by its own upper left corner of the bounding box:

circle.setOrigin(0, 0);
circle.scale(0.5);
circle.getBounds(); // { center: [50, 50], halfExtents: [50, 50] }

In the following example, we have created a rectangle whose default anchor point is the upper left corner of the enclosing box in the local coordinate system. If we want it to rotate at the center of the enclosing box, we need to set the transformation center to be offset by half the length and width relative to the anchor point, i.e., [150, 100].

const rect = new Rect({
id: 'rect',
style: {
width: 300,
height: 200,
},
});
rect.setOrigin(150, 100); // Set the rotation and scaling center to the center point of its own bounding box

For example, if we want to modify the transformation center of a circle to the upper left corner instead of the center of the circle, we can do so.

const circle = new Circle({
style: {
cx: 100,
cy: 100,
r: 100,
},
});
circle.setOrigin(0, 0);
// or
circle.style.transformOrigin = 'left top';
// or
circle.style.transformOrigin = '0px 0px';
// or
circle.style.transformOrigin = '0% 0%';

The difference between the two is that origin is defined relative to the anchor point, while transformOrigin is defined relative to the bounding box.

Get Bounding box

Based on different bounding box definitions, we provide the following methods to obtain them.

getGeometryBounds(): AABB | null

Gets the geometric bouding box of the base drawing, which is independent of other drawing properties (e.g. lineWidth, filter, shadowBlur, etc.), except for defining the required style properties (e.g. r for Circle, width/height for Rect).

const circle = new Circle({
style: {
cx: 100, // Coordinates in the local coordinate system do not affect Geometry Bounds
cy: 100, // Coordinates in the local coordinate system do not affect Geometry Bounds
r: 100,
lineWidth: 20, // Style properties do not affect Geometry Bounds
shadowBlur: 10, // Style properties do not affect Geometry Bounds
},
});
circle.getGeometryBounds(); // { center: [0, 0], halfExtents: [100, 100] }

Group returns null because there is no geometry definition.

const group = new Group();
group.getGeometryBounds(); // null

getBounds(): AABB | null

This should be the most common way of calculating the Geometry Bounds of itself and its children in the world coordinate system.

const circle = new Circle({
style: {
cx: 100, // Applying transformations in the world coordinate system
cy: 100,
r: 100,
},
});
circle.getBounds(); // { center: [100, 100], halfExtents: [100, 100] }

getRenderBounds(): AABB | null

Merge the Render Bounds of itself and its children in the world coordinate system, based on the Geometry Bounds, affected by the following style properties: lineWidth, filter, shadowBlur, etc.

const circle = new Circle({
style: {
cx: 100, // Applying transformations in the world coordinate system
cy: 100,
r: 100,
lineWidth: 20,
},
});
// r + lineWidth / 2
circle.getRenderBounds(); // { center: [100, 100], halfExtents: [110, 110] }

getLocalBounds(): AABB | null

The only difference in getBounds is that it is calculated under the local coordinate system of the parent node.

getBBox(): Rect

Compatible with SVG method of the same name, the calculation is equivalent to getBounds, except that the return value type is different, the latter returns AABB. This method returns a DOMRect.

interface DOMRect {
top: number;
left: number;
right: number;
bottom: number;
width: number;
height: number;
}

getBoundingClientRect(): DOMRect

Get the Geometry Bounds in the browser coordinate system, apply the transformation in the world coordinate system, and then add the offset of the canvas relative to the browser.

Node Operations

In the scene graph, we need to construct parent-child relationships, get parent-child nodes quickly, and sometimes query the list of nodes of a certain type in the subtree. Based on the inheritance relationship, each DisplayObject has Node and Element capabilities.

Simple Node Query

method/property namemethod/propertyreturn valueremarks
parentNodepropertyDisplayObject | nullParent node (if any)
parentElementpropertyDisplayObject | nullParent node (if any)
childNodespropertyDisplayObject[]Child Node List
childrenpropertyDisplayObject[]Child Node List
firstChildpropertyDisplayObject | nullReturns the first node in the list of child nodes (if any)
lastChildpropertyDisplayObject | nullReturns the last node in the list of child nodes (if any)
nextSiblingpropertyDisplayObject | nullReturn the next sibling node (if any)
previousSiblingpropertyDisplayObject | nullReturn the previous sibling node (if any)
containsmethodbooleanWhether the subtree contains a node (entry)
getRootNodemethodNodeReturns the root node of the current node
ownerDocumentpropertyDocumentBack to the canvas entrance Document
isConnectedpropertybooleanWhether the node is added to the canvas

Advanced Search

Referring to the CSS selector, we provide the following query that looks at the entire subtree of the current node, and not just the direct list of children, but all descendant nodes.

method nameparametersreturn valueremarks
getElementById(id: string)DisplayObject | nullQuery child nodes by id
getElementsByName(name: string)DisplayObject[]Query the list of child nodes by name
getElementsByClassName(className: string)DisplayObject[]Query the list of child nodes by className
getElementsByTagName(tagName: string)DisplayObject[]Query the list of child nodes by tagName
querySelector(selector: string)DisplayObject \| nullQuery the first child node that satisfies the condition
querySelectorAll(selector: string)DisplayObject[]Query the list of all child nodes that satisfy the condition
find(filter: Function)DisplayObject \| nullQuery the first child node that satisfies the condition
findAll(filter: Function)DisplayObject[]Query the list of all child nodes that satisfy the condition

We demonstrate how to use these query methods using the above example of the solar system.

solarSystem.getElementsByName('sun');
// sun
solarSystem.getElementsByTagName('circle');
solarSystem.getElementsByTagName(Shape.CIRCLE);
// [sun, earth, moon]
solarSystem.querySelector('[name=sun]');
// sun
solarSystem.querySelectorAll('[r=25]');
// [moon]

Sometimes the query criteria are not well described by CSS selectors, so you can use custom query methods: find/findAll. they can be compared to querySelector/querySelectorAll. the difference is that the former requires passing in a filter, for example the following is equivalent.

solarSystem.querySelector('[name=sun]');
solarSystem.find((element) => element.name === 'sun');
solarSystem.querySelectorAll('[r=25]');
solarSystem.findAll((element) => element.style.r === 25);

Add/Remove Nodes

The following add/remove node capabilities come from the inherited Element base class.

method nameparametersreturn valueremarks
appendChildchild: DisplayObjectDisplayObjectAdds a child node and returns the added node
insertBeforechild: DisplayObject or reference?: DisplayObjectDisplayObjectAdd a child node, before some child node (if any), and return the added node
append...nodes: DisplayObject[]Add a group of nodes in bulk at the end of the child node list of the current node
prepend...nodes: DisplayObject[]Add a group of nodes in bulk to the head of the current node's child node list
after...nodes: DisplayObject[]Add some sibling nodes in bulk after the current node
before...nodes: DisplayObject[]Add some sibling nodes in bulk before the current node
removeChildchild: DisplayObjectDisplayObjectDelete the child node and return the node that was deleted.
removeChildrenDelete and destroy all child nodes.
removedestroy = trueDisplayObjectRemove itself from the parent node (if any), destroy indicates whether to destroy
replaceChildchild: DisplayObjectDisplayObjectReplace a child node of the current node with the specified node, and return the replaced node
replaceWith...nodes: DisplayObject[]In the list of children of the parent node, replace the node with the list of nodes passed in
replaceChildren...nodes: DisplayObject[]Replace all children of the node. If no parameters are passed, all children of the node will be cleared

There are two ways to remove a child node from a parent node and destroy it.

// parent -> child
parent.removeChild(child);
// or
child.remove();

There are three ways to delete all child nodes.

parent.removeChildren();
// or
[...parent.children].forEach((child) => parent.removeChild(child));
[...parent.children].forEach((child) => child.remove());
// or
parent.replaceChildren();

The following points are noted when adding/removing nodes.

  1. The ChildInserted and Inserted events are triggered sequentially when a node is added.
  2. Removed and ChildRemoved events will be triggered sequentially, and destroy will be called by default to destroy itself. If the node is only temporarily removed from the scene graph and may be added back later, you can use remove(false).

Clone node

The method signature is cloneNode(deep?: boolean): this, with optional arguments for whether a deep copy is needed, and returns the new node obtained by cloning.

In the following example, we create a circle, set its radius and position. The new node is copied with the same style properties and position.

circle.style.r = 20;
circle.setPosition(10, 20);
const clonedCircle = circle.cloneNode();
clonedCircle instanceof Circle; // true
clonedCircle.style.r; // 20
clonedCircle.getPosition(); // [10, 20]

Caveats:

  • Deep copy support, i.e. itself and the whole subtree
  • The cloned node does not retain the parent-child relationship of the original node and needs to be added to the canvas using appendChild before it will be rendered
  • Consistent with the DOM API, event listeners on the original drawing are not copied

In this example, we demonstrate the above features.

  • The style properties of the original node can be changed at any time, and the copy obtained will be up-to-date, and the new node will also need to be added to the scene graph before it will be rendered
  • However, since no event listeners will be copied, only the original node can be dragged
  • In non-deep copy mode, Text (Drag me Text) is not copied as a child of Circle

Get/Set attribute values

method nameparametersreturn valuesremarks
getAttribute(name: string)null | anyGet attribute value based on attribute name
setAttribute(name: string, value: any)-Set attribute value

⚠️ Compatible with the old attr(name: string, value?: any), get and set attribute values.

⚠️ Compatible with HTMLElement Style:

  • style.getPropertyValue
  • style.setProperty
  • style.removeProperty

The following usage equivalents.

const circle = new Circle({
style: {
// or using attrs
r: 10,
fill: 'red',
},
});
// get attribute value
circle.getAttribute('fill'); // red
circle.attr('fill'); // red
circle.style.fill; // red
circle.style.getPropertyValue('fill');
// set attribute value
circle.setAttribute('r', 20);
circle.attr('r', 20);
circle.style.r = 20;
circle.style.setProperty('r', 20);

Get the parsed attribute value

Some properties such as Rect support units for width / height, if you want to get the calculated value, you can use parsedStyle.

rect.style.width = '100px';
rect.parsedStyle.width; // CSSUnitValue { unit: 'px', value: 100 }

Note that currently, when using animation, we also convert the values of the attributes to be interpolated, so if you want to get the absolute values in px, you need to use parsedStyle example.

animation.onframe = () => {
rect.style.width; // '100px'
rect.parsedStyle.width; // CSSUnitValue { unit: 'px', value: 100 }
};

Destroy

Calling destroy() will destroy the node. Destroyed nodes will not be added to the canvas rendering again. The destroyed attribute allows you to determine if a node has been destroyed.

circle.destroy();

When this method is invoked, the following actions are performed in sequence.

  1. Trigger Destroy event
  2. Call remove() to remove itself from the scene graph, so it will trigger the Removed and ChildRemoved events
  3. Remove all event listeners and animations on this node
  4. Set the destroyed flag to true

Status

The following properties allow you to determine the current state of the drawing, such as whether it has been added to the canvas, whether it has been destroyed, etc.

isConnected

用于判断一个图形是否已经被加入到画布中。

https://developer.mozilla.org/zh-CN/docs/Web/API/Node/isConnected

circle.isConnected; // false
canvas.appendChild(circle); // add to canvas
circle.isConnected; // true

ownerDocument

Used to determine if a drawing has been added to the canvas.

https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument

circle.ownerDocument; // null
canvas.appendChild(circle); // add to canvas
circle.ownerDocument; // canvas.document

destroyed

Used to determine if a graph has been destroyed.

By calling destroy() to actively destroy itself, or the parent node by destroyChildren() to actively remove and destroy all children, etc.

circle.destroyed; // false
circle.destroy();
circle.destroyed; // true

Lifecycle Event Listening

In the event system, we can add event listeners to nodes added to the canvas using a DOM Event API-like approach.

In addition to interactive events such as click and mouseenter, we also provide a series of built-in node lifecycle events, such as listening for node additions and deletions, which also have full propagation paths (bubbling, capturing), example.

import { ElementEvent, MutationEvent } from '@antv/g';
child.on(ElementEvent.INSERTED, (e: MutationEvent) => {
e.target; // child
e.relatedNode; // parent
});
child.on(ElementEvent.REMOVED, (e) => {
e.target; // child
e.relatedNode; // parent
});
child.on(ElementEvent.ATTR_MODIFIED, (e) => {
e.target; // child
e.attrName;
e.prevValue;
e.newValue;
});
parent.appendChild(child);

We currently support the following scenario map related events.

  • INSERTED Triggered when added as a child node
  • REMOVED Triggered when removed as a child node
  • MOUNTED Triggered when first entering the canvas
  • UNMOUNTED Triggered when removed from the canvas
  • ATTR_MODIFIED Triggered when modifying properties
  • DESTROY Triggered on destruction

Animation

Referring to the Web Animations API, you can use animate to complete the keyframe animation, the following is a ScaleIn animation effect.

circle.animate(
[
{
transform: 'scale(0)',
},
{
transform: 'scale(1)',
},
],
{
duration: 500,
easing: 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',
iterations: Infinity,
},
);

See animation system for more details on usage.

Dataset API

https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes

data-* attributes allow us to store extra information on standard.

group.dataset.type = 'a';
group.getAttribute('data-type'); // 'a'

It should be noted that the part after the data- prefix needs to use camel case when accessing through dataset:

group.setAttribute('data-a-b-c');
group.dataset.aBC;
// Wrong
group.dataset.abc;
group.dataset.abC;