All Components

Basic Shapes

The Drawing library provides a set of built-in basic shapes for constructing scenes.

Getting Started

The following example demonstrates the complete implementation for rendering a static scene. In terms of the Drawing API, this scene consists of a path (the border), text, and image.

import { Image, Surface, Path, Text, Group, geometry } from '@progress/kendo-drawing';
const { Rect, Point, Size, transform } = geometry;

export function drawScene(surface: Surface) {
  // Create the square border by drawing a straight path
  const path = new Path({
    stroke: {
      color: "#9999b6",
      width: 2
    }
  });

  // The path is constructed by using a chain of commands
  path.moveTo(0, 0)
  .lineTo(150, 0).lineTo(150, 65).lineTo(0, 65)
  .close();

  // This rectangle defines the image position and size
  const imageRect = new Rect(
    new Point(5, 5),
    new Size(50, 50)
  );

  // Create the image
  const imageUrl = `http://www.telerik.com/kendo-angular-ui/components/drawing/images/diego.jpg`;
  const image = new Image(imageUrl, imageRect);

  // Create the text
  const text = new Text(
    "Diego Roel",
    new Point(60, 25),
    { font: "bold 15px Arial" }
  );

  // Place all the shapes in a group
  const group = new Group();
  group.append(path, image, text);

  // Translate the group
  group.transform(
    transform().translate(50, 50)
  );

  // Render the group on the surface
  surface.draw(group);
}
import { Component, ElementRef, ViewChild } from '@angular/core';
import { AfterViewInit, OnDestroy } from '@angular/core';
import { Surface } from '@progress/kendo-drawing';

import { drawScene } from './draw-scene';

@Component({
  selector: 'my-app',
  template: `
      <div #surface></div>
  `
})
export class AppComponent implements AfterViewInit, OnDestroy {
  @ViewChild('surface')
  private surfaceElement: ElementRef;
  private surface: Surface;

  public ngAfterViewInit(): void {
    drawScene(this.createSurface());
  }

  public ngOnDestroy() {
    this.surface.destroy();
  }

  private createSurface(): Surface {
    // Obtain a reference to the native DOM element of the wrapper
    const element = this.surfaceElement.nativeElement;

    // Create a drawing surface
    this.surface = Surface.create(element);

    return this.surface;
  }
}

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

@NgModule({
  imports:      [ BrowserModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Constructing the Sample Scene

To replicate the static scene from the previous example and add an enclosing group for positioning:

  1. Import the types
  2. Draw the path
  3. Draw the image
  4. Draw the text
  5. Draw the gradient
  6. Group the shapes
  7. Create the surface
  8. Render the scene

Importing the Types

The main entry point rest of the types are exported in the main @progress/kendo-drawing module. The sample project uses the Path, Image, and Group elements. The geometry namespace contains geometric primitives and helpers, such as Point, Rect, and Size.

The following example demonstrates how to use the classes from the two namespaces.

import { geometry, Image, Surface, Path, Text, Group } from '@progress/kendo-drawing';
const { Rect, Point, Size, transform } = geometry;

Drawing the Path

To draw straight lines, curves, or a combination of both, use the Path element.

  1. Set the stroke (line) color and width to match the picture. The constructor accepts the ShapeOptions object that controls the appearance of the shape.

    const path = new Path({
       stroke: {
           color: "#9999b6",
           width: 2
       }
    });
  2. Set the initial position of the line by using the moveTo command. To draw the three sides, use the lineTo command. The last close command closes the path and draws a straight line to the initial position.

    path.moveTo(0, 0)
       .lineTo(150, 0).lineTo(150, 65).lineTo(0, 65)
       .close();

    Alternatively, you can also use the static fromRect method because the figure from the example is a rectangle.

    const borderRect = new Rect(
       new Point(0, 0),
       new Size(150, 65)
    );
    const path = Path.fromRect(borderRect, {
       stroke: {
           color: "#9999b6",
           width: 2
       }
    });

Drawing the Image

To draw an image, use the Image element which draws a bitmap image from a given URL.

  1. Define the position and size of the image as a Rect element.

    const imageRect = new Rect(
       new Point(5, 5),
       new Size(50, 50)
    );
  2. (Optional) Shorten the previous code statement.

    Each method that expects Point and Size also accepts [x, y] and [width, height] arrays.

    const imageRect = new geom.Rect([5, 5], [50, 50]);
  3. Create the image.

    const image = new Image('../images/diego.jpg', imageRect);

Drawing the Text

To draw the text, use the Text element which draws a single line of text. Appearance options, such as the font, are set through options. The Point configuration defines the position of the top-left corner.

const text = new Text(
    'Diego Roel',
    new Point(60, 25),
    { font: 'bold 15px Arial' }
);

Drawing the Gradient

To add a gradient color to the background, use the Gradient and LinearGradient classes.

import { Image, Surface, Path, Text, Group, LinearGradient, GradientStop, Rect, geometry } from '@progress/kendo-drawing';
const { Rect: RectGeometry, Point, Size, transform } = geometry;

export function drawScene(surface: Surface) {
    const gradient = new LinearGradient({
        name: "LG1",
        stops: [
          new GradientStop(0, "gray", 0),
          new GradientStop(0.5, "orange", 0.8)
        ]
    });

  // This rectangle demonstrates how to use the gradient as a fill.
  const rect = new RectGeometry(
    new Point(100, 100),
    new Size(50, 50)
  );

  const drawingRect = new Rect(rect, {
    stroke: {
      color: "#9999b6",
      width: 2
    },
    fill: gradient
  });

  // Place all the shapes in a group.
  const group = new Group();
  group.append(drawingRect);

  // Translate the group.
  group.transform(
    transform().translate(50, 50)
  );

  // Render the group on the surface.
  surface.draw(group);
}
import { Component, ElementRef, ViewChild } from '@angular/core';
import { AfterViewInit, OnDestroy } from '@angular/core';
import { Surface } from '@progress/kendo-drawing';

import { drawScene } from './draw-scene';

@Component({
  selector: 'my-app',
  template: `
      <div #surface></div>
  `
})
export class AppComponent implements AfterViewInit, OnDestroy {
  @ViewChild('surface')
  private surfaceElement: ElementRef;
  private surface: Surface;

  public ngAfterViewInit(): void {
    drawScene(this.createSurface());
  }

  public ngOnDestroy() {
    this.surface.destroy();
  }

  private createSurface(): Surface {
    // Obtain a reference to the native DOM element of the wrapper
    const element = this.surfaceElement.nativeElement;

    // Create a drawing surface
    this.surface = Surface.create(element, {width: 300, height: 300});

    return this.surface;
  }
}

import { enableProdMode, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';

@NgModule({
  imports:      [ BrowserModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})

export class AppModule { }

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

@NgModule({
  imports:      [ BrowserModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

Grouping the Shapes

It is convenient to treat a group of shapes as a single entity. To set the position of all elements at once, use the group constructor.

  1. Create a Group element and append the rest of the elements as children.

    const group = new Group();
    group.append(path, image, text);
  2. Set the transformation which applies to all group children—to effectively make the coordinates of the element relative, translate their parent group.

    group.transform(
       transform().translate(50, 50)
    );

Creating the Surface

To create the surface, use the Surface.create method which chooses an implementation that matches the capabilities of the browser. The default output is an SVG with a fallback to Canvas.

The following example demonstrates how to apply Surface.create. The surface is created in the AppComponent.

// Obtain a reference to the native DOM element of the wrapper
const element = this.surfaceElement.nativeElement;

// Create a drawing surface
this.surface = Surface.create(element);

Rendering the Scene

To render the scene, use the draw method of the surface which appends shapes to the scene graph.

surface.draw(group);
In this article