or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation.mdcore-zrender.mdevents.mdgraphics-primitives.mdindex.mdshapes.mdstyling.mdtext-images.mdutilities.md

utilities.mddocs/

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

```