1 2 3 4 | < div id = "ticker" style = "width:1920px" > < canvas id = "tape" width = "4096" height = "40" >Your browser doesn't support canvas</ canvas > </ div > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | < 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 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 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); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < head > < title >Ticker</ title > < 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 > 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 > |
11 comments:
Seems great, though, you may update your live demo link: I doubt I can reach your localhost:50005 from my home ;)
David,
Your link to the running version points to your localhost so it won't load on the web :(
Looks good though once you download it.
Whoops, sorry about the bad link to the onlinet icker demo (now fixed).
It Flickers, any way to make it sliding smoother ??
Thanks
Tomahawk1955, leveraging CSS transitions and animation would likely be the way to make this really smooth. Perhaps I'll do an update using that method down the road once I'm a little more savvy in that area.
Thanks Sir :)
Any possibility of eliminating the horizontal scroll bar it enables at the bottom of the screen?
Anonymous, I'm looking to eliminate that horizontal scroll bar haven't hit upon the answer yet.
Hello,
thank you for this code, really saves me lot of time.
But it is possible to display the ticker only in an area of the screen (the area defined by the div ticker)?
Lets say in the upper right quarter (top:45% left:50%).
The canvas will move straight through the div 'ticker' and the text is shown on the left side.
Yes, I don't like the horizontal scroll bar either. I think I've learned enough over the last few months to re-do this ticker letting CSS do a lot more of the work. When I have an updated version, I'll be sure to post it.
excellent. thank you.
Post a Comment