Using draw package in Sencha Touch


SenchaDrawPkg

Problem Statement

With the inclusion of Draw and Chart packages in sencha touch it the Sencha Touch framework has become even more powerful than ever.   As part of this article I will be introducing the draw package of Sencha Touch and illustrate the important API by creating an analog clock like interface shown in above image.

Pre-requisites

  • Basic familiarity with Sencha Touch
  • A default project created using Sencha Architect

Following is the default code with a Main class added as the only view:

 
Ext.Loader.setConfig({
	src : 'sdk/src'
});

Ext.application({
    views: [
        'Main'
    ],
    name: 'MyApp',

    launch: function() {

        Ext.create('MyApp.view.Main', {fullscreen: true});
    }

});

Terms / Definitions

  •  The Draw Component manages and holds a Surface instance on which actual drawing (shapes) gets rendered.
  • Sprites are objects (e.g. circle, rectangle, ellipse, image, text, path or any custom object) that get rendered on a drawing surface. Sprites respond to interactions, and also provide rich animations.
  • Scalable Vector Graphics (SVG) is an XML-based vector image format for two-dimensional graphics that has support for interactivity and animation. Most of the commonly used browsers like Firefox, Internet Explorer (IE 9+), Opera, Safari and Google Chrome supports SVG.
  • Vector Markup Language (VML) is an XML-based file format for two-dimensional vector graphics. VML has been largely deprecated in favor of other formats, such as SVG. VML is implemented in Internet Explorer from version 5 to version 9 and in Microsoft Office 2000.
  • The Canvas element is part of HTML5 and allows for dynamic, scriptable rendering of 2D shapes and bitmap images.
  • Surface is an interface that has an SVG, VML or Canvas implementation depending on the browser capabilities, where Sprites can be added and rendered. Sencha Touch simplifies the development tasks by abstracting the APIs of different engines into Surface class.

How do we do?

The first thing I have done is that I have downloaded the zip file from below link, which gives me a very nice image for the analog clock:

http://www.sencha.com/forum/showthread.php?115907

Step 1: Create a draw object with the clock image

First you need to create an instance of draw object, which consists of surface, on which the actual sprite will be rendered. The sprite can be added as part of items configuration or you can add sprites using the “add” method available on the Surface object. Here I have included the image sprite as part of items declaration itself.

Following is the most primitive code

Ext.define('MyApp.view.Main', {
    extend : 'Ext.Container',

	xtype: 'mainview',

	constructor : function(config) {

		var me = this;

		config.items = [
			{
				xtype : 'panel',
				layout: 'card',
				activeItem : 0,
				height : '100%',
				width : '100%',
				items: [
					{
						xtype : 'draw',
						viewBox: true,
						id : 'clockCmp',
						items: [
							Ext.create( 'Ext.draw.sprite.Image', {
								src : './resources/images/bg-clock.png',
								width : 300,
								height : 300,
								x : 50,
								y : 50
							}
						)
					]
				} ]
			}
        ];

		Ext.apply(this, config);
		this.callParent(arguments);
	}
});

below screenshot shows the image sprite being rendered on the surface:
ImageSprite

Using the appropriate value of x and y configuration of the image sprite you can decide the initial position of the clock with respect to the x-axis and y-axis respectively. Now that you have got the basic shape of the clock, let’s put a circle inside it.

Step 2 : Adding a circle sprite 

Using the “circle”  type sprite with black background, we can give a more authentic look to the clock. All you need to do is, add following items as part of your sprite array:

{
	type: 'circle',
	fill: 'black',
	radius: 100,
	cx: 200,
	cy: 200
}

In above code, cx and cy is the center coordinate of the sprite. With above changes in place, now your analog clock looks like as shown below:

AnalogClockWithBC

Step 3 : Draw a small and shining circle in the centre

While the configuration of this sprite will be similar to the one used in previous step, we want a glossy central circle around which the needle will be drawn. In addition, we want this circle to be shown on top of the needles hands. By adding following sprite into your surface (on top of the circle with black background), you can achieve the desired result:

{
	type: 'circle',
	radius: 18,
	x: 200,
	y: 200,
	zIndex : 99,
	fillStyle : {
		type : 'radial',
		stops : [
			{
				offset : .25,
				color : 'green'
			}, 
			{
				offset : .60,
				color : 'yellow'
			}, 
			{
				offset : .85,
				color : 'black'
			},
			{
				offset : 1.0,
				color : 'blue'
			}
		]
	}
}

In above code you will see that instead of passing a color value to the fill object, I have provided a fillStyle object with radial gradient and few colors with different offsets. Note that offset values are between 0 and 1. In case the radial gradient is not desired then Sencha Touch also provides you linear gradient. Following image shows the difference between linear and radial gradient:

RadialLinear

Also, you will note that instead of going ahead with default zindex of 0, I have used 99 so that the circle in the centre always remains on top. Following screen shows the result of adding the above sprite:

AnalogClockWithBCAndCentre

Step 4 : Put minutes hand

Now that you have got the basic shape, let’s add a minutes hand by using following path sprite:

 
{
	type: "path",
	path: "M206 206 L290 200 L196 196 Z",  
	fill: 'purple',
	lineJoin : 'round',
	lineCap : 'round',
	miterLimit : 30,
	strokeStyle : 'purple',
	"stroke-width":"4",
	id : 'minutesHand',
	shadowColor : 'yellow',
	shadowOffsetY  : -3,
	shadowOffsetX : 2
}

In above code, I am basically drawing a triangular minutes hand using the path type sprite. Here, I have used a value of ’round’ for lineJoin (possible values are miter, bevel and round) as well as lineCap (possible values are butt, round, square) to make the tip of the minute hand round. Following image shows different caps and joins and how do they look:
CapsAndJoins

The path sprite basically follows the SVG path syntax. Following is the summary of  the SVG path commands that you can use to draw a shape in your mobile APP:

Command Syntax Description
M M x y The Move To command instructs the drawing engine to move to the point represented by (x , y) coordinate. The “Move To” command appears at the beginning of paths to specify where the drawing should start. If the engine was already drawing something and it encounters move to command then it doesn’t draw any line between the current position and the new position.
L L x y Draws a line between current position (Cx, Cy) and the point represented by (x , y) coordinate.
H H x Draws a horizontal line between the current position and the position identified by the coordinate (x, Cx).
V V y Draws a vertical line between the current position and the position identified by the coordinate (Cx, y).
Z Z The command Z instructs the engine to close the path from where the drawing started (i.e. the most recent moved to coordinate). It draws a straight line from the current position back to the first point that started the path.
Note:
In case you are not sure about the exact coordinate or your need is to draw a shape using relative values (for example you may start from a known position and from there work with relative values) then you need to use the lower case commands like l, h and v.
C C x1 y1, x2 y2, x y The command C is for the Cubic Bezier Curve. It expects two additional (control points) for each point. The curve starts at the current position and ends at a point represented by the last coordinate (x, y). The point (x1,y1) is the control point for deciding the slope for the start of the curve, and the point (x2,y2) is for deciding the slope for the end point of the curve. In between the bezier function does its magic to provide you the smooth curve governed by these two slopes.
S S x2 y2, x y Several Cubic Bezier curve can be combined to create a long smooth curve. In that case you can make use of S command (short cut) to indicate that the slope on the starting point of the next curve will be reflection of the slope of the previous curve’s end point. This is of course required to keep the curve smooth. Since we already have a knowledge of the starting slope, we just need two more coordinates (i.e. (x1, y1) point is not required).
Q Q x1 y1, x y The command Q is for the Quadratic Bezier Curve. Only one control point is required and based on this control point the engine determines the slope of the curve from the start (the current position is the starting point) and the end point (in this case (x,y) is the end point).
T T x y Several Quadratic Bezier Curve can be combined together and the T command allows you to use the short cut notation for the same (This is similar to the multiple cubic Bezier curve).
A A rx ry x-axis-rotation large-arc-flag sweep-flag x y The A command instructs drawing engine to draw an arc (essentially a section of circle or ellipse driven by the x-radius and y-radius. The parameter x-axis-rotation defines the rotation of the arc along x-axis. The point (x, y) determines the end point. The large-arc-flag (it accepts a value of 0 or 1) determines if the arc that should be drawn should be greater than (large arc), or less than 180 degrees (small arc). The sweep-flag determines if the arc should begin moving at negative angles (clockwise direction) or positive angles (anti-clockwise direction).

With minutes hand in place (using path sprite), the analog clock looks like as shown below:
ClockWithMinutesHand

Step 5 : Put hours hand

Let’s again use path sprite (for hour hand) and ellipse sprite (for showing special tip) as shown in below code to draw an hour hand:

{
	type: "path",
	path: "M200 200 L270 205",  
	fill: "blue",
	lineWidth : 7,
	fillStyle : 'rgba(155, 0, 255, .2)',
	strokeStyle : 'purple',
	id : 'hoursHand',
	rotationRads : 1,
	rotationCenterX : 200,
	rotationCenterY : 200
},
{
	type : "ellipse",
	fill : 'yellow',
	rx : 7,
	ry : 4,
	x : 270,
	y : 205,
	id : 'hoursHandTip',
	rotationRads : 1,
	rotationCenterX : 200,
	rotationCenterY : 200
}

In above code, I have rotated the hours hand around the coordinate (200, 200) by 1 radians. With above sprites added into the surface, you shall be able to see a clock similar to below:

ClockMH

So using the concept of Sencha Touch Draw Package, we are able to draw an analog clock like interface. Of course some work is still pending to make this a reusable (and real) clock (I will cover them in next few articles).

Below is the final code in Main.js file

Ext.define('MyApp.view.Main', {
    extend : 'Ext.Container',

	xtype: 'mainview',

	constructor : function(config) {

		var me = this;

		config.items = [
			{
				xtype : 'panel',
				layout: 'card',
				activeItem : 0,
				height : '100%',
				width : '100%',
				items: [
					{
						xtype : 'draw',
						viewBox: true,
						id : 'clockCmp',
						animation : {
							duration : 6000,
							easing : 'easeIn'
						},
						items: [
							Ext.create( 'Ext.draw.sprite.Image', {
								src : './resources/images/bg-clock.png',
								width : 300,
								height : 300,
								x : 50,
								y : 50
							}
						), 
						{
							type: 'circle',
							radius: 100,
							cx: 200,
							cy: 200,
							fill : 'black'
						},
						{
							type: 'circle',
							radius: 18,
							x: 200,
							y: 200,
							zIndex : 4,
							fillStyle : {
								type : 'radial',
								stops : [
									{
										offset : .25,
										color : 'green'
									}, 
									{
										offset : .60,
										color : 'yellow'
									}, 
									{
										offset : .85,
										color : 'black'
									},
									{
										offset : 1.0,
										color : 'blue'
									}
								]
							}
						}, {
							type: "path",
							path: "M206 206 L290 200 L196 196 Z",  
							fill: 'purple',
							lineJoin : 'round',
							lineCap : 'round',
							miterLimit : 30,
							strokeStyle : 'purple',
							"stroke-width":"4",
							id : 'minutesHand',
							shadowBlur : 0,
							shadowColor : 'yellow',
							shadowOffsetY  : -3,
							shadowOffsetX : 3
						},
						{
							type: "path",
							path: "M200 200 L270 205",  
							fill: "blue",
							lineWidth : 7,
							fillStyle : 'rgba(155, 0, 255, .2)',
							strokeStyle : 'purple',
							id : 'hoursHand',
							rotationRads : 1,
							rotationCenterX : 200,
							rotationCenterY : 200
						},
						{
							type: "ellipse",
							fill: 'yellow',
							rx : 7,
							ry : 4,
							x : 270,
							y : 205,
							id : 'hoursHandTip',
							rotationRads : 1,
							rotationCenterX : 200,
							rotationCenterY : 200
						}
					]
				} ]
			}
        ];		Ext.apply(this, config);
		this.callParent(arguments);
	}
});

Summary

As part of this article, I have explained the basics of draw component in Sencha Touch and I have used the analog clock example to demonstrate the common features. After reading this article you shall be able to make use of the simple / specific sprites like circle, ellipse, text, image and rectangle with ease. Also, I have covered path’s basic and that shall enable you to understand and use path sprite in your touch application.

Reference

Alok is co-founder of Walking Tree, a company which acts as a product engineering team of the customers across the globe and delivers end-to-end products / solutions to ensure "Great Experience". Walking Tree provides Design, Development, QA, Maintenance and Support, Consulting, Training and Skill Augmentation services around Ext JS, Sencha Touch, Angular JS, Xamarin, Native Android, Native iOS, MongoDB, Cassandra, Hadoop, Pentaho, etc. | Twitter

Tagged with: , , , , , ,
Posted in Sencha Touch
4 comments on “Using draw package in Sencha Touch
  1. Ajit Kumar says:

    @Joseph,

    Draw package code is available with the Sencha Touch SDK – free as well as commercial. Only thing is if you are using the open source version of the SDK, you would see “Powered by Sencha Touch GPLv3” marker on the bottom-right corner.

  2. Joseph says:

    Good article about Sencha Touch Draw. I will book mark it.

    I have one Question, shall we use this in free version, i mean the open source version.

  3. Thanks for this article, there is a distinct lack of documentation for the drawing component currently, and this has been most useful in supplementing knowledge.

Leave a comment

We Have Moved Our Blog!

We have moved our blog to our company site. Check out https://walkingtree.tech/index.php/blog for all latest blogs.

Sencha Select Partner Sencha Training Partner
Xamarin Authorized Partner
Do More. With Sencha.

Recent Publication