0
# Graphics Primitives
1
2
ZRender's graphics system is built on a hierarchical structure of elements, with specialized classes for different types of graphics content. All graphics elements inherit from the base Element class and support styling, transformations, animations, and event handling.
3
4
## Base Element Classes
5
6
### Element
7
8
The foundational class for all graphics objects in ZRender:
9
10
```typescript { .api }
11
class Element {
12
// Hierarchy management
13
add(el: Element): void;
14
remove(el: Element): void;
15
removeAll(): void;
16
parent: Group | null;
17
children(): Element[];
18
19
// Transformations
20
position: number[];
21
rotation: number;
22
scale: number[];
23
origin: number[];
24
25
// Display properties
26
invisible: boolean;
27
ignore: boolean;
28
silent: boolean;
29
zlevel: number;
30
z: number;
31
32
// Animation
33
animate(props?: string): Animator;
34
stopAnimation(forwardToLast?: boolean): this;
35
36
// Events
37
on(eventName: string, handler: ElementEventCallback, context?: any): this;
38
off(eventName?: string, handler?: ElementEventCallback): void;
39
trigger(eventName: string, event?: any): void;
40
41
// Utilities
42
getBoundingRect(): BoundingRect;
43
clone(): Element;
44
dispose(): void;
45
}
46
```
47
48
### Displayable
49
50
Base class for visible elements that can be rendered:
51
52
```typescript { .api }
53
class Displayable extends Element {
54
style: any;
55
dirty(): void;
56
styleChanged(): boolean;
57
useStyle(obj: any): void;
58
getBoundingRect(): BoundingRect;
59
}
60
61
interface DisplayableProps extends ElementProps {
62
style?: any;
63
zlevel?: number;
64
z?: number;
65
culling?: boolean;
66
cursor?: string;
67
}
68
```
69
70
### Group
71
72
Container element for organizing and transforming multiple elements as a unit:
73
74
```typescript { .api }
75
class Group extends Element {
76
children(): Element[];
77
childAt(idx: number): Element;
78
childOfName(name: string): Element;
79
childCount(): number;
80
eachChild<T>(cb: (this: T, child: Element, index: number) => void, context?: T): void;
81
traverse<T>(cb: (this: T, el: Element) => boolean | void, context?: T): void;
82
getBoundingRect(includeChildren?: Element[]): BoundingRect;
83
}
84
85
interface GroupProps extends ElementProps {
86
// Groups primarily use inherited properties from ElementProps
87
}
88
```
89
90
### Path
91
92
Base class for vector graphics elements (shapes):
93
94
```typescript { .api }
95
class Path extends Displayable {
96
shape: any;
97
buildPath(ctx: CanvasRenderingContext2D | SVGPathElement, shape: any): void;
98
getBoundingRect(): BoundingRect;
99
contain(x: number, y: number): boolean;
100
}
101
102
interface PathProps extends DisplayableProps {
103
shape?: any;
104
style?: PathStyleProps;
105
}
106
107
interface PathStyleProps {
108
fill?: string | LinearGradient | RadialGradient | Pattern;
109
stroke?: string;
110
lineWidth?: number;
111
lineDash?: number[];
112
lineDashOffset?: number;
113
lineCap?: 'butt' | 'round' | 'square';
114
lineJoin?: 'bevel' | 'round' | 'miter';
115
miterLimit?: number;
116
opacity?: number;
117
fillOpacity?: number;
118
strokeOpacity?: number;
119
shadowBlur?: number;
120
shadowColor?: string;
121
shadowOffsetX?: number;
122
shadowOffsetY?: number;
123
}
124
```
125
126
### Text
127
128
Specialized element for text rendering:
129
130
```typescript { .api }
131
class Text extends Displayable {
132
style: TextStyleProps;
133
}
134
135
interface TextProps extends DisplayableProps {
136
style?: TextStyleProps;
137
}
138
139
interface TextStyleProps {
140
text?: string;
141
fontSize?: number;
142
fontFamily?: string;
143
fontStyle?: 'normal' | 'italic' | 'oblique';
144
fontWeight?: string | number;
145
fill?: string | LinearGradient | RadialGradient | Pattern;
146
stroke?: string;
147
lineWidth?: number;
148
textAlign?: 'left' | 'center' | 'right';
149
textVerticalAlign?: 'top' | 'middle' | 'bottom';
150
textBaseline?: 'top' | 'middle' | 'bottom' | 'alphabetic' | 'ideographic' | 'hanging';
151
opacity?: number;
152
textShadowBlur?: number;
153
textShadowColor?: string;
154
textShadowOffsetX?: number;
155
textShadowOffsetY?: number;
156
width?: number;
157
height?: number;
158
textPadding?: number | number[];
159
textLineHeight?: number;
160
rich?: Record<string, TextStyleProps>;
161
truncate?: {
162
outerWidth?: number;
163
outerHeight?: number;
164
ellipsis?: string;
165
placeholder?: string;
166
};
167
blend?: string;
168
}
169
170
interface TextState {
171
style?: Partial<TextStyleProps>;
172
}
173
```
174
175
### TSpan
176
177
Text span element for rich text formatting:
178
179
```typescript { .api }
180
class TSpan extends Displayable {
181
style: TSpanStyleProps;
182
}
183
184
interface TSpanProps extends DisplayableProps {
185
style?: TSpanStyleProps;
186
}
187
188
interface TSpanStyleProps extends TextStyleProps {
189
x?: number;
190
y?: number;
191
text?: string;
192
}
193
194
interface TSpanState {
195
style?: Partial<TSpanStyleProps>;
196
}
197
```
198
199
### Image
200
201
Element for displaying bitmap images:
202
203
```typescript { .api }
204
class Image extends Displayable {
205
style: ImageStyleProps;
206
}
207
208
interface ImageProps extends DisplayableProps {
209
style?: ImageStyleProps;
210
}
211
212
interface ImageStyleProps {
213
image?: string | HTMLImageElement | HTMLCanvasElement;
214
x?: number;
215
y?: number;
216
width?: number;
217
height?: number;
218
sx?: number; // Source x
219
sy?: number; // Source y
220
sWidth?: number; // Source width
221
sHeight?: number; // Source height
222
opacity?: number;
223
shadowBlur?: number;
224
shadowColor?: string;
225
shadowOffsetX?: number;
226
shadowOffsetY?: number;
227
}
228
229
interface ImageState {
230
style?: Partial<ImageStyleProps>;
231
}
232
```
233
234
### CompoundPath
235
236
Element for creating complex paths from multiple sub-paths:
237
238
```typescript { .api }
239
class CompoundPath extends Path {
240
shape: CompoundPathShape;
241
}
242
243
interface CompoundPathShape {
244
paths: Path[];
245
}
246
```
247
248
### IncrementalDisplayable
249
250
Special element for progressive/streaming rendering:
251
252
```typescript { .api }
253
class IncrementalDisplayable extends Displayable {
254
incremental: boolean;
255
clearIncrementalNewAdded(): void;
256
markIncrementalNewAdded(): void;
257
}
258
```
259
260
## Common Element Properties
261
262
All graphics elements support these common properties through the ElementProps interface:
263
264
```typescript { .api }
265
interface ElementProps {
266
// Transform properties
267
position?: number[]; // [x, y]
268
rotation?: number; // Rotation in radians
269
scale?: number[]; // [scaleX, scaleY]
270
origin?: number[]; // [originX, originY] transform origin
271
272
// Display properties
273
zlevel?: number; // Layer level (affects rendering order)
274
z?: number; // Z-index within layer
275
invisible?: boolean; // Hide element
276
ignore?: boolean; // Ignore in hit testing and rendering
277
silent?: boolean; // Disable event handling
278
279
// Interaction
280
cursor?: string; // CSS cursor style
281
draggable?: boolean; // Enable dragging
282
progressive?: number; // Progressive rendering threshold
283
284
// Animation
285
culling?: boolean; // Enable view culling
286
rectHover?: boolean; // Use rectangular hover area
287
useHoverLayer?: boolean; // Render hover state on separate layer
288
}
289
```
290
291
## Usage Examples
292
293
### Creating Basic Elements
294
295
```typescript
296
import { Group, Circle, Text } from "zrender";
297
298
// Create a group to contain multiple elements
299
const group = new Group({
300
position: [100, 100],
301
rotation: Math.PI / 4
302
});
303
304
// Create a circle
305
const circle = new Circle({
306
shape: { cx: 0, cy: 0, r: 50 },
307
style: { fill: '#ff0000', stroke: '#000000', lineWidth: 2 },
308
z: 1
309
});
310
311
// Create text
312
const text = new Text({
313
style: {
314
text: 'Hello ZRender',
315
fontSize: 16,
316
fill: '#333333',
317
textAlign: 'center'
318
},
319
position: [0, -60],
320
z: 2
321
});
322
323
// Build hierarchy
324
group.add(circle);
325
group.add(text);
326
327
// Add to ZRender instance
328
zr.add(group);
329
```
330
331
### Element Animation
332
333
```typescript
334
import { Rect } from "zrender";
335
336
const rect = new Rect({
337
shape: { x: 0, y: 0, width: 100, height: 50 },
338
style: { fill: '#0066cc' },
339
position: [50, 50]
340
});
341
342
// Animate properties
343
rect.animate('position')
344
.when(1000, [300, 200])
345
.when(2000, [50, 50])
346
.start();
347
348
// Animate shape
349
rect.animate('shape')
350
.when(1000, { width: 200, height: 100 })
351
.start('easeInOut');
352
353
// Animate style
354
rect.animate('style')
355
.when(500, { fill: '#ff6600' })
356
.start();
357
```
358
359
### Event Handling
360
361
```typescript
362
import { Circle } from "zrender";
363
364
const circle = new Circle({
365
shape: { cx: 100, cy: 100, r: 30 },
366
style: { fill: '#00cc66' }
367
});
368
369
// Add event handlers
370
circle.on('click', (e) => {
371
console.log('Circle clicked!', e);
372
});
373
374
circle.on('mouseover', (e) => {
375
circle.animate('style')
376
.when(200, { fill: '#66ff99' })
377
.start();
378
});
379
380
circle.on('mouseout', (e) => {
381
circle.animate('style')
382
.when(200, { fill: '#00cc66' })
383
.start();
384
});
385
386
zr.add(circle);
387
```
388
389
### Complex Hierarchies
390
391
```typescript
392
import { Group, Rect, Text, Circle } from "zrender";
393
394
// Create a button-like component
395
function createButton(text: string, x: number, y: number) {
396
const button = new Group({
397
position: [x, y]
398
});
399
400
const background = new Rect({
401
shape: { x: 0, y: 0, width: 120, height: 40, r: 5 },
402
style: {
403
fill: '#4a90e2',
404
stroke: '#357abd',
405
lineWidth: 1
406
}
407
});
408
409
const label = new Text({
410
style: {
411
text: text,
412
fontSize: 14,
413
fill: '#ffffff',
414
textAlign: 'center',
415
textVerticalAlign: 'middle'
416
},
417
position: [60, 20]
418
});
419
420
button.add(background);
421
button.add(label);
422
423
// Add hover effects
424
button.on('mouseover', () => {
425
background.animate('style')
426
.when(150, { fill: '#5aa3f0' })
427
.start();
428
});
429
430
button.on('mouseout', () => {
431
background.animate('style')
432
.when(150, { fill: '#4a90e2' })
433
.start();
434
});
435
436
return button;
437
}
438
439
// Use the component
440
const btn1 = createButton('Click Me', 50, 50);
441
const btn2 = createButton('Cancel', 200, 50);
442
443
zr.add(btn1);
444
zr.add(btn2);
445
```