AzureFeeds - All your Azure feeds in one place.

Sponsors

Monday, October 31, 2011

Adventures in HTML5: An HTML5 Canvas Ticker

by David Pallmann via Fire & Ice: David Pallmann's Web & Cloud Blog on 10/31/2011 6:30:00 PM

For my third experiment in JavaScript, I created a ticker that you could use to scroll stock information, news, or pretty much any textual content that has a label and a value. It looks like this and animates by scrolling to the left in a loop,. You can see a running version here. All the source is right there in the page, and there's a full listing at the end of this post as well.

I considered using CSS animation for this, but as it is not supported sufficiently in the widestream browsers yet I decided to go with HTML5 canvas and JavaScript.Let's start by looking at the HTML. In the body, we define a canvas named "tape" within a div container named "ticker". The canvas should be set to twice the width it needs to be for the widest size you expect to run it in--that's because we do some repetition of content in order to smoothly scroll it continuously.

<div id="ticker" style="width:1920px">
<canvas id="tape" width="4096" height="40">Your browser doesn't support canvas</canvas>
</div>
 
A small amount of JavaScript in the onload event starts the ticker running with data--an array of objects each with a Symbol and Value property.

<body onload="OnLoad();">

<div id="ticker" style="width:1920px">
<canvas id="tape" width="4096" height="40">Your browser doesn't support canvas</canvas>
</div>

...

<script>
function OnLoad() {
var items = [];
items.push({ Symbol: 'AAA', Value: '1' });
items.push({ Symbol: 'BBB', Value: '22' });
items.push({ Symbol: 'CCC', Value: '3.3' });
items.push({ Symbol: 'DDD', Value: '44 1/4' });
items.push({ Symbol: 'EEE', Value: '5,000' });
items.push({ Symbol: 'FFF', Value: '-66' });
items.push({ Symbol: 'GGG', Value: '700' });
items.push({ Symbol: 'HHH', Value: '88' });
items.push({ Symbol: 'III', Value: '9999' });
items.push({ Symbol: 'JJJ', Value: '10' });
Ticker("ticker", "tape", items);
}
</script>

</body>
 
In the JavaScript, there is a Ticker function that starts off the ticker, a MoveTicker function that continues the animation based on a timer, and a TickerState object that maintains housekeeping information for the animation between calls to MoveTicker.
 
In Ticker, the first order of business is to write out the symbols and values in the data array that was passed in. This is done, as many times as needed, to fill the canvas for the target width. That allows scrolling that looks smooth, even if the data doesn't fully fit the ticker width, and the animation can be reset back to its starting point without any visual roughage. Ticker's final act is to start a timer to call MoveTicker. The interval affects the scolling speed: 10 is fast, 50 is medium, 100 is slow.
 
In MoveTicker, we use CSS to move the ticker left--specifically by decrementing the canvas left margin(which is negative throughout) and counter-adjusting the ticker tape rectangle with CSS clip. This creates the illusion of a ticker rectangle that does not appear to move but has content that does. Once a full set of the data has been slid off the left of the screen, it is reset back to the starting offset. MoveTicker then sets a timer again so it will be called over and over. The result is a gliding ticker tape.

var TickerState = {
canvas: undefined,
ctx: undefined,
tickerX: 0,
dataWidth: 0,
interval: 10 /* Fast: 10 Medium: 50 Slow: 100 */
};


function Ticker(divId, canvasId, items) {

ticker = document.getElementById(divId);
maxWidth = parseInt(ticker.style.width);

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

TickerState.ctx.font = "20px sans-serif";
TickerState.ctx.font = "20px Nova Flat, 20px sans-serif";
TickerState.ctx.textAlign = "left";

var x = 10;
var y = 20;

var firstTime = true;
while (x < maxWidth * 4) {

for (var i = 0; i < items.length; i++) {

TickerState.ctx.fillStyle = "Blue";
TickerState.ctx.fillText(items[i].Symbol, x, y);
x += TickerState.ctx.measureText(items[i].Symbol).width;

TickerState.ctx.fillStyle = "Green";
TickerState.ctx.fillText(items[i].Value, x, y + 10);
x += TickerState.ctx.measureText(items[i].Value).width;
x += 10 + 6;
}

if (firstTime) {
TickerState.dataWidth = x;
firstTime = false;
}

}
setTimeout(MoveTicker, TickerState.interval);
}

function MoveTicker() {

TickerState.tickerX += 1;

if (TickerState.tickerX >= TickerState.dataWidth) {
TickerState.tickerX = 10;
}

TickerState.canvas.style.marginLeft = "-" + TickerState.tickerX.toString() + "px";
TickerState.canvas.style.clip = "rect(0px " + (maxWidth + TickerState.tickerX).toString() + "px 40px -" + TickerState.tickerX.toString() + "px)";

setTimeout(MoveTicker, TickerState.interval);
}
 
Here's the HTML page in its entirety:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Ticker</title>

<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Nova+Flat">


<style>

#ticker {
font-family: 'Nova Flat', cursive;
font-size: 20px;
}

#tape {
font-family: 'Nova Flat', cursive;
font-size: 20px;
position: absolute;
clip: rect(0px 2048px 40px 0px);
vertical-align: top;
margin-left: 0px;
background-color: LightYellow;
}
</style>


<script>

var TickerState = {
canvas: undefined,
ctx: undefined,
tickerX: 0,
dataWidth: 0,
interval: 10 /* Fast: 10 Medium: 50 Slow: 100 */
};


function Ticker(divId, canvasId, items) {

ticker = document.getElementById(divId);
maxWidth = parseInt(ticker.style.width);

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

TickerState.ctx.font = "20px sans-serif";
TickerState.ctx.font = "20px Nova Flat, 20px sans-serif";
TickerState.ctx.textAlign = "left";

var x = 10;
var y = 20;

var firstTime = true;
while (x < maxWidth * 4) {

for (var i = 0; i < items.length; i++) {

TickerState.ctx.fillStyle = "Blue";
TickerState.ctx.fillText(items[i].Symbol, x, y);
x += TickerState.ctx.measureText(items[i].Symbol).width;

TickerState.ctx.fillStyle = "Green";
TickerState.ctx.fillText(items[i].Value, x, y + 10);
x += TickerState.ctx.measureText(items[i].Value).width;
x += 10 + 6;
}

if (firstTime) {
TickerState.dataWidth = x;
firstTime = false;
}

}
setTimeout(MoveTicker, TickerState.interval);
}

function MoveTicker() {

TickerState.tickerX += 1;

if (TickerState.tickerX >= TickerState.dataWidth) {
TickerState.tickerX = 10;
}

TickerState.canvas.style.marginLeft = "-" + TickerState.tickerX.toString() + "px";
TickerState.canvas.style.clip = "rect(0px " + (maxWidth + TickerState.tickerX).toString() + "px 40px -" + TickerState.tickerX.toString() + "px)";

setTimeout(MoveTicker, TickerState.interval);
}
</script>

</head>
<body onload="OnLoad();">

<div id="ticker" style="width:1920px">
<canvas id="tape" width="4096" height="40">Your browser doesn't support canvas</canvas>
</div>

&nbsp;<br />
&nbsp;<br />
&nbsp;<br />
Hello

<script>

var loaded = false;

function OnLoad() {
loaded = true;
var items = [];
items.push({ Symbol: 'AAA', Value: '1' });
items.push({ Symbol: 'BBB', Value: '22' });
items.push({ Symbol: 'CCC', Value: '3.3' });
items.push({ Symbol: 'DDD', Value: '44 1/4' });
items.push({ Symbol: 'EEE', Value: '5,000' });
items.push({ Symbol: 'FFF', Value: '-66' });
items.push({ Symbol: 'GGG', Value: '700' });
items.push({ Symbol: 'HHH', Value: '88' });
items.push({ Symbol: 'III', Value: '9999' });
items.push({ Symbol: 'JJJ', Value: '10' });
Ticker("ticker", "tape", items);
}
</script>

</body>
</html>
 
email it!bookmark it!digg it!

Original Post: Adventures in HTML5: An HTML5 Canvas Ticker

Legal Note

The content of the postings is owned by the respective author. AzureFeeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on AzureFeeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.

Advertise with us