Tutorial: Using HTML5 to produce the HTML5 logo



Tutorial: Using HTML5 to produce the HTML5 logo

This is a tutorial describing how to use features of HTML5 and JavaScript to produce the W3C HTML5 logo (). Here is a screen shot of the HTML document displayed by the Chrome browser:

[pic]

Note the slider that can be used to reduce the size of the logo. The document also makes use of the new semantic elements formatted using CSS to put an orange line as part of the footer.

You have alternatives to reading the whole tutorial: you can use the view source feature of your browser to look at the coding in my example: . You also may look ahead in this document to where I provide an outline of the coding and then give a table with a comment for each line. However, if you have some time, start here for a fuller description of the canvas element, drawing paths, transformations, input elements of type range, drawing text on/in a canvas element, font specification, and use of semantic elements.

Examples, tutorials and notes on HTML5 can be found in many places, including (this is a plug) my book: The Essential Guide to HTML5: Using Games to learn HTML5 and JavaScript. . I built this example based on one done by Daniel Davis, who works for Opera.

Warning: the HTML5 specification by W3C is not official and all browsers do not recognize all features. This example has been tested in Chrome and Safari. I am told it works in Opera. See below concerning the fallback for the slider input element in Firefox.

Features

Drawing on canvas

HTML5 provides a new element type called canvas. You/your code can draw rectangles, paths (consisting of lines and arcs) filled in or as outlines (stroke), images, text and even video. You can produce animations by clearing and then re-drawing at intervals of time. You can set up event handling for mouse events such as clicks on the canvas. The logo example uses filled in paths and text.

To draw on a canvas element, you include a canvas element in the body of the html document and give it an id. A recommended way to do this is:

Your browser does not support the canvas element .

If the browser does not support (recognize) the canvas element, its contents, namely, the words in-between the and tag will appear on-screen.

The JavaScript coding uses the id to identify the element and to access what is termed the 2D context of the element that is used for all drawing. (I view this as a teaser for a possible future 3D context. So far, there is only the 2D context.) In this example, the body tag sets up a call to a function, init.

What happens in this function and what is done in the two other functions (dologo and changescale) will be explained later. The first critical step is the setting of a global variable, which I and others call ctx

ctx = document.getElementById('canvas').getContext('2d');

Methods of ctx are used for all the drawing. Here I will explain text and then what will turn out to be the different colored polygons that make up the shield part of the logo.

For text, I first set the font. I accomplish this using a variable I name fontfamily, but I could do it without the variable.

var fontfamily = "65px 'Gill Sans Ultra Bold', sans-serif";

...

ctx.font = fontfamily;

When specifying fonts, it is important to accept that not all fonts are available on all computers. My coding specifies the 'Gill Sans Ultra Bold' be used if it is available, otherwise, use the standard sans-serif font. The quotation marks are necessary because the name of the font includes blanks. I could have made this list longer. Alternatively, you can acquire a font and place it on your server and refer to it by name.

The next step is to draw the font on the canvas. This is done using the fillText method with arguments: text string, horizontal position and vertical position. In this situation, the color of the text is the default, black.

ctx.fillText("HTML", 31, 60);

Note: you can draw text in outline form using ctx.strokeText. For drawing on canvas, like many other computer applications, the origin of the coordinate system is the upper left corner of the canvas. Horizontal (x) values increase going from the left to the right; vertical values (y) increase going down from the top.

The shield is drawn in steps, with successive actions drawing on top of previous sections as follows:

1. the darker orange, 5-sided background

2. the lighter orange, 4-sided inner part on the right

3. the light gray, two parts of the 5 on the left

4. the white, two parts of the 5 on the right

HTML5 provides the path construct for specifying a shape and then either filling it in or drawing it in outline. For the logo, we use just fill. The W3C site indicates the hexadecimal pattern for the colors of the logo. [See my book or other places for ways to specify colors such as a certain set of named colors ("blue", "red", "maroon", etc.) or a string such as "rgb(200,100,0)".] Note: in the RGB scheme, white is #FFFFFF and black is #000000.

A path is started using ctx.beginPath() and ended with ctx.closePath() and then ctx.fill() or ctx.stroke(), the commands that actually perform the drawing. A path is constructed using ctx.moveTo, ctx.lineTo and ctx.arc commands. Look elsewhere for explanations on drawing arcs, for example, or the dice game or hangman game chapters in my book.

The path construct has the notion of a current position. Think of moveTo as picking up your pencil and moving to a spot on the canvas with that being the new current position. Think of lineTo as keeping the pencil down on the canvas AND moving to a new position. Nothing is drawn until the fill or stroke command, but lineTo indicates where a line is to be drawn. The closePath closes up the path by going to the first position. Here is the code for the 5-sided, dark orange background of the shield shown below, with the arrow indicating where the drawing starts.

[pic]

ctx.fillStyle = "#E34C26";

ctx.beginPath();

ctx.moveTo(39, 250);

ctx.lineTo(17, 0);

ctx.lineTo(262, 0);

ctx.lineTo(239, 250);

ctx.lineTo(139, 278);

ctx.closePath();

ctx.fill();

The teacher in me suggests that you examine each path in the code to see if you can determine how the shape is produced!

Now I get to explain how I added the HTML text above the shield while still using Daniel Davis's coordinates and how I implemented the scaling of the logo. The input value for how much to scale the logo will be discussed in the next section.

HTML5 and JavaScript provide a way to change (transform) the coordinate system for the canvas. That is, our code can translate, scale, or rotate the axes. Moreover, HTML5 provides a way to save the current state of the coordinate system, make changes and then restore the saved system. Adding the HTML text at the top of the canvas provides a good example of the use of translate. I wanted to add HTML at the top, but I didn't want to change all the numbers in the path code. So, I drew the text and then used

var offsety = 80;

ctx.translate(0, offsety);

Then the rest of the code worked as before using a coordinate system that was down the screen 80 pixels. Note: this is another case of using a variable when it wasn't strictly necessary. I could have written:

ctx.translate(0, 80);

The scaling works the same way. I set up a variable I named factorvalue. It is initializes to be 1. Use of the slider could change this, say to .50. The statement:

ctx.scale(factorvalue,factorvalue);

transforms the coordinate system horizontally and vertically by whatever the value is in factorvalue. If the scaling was ctx.scale(.50, .50), then a line that was specified as being from 100 to 200 would actually be from 50 to 100.

The commands ctx.save() and ctx.restore() do what the names indicate: save the current coordinate system and restore the last saved coordinate system. This is necessary in the logo example because we don't want the modifications to be cumulative. My code executes a save early on and then executes it again after the restore.

Whenever my code draws the logo, it erases the canvas using

ctx.clearRect(0,0,600,400);

Implementation of slider

HTML5 provides a new input type called range. This produces a slider on some browsers. The code is

This code sets up the slider, defines the minimum and maximum values along with the initial value, defines what the quantum changes can be by setting the step value, and sets up the event handling for changes. When the user changes the value, the function changescale is invoked with parameter the current value. The changescale function something I wrote, that is, it is defined in the script element of the document. For this application, changescale sets the variable factorvalue to the parameter, the current value, divided by 100 and draws (re-draws) the logo.

The last time I checked, Firefox on a PC substitutes an ordinary text field for the slider. This is better than nothing! It makes you appreciate what the type="range" and the associated other attributes all do. A user can put in a value over 100 and since my code does not do any checking, there is an attempt to produce a bigger picture. Values given for drawing on canvas do not produce errors, but they will produce something like this:

Semantic elements

HTML5 provides new element types to represent specific, common parts of documents. These include header, footer, section, and article. These elements do not come with any formatting. That must be done using Cascading Style Sheets in the style section. You can say that these new elements provide no new functionality and that is partially correct. What they do provide is a way to describe pieces of documents independent of formatting and this can be useful for groups of people or organizations or products working together.

In the logo example, motivated to make use of at least some of the new elements, I decided to put the text before the slider with the slider in one article element and comments on the work in another. I put the citation to W3C in a footer element and used CSS to put a line (border-top) over the text. The styles are

footer {display:block; border-top: 1px solid orange; margin: 10px; font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; font-weight: bold;}

article {display:block; font-family: Georgia, "Times New Roman", Times, serif; margin: 5px;}

The display:block for both element types means that they are proceeded and followed by line breaks. The margin specifications puts extra spacing around each element. In both cases, I used font-family to specify a set of fonts. I used two standard groupings. I made the footer text bold using the font-weight attribute. Lastly, I decided I wanted a line above the footer text. I accomplished this by specifying border-top to be a 1 pixel, solid orange line. Colors can be specified using hexadecimal or any of a set of named colors. See . (The html4 in this link does NOT refer to HTML4!).

Implementation

The html5logoscale document consists of

styling, for article and footer elements

variables

function definition: init (calls dologo)

function definition: dologo

function definition: changescale (calls dologo)

canvas element

article with input of type range (slider)

article with comments the work

footer with link to W3C

The code is

| |required by some browsers |

| |start tag for html |

| |start tag for head |

|HTML5 Logo |complete title |

| |may be required in the future |

| |start of style |

|footer {display:block; border-top: 1px solid orange; margin: 10px; font-family: "Trebuchet |sets line break before and after |

|MS", Arial, Helvetica, sans-serif; font-weight: bold;} |footer. Does NOT move any footer |

| |elements to end of document. Puts |

| |orange line before text. Sets font, |

| |bold, margin. |

|article {display:block; font-family: Georgia, "Times New Roman", Times, serif; margin: 5px;}|sets line break before and after |

| |article. Sets font, margin. |

| |end style |

| |start script element |

|var ctx; |variable holding context, used in all |

| |drawing |

|var factorvalue = 1; |variable used for scaling, initialized|

| |to 1 |

|var fontfamily = "65px 'Gill Sans Ultra Bold', sans-serif"; |to be used for setting fonts, fallback|

| |to sans-serif |

|function init() { |init function header |

| ctx = document.getElementById('canvas').getContext('2d'); |sets ctx |

| ctx.font = fontfamily; |sets font |

| ctx.save(); |saves initial coordinate system |

| dologo(); |invoke function to draw logo |

|} |ends init function |

|function dologo() { |dologo function header |

| var offsety = 80 ; |set offsety to 80 |

| ctx.restore(); |restore the saved coordinate system |

| ctx.save(); |saves coordinate system |

| ctx.clearRect(0,0,600,400); |clear the canvas |

| ctx.scale(factorvalue,factorvalue); |apply scaling to x and y |

| ctx.fillText("HTML", 31,60); |write out HTML |

| ctx.translate(0,offsety); |adjust coordinate system |

| | |

|// 5 sided orange background | |

|ctx.fillStyle = "#E34C26"; |set color to orange |

|ctx.beginPath(); |start path |

|ctx.moveTo(39, 250); |move to lower left |

|ctx.lineTo(17, 0); |make line up to upper left corner of |

| |shield |

|ctx.lineTo(262, 0); |make line over to right |

|ctx.lineTo(239, 250); |make line down |

|ctx.lineTo(139, 278); |make line to the point in the middle |

| |at bottom |

|ctx.closePath(); |close path (will draw line to starting|

| |point) |

|ctx.fill(); |fill in the shape outlined |

| | |

|// right hand, lighter orange part of the background |4-sided light orange over the 5-sided |

| |darker orange |

|ctx.fillStyle = "#F06529"; |set color to lighter orange |

|ctx.beginPath(); |start path |

|ctx.moveTo(139, 257); |move to position above middle, lower |

| |point |

|ctx.lineTo(220, 234); |line to the right and up |

|ctx.lineTo(239, 20); |line slightly to the right and further|

| |up |

|ctx.lineTo(139, 20); |line over to the left |

|ctx.closePath(); |close path (will draw line to starting|

| |point) |

|ctx.fill(); |fill in the shape outlined |

| | |

|// light gray, left hand side part of the five |drawn in two parts, first is 8 sided, |

| |next is |

|ctx.fillStyle = "#EBEBEB"; |set color to light gray |

|ctx.beginPath(); |start path |

|ctx.moveTo(139, 113); |move to middle |

|ctx.lineTo(98, 113); |draw line to the left |

|ctx.lineTo(96, 82); |draw line very slight to the left and |

| |up |

|ctx.lineTo(139, 82); |draw line over to right |

|ctx.lineTo(139, 51); |draw line straight up |

|ctx.lineTo(62, 51); |draw line over to left |

|ctx.lineTo(70, 144); |draw line down and slightly right |

|ctx.lineTo(139, 144); |draw line over to right |

|ctx.closePath(); |close path (will draw line to starting|

| |point) |

|ctx.fill(); |fill in the shape outlined |

| | |

|ctx.beginPath(); |start (new) path |

|ctx.moveTo(139, 193); |move to middle (below previous |

| |midpoint) |

|ctx.lineTo(105, 184); |draw slanted line, left and up |

|ctx.lineTo(103, 159); |draw slightly left and up |

|ctx.lineTo(72, 159); |draw straight left |

|ctx.lineTo(76, 207); |draw slightly right and down |

|ctx.lineTo(139, 225); |draw slanted left and down |

|ctx.closePath(); |close path (will draw line to starting|

| |point) |

|ctx.fill(); |fill in the shape outlined |

| | |

|// white, right hand side of the 5 | |

|ctx.fillStyle = "#FFFFFF"; |set color to white |

|ctx.beginPath(); |start path |

|ctx.moveTo(139, 113); |move to middle point |

|ctx.lineTo(139, 144); |draw line straight down |

|ctx.lineTo(177, 144); |draw line over to right |

|ctx.lineTo(173, 184); |draw line down and slightly left |

|ctx.lineTo(139, 193); |draw slant to left and down |

|ctx.lineTo(139, 225); |draw line straight down |

|ctx.lineTo(202, 207); |draw slant up and to right |

|ctx.lineTo(210, 113); |draw slight slant right and up |

|ctx.closePath(); |close path (will draw line to starting|

| |point) |

|ctx.fill(); |fill in the shape outlined |

| | |

|ctx.beginPath(); |begin new path |

|ctx.moveTo(139, 51); |move to middle point |

|ctx.lineTo(139, 82); |draw line down |

|ctx.lineTo(213, 82); |draw line straight right |

|ctx.lineTo(216, 51); |draw line slightly right and up |

|ctx.closePath(); |close path (will draw line to starting|

| |point) |

|ctx.fill(); |fill in the shape outlined |

| | |

| | |

|} | |

| | |

|function changescale(val) { |header for changescale function, |

| |invoked when input range changed with |

| |current value |

| factorvalue = val / 100; |set factorvalue to be the parameter |

| |divided by 100 |

| dologo(); |invoke dologo to (re)draw logo |

|} |end changescale function |

| |end script element |

| |end head element |

| |start body, set up call to init when |

| |body is loaded |

| |canvas start element. sets width and |

| |height |

|Your browser does not support the canvas element . |message if browser not html5 compliant|

| |ends canvas element |

| |start article |

|Scale percentage: |input element of type range, min, max,|

|Note: slider treated as text field in some browsers. |value, step each set. onchange sets up|

| |handling for changes. Explanatory |

| |note. |

| |close article |

|Built on work by Daniel |complete article element with |

|Davis, et al, but don't blame them for the fonts. Check out the use of |information on this application |

|font-family in the style element and the fontfamily variable in the script| |

|element for safe ways to do fonts. I did the scaling. Note also use of semantic | |

|elements. | |

|HTML5 Logo by W3C. |reference to W3C |

| |close body |

| |close html |

| | |

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download