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

styling.mddocs/

0

# Styling and Gradients

1

2

ZRender provides a comprehensive styling system for controlling the visual appearance of graphics elements. This includes solid colors, gradients, patterns, shadows, and advanced rendering effects.

3

4

## Basic Styling Properties

5

6

All visual elements support these fundamental styling properties:

7

8

```typescript { .api }

9

interface PathStyleProps {

10

// Fill properties

11

fill?: string | LinearGradient | RadialGradient | Pattern;

12

fillOpacity?: number;

13

14

// Stroke properties

15

stroke?: string;

16

strokeOpacity?: number;

17

lineWidth?: number;

18

lineDash?: number[];

19

lineDashOffset?: number;

20

lineCap?: 'butt' | 'round' | 'square';

21

lineJoin?: 'bevel' | 'round' | 'miter';

22

miterLimit?: number;

23

24

// Overall opacity

25

opacity?: number;

26

27

// Shadow effects

28

shadowBlur?: number;

29

shadowColor?: string;

30

shadowOffsetX?: number;

31

shadowOffsetY?: number;

32

33

// Advanced rendering

34

blend?: string;

35

globalCompositeOperation?: string;

36

}

37

```

38

39

## Gradient Classes

40

41

### LinearGradient

42

43

Creates linear gradients with customizable direction and color stops:

44

45

```typescript { .api }

46

class LinearGradient {

47

constructor(x1: number, y1: number, x2: number, y2: number, colorStops: ColorStop[], globalCoord?: boolean);

48

49

x1: number; // Start point X (0-1 in local coordinates)

50

y1: number; // Start point Y (0-1 in local coordinates)

51

x2: number; // End point X (0-1 in local coordinates)

52

y2: number; // End point Y (0-1 in local coordinates)

53

colorStops: ColorStop[];

54

global: boolean; // Use global coordinates instead of local

55

}

56

57

interface LinearGradientObject {

58

type: 'linear';

59

x1: number;

60

y1: number;

61

x2: number;

62

y2: number;

63

colorStops: ColorStop[];

64

global?: boolean;

65

}

66

67

interface ColorStop {

68

offset: number; // Position along gradient (0-1)

69

color: string; // Color at this stop

70

}

71

```

72

73

### RadialGradient

74

75

Creates radial gradients emanating from a center point:

76

77

```typescript { .api }

78

class RadialGradient {

79

constructor(x: number, y: number, r: number, colorStops: ColorStop[], globalCoord?: boolean);

80

81

x: number; // Center X (0-1 in local coordinates)

82

y: number; // Center Y (0-1 in local coordinates)

83

r: number; // Radius (0-1 in local coordinates)

84

colorStops: ColorStop[];

85

global: boolean; // Use global coordinates instead of local

86

}

87

88

interface RadialGradientObject {

89

type: 'radial';

90

x: number;

91

y: number;

92

r: number;

93

colorStops: ColorStop[];

94

global?: boolean;

95

}

96

```

97

98

## Pattern Class

99

100

Creates pattern fills using images or other elements:

101

102

```typescript { .api }

103

class Pattern {

104

constructor(image: PatternImageSource, repeat: PatternRepeat);

105

106

image: PatternImageSource;

107

repeat: PatternRepeat;

108

}

109

110

type PatternImageSource =

111

| HTMLImageElement

112

| HTMLCanvasElement

113

| HTMLVideoElement

114

| string; // URL or data URI

115

116

type PatternRepeat = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat';

117

118

interface PatternObjectBase {

119

type: 'pattern';

120

repeat: PatternRepeat;

121

}

122

123

interface ImagePatternObject extends PatternObjectBase {

124

image: HTMLImageElement | HTMLCanvasElement | string;

125

x?: number;

126

y?: number;

127

rotation?: number;

128

scaleX?: number;

129

scaleY?: number;

130

}

131

132

interface SVGPatternObject extends PatternObjectBase {

133

svgElement: SVGElement;

134

svgWidth: number;

135

svgHeight: number;

136

x?: number;

137

y?: number;

138

rotation?: number;

139

scaleX?: number;

140

scaleY?: number;

141

}

142

143

type PatternObject = ImagePatternObject | SVGPatternObject;

144

```

145

146

## Text Styling

147

148

Text elements have additional styling properties:

149

150

```typescript { .api }

151

interface TextStyleProps {

152

// Text content and basic properties

153

text?: string;

154

fontSize?: number;

155

fontFamily?: string;

156

fontStyle?: 'normal' | 'italic' | 'oblique';

157

fontWeight?: string | number;

158

159

// Text positioning and alignment

160

textAlign?: 'left' | 'center' | 'right';

161

textVerticalAlign?: 'top' | 'middle' | 'bottom';

162

textBaseline?: 'top' | 'middle' | 'bottom' | 'alphabetic' | 'ideographic' | 'hanging';

163

164

// Text appearance

165

fill?: string | LinearGradient | RadialGradient | Pattern;

166

stroke?: string;

167

lineWidth?: number;

168

opacity?: number;

169

170

// Text shadows

171

textShadowBlur?: number;

172

textShadowColor?: string;

173

textShadowOffsetX?: number;

174

textShadowOffsetY?: number;

175

176

// Text layout

177

width?: number;

178

height?: number;

179

textPadding?: number | number[];

180

textLineHeight?: number;

181

182

// Rich text formatting

183

rich?: Record<string, TextStyleProps>;

184

185

// Text truncation

186

truncate?: {

187

outerWidth?: number;

188

outerHeight?: number;

189

ellipsis?: string;

190

placeholder?: string;

191

};

192

193

// Rendering effects

194

blend?: string;

195

}

196

```

197

198

## Usage Examples

199

200

### Solid Colors and Basic Styling

201

202

```typescript

203

import { Circle, Rect } from "zrender";

204

205

// Simple solid color fill

206

const circle = new Circle({

207

shape: { cx: 100, cy: 100, r: 50 },

208

style: {

209

fill: '#ff6b6b', // Solid red fill

210

stroke: '#d63031', // Dark red border

211

lineWidth: 3,

212

opacity: 0.8

213

}

214

});

215

216

// Advanced stroke styling

217

const rect = new Rect({

218

shape: { x: 200, y: 50, width: 120, height: 80 },

219

style: {

220

fill: 'none',

221

stroke: '#74b9ff',

222

lineWidth: 4,

223

lineDash: [10, 5], // Dashed line

224

lineCap: 'round', // Rounded line ends

225

lineJoin: 'round' // Rounded corners

226

}

227

});

228

229

zr.add(circle);

230

zr.add(rect);

231

```

232

233

### Linear Gradients

234

235

```typescript

236

import { Rect, LinearGradient } from "zrender";

237

238

// Horizontal gradient

239

const horizontalGradient = new LinearGradient(0, 0, 1, 0, [

240

{ offset: 0, color: '#ff7675' },

241

{ offset: 0.5, color: '#fd79a8' },

242

{ offset: 1, color: '#fdcb6e' }

243

]);

244

245

// Vertical gradient

246

const verticalGradient = new LinearGradient(0, 0, 0, 1, [

247

{ offset: 0, color: '#74b9ff' },

248

{ offset: 1, color: '#0984e3' }

249

]);

250

251

// Diagonal gradient

252

const diagonalGradient = new LinearGradient(0, 0, 1, 1, [

253

{ offset: 0, color: '#00b894' },

254

{ offset: 1, color: '#00cec9' }

255

]);

256

257

const rect1 = new Rect({

258

shape: { x: 50, y: 50, width: 150, height: 80 },

259

style: { fill: horizontalGradient }

260

});

261

262

const rect2 = new Rect({

263

shape: { x: 250, y: 50, width: 80, height: 150 },

264

style: { fill: verticalGradient }

265

});

266

267

const rect3 = new Rect({

268

shape: { x: 50, y: 180, width: 120, height: 120 },

269

style: { fill: diagonalGradient }

270

});

271

272

zr.add(rect1);

273

zr.add(rect2);

274

zr.add(rect3);

275

```

276

277

### Radial Gradients

278

279

```typescript

280

import { Circle, RadialGradient } from "zrender";

281

282

// Center-focused radial gradient

283

const radialGradient = new RadialGradient(0.5, 0.5, 0.5, [

284

{ offset: 0, color: '#ffffff' },

285

{ offset: 0.7, color: '#74b9ff' },

286

{ offset: 1, color: '#0984e3' }

287

]);

288

289

// Off-center radial gradient for lighting effect

290

const lightingGradient = new RadialGradient(0.3, 0.3, 0.8, [

291

{ offset: 0, color: '#fff5b4' },

292

{ offset: 0.4, color: '#ffda79' },

293

{ offset: 1, color: '#e17055' }

294

]);

295

296

const circle1 = new Circle({

297

shape: { cx: 150, cy: 150, r: 80 },

298

style: { fill: radialGradient }

299

});

300

301

const circle2 = new Circle({

302

shape: { cx: 350, cy: 150, r: 80 },

303

style: {

304

fill: lightingGradient,

305

stroke: '#d63031',

306

lineWidth: 2

307

}

308

});

309

310

zr.add(circle1);

311

zr.add(circle2);

312

```

313

314

### Pattern Fills

315

316

```typescript

317

import { Rect, Pattern } from "zrender";

318

319

// Create pattern from image

320

const createImagePattern = (imageUrl: string) => {

321

const img = new Image();

322

img.src = imageUrl;

323

return new Pattern(img, 'repeat');

324

};

325

326

// Create pattern from canvas

327

const createCanvasPattern = () => {

328

const canvas = document.createElement('canvas');

329

canvas.width = 20;

330

canvas.height = 20;

331

const ctx = canvas.getContext('2d')!;

332

333

// Draw a simple pattern

334

ctx.fillStyle = '#e17055';

335

ctx.fillRect(0, 0, 10, 10);

336

ctx.fillStyle = '#fdcb6e';

337

ctx.fillRect(10, 10, 10, 10);

338

339

return new Pattern(canvas, 'repeat');

340

};

341

342

const patternRect = new Rect({

343

shape: { x: 100, y: 100, width: 200, height: 150 },

344

style: {

345

fill: createCanvasPattern(),

346

stroke: '#2d3436',

347

lineWidth: 2

348

}

349

});

350

351

zr.add(patternRect);

352

```

353

354

### Shadow Effects

355

356

```typescript

357

import { Circle, Text } from "zrender";

358

359

// Drop shadow effect

360

const shadowCircle = new Circle({

361

shape: { cx: 150, cy: 150, r: 60 },

362

style: {

363

fill: '#74b9ff',

364

shadowBlur: 20,

365

shadowColor: 'rgba(116, 185, 255, 0.6)',

366

shadowOffsetX: 10,

367

shadowOffsetY: 10

368

}

369

});

370

371

// Glow effect

372

const glowCircle = new Circle({

373

shape: { cx: 350, cy: 150, r: 50 },

374

style: {

375

fill: '#00b894',

376

shadowBlur: 30,

377

shadowColor: '#00b894'

378

// No offset for glow effect

379

}

380

});

381

382

// Text with shadow

383

const shadowText = new Text({

384

style: {

385

text: 'Shadow Text',

386

fontSize: 24,

387

fill: '#2d3436',

388

textShadowBlur: 5,

389

textShadowColor: 'rgba(0, 0, 0, 0.5)',

390

textShadowOffsetX: 2,

391

textShadowOffsetY: 2

392

},

393

position: [200, 300]

394

});

395

396

zr.add(shadowCircle);

397

zr.add(glowCircle);

398

zr.add(shadowText);

399

```

400

401

### Advanced Text Styling

402

403

```typescript

404

import { Text } from "zrender";

405

406

// Rich text with multiple styles

407

const richText = new Text({

408

style: {

409

text: '{title|ZRender} {subtitle|Graphics Library}\n{body|Create beautiful 2D graphics}',

410

rich: {

411

title: {

412

fontSize: 28,

413

fontWeight: 'bold',

414

fill: '#2d3436'

415

},

416

subtitle: {

417

fontSize: 16,

418

fill: '#636e72',

419

fontStyle: 'italic'

420

},

421

body: {

422

fontSize: 14,

423

fill: '#74b9ff',

424

textPadding: [10, 0, 0, 0]

425

}

426

},

427

width: 300,

428

textAlign: 'center'

429

},

430

position: [150, 100]

431

});

432

433

// Gradient text fill

434

const gradientText = new Text({

435

style: {

436

text: 'Gradient Text',

437

fontSize: 32,

438

fontWeight: 'bold',

439

fill: new LinearGradient(0, 0, 1, 0, [

440

{ offset: 0, color: '#ff7675' },

441

{ offset: 0.5, color: '#fd79a8' },

442

{ offset: 1, color: '#e84393' }

443

]),

444

stroke: '#2d3436',

445

lineWidth: 1

446

},

447

position: [150, 250]

448

});

449

450

zr.add(richText);

451

zr.add(gradientText);

452

```

453

454

### Animated Styling

455

456

```typescript

457

import { Circle, LinearGradient } from "zrender";

458

459

// Create animated gradient

460

const animatedCircle = new Circle({

461

shape: { cx: 200, cy: 200, r: 60 },

462

style: {

463

fill: new LinearGradient(0, 0, 1, 0, [

464

{ offset: 0, color: '#74b9ff' },

465

{ offset: 1, color: '#0984e3' }

466

]),

467

shadowBlur: 0

468

}

469

});

470

471

// Animate color transitions

472

animatedCircle.animate('style')

473

.when(1000, {

474

shadowBlur: 20,

475

shadowColor: '#74b9ff'

476

})

477

.when(2000, {

478

shadowBlur: 0

479

})

480

.start('easeInOut');

481

482

// Animate gradient color stops

483

const animateGradient = () => {

484

const newGradient = new LinearGradient(0, 0, 1, 0, [

485

{ offset: 0, color: '#e17055' },

486

{ offset: 1, color: '#fdcb6e' }

487

]);

488

489

animatedCircle.animate('style')

490

.when(1500, { fill: newGradient })

491

.start();

492

};

493

494

// Trigger gradient animation on click

495

animatedCircle.on('click', animateGradient);

496

497

zr.add(animatedCircle);

498

```

499

500

### Style State Management

501

502

```typescript

503

import { Rect } from "zrender";

504

505

// Interactive styling with state management

506

const interactiveRect = new Rect({

507

shape: { x: 100, y: 100, width: 120, height: 80, r: 8 },

508

style: {

509

fill: '#74b9ff',

510

stroke: '#0984e3',

511

lineWidth: 2,

512

opacity: 1

513

}

514

});

515

516

// Store original style

517

const originalStyle = { ...interactiveRect.style };

518

519

// Hover states

520

interactiveRect.on('mouseover', () => {

521

interactiveRect.animate('style')

522

.when(200, {

523

fill: '#a29bfe',

524

shadowBlur: 10,

525

shadowColor: '#74b9ff',

526

opacity: 0.9

527

})

528

.start('easeOut');

529

});

530

531

interactiveRect.on('mouseout', () => {

532

interactiveRect.animate('style')

533

.when(200, originalStyle)

534

.start('easeOut');

535

});

536

537

// Active/pressed state

538

interactiveRect.on('mousedown', () => {

539

interactiveRect.animate('style')

540

.when(100, {

541

fill: '#6c5ce7',

542

shadowBlur: 5

543

})

544

.start();

545

});

546

547

interactiveRect.on('mouseup', () => {

548

interactiveRect.animate('style')

549

.when(100, {

550

fill: '#a29bfe',

551

shadowBlur: 10

552

})

553

.start();

554

});

555

556

zr.add(interactiveRect);

557

```