Import
287
nixie.html
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<!-- SOURCE: http://cestmir.freeside.sk/projects/dhtml-nixie-display/ -->
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<title>Virtual nixie tube display</title>
|
||||||
|
<script type="text/javascript" src="nixie.js?1"></script>
|
||||||
|
<style type="text/css">
|
||||||
|
html, body, td, th {
|
||||||
|
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
color: black;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 30px;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: top;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
border-bottom: 1px solid #DFDFDF;
|
||||||
|
color: #660000;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
h5 {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.note {
|
||||||
|
font-size: 9px;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
margin: 0.2em;
|
||||||
|
}
|
||||||
|
table.references td {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
.skin-switch {
|
||||||
|
display: none;
|
||||||
|
font-size: 9px;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div style="text-align: center; display: none">
|
||||||
|
<div style="position: absolute; right: 3em;"><a href="#" id="ndDate1SkinSwitch" class="skin-switch">skin...</a></div>
|
||||||
|
<table style="margin: 0 auto;"><tr><td>
|
||||||
|
<div style="background: black; padding: 5px 20px; ">
|
||||||
|
<div id="ndDate1" style="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td></tr></table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="text-align: center; margin-top: 4em;">
|
||||||
|
<div style="position: absolute; right: 3em;"><a href="#" id="ndTime1SkinSwitch" class="skin-switch">skin...</a></div>
|
||||||
|
<table style="margin: 0 auto;"><tr><td>
|
||||||
|
<div style="background: white; padding: 5px 20px; border: none;">
|
||||||
|
<div id="ndTime1" style="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td></tr></table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="text-align: center; display:none;">
|
||||||
|
<div style="position: absolute; right: 3em;"><a href="#" id="ndCalc1SkinSwitch" class="skin-switch">skin...</a></div>
|
||||||
|
<table style="margin: 0 auto;"><tr><td>
|
||||||
|
<div style="background: black; padding: 5px 20px; ">
|
||||||
|
<div id="ndCalc1" style="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 80%; line-height: 150%;">
|
||||||
|
(just type expressions on keyboard as on any basic electronic calculator)<br />
|
||||||
|
[q] sqrt [Q] sqr [^] pow [m] +/- [p] PI [Enter] = [Esc] clear
|
||||||
|
</div>
|
||||||
|
</td></tr></table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
// *** Simple display ***
|
||||||
|
|
||||||
|
nixieDate1 = new NixieDisplay();
|
||||||
|
nixieDate1.id = 'ndDate1';
|
||||||
|
nixieDate1.charCount = 8;
|
||||||
|
nixieDate1.extraGapsWidths[3] = 20;
|
||||||
|
nixieDate1.extraGapsWidths[5] = 20;
|
||||||
|
nixieDate1.init();
|
||||||
|
var d = new Date();
|
||||||
|
nixieDate1.setText(d.getFullYear().toString() + (d.getMonth() + 1).toString().replace(/^(\d)$/, '0$1') + d.getDate().toString().replace(/^(\d)$/, '0$1'));
|
||||||
|
|
||||||
|
// setup skin switching
|
||||||
|
nixieDate1.__skinId = 0 - 1;
|
||||||
|
nixieDate1.__skinCount = 3;
|
||||||
|
nixieDate1.__skinSwitch = function() {
|
||||||
|
var nd = nixieDate1;
|
||||||
|
nd.__skinId = (nd.__skinId + 1) % nd.__skinCount;
|
||||||
|
switch (nd.__skinId) {
|
||||||
|
case 0:
|
||||||
|
nd.urlCharsetImage = 'zm1082_l1_09bdm_62x150_8b.png';
|
||||||
|
nd.charWidth = 62;
|
||||||
|
nd.charHeight = 150;
|
||||||
|
nixieDate1.extraGapsWidths[3] = 20;
|
||||||
|
nixieDate1.extraGapsWidths[5] = 20;
|
||||||
|
nd.charGapWidth = 0;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "white";
|
||||||
|
document.getElementById(nd.id).parentNode.style.border = "none";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
nd.urlCharsetImage = 'zm1080_l1_09bdm_62x150_8b.png';
|
||||||
|
nd.charWidth = 62;
|
||||||
|
nd.charHeight = 150;
|
||||||
|
nixieDate1.extraGapsWidths[3] = 20;
|
||||||
|
nixieDate1.extraGapsWidths[5] = 20;
|
||||||
|
nd.charGapWidth = 0;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "white";
|
||||||
|
document.getElementById(nd.id).parentNode.style.border = "none";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
nd.urlCharsetImage = 'zm1080_l2_09bdm_45x75_8b.png';
|
||||||
|
nd.charWidth = 45;
|
||||||
|
nd.charHeight = 75;
|
||||||
|
nixieDate1.extraGapsWidths[3] = 20;
|
||||||
|
nixieDate1.extraGapsWidths[5] = 20;
|
||||||
|
nd.charGapWidth = 10;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "black";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nd.init();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
document.getElementById('ndDate1SkinSwitch').onclick = nixieDate1.__skinSwitch; // attach skinswitch event handler
|
||||||
|
nixieDate1.__skinSwitch(); // assign primary skin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// *** Clock ***
|
||||||
|
|
||||||
|
nixieTime1 = new NixieClock(); // create component instance
|
||||||
|
nixieTime1.id = 'ndTime1'; // assign instance id
|
||||||
|
nixieTime1.init(); // initialize component (after assigning params)
|
||||||
|
nixieTime1.run(); // run clock
|
||||||
|
|
||||||
|
// setup skin switching
|
||||||
|
nixieTime1.__skinId = 3 - 1;
|
||||||
|
nixieTime1.__skinCount = 4;
|
||||||
|
nixieTime1.__skinSwitch = function() {
|
||||||
|
var nd = nixieTime1;
|
||||||
|
nd.__skinId = (nd.__skinId + 1) % nd.__skinCount;
|
||||||
|
switch (nd.__skinId) {
|
||||||
|
case 0:
|
||||||
|
nd.urlCharsetImage = 'zm1082_l1_09bdm_62x150_8b.png';
|
||||||
|
nd.charWidth = 62;
|
||||||
|
nd.charHeight = 150;
|
||||||
|
nd.extraGapsWidths[1] = 15;
|
||||||
|
nd.extraGapsWidths[3] = 15;
|
||||||
|
nd.charGapWidth = 0;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "white";
|
||||||
|
document.getElementById(nd.id).parentNode.style.border = "none";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
nd.urlCharsetImage = 'zm1080_l1_09bdm_62x150_8b.png';
|
||||||
|
nd.charWidth = 62;
|
||||||
|
nd.charHeight = 150;
|
||||||
|
nd.extraGapsWidths[1] = 15;
|
||||||
|
nd.extraGapsWidths[3] = 15;
|
||||||
|
nd.charGapWidth = 0;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "white";
|
||||||
|
document.getElementById(nd.id).parentNode.style.border = "none";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
nd.urlCharsetImage = 'zm1080_l2_09bdm_45x75_8b.png';
|
||||||
|
nd.charWidth = 45;
|
||||||
|
nd.charHeight = 75;
|
||||||
|
nd.extraGapsWidths[1] = 12;
|
||||||
|
nd.extraGapsWidths[3] = 12;
|
||||||
|
nd.charGapWidth = 10;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "black";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
nd.urlCharsetImage = 'zm1080_d1_09bdm_62x100_8b.png';
|
||||||
|
nd.charWidth = 62;
|
||||||
|
nd.charHeight = 100;
|
||||||
|
nd.extraGapsWidths[1] = 20;
|
||||||
|
nd.extraGapsWidths[3] = 20;
|
||||||
|
nd.charGapWidth = 10;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "black";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nd.init();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
document.getElementById('ndTime1SkinSwitch').onclick = nixieTime1.__skinSwitch; // attach skinswitch event handler
|
||||||
|
nixieTime1.__skinSwitch(); // assign primary skin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// *** Calculaor ***
|
||||||
|
|
||||||
|
nixieCalc1 = new NixieCalculator(); // create component instance
|
||||||
|
nixieCalc1.id = 'ndCalc1'; // assign instance id
|
||||||
|
|
||||||
|
// assign keyboard event handlers
|
||||||
|
document.onkeydown = function(e0) { return nixieCalc1.keyDown(e0); };
|
||||||
|
document.onkeypress = function(e0) { return nixieCalc1.keyPress(e0); };
|
||||||
|
|
||||||
|
nixieCalc1.init(); // initialize component (after assigning params)
|
||||||
|
|
||||||
|
// setup skin switching
|
||||||
|
nixieCalc1.display.__skinId = 2 - 1;
|
||||||
|
nixieCalc1.display.__skinCount = 4;
|
||||||
|
nixieCalc1.__skinSwitch = function() {
|
||||||
|
var nd = nixieCalc1.display;
|
||||||
|
nd.__skinId = (nd.__skinId + 1) % nd.__skinCount;
|
||||||
|
switch (nd.__skinId) {
|
||||||
|
case 0:
|
||||||
|
nd.urlCharsetImage = 'zm1082_l1_09bdm_62x150_8b.png';
|
||||||
|
nd.charWidth = 62;
|
||||||
|
nd.charHeight = 150;
|
||||||
|
nd.charGapWidth = 0;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "white";
|
||||||
|
document.getElementById(nd.id).parentNode.style.border = "none";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
nd.urlCharsetImage = 'zm1080_l1_09bdm_62x150_8b.png';
|
||||||
|
nd.charWidth = 62;
|
||||||
|
nd.charHeight = 150;
|
||||||
|
nd.charGapWidth = 0;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "white";
|
||||||
|
document.getElementById(nd.id).parentNode.style.border = "none";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
nd.urlCharsetImage = 'zm1080_l2_09bdm_45x75_8b.png';
|
||||||
|
nd.charWidth = 45;
|
||||||
|
nd.charHeight = 75;
|
||||||
|
nd.charGapWidth = 10;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "black";
|
||||||
|
document.getElementById(nd.id).parentNode.style.border = "2px solid #AAAAAA";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
nd.urlCharsetImage = 'zm1080_d1_09bdm_46x75_8b.png';
|
||||||
|
nd.charWidth = 46;
|
||||||
|
nd.charHeight = 75;
|
||||||
|
nd.charGapWidth = 10;
|
||||||
|
document.getElementById(nd.id).parentNode.style.background = "black";
|
||||||
|
document.getElementById(nd.id).parentNode.style.border = "2px solid #AAAAAA";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nd.init();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
document.getElementById('ndCalc1SkinSwitch').onclick = nixieCalc1.__skinSwitch; // attach skinswitch event handler
|
||||||
|
nixieCalc1.__skinSwitch(); // assign primary skin
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
545
nixie.js
Normal file
@ -0,0 +1,545 @@
|
|||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
Virtual nixie tube display, clock & calculator DHTML components
|
||||||
|
|
||||||
|
v 1.05, 20080214a
|
||||||
|
|
||||||
|
(c) 2007-08 Cestmir Hybl, cestmir.hybl@nustep.net
|
||||||
|
http://cestmir.freeside.sk/projects/dhtml-nixie-display
|
||||||
|
|
||||||
|
license: free for non-commercial use, copyright must be preserved
|
||||||
|
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* NixieDisplay */
|
||||||
|
|
||||||
|
// public class NixieDisplay
|
||||||
|
function NixieDisplay()
|
||||||
|
{
|
||||||
|
// public
|
||||||
|
this.id = 'nixie';
|
||||||
|
this.elContainer = null;
|
||||||
|
this.charCount = 10;
|
||||||
|
this.autoDecimalPoint = true; // automatically extracts decimal point index in setText() call
|
||||||
|
this.align = 'left'; // alignment of text via setText() call
|
||||||
|
this.afterUpdate = null; // after display update callback
|
||||||
|
|
||||||
|
this.charWidth = 62;
|
||||||
|
this.charHeight = 150;
|
||||||
|
this.charGapWidth = 0;
|
||||||
|
this.extraGapsWidths = [];
|
||||||
|
this.createCharElements = true;
|
||||||
|
|
||||||
|
this.text = '';
|
||||||
|
this.decimalPoint = -1;
|
||||||
|
|
||||||
|
this.urlCharsetImage = 'nixie/zm1082_l1_09bdm_62x150_8b.png';
|
||||||
|
this.charMap = {
|
||||||
|
0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9,
|
||||||
|
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, ' ': 10, '-': 11,
|
||||||
|
'default': 10
|
||||||
|
};
|
||||||
|
// maps displayable chars onto glyph matrix indexes
|
||||||
|
|
||||||
|
// protected
|
||||||
|
function _drawChar(index)
|
||||||
|
{
|
||||||
|
var el = document.getElementById(this.id + '_d' + index);
|
||||||
|
var charIndex = this.charMap[this.text.charAt(index)];
|
||||||
|
if (!charIndex && charIndex !== 0)
|
||||||
|
charIndex = this.charMap['default'];
|
||||||
|
var x = - (charIndex * this.charWidth);
|
||||||
|
var y = (index === this.decimalPoint ? - this.charHeight : 0);
|
||||||
|
el.style.backgroundPosition = x + 'px ' + y + 'px';
|
||||||
|
}
|
||||||
|
this._drawChar = _drawChar;
|
||||||
|
|
||||||
|
// Shows given string on display
|
||||||
|
// public
|
||||||
|
function setText(text, updateDecimalPoint)
|
||||||
|
{
|
||||||
|
// force string type
|
||||||
|
this.text = text + '';
|
||||||
|
|
||||||
|
// extract decimal point
|
||||||
|
updateDecimalPoint = (typeof(updateDecimalPoint) != 'undefined' ? updateDecimalPoint : this.autoDecimalPoint);
|
||||||
|
if (updateDecimalPoint) {
|
||||||
|
var i = this.text.indexOf('.');
|
||||||
|
if (i >= 0) {
|
||||||
|
this.decimalPoint = i - 1;
|
||||||
|
// alert(this.decimalPoint);
|
||||||
|
this.text = this.text.substr(0, i) + this.text.substr(i + 1);
|
||||||
|
} else
|
||||||
|
this.decimalPoint = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pad up to display width (from left/right acording to this.align)
|
||||||
|
if (this.text.length < this.charCount) {
|
||||||
|
var pad = '';
|
||||||
|
var padWidth = this.charCount - this.text.length;
|
||||||
|
for (var i = 0; i < padWidth; i++)
|
||||||
|
pad += ' ';
|
||||||
|
if (this.align == 'left')
|
||||||
|
this.text = this.text + pad;
|
||||||
|
else {
|
||||||
|
if (this.decimalPoint >= 0)
|
||||||
|
this.decimalPoint += padWidth;
|
||||||
|
this.text = pad + this.text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.text.length > this.charCount)
|
||||||
|
this.text = this.text.substr(0, this.charCount);
|
||||||
|
|
||||||
|
// draw chars
|
||||||
|
for (var i = 0; i < this.text.length; i++) {
|
||||||
|
this._drawChar(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.afterUpdate)
|
||||||
|
this.afterUpdate(this);
|
||||||
|
}
|
||||||
|
this.setText = setText;
|
||||||
|
|
||||||
|
// Sets char at given display position
|
||||||
|
// public
|
||||||
|
function setChar(index, chr)
|
||||||
|
{
|
||||||
|
// alert(chr);
|
||||||
|
this.text = this.text.substring(0, index) + chr + this.text.substring(index + 1);
|
||||||
|
this.setText(this.text, false);
|
||||||
|
}
|
||||||
|
this.setChar = setChar;
|
||||||
|
|
||||||
|
function setDecimalPoint(index)
|
||||||
|
{
|
||||||
|
var oldDecimalPoint = this.decimalPoint;
|
||||||
|
this.decimalPoint = ((!index && index !== 0) ? -1 : index);
|
||||||
|
if (oldDecimalPoint != this.decimalPoint) {
|
||||||
|
if (oldDecimalPoint >= 0)
|
||||||
|
this._drawChar(oldDecimalPoint);
|
||||||
|
if (this.decimalPoint >= 0)
|
||||||
|
this._drawChar(this.decimalPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.setDecimalPoint = setDecimalPoint;
|
||||||
|
|
||||||
|
// Clears display - fills all positions with given char (space by default).
|
||||||
|
// public
|
||||||
|
function clear(chr)
|
||||||
|
{
|
||||||
|
chr = (typeof(chr) == 'undefined' ? ' ' : chr);
|
||||||
|
this.text = '';
|
||||||
|
for (var i = 0; i < this.charCount; i++)
|
||||||
|
this.text += chr;
|
||||||
|
this.decimalPoint = -1;
|
||||||
|
this.setText(this.text);
|
||||||
|
}
|
||||||
|
this.clear = clear;
|
||||||
|
|
||||||
|
// Shifts display contents left or right
|
||||||
|
// public
|
||||||
|
function shift(direction, step)
|
||||||
|
{
|
||||||
|
step = (!step && step !== 0 ? 1 : step);
|
||||||
|
direction = (!direction ? 'left' : direction);
|
||||||
|
|
||||||
|
if (this.decimalPoint >= 0) {
|
||||||
|
this.decimalPoint += (direction == 'left' ? - step : + step);
|
||||||
|
if (this.decimalPoint >= this.charCount)
|
||||||
|
this.decimalPoint = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == 'left')
|
||||||
|
this.text = this.text.substr(step) + ' '; // @todo padding for step != +/-1
|
||||||
|
else if (direction == 'right')
|
||||||
|
this.text = ' ' + this.text.substr(0, this.text.length - 1); // @todo padding for step != +/-1
|
||||||
|
this.setText(this.text, false);
|
||||||
|
}
|
||||||
|
this.shift = shift;
|
||||||
|
|
||||||
|
// public
|
||||||
|
function init()
|
||||||
|
{
|
||||||
|
if (!this.elContainer) {
|
||||||
|
this.elContainer = document.getElementById(this.id);
|
||||||
|
if (!this.elContainer)
|
||||||
|
throw "Container element '" + this.id + "' not found";
|
||||||
|
}
|
||||||
|
this.elContainer.style.position = 'relative';
|
||||||
|
|
||||||
|
if (this.createCharElements) {
|
||||||
|
var totalWidth = 0;
|
||||||
|
for (var i = 0; i < this.charCount; i++) {
|
||||||
|
var charWidthIncludingGap = (this.charWidth + this.charGapWidth);
|
||||||
|
|
||||||
|
var elId = this.id + '_d' + i;
|
||||||
|
var el0 = document.getElementById(elId);
|
||||||
|
var el = (el0 ? el0 : document.createElement('div'));
|
||||||
|
el.id = this.id + '_d' + i;
|
||||||
|
el.className = 'digit d' + i;
|
||||||
|
el.style.position = 'absolute';
|
||||||
|
el.style.left = totalWidth + 'px';
|
||||||
|
el.style.width = this.charWidth + 'px';
|
||||||
|
el.style.height = this.charHeight + 'px';
|
||||||
|
el.style.background = 'url(' + this.urlCharsetImage + ')';
|
||||||
|
if (!el.parentNode)
|
||||||
|
this.elContainer.appendChild(el);
|
||||||
|
|
||||||
|
totalWidth += charWidthIncludingGap + (this.extraGapsWidths[i] ? this.extraGapsWidths[i] : 0);
|
||||||
|
}
|
||||||
|
this.elContainer.style.width = totalWidth + 'px';
|
||||||
|
this.elContainer.style.height = this.charHeight + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.text)
|
||||||
|
this.setText(this.text)
|
||||||
|
else
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
this.init = init;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* NixieClock */
|
||||||
|
|
||||||
|
// public class NixieClock : NixieDisplay
|
||||||
|
function NixieClock()
|
||||||
|
{
|
||||||
|
// public
|
||||||
|
|
||||||
|
// private
|
||||||
|
this.lastSeconds = -1;
|
||||||
|
|
||||||
|
// Show current time on "display"
|
||||||
|
// public
|
||||||
|
function showCurrentTime(refreshAfterChangeOnly)
|
||||||
|
{
|
||||||
|
var d = new Date();
|
||||||
|
|
||||||
|
var s = d.getSeconds();
|
||||||
|
|
||||||
|
if (refreshAfterChangeOnly && s == this.lastSeconds)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
this.lastSeconds = s;
|
||||||
|
|
||||||
|
var h = d.getHours();
|
||||||
|
var m = d.getMinutes();
|
||||||
|
|
||||||
|
var digits = '';
|
||||||
|
|
||||||
|
digits += (h / 10) | 0;
|
||||||
|
digits += h % 10;
|
||||||
|
digits += (m / 10) | 0;
|
||||||
|
digits += m % 10;
|
||||||
|
digits += (s / 10) | 0;
|
||||||
|
digits += s % 10;
|
||||||
|
|
||||||
|
this.setText(digits);
|
||||||
|
}
|
||||||
|
this.showCurrentTime = showCurrentTime;
|
||||||
|
|
||||||
|
// Run clock (via scheduling a periodic callback to showCurrentTime())
|
||||||
|
// public
|
||||||
|
function run()
|
||||||
|
{
|
||||||
|
if (!this.elContainer)
|
||||||
|
this.init();
|
||||||
|
var __nixieClock = this;
|
||||||
|
window.setInterval(function() { __nixieClock.showCurrentTime(true); }, 100);
|
||||||
|
}
|
||||||
|
this.run = run;
|
||||||
|
|
||||||
|
this.ancestor = NixieDisplay;
|
||||||
|
this.ancestor();
|
||||||
|
|
||||||
|
this.charCount = 6;
|
||||||
|
this.extraGapsWidths[1] = 20;
|
||||||
|
this.extraGapsWidths[3] = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* NixieCalculator */
|
||||||
|
|
||||||
|
// @todo rounding of rightmost digit
|
||||||
|
|
||||||
|
// public class NixieCalculator : NixieDisplay
|
||||||
|
function NixieCalculator()
|
||||||
|
{
|
||||||
|
// public
|
||||||
|
this.id = 'nixieCalc';
|
||||||
|
this.digitCount = 13;
|
||||||
|
this.display = new NixieDisplay();
|
||||||
|
|
||||||
|
// private
|
||||||
|
this.operandStack = [];
|
||||||
|
this.newValueAtNextChar = false;
|
||||||
|
this.fullPrecisionValue = 0;
|
||||||
|
|
||||||
|
// private
|
||||||
|
function push(value)
|
||||||
|
{
|
||||||
|
this.operandStack[this.operandStack.length] = value; // JS50 compatible .push()
|
||||||
|
}
|
||||||
|
this.push = push;
|
||||||
|
|
||||||
|
// private
|
||||||
|
function pop()
|
||||||
|
{
|
||||||
|
if (!this.operandStack.length)
|
||||||
|
return null;
|
||||||
|
var v = this.operandStack[this.operandStack.length - 1];
|
||||||
|
this.operandStack = this.operandStack.slice(0, this.operandStack.length - 1); // JS50 compatible .pop()
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
this.pop = pop;
|
||||||
|
|
||||||
|
// public
|
||||||
|
function getValue()
|
||||||
|
{
|
||||||
|
if (this.fullPrecisionValue !== null)
|
||||||
|
return this.fullPrecisionValue;
|
||||||
|
|
||||||
|
var v = this.display.text;
|
||||||
|
|
||||||
|
// insert decimal point
|
||||||
|
if (this.display.decimalPoint >= 0 && this.display.decimalPoint < this.digitCount - 1)
|
||||||
|
v = v.substr(0, this.display.decimalPoint + 1) + '.' + v.substr(this.display.decimalPoint + 1);
|
||||||
|
|
||||||
|
// remove padding spaces
|
||||||
|
var i = 0;
|
||||||
|
while (i < v.length && v.charAt(i) == ' ')
|
||||||
|
i++;
|
||||||
|
v = v.substr(i);
|
||||||
|
|
||||||
|
// convert to number
|
||||||
|
v = parseFloat(v);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
this.getValue = getValue;
|
||||||
|
|
||||||
|
// public
|
||||||
|
function setValue(v)
|
||||||
|
{
|
||||||
|
if (typeof(v) != 'number')
|
||||||
|
v = parseFloat(v);
|
||||||
|
if (isNaN(v) || v > this.maxNumber || v < -this.maxNumber)
|
||||||
|
this.error();
|
||||||
|
else {
|
||||||
|
this.fullPrecisionValue = v;
|
||||||
|
if (v.toFixed) {
|
||||||
|
// force fixed-point notation (JS5.5+)
|
||||||
|
var s = (v >= 0 ? ' ' : '') + v.toFixed(1);
|
||||||
|
s = s.substring(0, s.length - 2);
|
||||||
|
// (s now contains string with integer part of value, prefixed by either ' ' or '-')
|
||||||
|
v = v.toFixed(this.digitCount - s.length); // to fixed point + round rightmost digit
|
||||||
|
} else {
|
||||||
|
v = v.toString();
|
||||||
|
if (v.toLowerCase().indexOf('e') >= 0) {
|
||||||
|
// we won't handle exp notation in JS<5.5
|
||||||
|
this.error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (v !== '0') {
|
||||||
|
if (v.charAt(0) != '-')
|
||||||
|
v = ' ' + v;
|
||||||
|
var c = this.digitCount + (v.indexOf('.') >= 0 ? 1 : 0);
|
||||||
|
if (v.length > c)
|
||||||
|
v = v.substr(0, c);
|
||||||
|
v = v.replace(/^(.{1,}?)\.?0+$/g, '$1'); // strip zero's from right
|
||||||
|
}
|
||||||
|
this.display.setText(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.setValue = setValue;
|
||||||
|
|
||||||
|
// private
|
||||||
|
function eval(v1, o, v2)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
switch (o) {
|
||||||
|
case '+':
|
||||||
|
return v1 + v2;
|
||||||
|
case '-':
|
||||||
|
return v1 - v2;
|
||||||
|
case '*':
|
||||||
|
return v1 * v2;
|
||||||
|
case '/':
|
||||||
|
return v1 / v2;
|
||||||
|
case '^':
|
||||||
|
return Math.pow(v1, v2);
|
||||||
|
case 'sqrt':
|
||||||
|
return Math.sqrt(v1);
|
||||||
|
case 'sqr':
|
||||||
|
return v1 * v1;
|
||||||
|
default:
|
||||||
|
throw "Unsupported operand: '" + o + "'";
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
this.error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.eval = eval;
|
||||||
|
|
||||||
|
// public
|
||||||
|
function error()
|
||||||
|
{
|
||||||
|
var s= '';
|
||||||
|
for (var i = 0; i < this.digitCount; i++)
|
||||||
|
s += '-';
|
||||||
|
this.operandStack = [];
|
||||||
|
this.newValueAtNextChar = true;
|
||||||
|
this.fullPrecisionValue = null;
|
||||||
|
this.display.setText(s);
|
||||||
|
}
|
||||||
|
this.error = error;
|
||||||
|
|
||||||
|
// public
|
||||||
|
function clear()
|
||||||
|
{
|
||||||
|
this.display.clear();
|
||||||
|
this.setValue(0);
|
||||||
|
this.operandStack = [];
|
||||||
|
this.fullPrecisionValue = null;
|
||||||
|
}
|
||||||
|
this.clear = clear;
|
||||||
|
|
||||||
|
// public
|
||||||
|
function keyDown(event0)
|
||||||
|
{
|
||||||
|
var e = (event0 ? event0 : event);
|
||||||
|
var k = e.keyCode;
|
||||||
|
|
||||||
|
var cancelEvent = true;
|
||||||
|
|
||||||
|
if (k == 8) {
|
||||||
|
// backspace
|
||||||
|
if (this.display.text.charAt(this.digitCount - 2) == ' ')
|
||||||
|
this.display.setChar(this.digitCount - 1, '0');
|
||||||
|
else
|
||||||
|
this.display.shift('right');
|
||||||
|
this.fullPrecisionValue = null;
|
||||||
|
} else if (k == 27) {
|
||||||
|
// escape
|
||||||
|
this.clear();
|
||||||
|
} else
|
||||||
|
cancelEvent = false;
|
||||||
|
|
||||||
|
return !cancelEvent;
|
||||||
|
}
|
||||||
|
this.keyDown = keyDown;
|
||||||
|
|
||||||
|
// public
|
||||||
|
function keyPress(event0)
|
||||||
|
{
|
||||||
|
var e = (event0 ? event0 : event);
|
||||||
|
var k = (e.keyCode ? e.keyCode : e.which); // IE: .keyCode, FF: .which
|
||||||
|
var chr = String.fromCharCode(k);
|
||||||
|
|
||||||
|
var cancelEvent = true;
|
||||||
|
|
||||||
|
var newValueAtThisChar = this.newValueAtNextChar;
|
||||||
|
this.newValueAtNextChar = true;
|
||||||
|
|
||||||
|
if (chr >= '0' && chr <= '9') {
|
||||||
|
this.fullPrecisionValue = null;
|
||||||
|
if (newValueAtThisChar) {
|
||||||
|
this.display.clear();
|
||||||
|
}
|
||||||
|
if (this.display.text.charAt(1) == ' ' || this.display.text.charAt(1) == '-') {
|
||||||
|
if (this.display.text.charAt(this.digitCount - 1) == '0' && this.display.text.charAt(this.digitCount - 2) == ' ' && this.display.decimalPoint < 0)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
this.display.shift('left');
|
||||||
|
this.display.setChar(this.digitCount - 1, chr);
|
||||||
|
}
|
||||||
|
this.newValueAtNextChar = false;
|
||||||
|
}
|
||||||
|
else if (chr == '.' || chr == ',') {
|
||||||
|
this.fullPrecisionValue = null;
|
||||||
|
if (newValueAtThisChar)
|
||||||
|
this.display.setText(0);
|
||||||
|
if (this.display.decimalPoint < 0)
|
||||||
|
this.display.setDecimalPoint(this.digitCount - 1);
|
||||||
|
this.newValueAtNextChar = false;
|
||||||
|
}
|
||||||
|
else if (chr == '+' || chr == '-' || chr == '*' || chr == '/' || chr == '^') {
|
||||||
|
if (this.operandStack.length > 2)
|
||||||
|
// cancel repeated evaluation
|
||||||
|
this.operandStack = [];
|
||||||
|
if (this.operandStack.length == 2) {
|
||||||
|
// previous expression without explicit '=', evaluate it
|
||||||
|
this.setValue(this.eval(this.operandStack[this.operandStack.length - 2], this.operandStack[this.operandStack.length - 1], this.getValue()));
|
||||||
|
this.operandStack = [];
|
||||||
|
}
|
||||||
|
// push left operand
|
||||||
|
this.push(this.getValue());
|
||||||
|
// push operator
|
||||||
|
this.push(chr);
|
||||||
|
}
|
||||||
|
else if (chr == 'm' || chr == 'M') {
|
||||||
|
this.setValue(- this.getValue());
|
||||||
|
this.newValueAtNextChar = false;
|
||||||
|
}
|
||||||
|
else if (chr == 'p' || chr == 'P') {
|
||||||
|
this.setValue(Math.PI);
|
||||||
|
}
|
||||||
|
else if (chr == 'q') {
|
||||||
|
this.setValue(this.eval(this.getValue(), 'sqrt', null));
|
||||||
|
}
|
||||||
|
else if (chr == 'Q') {
|
||||||
|
this.setValue(this.eval(this.getValue(), 'sqr', null));
|
||||||
|
}
|
||||||
|
else if (k == 13 || chr == '=') {
|
||||||
|
if (this.operandStack.length >= 2) {
|
||||||
|
if (this.operandStack.length <= 2)
|
||||||
|
// push right operand
|
||||||
|
this.push(this.getValue())
|
||||||
|
else
|
||||||
|
// repeated evaluation (e.g. [1] [+] [1] [=] [=] ...), replace left operand with current display value
|
||||||
|
this.operandStack[this.operandStack.length - 3] = this.getValue();
|
||||||
|
// alert(this.operandStack);
|
||||||
|
var result = this.eval(this.operandStack[this.operandStack.length - 3], this.operandStack[this.operandStack.length - 2], this.operandStack[this.operandStack.length - 1]);
|
||||||
|
this.setValue(result);
|
||||||
|
// this.operandStack = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else if (k == 27) { // Fix: chromium: Esc not handled in keyPress(), http://code.google.com/p/chromium/issues/detail?id=12744
|
||||||
|
// // escape
|
||||||
|
// this.clear();
|
||||||
|
// }
|
||||||
|
else {
|
||||||
|
cancelEvent = false;
|
||||||
|
this.newValueAtNextChar = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !cancelEvent;
|
||||||
|
}
|
||||||
|
this.keyPress = keyPress;
|
||||||
|
|
||||||
|
// public
|
||||||
|
function init()
|
||||||
|
{
|
||||||
|
this.display.id = this.id;
|
||||||
|
this.display.charCount = this.digitCount;
|
||||||
|
this.display.align = 'right';
|
||||||
|
this.display.init();
|
||||||
|
this.display.setText('0');
|
||||||
|
this.maxNumber = Math.pow(10, this.digitCount - 1) - 1;
|
||||||
|
}
|
||||||
|
this.init = init;
|
||||||
|
|
||||||
|
// assign default glyph matrix
|
||||||
|
this.display.urlCharsetImage = 'nixie/zm1080_l2_09bdm_45x75_8b.png';
|
||||||
|
this.display.charWidth = 45;
|
||||||
|
this.display.charHeight = 75;
|
||||||
|
this.display.charGapWidth = 5;
|
||||||
|
}
|
BIN
zm1080_d1_09bdm_30x50_8b.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
zm1080_d1_09bdm_46x75_8b.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
zm1080_d1_09bdm_62x100_8b.png
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
zm1080_l1_09bdm_42x100_8b.png
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
zm1080_l1_09bdm_62x150_8b.png
Normal file
After Width: | Height: | Size: 152 KiB |
BIN
zm1080_l2_09bdm_30x50_8b.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
zm1080_l2_09bdm_45x75_8b.png
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
zm1080_l2_09bdm_90x150_8b.png
Normal file
After Width: | Height: | Size: 198 KiB |
BIN
zm1080_r_anim_86x150_100ms_5s.gif
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
zm1082_l1_09bdm_42x100_8b.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
zm1082_l1_09bdm_62x150_8b.png
Normal file
After Width: | Height: | Size: 152 KiB |