Introduction to Drawing

OpenLaszlo provides capability to do two-dimensional graphics. You use procedural code in a drawview element to draw lines and fill in shapes. In this tip, we'll look at some of the key parts of the API and show some interesting effects that you can get with a few lines of code.

Background of the programming model
----------------

The Web Hypertext Application Technology Working Group ("whatwg") is "a loose unofficial collaboration of Web browser manufacturers and interested parties who wish to develop new technologies designed to allow authors to write and deploy Applications over the World Wide Web." This group recently published a
specification for drawing
.

OpenLaszlo implements a subset of the whatwg drawing APIs. For a discussion of where OpenLaszlo differs from the full whatwg specification, please see the LZX Reference Manual.

The drawview
-----------------
The drawview class extends the view class. Thus, it inherits all the view properties; a drawview tag creates a rectangular view. At first glance a drawview seems like just another view:
________________
[code lang="xml"]





[/code]
____________

data="/files/draw_example0.lzx.swf" width="500" height="100">

There are no additional tag attributes in the drawview class beyond those of view. However, drawview has four attributes in addition to those it inherits:

  • fillStyle
  • globalAlpha
  • lineWidth
  • strokeStyle

These attributes can be accessed and manipulated by procedural (script) code inside method tags inside a drawview element. The drawview class has ten methods associated with it. We'll take a look at them below, after explaining some more concepts.

Lines, shapes, fills
----------------------

To draw a line shape (or "path"), you position a logical pen at a starting point and then move it sequentially to x and y coordinates connecting points either by
straight or quadratic lines. This line remains invisible until you "stroke" it. When you stroke a path you apply to it the defined line width and style, thereby
making it visible.

For example, this code produces nothing visible:
_____________________
[code lang="xml"]



this.moveTo(100,100)
this.lineTo(200,100)
this.quadraticCurveTo(120, 200, 300, 100)
//this.stroke()



[/code]
_____________________
But by uncommenting the line this.stroke() we produce the following:

data="/files/draw_example1.lzx.swf" width="500" height="160">

The closePath() method draws a line back to the beginning of the current path:

_____________________
[code lang="xml"]



this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.closePath()
this.stroke()



[/code]
_____________________

data="/files/draw_example2.lzx.swf" width="500" height="160">

Now that we have a closed shape, we can fill it. First we define a fillStyle, and then we fill the shape.

_____________________
[code lang="xml"]



this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.stroke()
//fillSytles are hex numbers representing color.
this.fillStyle = 0xff00ff
this.fill()



[/code]
_____________________

data="/files/draw_example3.lzx.swf" width="500" height="160">

Note that if you don't close a path but call the fill() method, the path will be closed implicitly. Please consult the reference page for particulars.

Opacity and Gradients
------------------------------

The globalAlpha attribute is used to set the opacity of lines and fills. It takes a value between zero (transparent) and one (opaque).

_____________________
[code lang="xml"]



this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.stroke()
this.fillStyle = 0xff00ff
this.globalAlpha= .3
this.fill()



[/code]
_____________________

data="/files/draw_example4.lzx.swf" width="500" height="160">

Remember that the code here is procedural, so alpha values apply to fillStyles and lineStyles that are in effect at the time that a stroke() or fill() method is called. In the above example, the globalAlpha value is 1 (the default) when the line is stroked and .3 when the color is filled in.

A fillStyle can be a color gradient, that is, a pattern that blends colors over its area. To use a gradient, first create it using the appropriate (linear or radial) constructor function, then set the fillStyle to be the gradient. A gradient is an object of the type LzCanvasGradient; you define the parameters of the gradient by using methods such as addColorStop() on it. addColorStop() takes two arguments: the number of the stop, and the color.

_____________________
[code lang="xml"]



this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.stroke()
//the gradient starts at the x and y where the curve begins
var g = this.createLinearGradient(200,100, 150, 300)
//opacity is 0 -- the fill is invisible
this.globalAlpha = 0;
//starting color is black
g.addColorStop(0, 0x000000);
//now the opacity is set to opaque
this.globalAlpha = 1;
//the gradient goes from black to purple
g.addColorStop(1, 0xff00ff);
this.fillStyle = g;
this.fill();



[/code]
_____________________

data="/files/draw_example5.lzx.swf" width="500" height="160">

To get a sense of what gradients look like, try varying the parameters of the ending x and y.

Also, remember that drawviews have background colors. You can use them in conjunction with gradients and alpha values:

_____________________

[code lang="xml"]



this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.stroke()
var g = this.createLinearGradient(200,100, 150, 300)
this.globalAlpha = 0;
g.addColorStop(0, 0xffffff);
this.globalAlpha = 1;
g.addColorStop(.3, 0xff00ff);
this.fillStyle = g;
this.fill();



[/code]
_____________________

data="/files/draw_example6.lzx.swf" width="500" height="160">

The gradient can be linear or radial (for details, see the Reference).

Starting Over
---------------------
We've said that drawing a line is like moving a pen. So, how do you pick up the pen in order to move it to another spot on the canvas? Use the beginPath()
method.

_____________________
[code lang="xml"]



this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.closePath()
this.stroke()
this.beginPath()
this.moveTo(200,000);
this.lineTo(100,200);
this.quadraticCurveTo(120, 200, 300, 100)
this.closePath()
this.stroke()



[/code]
_____________________

data="/files/draw_example7.lzx.swf" width="500" height="200">

The clear() method wipes the slate clean, so to speak.

_____________________
[code lang="xml"]



this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.closePath()
this.stroke()
this.beginPath()
this.moveTo(200,000);
this.lineTo(100,200);
this.quadraticCurveTo(120, 200, 300, 100)
this.closePath()
this.stroke()

Comments are closed.