Dojo, Now with Drawing Tools!
The gfx API exposes a number of intuitive functions for common operations, such as creating rectangles, circles, lines, polylines and paths that are loosely based on the SVG standard as well as a set of custom attributes, such as stroke, fill color, rounded corners and more. Most of the methods support “chaining syntax”, which allows you to operate on the results of the previous operation repeatedly, leading to crisp code and clean syntax, so long as you do not abuse the device (Listing 2).
Listing 2. An Assortment of Shapes
dojo.addOnLoad(function() {
var node = dojo.byId("surface");
var surface = dojox.gfx.createSurface(node, 600, 600);
surface.createEllipse({
cx : 300,
cy : 300,
rx : 50,
ry : 100
})
.setFill("yellow")
;
surface.createRect({
x : 90,
y : 90,
width : 50,
height : 170
})
.setFill([255,0,0,0.5])
;
surface.createCircle({
cx : 400,
cy : 200,
r : 50
})
.setFill([255,0,0,0.5]);
surface.createCircle({
cx : 425,
cy : 225,
r : 50
})
.setFill([0,255,0,0.5])
;
surface.createCircle({
cx : 425,
cy : 175,
r : 50
})
.setFill([0,0,255,0.5])
;
surface.createPolyline([
100,400,
200,300,
350,350,
500,350
])
.setStroke({
width : 10,
join : "round",
cap : "round"
})
;
surface.createCircle({
r : 50,
cx : 200,
cy: 200
})
.setFill({
type: "radial",
cx : 200,
cy: 200,
r:50,
colors: [
{color:"white",offset:0},
{color:"red",offset:1}]
})
;
});

Figure 5. Dojo's fairly intuitive gfx API makes drawing a variety of customized elements easy and fun.
Hopefully, the code mostly speaks for itself. The various types of objects that you can create are usually framed in the same way that they are presented in grade school. For example, a circle has a center point and a radius defined by cx, cy and r. Given a circle, you could set a fill color in a number of different ways: a string value, an rgb(a) tuple or even something more complex like a radial gradient with custom parameters of its own.
Using a well-designed API with nice mnemonic devices is useful for much of the routine drawing you'll be doing, but what about when you need to do something a lot more in depth? Although this is where a lot of JavaScript graphics libraries fall short, gfx absolutely shines here by equipping you with the ability to perform arbitrary 3x3 matrix transformations.
Just in case you don't have a background with graphics, it may not be immediately apparent how 3x3 matrices and “all of that math” is useful. Basically, 3x3 matrices provide a compact way to express the three common operations that you do with objects all at the same time:
Translation: adjusting the position of an object in the x and y directions.
Rotation: adjusting the position of an object in the clockwise or counterclockwise directions usually (but not necessarily) around its center point.
Scaling: adjusting the size of an object by a scalar multiplier.
Don't freak out quite yet if you're not a math buff and don't want to sink time into re-learning linear algebra just to get started with that great idea you had for a game or drawing application. Many of the common operations for manipulating shapes come with intuitive wrappers. To illustrate a trivial example, let's assume that you want to draw a square but then rotate it around its center point so that it looks like a diamond:
dojo.addOnLoad(function() {
var node = dojo.byId("surface");
var surface = dojox.gfx.createSurface(node, 600, 600);
rect1 = surface.createRect({
x: 200,
y: 200,
width : 200,
height:200
})
.setFill("red")
.setTransform([dojox.gfx.matrix.rotategAt(45,300,300)])
;
});
With an upper-left corner at point (200,200) and a width and height of 200 pixels, the square originally was centered on the surface. Then, applying a 45-degree rotation around the square's center point of (300,300) rotated it in place.
To illustrate the effect of successively applying transformation matrices, let's draw the very same diamond but rely on explicit translation to position it in the center of the surface before rotating it versus positioning it via the createRect function:
dojo.addOnLoad(function() {
var node = dojo.byId("surface");
var surface = dojox.gfx.createSurface(node, 600, 600);
rect1 = surface.createRect({
/* x and y default to (0,0) */
width : 200,
height:200
})
.setFill("red")
.setTransform([
dojox.gfx.matrix.translate(200,200),
dojox.gfx.matrix.rotategAt(45,100,100)
])
;
});
In general, it is immensely more convenient to draw most shapes initially in a coordinate system with perpendicular x and y axes and then apply final positioning via translation and rotation. An important technicality to be aware of with successive transformations, however, is that the order in which the transforms are applied does matter, and the original position of the object is normally the point of reference. For instance, in the previous example, the shape explicitly was translated as 200 pixels in the x and y directions, but its original center point from before the translation is applied serves as the basis of rotation.
If you're unconvinced that a shape as simple as a diamond would benefit much from the convenience of matrix transforms, just consider the extra work involved in calculating the exact coordinates for its corners, and you'll quickly see that it's easier to reason about “rotated squares” than it is about “native diamonds”.
Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
Web Development News
Developer Poll
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
| Trying to Tame the Tablet | May 08, 2013 |
| Dart: a New Web Programming Experience | May 07, 2013 |
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- A Topic for Discussion - Open Source Feature-Richness?
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Home, My Backup Data Center
- What's the tweeting protocol?
- Readers' Choice Awards
- New Products
- RSS Feeds
- Dart: a New Web Programming Experience
- Reply to comment | Linux Journal
8 hours 46 min ago - Reply to comment | Linux Journal
11 hours 19 min ago - Reply to comment | Linux Journal
12 hours 36 min ago - great post
13 hours 11 min ago - Google Docs
13 hours 34 min ago - Reply to comment | Linux Journal
18 hours 22 min ago - Reply to comment | Linux Journal
19 hours 9 min ago - Web Hosting IQ
20 hours 43 min ago - Thanks for taking the time to
22 hours 19 min ago - Linux is good
1 day 17 min ago









Comments
Please post missing file 10308.tgz
When I try this link in the resources:
ftp://ftp.linuxjournal.com/pub/lj/issue178/10308.tgz
It's a bad link. I found this
ftp://ftp.linuxjournal.com/pub/lj/listings/issue178/README178
10042.tgz -- Web 2.0 Development with the Google Web Toolkit
Federico Kereki
10308.tgz -- Dojo, Now with Drawing Tools!
Matthew Russell
but this file is missing: 10308.tgz
very interesting, good for
very interesting, good for gfx beginner just like me. thanks!
where is the download for listing 4
Trying to download the code from listing 4 from the ftp link in Resources. I get a "550 Failed to change directory" error.
Tried browsing the ftp site, but there seems to be nothing there for this issue (178).