Introduction to the Draw Package
The drawing package enables you to draw general purpose graphics and animations. These creations can be used with the charting classes and other interfaces to create graphics that work on all browsers and mobile devices. This guide show introduce you to the basic principles of the Drawing package.
Draw Container
The Draw Container is a surface to which sprites can be rendered. The Draw Container manages and holds a Surface instance. Depending on the browser, this interface has an SVG or Canvas implementation where Sprites can be appended.
Drawing Surface
You can create a simple drawing surface without loading the Charting package at all. This enables you to create arbitrary graphics that work on all browsers/devices and animate well. For example, you could create an interactive map of the United States where each state is a sprite, or an infographic where each element is also a sprite. Sprites give you an effective manner to create imagery with helpful interactivity. Also, because the images are Canvas and SVG based, they will never lose quality when sized or scaled. This ensures that will always look “right” and wil be printed correctly 100% of the time.
In order to use the Draw package directly, you need to create a Draw Container.
Ext.create('Ext.draw.Container', {
sprites: [{
type: 'circle',
fillStyle: 'red',
r: 100,
cx: 100,
cy: 100
}],
height:205,
width:205,
renderTo:Ext.getBody()
});
In this case, we’ve added a sprite to our Draw container. The type of the sprite is circle so if you run this code you’ll see a red circle appear in your browser.
You can also add sprites by using the surface’s add method:
var main = Ext.create('Ext.draw.Container', {
height:500,
width: 500,
renderTo:Ext.getBody()
});
main.getSurface().add({
type: 'circle',
fillStyle: 'red',
r: 100,
cx: 100,
cy: 100
});
main.renderFrame();
Note: Additions and deletions from a surface are not immediately seen. You must forcibly re-render the surface in order to realize your modifications. This is why we use renderFrame() above.
Sprites
A sprite is an object rendered in a drawing Surface. They are added to a surface in the getItems() collection. Ext.draw.sprite.Sprite is an abstract class and is not meant to be used directly. Instead, use the standard Sprite subclasses listed below:
- Ext.draw.sprite.Path - A sprite that represents a path.
- Ext.draw.sprite.Rect - A sprite that represents a rectangle.
- Ext.draw.sprite.Circle - A sprite that represents a circle.
- Ext.draw.sprite.Sector - A sprite representing a pie slice.
- Ext.draw.sprite.Arc - A sprite that represents a circular arc.
- Ext.draw.sprite.Ellipse - A sprite that represents an ellipse.
- Ext.draw.sprite.EllipticalArc - A sprite that represents an elliptical arc.
- Ext.draw.sprite.Text - A sprite that represents text.
- Ext.draw.sprite.Image - A sprite that represents an image.
- Ext.draw.sprite.Instancing - A sprite that represents multiple instances based on the given template.
- Ext.draw.sprite.Composite - Represents a group of sprites.
The configuration of a Sprite is an object with the following properties:
- type - (String) The type of the sprite. Possible options are ‘circle’, ‘path’, ‘rect’, ‘text’, ‘square’.
- width - (Number) Used in rectangle sprites, the width of the rectangle.
- height - (Number) Used in rectangle sprites, the height of the rectangle.
- size - (Number) Used in square sprites, the dimension of the square.
- radius - (Number) Used in circle sprites, the radius of the circle.
- x - (Number) The position along the x-axis.
- y - (Number) The position along the y-axis.
- path - (Array) Used in path sprites, the path of the sprite written in SVG-like path syntax.
- opacity - (Number) The opacity of the sprite.
- fill - (String) The fill color.
- stroke - (String) The stroke color.
- stroke-width - (Number) The width of the stroke.
- font - (String) Used with text type sprites. The full font description. Uses the same syntax as the CSS font parameter.
- text - (String) Used with text type sprites. The text itself.
Additionally there are three transform objects that can be set with setAttributes. These transform objects are translate, rotate, and scale.
Drawing with SVG Paths
As mentioned above, sprite items accept a path value for creating custom sprites that may exceed the complexity of our pre-defined sprite types. You may use special SVG Path syntax to “describe” the drawing path. Here are the SVG path commands:
- M = moveto
- L = lineto
- H = horizontal lineto
- V = vertical lineto
- C = curveto
- S = smooth curveto
- Q = quadratic Bézier curve
- T = smooth quadratic Bézier curveto
- A = elliptical Arc
- Z = closepath
Note: Capital letters indicate that the item should be absolutely positioned. Use lower case letters for relative positioning.
Ext.create('Ext.draw.Container', {
renderTo: Ext.getBody(),
width: 300,
height:200,
sprites: [{
type: 'path',
path: 'M150 0 L25 100 L300 100 Z',
strokeStyle: '#333',
fill: '#999',
lineWidth: 2
}]
});
You can see that the above path creates a triangle.
M150 0 L25 100 L300 100 Z
This reads as:
- M150 0 - Move 150 pixels from the starting point on the x axis, while staying at 0 on the y axis. This makes our origin (150,0).
- L25 100 - Draw a line from the starting point (150,0) to (25,100)
- L300 100 - Draw a line from the last point (25,100) to (300,100)
- Z - Close the path by drawing a line from the last point (300,100) to the origin (150,0)
Translate
Translate can be used to position your sprite after it’s been rendered. This configuration object contains x and y attributes for the translation. For example:
var main = Ext.create('Ext.draw.Container', {
height:205,
width:205,
sprites: [{
type: 'rect',
fillStyle: 'red',
width: 100,
height:100,
translate: {
x:10,
y:10
}
}],
renderTo:Ext.getBody()
});
Rotate
Rotate can be used to rotate a sprite. The configuration object contains x and y attributes for the center of the rotation (which are optional), and a degrees attribute that specifies the rotation in degrees. For example:
var main = Ext.create('Ext.draw.Container', {
height:205,
width:205,
sprites: [{
type: 'rect',
fillStyle: 'red',
width: 100,
height:100,
rotate: {
degrees: 45
}
}],
renderTo:Ext.getBody()
});
Scale
Scale can be used to dynamically resize your sprite. For scale, the configuration object contains x and y attributes for the x-axis and y-axis scaling. For example:
var main = Ext.create('Ext.draw.Container', {
height:305,
width:305,
sprites: [{
type: 'rect',
fillStyle: 'red',
width: 100,
height:100,
scale: {
x: 3,
y: 3
}
}],
renderTo:Ext.getBody()
});
Interacting with a Sprite
Now that we’ve created a draw surface with a sprite in it, let’s dive into sprite interactivity. We can get a reference to the sprite after adding that sprite to the surface:
var main = Ext.create('Ext.draw.Container', {
sprites: [{
type: 'rect',
width: 100,
height: 100,
fillStyle: 'red'
}],
height:205,
width:205,
renderTo:Ext.getBody(),
listeners: {
afterrender: function(me){
var surface = me.getSurface(),
sprite = surface.getItems()[0];
sprite.setAttributes({
fillStyle:'black'
});
Ext.create('Ext.fx.Anim', {
target: surface,
duration: 8000,
to: {
opacity: .5
}
});
}
}
});
In the above example, you can see how to set sprite attributes and animate these attributes using the draw package.
As you can see, this package provides a versatile abstraction over the graphics we can create. What’s most interesting about this class is that we aren’t tied to a specific shape or structure. Also, all elements support setting attributes and creating animations. Most important, all of this is compatible in all browsers and devices.