0
# Utility Libraries
1
2
ZRender provides comprehensive utility libraries for mathematical operations, color manipulation, path processing, and platform abstractions. These utilities are essential for graphics programming and provide cross-platform compatibility.
3
4
## Core Utilities (util namespace)
5
6
The util namespace provides fundamental utility functions:
7
8
### Object and Array Utilities
9
10
```typescript { .api }
11
namespace util {
12
// Object utilities
13
function clone<T>(obj: T): T;
14
function merge<T, S>(target: T, source: S, overwrite?: boolean): T & S;
15
function extend<T, S>(target: T, source: S): T & S;
16
function defaults<T>(target: T, ...sources: Partial<T>[]): T;
17
18
// Array utilities
19
function map<T, R>(arr: T[], cb: (item: T, index: number) => R): R[];
20
function reduce<T, R>(arr: T[], cb: (prev: R, item: T, index: number) => R, memo?: R): R;
21
function filter<T>(arr: T[], cb: (item: T, index: number) => boolean): T[];
22
function find<T>(arr: T[], cb: (item: T, index: number) => boolean): T | undefined;
23
function indexOf<T>(arr: T[], item: T): number;
24
25
// Type checking
26
function isArray(value: any): value is any[];
27
function isFunction(value: any): value is Function;
28
function isString(value: any): value is string;
29
function isObject(value: any): value is object;
30
function isNumber(value: any): value is number;
31
function isBoolean(value: any): value is boolean;
32
function isDom(value: any): value is Element;
33
34
// Value utilities
35
function retrieve<T>(...args: T[]): T;
36
function retrieve2<T>(value0: T, value1: T): T;
37
function retrieve3<T>(value0: T, value1: T, value2: T): T;
38
function slice<T>(arr: ArrayLike<T>, start?: number, end?: number): T[];
39
function normalizeCssArray(val: number | number[]): number[];
40
41
// String utilities
42
function trim(str: string): string;
43
function toCamelCase(str: string): string;
44
function toHyphenCase(str: string): string;
45
46
// Unique ID generation
47
function guid(): number;
48
49
// Performance utilities
50
function createHashMap<T>(obj?: Record<string, T>): HashMap<T>;
51
function concatArray<T>(a: T[], b: T[]): T[];
52
function each<T>(obj: T[] | Record<string, T>, cb: (value: T, key: string | number) => void): void;
53
}
54
55
interface HashMap<T> {
56
data: Record<string, T>;
57
get(key: string): T;
58
set(key: string, value: T): T;
59
has(key: string): boolean;
60
removeKey(key: string): void;
61
}
62
```
63
64
## Matrix Operations (matrix namespace)
65
66
2D transformation matrix utilities:
67
68
```typescript { .api }
69
namespace matrix {
70
// Matrix creation and manipulation
71
function create(): number[];
72
function identity(): number[];
73
function copy(out: number[], m: number[]): number[];
74
75
// Basic transformations
76
function translate(out: number[], a: number[], v: number[]): number[];
77
function rotate(out: number[], a: number[], rad: number): number[];
78
function scale(out: number[], a: number[], v: number[]): number[];
79
80
// Matrix operations
81
function mul(out: number[], a: number[], b: number[]): number[];
82
function invert(out: number[], a: number[]): number[] | null;
83
84
// Point transformations
85
function applyTransform(out: number[], v: number[], m: number[]): number[];
86
87
// Decomposition
88
function decompose(m: number[], a: number[], translate: number[], rotate: number[], scale: number[]): boolean;
89
}
90
```
91
92
## Vector Operations (vector namespace)
93
94
2D vector mathematics:
95
96
```typescript { .api }
97
namespace vector {
98
// Vector creation
99
function create(x?: number, y?: number): number[];
100
function copy(out: number[], v: number[]): number[];
101
function clone(v: number[]): number[];
102
function set(out: number[], a: number, b: number): number[];
103
104
// Arithmetic operations
105
function add(out: number[], a: number[], b: number[]): number[];
106
function scaleAndAdd(out: number[], a: number[], b: number[], scale: number): number[];
107
function sub(out: number[], a: number[], b: number[]): number[];
108
function len(v: number[]): number;
109
function lenSquare(v: number[]): number;
110
function mul(out: number[], a: number[], b: number[]): number[];
111
function div(out: number[], a: number[], b: number[]): number[];
112
function dot(a: number[], b: number[]): number;
113
function scale(out: number[], a: number[], b: number): number[];
114
function normalize(out: number[], a: number[]): number[];
115
116
// Distance and angle calculations
117
function distance(a: number[], b: number[]): number;
118
function distanceSquare(a: number[], b: number[]): number;
119
function negate(out: number[], a: number[]): number[];
120
function lerp(out: number[], a: number[], b: number[], t: number): number[];
121
122
// Geometric utilities
123
function applyTransform(out: number[], v: number[], m: number[]): number[];
124
function min(out: number[], a: number[], b: number[]): number[];
125
function max(out: number[], a: number[], b: number[]): number[];
126
}
127
```
128
129
## Color Manipulation (color namespace)
130
131
Color parsing, conversion, and manipulation:
132
133
```typescript { .api }
134
namespace color {
135
// Color parsing
136
function parse(colorStr: string): number[] | null;
137
function rgba2String(rgba: number[]): string;
138
139
// Color format conversion
140
function toHex(color: string): string;
141
function toRGB(color: string): string;
142
function toHSL(color: string): string;
143
function toHSV(color: string): string;
144
145
// Color space conversions
146
function rgb2hsv(r: number, g: number, b: number): number[];
147
function hsv2rgb(h: number, s: number, v: number): number[];
148
function rgb2hsl(r: number, g: number, b: number): number[];
149
function hsl2rgb(h: number, s: number, l: number): number[];
150
151
// Color interpolation
152
function lerp(t: number, a: string, b: string, out?: number[]): string;
153
function lerpArray(t: number, a: number[], b: number[], out?: number[]): number[];
154
155
// Color analysis
156
function lum(color: string, backgroundLum?: number): number;
157
function random(): string;
158
159
// Color modification
160
function modifyHSL(color: string, h?: number, s?: number, l?: number): string;
161
function modifyAlpha(color: string, alpha: number): string;
162
163
// Palette generation
164
function stringify(arrColor: number[], type: 'rgba' | 'rgb'): string;
165
}
166
```
167
168
## Path Processing (path namespace)
169
170
SVG path manipulation and processing:
171
172
```typescript { .api }
173
namespace path {
174
// Path parsing and creation
175
function createFromString(str: string): PathProxy;
176
function extendFromString(path: PathProxy, str: string): void;
177
function mergePath(path1: PathProxy, path2: PathProxy): PathProxy;
178
179
// Path transformation
180
function transformPath(path: PathProxy, m: number[]): void;
181
182
// Path analysis
183
function getPathBoundingRect(path: PathProxy): BoundingRect;
184
function getPathLength(path: PathProxy): number;
185
function getPointAtPath(path: PathProxy, percent: number): number[];
186
187
// Path utilities
188
function clone(path: PathProxy): PathProxy;
189
function parseSVGPath(str: string): PathProxy;
190
function normalizeArcPath(path: PathProxy): void;
191
}
192
193
interface PathProxy {
194
data: number[];
195
len(): number;
196
setData(data: ArrayLike<number>): void;
197
appendPath(path: PathProxy): void;
198
addData(cmd: number, ...args: number[]): void;
199
moveTo(x: number, y: number): void;
200
lineTo(x: number, y: number): void;
201
bezierCurveTo(x1: number, y1: number, x2: number, y2: number, x: number, y: number): void;
202
quadraticCurveTo(x1: number, y1: number, x: number, y: number): void;
203
arc(cx: number, cy: number, r: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void;
204
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
205
rect(x: number, y: number, w: number, h: number): void;
206
closePath(): void;
207
}
208
```
209
210
## Path Morphing (morph namespace)
211
212
Advanced path morphing and interpolation:
213
214
```typescript { .api }
215
namespace morph {
216
// Path morphing
217
function morphPath(from: string, to: string, animationOpts?: any): string;
218
function getPathKey(path: string): string;
219
function morphingPathKey(path: string): string;
220
221
// Combined morphing
222
function combineMorphing(morphList: any[]): any;
223
function isCombineMorphing(obj: any): boolean;
224
225
// Morphing utilities
226
function pathToAbsolute(path: string): string;
227
function pathToBezier(path: string): number[][];
228
}
229
```
230
231
## Platform Abstraction
232
233
Platform-specific API configuration:
234
235
```typescript { .api }
236
function setPlatformAPI(platformAPI: PlatformAPI): void;
237
238
interface PlatformAPI {
239
createCanvas?: () => HTMLCanvasElement;
240
measureText?: (text: string, font: string) => { width: number };
241
loadImage?: (src: string, onload: () => void, onerror: () => void) => HTMLImageElement;
242
243
// Platform detection
244
$override?: {
245
createCanvas?: () => HTMLCanvasElement;
246
measureText?: (text: string, font: string) => { width: number };
247
loadImage?: (src: string, onload: () => void, onerror: () => void) => HTMLImageElement;
248
};
249
}
250
```
251
252
## Geometry Utilities
253
254
Additional geometric calculations and utilities:
255
256
```typescript { .api }
257
// Point and rectangle utilities
258
interface Point {
259
x: number;
260
y: number;
261
}
262
263
interface PointLike {
264
x: number;
265
y: number;
266
}
267
268
interface RectLike {
269
x: number;
270
y: number;
271
width: number;
272
height: number;
273
}
274
275
class BoundingRect {
276
x: number;
277
y: number;
278
width: number;
279
height: number;
280
281
constructor(x: number, y: number, width: number, height: number);
282
283
// Geometric operations
284
union(other: BoundingRect): void;
285
intersect(other: BoundingRect): void;
286
contain(x: number, y: number): boolean;
287
clone(): BoundingRect;
288
copy(other: BoundingRect): void;
289
plain(): RectLike;
290
291
// Static utilities
292
static create(rect: RectLike): BoundingRect;
293
static copy(target: BoundingRect, source: BoundingRect): void;
294
static applyTransform(target: BoundingRect, source: BoundingRect, m: number[]): void;
295
}
296
297
class OrientedBoundingRect {
298
cx: number;
299
cy: number;
300
width: number;
301
height: number;
302
rotation: number;
303
304
constructor();
305
306
// Geometric operations
307
intersect(other: OrientedBoundingRect): boolean;
308
contain(x: number, y: number): boolean;
309
clone(): OrientedBoundingRect;
310
311
// Static utilities
312
static fromPoints(points: number[][]): OrientedBoundingRect;
313
}
314
```
315
316
## Usage Examples
317
318
### Utility Functions
319
320
```typescript
321
import { util, matrix, vector, color } from "zrender";
322
323
// Object manipulation
324
const obj1 = { a: 1, b: 2 };
325
const obj2 = { b: 3, c: 4 };
326
const merged = util.merge({}, obj1, obj2); // { a: 1, b: 3, c: 4 }
327
328
// Array operations
329
const numbers = [1, 2, 3, 4, 5];
330
const doubled = util.map(numbers, x => x * 2); // [2, 4, 6, 8, 10]
331
const evens = util.filter(numbers, x => x % 2 === 0); // [2, 4]
332
333
// Type checking
334
if (util.isArray(someValue)) {
335
console.log('It is an array');
336
}
337
338
// Unique IDs
339
const uniqueId = util.guid(); // Returns unique number
340
```
341
342
### Matrix Operations
343
344
```typescript
345
import { matrix } from "zrender";
346
347
// Create transformation matrix
348
const m = matrix.identity();
349
350
// Apply transformations
351
matrix.translate(m, m, [100, 50]); // Translate by (100, 50)
352
matrix.rotate(m, m, Math.PI / 4); // Rotate 45 degrees
353
matrix.scale(m, m, [1.5, 1.5]); // Scale by 1.5x
354
355
// Transform a point
356
const point = [0, 0];
357
const transformedPoint = matrix.applyTransform([], point, m);
358
console.log('Transformed point:', transformedPoint);
359
360
// Matrix multiplication
361
const m1 = matrix.identity();
362
const m2 = matrix.identity();
363
matrix.scale(m1, m1, [2, 2]);
364
matrix.rotate(m2, m2, Math.PI / 2);
365
366
const combined = matrix.mul([], m1, m2);
367
```
368
369
### Vector Mathematics
370
371
```typescript
372
import { vector } from "zrender";
373
374
// Vector operations
375
const v1 = vector.create(3, 4);
376
const v2 = vector.create(1, 2);
377
378
const sum = vector.add([], v1, v2); // [4, 6]
379
const length = vector.len(v1); // 5
380
const normalized = vector.normalize([], v1); // [0.6, 0.8]
381
const distance = vector.distance(v1, v2); // ~2.83
382
383
// Interpolation
384
const lerped = vector.lerp([], v1, v2, 0.5); // Midpoint between v1 and v2
385
386
// Dot product for angle calculations
387
const dotProduct = vector.dot(v1, v2); // 11
388
const angle = Math.acos(dotProduct / (vector.len(v1) * vector.len(v2)));
389
```
390
391
### Color Manipulation
392
393
```typescript
394
import { color } from "zrender";
395
396
// Color parsing and conversion
397
const rgbaArray = color.parse('#ff6b6b'); // [255, 107, 107, 1]
398
const hexColor = color.toHex('rgb(255, 107, 107)'); // '#ff6b6b'
399
const hslColor = color.toHSL('#ff6b6b'); // 'hsl(0, 100%, 71%)'
400
401
// Color interpolation
402
const startColor = '#ff0000';
403
const endColor = '#00ff00';
404
const midColor = color.lerp(0.5, startColor, endColor); // Blend colors
405
406
// Color modification
407
const brighterColor = color.modifyHSL('#3498db', 0, 0.2, 0.1); // Increase saturation and lightness
408
const transparentColor = color.modifyAlpha('#3498db', 0.5); // 50% opacity
409
410
// Color analysis
411
const luminance = color.lum('#3498db'); // Get relative luminance
412
const randomColor = color.random(); // Generate random color
413
414
// Palette generation
415
const palette = [];
416
for (let i = 0; i < 5; i++) {
417
palette.push(color.lerp(i / 4, '#ff6b6b', '#4ecdc4'));
418
}
419
```
420
421
### Path Processing
422
423
```typescript
424
import { path, parseSVG } from "zrender";
425
426
// Create path from SVG string
427
const svgPath = "M 10 10 L 100 10 L 100 100 L 10 100 Z";
428
const pathProxy = path.createFromString(svgPath);
429
430
// Get path properties
431
const bounds = path.getPathBoundingRect(pathProxy);
432
const length = path.getPathLength(pathProxy);
433
434
// Get point at specific position along path
435
const midPoint = path.getPointAtPath(pathProxy, 0.5); // 50% along path
436
437
// Transform path
438
const transformMatrix = matrix.identity();
439
matrix.scale(transformMatrix, transformMatrix, [2, 2]);
440
path.transformPath(pathProxy, transformMatrix);
441
442
// Parse SVG content
443
const svgElement = document.querySelector('svg')!;
444
const elements = parseSVG(svgElement);
445
// Returns ZRender elements created from SVG
446
```
447
448
### Custom Utilities Integration
449
450
```typescript
451
import { util, BoundingRect } from "zrender";
452
453
// Custom utility function using ZRender utilities
454
function createBoundedElements(bounds: RectLike, count: number) {
455
const elements = [];
456
457
for (let i = 0; i < count; i++) {
458
// Use util functions for safe operations
459
const x = bounds.x + Math.random() * bounds.width;
460
const y = bounds.y + Math.random() * bounds.height;
461
const size = 10 + Math.random() * 20;
462
463
const circle = new Circle({
464
shape: { cx: x, cy: y, r: size },
465
style: {
466
fill: color.random(),
467
opacity: 0.7
468
}
469
});
470
471
elements.push(circle);
472
}
473
474
return elements;
475
}
476
477
// Use the custom utility
478
const canvasBounds = new BoundingRect(0, 0, 800, 600);
479
const randomElements = createBoundedElements(canvasBounds.plain(), 50);
480
481
randomElements.forEach(el => zr.add(el));
482
```
483
484
### Performance Optimized Operations
485
486
```typescript
487
import { util } from "zrender";
488
489
// Efficient array operations
490
const largeArray = new Array(10000).fill(0).map((_, i) => i);
491
492
// Use ZRender's optimized utilities instead of native methods when possible
493
const processedData = util.map(largeArray, (value, index) => {
494
return { id: index, value: value * 2, processed: true };
495
});
496
497
// Efficient object creation
498
const hashMap = util.createHashMap<number>();
499
for (let i = 0; i < 1000; i++) {
500
hashMap.set(`key${i}`, i);
501
}
502
503
// Memory-efficient cloning
504
const originalData = {
505
positions: [[0, 0], [100, 100], [200, 200]],
506
colors: ['#ff0000', '#00ff00', '#0000ff'],
507
metadata: { created: Date.now() }
508
};
509
510
const clonedData = util.clone(originalData); // Deep clone
511
```
512
513
## SVG Processing
514
515
### SVG Parser
516
517
Parse SVG markup into ZRender elements for rendering and manipulation:
518
519
```typescript { .api }
520
/**
521
* Parse SVG markup into ZRender graphics elements
522
* @param svg - SVG string, Document, or SVGElement to parse
523
* @param options - Parsing configuration options
524
* @returns Parsed SVG result with root group and metadata
525
*/
526
function parseSVG(svg: string | Document | SVGElement, options?: SVGParserOption): SVGParserResult;
527
528
interface SVGParserOption {
529
width?: number; // Default width if not specified in SVG
530
height?: number; // Default height if not specified in SVG
531
ignoreViewBox?: boolean; // Whether to ignore SVG viewBox
532
}
533
534
interface SVGParserResult {
535
root: Group; // Root group containing all parsed elements
536
width: number; // Computed viewport width
537
height: number; // Computed viewport height
538
viewBoxRect: RectLike; // ViewBox rectangle if specified
539
viewBoxTransform: { // Transform from viewBox to viewport
540
scale: number[];
541
position: number[];
542
};
543
}
544
```
545
546
**Usage Examples:**
547
548
```typescript
549
import { parseSVG } from "zrender";
550
551
// Parse SVG string
552
const svgString = `
553
<svg width="200" height="200">
554
<circle cx="100" cy="100" r="50" fill="red"/>
555
<rect x="50" y="50" width="100" height="100" fill="blue" opacity="0.5"/>
556
</svg>
557
`;
558
559
const result = parseSVG(svgString, {
560
width: 400,
561
height: 400
562
});
563
564
// Add parsed elements to ZRender instance
565
zr.add(result.root);
566
567
// Access parsed elements
568
console.log(`SVG dimensions: ${result.width}x${result.height}`);
569
console.log(`Root contains ${result.root.children().length} elements`);
570
```
571
572
## Debug Utilities
573
574
### Debug Dirty Rectangle Visualization
575
576
Development utility for visualizing dirty rectangles in canvas rendering:
577
578
```typescript { .api }
579
/**
580
* Show debug visualization of dirty rectangles on canvas
581
* @param zr - ZRender instance to debug
582
* @param options - Debug visualization options
583
*/
584
function showDebugDirtyRect(zr: ZRender, options?: DebugDirtyRectOptions): void;
585
586
interface DebugDirtyRectOptions {
587
style?: {
588
backgroundColor?: string; // Default: 'rgba(0, 0, 255, 0.2)'
589
border?: string; // Default: '1px solid #00f'
590
[key: string]: any; // Additional CSS properties
591
};
592
autoHideDelay?: number; // Auto-hide delay in milliseconds
593
}
594
```
595
596
**Usage Examples:**
597
598
```typescript
599
import { init, showDebugDirtyRect } from "zrender";
600
601
// Initialize ZRender with debug mode
602
const zr = init(document.getElementById('canvas'));
603
604
// Enable dirty rectangle visualization
605
showDebugDirtyRect(zr, {
606
style: {
607
backgroundColor: 'rgba(255, 0, 0, 0.3)',
608
border: '2px solid #f00'
609
},
610
autoHideDelay: 1000
611
});
612
613
// Now dirty rectangles will be highlighted when elements are updated
614
const circle = new Circle({
615
shape: { cx: 100, cy: 100, r: 50 },
616
style: { fill: 'blue' }
617
});
618
619
zr.add(circle);
620
621
// This update will show a debug rectangle
622
circle.attr('shape', { cx: 150, cy: 150 });
623
```