Well, I’ve managed to keep up with one of my resolutions this year and now I have some JavaScript.
As a first go I’ve written some code to provide a “Teletype” effect, which was inspired by the title graphics on Code Lyoko, and also is a bit similar to the “Ticker” on the front page of news.bbc.co.uk. It is however my own interpretation of this before anyone claims plagarism 🙂
In what is also to be an experiment on how wordpress works, I should have hidden this behind an excerpt, so for people not into code, you’re done…
First up the “legal” bit, I haven’t got round to putting this everywhere on my work yet, but it’s here.
This work is licenced under a Creative Commons Licence.
Now for the more interesting stuff, the code!
/******************************************************************************************
* Author : Francis Cook
* Version : 1.0
* Copyright : http://creativecommons.org/licenses/by-sa/2.0/uk/
******************************************************************************************
* This file contains the Teletype Effect - this effect can be applied to any element
* with an id that can take a text string.
*
******************************************************************************************
* Bugs/Todos:
* - Needs a render function to be called - should not really need that
* - Doesn't check element type, could apply this to a table
* - Doesn't take in a cursor array parameter, so it's fixed throughout.
******************************************************************************************/
// Object to describe a Teletype - a string and the element id - only used by the
// Teletype Effect.
function Teletype( string, elementId ) {
this.string = string;
this.elementId = elementId;
}
// Here is the startup code for the teletype
// This contains the global state. Why not an object ? Small problem of setTime() running
// separate threads that don't have appropriate scope.
var teletypeChars;
var teletypeStringLength = 0;
var teletypeOutput = "";
var teletypeIndex = 0;
// Cursor - Characters and index
var cursorChars = [ '_' ];
// var cursorChars = [ '-','_' ];
// var cursorChars = [ '\','-','|','/','_' ];
var cursorIndex = 0;
// Char timeout - adjust to
var charTimeout = 50;
// Teletype output - hold a reference to the output object.
var ttOutput;
// Lame thing - rather then run on a named element, we have to build a collection and then
// iterate over it. I think I might hate the execution model of JavaScript.
var teletypeElements = new Array();
/*
* attachTeletypeEffect( string, elementId ) - The main user function. Each time this is called,
* it pushes a new Teletype Object onto the global list which is then rendered by a call to
* renderTeletypes(). The arguments are:
*
* string - input string
* elementId - id value of the element that is the destination of this string.
*/
function attachTeletypeEffect( string, elementId ) {
teletypeElements.push( new Teletype( string, elementId ) );
}
/*
* renderTeletypes() - This function must be called at the end to allow the effects to render.
* If the browser cannot find the elements by id, a comment is inserted into the document.
*/
function renderTeletypes() {
if( document.getElementById ) {
nextTeletype();
}
else {
document.writeln( "<!-- Teletype: Cannot find document.getElementById -->" );
}
}
/*
* nextTeletype() - iterator style function - this shifts a Teletype object off the global list in
* teletypeElements. This is then operated by the runTeletype() function.
*/
function nextTeletype() {
var tt = teletypeElements.shift();
if( tt ) {
ttOutput = document.getElementById( tt.elementId );
if( ttOutput ) {
// Reset the environment
teletypeChars = tt.string.split("");
teletypeStringLength = tt.string.length;
teletypeOutput = "";
teletypeIndex = 0;
cursorIndex = 0;
runTeletype(); // new thread - need a "finished" flag.
}
}
}
/*
* runTeletype() - this function is called via a setTime call, which is run in it's own thread.
* This function is responsible for all the rendering logic. In summary it iterates over the cursor
* characters which are printed in the order of the array in which they are in, then after each run
* through the cursor characters, a character from the input string is added. This repeats until all
* the characters of the input string have been printed. The repition rate of runTeletype() is held in
* the variable charTimeout
*
* cursorChars - array holding the set of characters that are printed as the cursor
* cursorIndex - index pointing to the current cursor character
*
* teletypeChars - array of character making up the input string.
* teletypeIndex - index pointing to the current input string character
*
* charTimeout - time in milli-seconds between sucessive runteletype() calls.
*/
function runTeletype() {
// need to print a cursor, so rattle through the cursors and then
// the teletype.
if( cursorIndex < cursorChars.length ) {
ttOutput.textContent = teletypeOutput + cursorChars[cursorIndex];
cursorIndex++;
}
else if( cursorIndex = cursorChars.length ) { // Finished the cursors
// add another character
teletypeOutput += teletypeChars[teletypeIndex];
teletypeIndex++;
cursorIndex = 0;
// Printout a part of the string and then re-run.
ttOutput.textContent = teletypeOutput;
}
// If the string is completed, stop, so keep going until we
// hit the end
if( teletypeIndex < teletypeStringLength ) {
setTimeout( "runTeletype()", charTimeout );
}
else { // Start the next string
nextTeletype();
}
}
So, first attempt at putting code up, and I've learnt that:
- Putting code up via Windows Live Writer is not working
- Windows Live Writer is also not so great at inserting the WordPress codes - well not entirely, but switching entry modes is a bit annoying... 😦
- WordPress's <code> tags aren't like "pre" tags, or even remotely "intelligent" about it 😦 Time to build a perl formatter (or just use <pre>)
Anyway, it's a start, hopefully someone can tell me where I've gone wrong.