CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-zrender

A lightweight 2D graphics library providing canvas and SVG rendering for Apache ECharts

Overview
Eval results
Files

graphics-primitives.mddocs/

Graphics Primitives

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.

Base Element Classes

Element

The foundational class for all graphics objects in ZRender:

class Element {
  // Hierarchy management
  add(el: Element): void;
  remove(el: Element): void;
  removeAll(): void;
  parent: Group | null;
  children(): Element[];
  
  // Transformations
  position: number[];
  rotation: number;
  scale: number[];
  origin: number[];
  
  // Display properties
  invisible: boolean;
  ignore: boolean;
  silent: boolean;
  zlevel: number;
  z: number;
  
  // Animation
  animate(props?: string): Animator;
  stopAnimation(forwardToLast?: boolean): this;
  
  // Events
  on(eventName: string, handler: ElementEventCallback, context?: any): this;
  off(eventName?: string, handler?: ElementEventCallback): void;
  trigger(eventName: string, event?: any): void;
  
  // Utilities
  getBoundingRect(): BoundingRect;
  clone(): Element;
  dispose(): void;
}

Displayable

Base class for visible elements that can be rendered:

class Displayable extends Element {
  style: any;
  dirty(): void;
  styleChanged(): boolean;
  useStyle(obj: any): void;
  getBoundingRect(): BoundingRect;
}

interface DisplayableProps extends ElementProps {
  style?: any;
  zlevel?: number;
  z?: number;
  culling?: boolean;
  cursor?: string;
}

Group

Container element for organizing and transforming multiple elements as a unit:

class Group extends Element {
  children(): Element[];
  childAt(idx: number): Element;
  childOfName(name: string): Element;
  childCount(): number;
  eachChild<T>(cb: (this: T, child: Element, index: number) => void, context?: T): void;
  traverse<T>(cb: (this: T, el: Element) => boolean | void, context?: T): void;
  getBoundingRect(includeChildren?: Element[]): BoundingRect;
}

interface GroupProps extends ElementProps {
  // Groups primarily use inherited properties from ElementProps
}

Path

Base class for vector graphics elements (shapes):

class Path extends Displayable {
  shape: any;
  buildPath(ctx: CanvasRenderingContext2D | SVGPathElement, shape: any): void;
  getBoundingRect(): BoundingRect;
  contain(x: number, y: number): boolean;
}

interface PathProps extends DisplayableProps {
  shape?: any;
  style?: PathStyleProps;
}

interface PathStyleProps {
  fill?: string | LinearGradient | RadialGradient | Pattern;
  stroke?: string;
  lineWidth?: number;
  lineDash?: number[];
  lineDashOffset?: number;
  lineCap?: 'butt' | 'round' | 'square';
  lineJoin?: 'bevel' | 'round' | 'miter';
  miterLimit?: number;
  opacity?: number;
  fillOpacity?: number;
  strokeOpacity?: number;
  shadowBlur?: number;
  shadowColor?: string;
  shadowOffsetX?: number;
  shadowOffsetY?: number;
}

Text

Specialized element for text rendering:

class Text extends Displayable {
  style: TextStyleProps;
}

interface TextProps extends DisplayableProps {
  style?: TextStyleProps;
}

interface TextStyleProps {
  text?: string;
  fontSize?: number;
  fontFamily?: string;
  fontStyle?: 'normal' | 'italic' | 'oblique';
  fontWeight?: string | number;
  fill?: string | LinearGradient | RadialGradient | Pattern;
  stroke?: string;
  lineWidth?: number;
  textAlign?: 'left' | 'center' | 'right';
  textVerticalAlign?: 'top' | 'middle' | 'bottom';
  textBaseline?: 'top' | 'middle' | 'bottom' | 'alphabetic' | 'ideographic' | 'hanging';
  opacity?: number;
  textShadowBlur?: number;
  textShadowColor?: string;
  textShadowOffsetX?: number;
  textShadowOffsetY?: number;
  width?: number;
  height?: number;
  textPadding?: number | number[];
  textLineHeight?: number;
  rich?: Record<string, TextStyleProps>;
  truncate?: {
    outerWidth?: number;
    outerHeight?: number;
    ellipsis?: string;
    placeholder?: string;
  };
  blend?: string;
}

interface TextState {
  style?: Partial<TextStyleProps>;
}

TSpan

Text span element for rich text formatting:

class TSpan extends Displayable {
  style: TSpanStyleProps;
}

interface TSpanProps extends DisplayableProps {
  style?: TSpanStyleProps;
}

interface TSpanStyleProps extends TextStyleProps {
  x?: number;
  y?: number;
  text?: string;
}

interface TSpanState {
  style?: Partial<TSpanStyleProps>;
}

Image

Element for displaying bitmap images:

class Image extends Displayable {
  style: ImageStyleProps;
}

interface ImageProps extends DisplayableProps {
  style?: ImageStyleProps;
}

interface ImageStyleProps {
  image?: string | HTMLImageElement | HTMLCanvasElement;
  x?: number;
  y?: number;
  width?: number;
  height?: number;
  sx?: number;  // Source x
  sy?: number;  // Source y  
  sWidth?: number;  // Source width
  sHeight?: number; // Source height
  opacity?: number;
  shadowBlur?: number;
  shadowColor?: string;
  shadowOffsetX?: number;
  shadowOffsetY?: number;
}

interface ImageState {
  style?: Partial<ImageStyleProps>;
}

CompoundPath

Element for creating complex paths from multiple sub-paths:

class CompoundPath extends Path {
  shape: CompoundPathShape;
}

interface CompoundPathShape {
  paths: Path[];
}

IncrementalDisplayable

Special element for progressive/streaming rendering:

class IncrementalDisplayable extends Displayable {
  incremental: boolean;
  clearIncrementalNewAdded(): void;
  markIncrementalNewAdded(): void;
}

Common Element Properties

All graphics elements support these common properties through the ElementProps interface:

interface ElementProps {
  // Transform properties
  position?: number[];      // [x, y]
  rotation?: number;        // Rotation in radians
  scale?: number[];         // [scaleX, scaleY]
  origin?: number[];        // [originX, originY] transform origin
  
  // Display properties
  zlevel?: number;          // Layer level (affects rendering order)
  z?: number;              // Z-index within layer
  invisible?: boolean;      // Hide element
  ignore?: boolean;         // Ignore in hit testing and rendering
  silent?: boolean;         // Disable event handling
  
  // Interaction
  cursor?: string;          // CSS cursor style
  draggable?: boolean;      // Enable dragging
  progressive?: number;     // Progressive rendering threshold
  
  // Animation
  culling?: boolean;        // Enable view culling
  rectHover?: boolean;      // Use rectangular hover area
  useHoverLayer?: boolean;  // Render hover state on separate layer
}

Usage Examples

Creating Basic Elements

import { Group, Circle, Text } from "zrender";

// Create a group to contain multiple elements
const group = new Group({
  position: [100, 100],
  rotation: Math.PI / 4
});

// Create a circle
const circle = new Circle({
  shape: { cx: 0, cy: 0, r: 50 },
  style: { fill: '#ff0000', stroke: '#000000', lineWidth: 2 },
  z: 1
});

// Create text
const text = new Text({
  style: {
    text: 'Hello ZRender',
    fontSize: 16,
    fill: '#333333',
    textAlign: 'center'
  },
  position: [0, -60],
  z: 2
});

// Build hierarchy
group.add(circle);
group.add(text);

// Add to ZRender instance
zr.add(group);

Element Animation

import { Rect } from "zrender";

const rect = new Rect({
  shape: { x: 0, y: 0, width: 100, height: 50 },
  style: { fill: '#0066cc' },
  position: [50, 50]
});

// Animate properties
rect.animate('position')
  .when(1000, [300, 200])
  .when(2000, [50, 50])
  .start();

// Animate shape
rect.animate('shape')
  .when(1000, { width: 200, height: 100 })
  .start('easeInOut');

// Animate style
rect.animate('style')
  .when(500, { fill: '#ff6600' })
  .start();

Event Handling

import { Circle } from "zrender";

const circle = new Circle({
  shape: { cx: 100, cy: 100, r: 30 },
  style: { fill: '#00cc66' }
});

// Add event handlers
circle.on('click', (e) => {
  console.log('Circle clicked!', e);
});

circle.on('mouseover', (e) => {
  circle.animate('style')
    .when(200, { fill: '#66ff99' })
    .start();
});

circle.on('mouseout', (e) => {
  circle.animate('style')
    .when(200, { fill: '#00cc66' })
    .start();
});

zr.add(circle);

Complex Hierarchies

import { Group, Rect, Text, Circle } from "zrender";

// Create a button-like component
function createButton(text: string, x: number, y: number) {
  const button = new Group({
    position: [x, y]
  });
  
  const background = new Rect({
    shape: { x: 0, y: 0, width: 120, height: 40, r: 5 },
    style: { 
      fill: '#4a90e2', 
      stroke: '#357abd', 
      lineWidth: 1 
    }
  });
  
  const label = new Text({
    style: {
      text: text,
      fontSize: 14,
      fill: '#ffffff',
      textAlign: 'center',
      textVerticalAlign: 'middle'
    },
    position: [60, 20]
  });
  
  button.add(background);
  button.add(label);
  
  // Add hover effects
  button.on('mouseover', () => {
    background.animate('style')
      .when(150, { fill: '#5aa3f0' })
      .start();
  });
  
  button.on('mouseout', () => {
    background.animate('style')
      .when(150, { fill: '#4a90e2' })
      .start();
  });
  
  return button;
}

// Use the component
const btn1 = createButton('Click Me', 50, 50);
const btn2 = createButton('Cancel', 200, 50);

zr.add(btn1);
zr.add(btn2);

Install with Tessl CLI

npx tessl i tessl/npm-zrender

docs

animation.md

core-zrender.md

events.md

graphics-primitives.md

index.md

shapes.md

styling.md

text-images.md

utilities.md

tile.json