<!DOCTYPE html>
<!--
Author: Twily 2025
Website: twily.info
-->
<html>
<head>
<style type="text/css">
html,body { width: 100%; height: 100%; margin: 0; padding: 0; background-color: transparent; overflow: hidden; }
*:focus { outline: none; }
</style>
<script type="text/javascript">
var $=function(id) { return document.getElementById(id); };
var isOdd=function(number) { return Math.abs(number % 2) === 1; };
var letterC=[ // 65 - 90
[ // A
0b01110,
0b10001,
0b11111,
0b10001,
0b10001
],
[ // B
0b11110,
0b10001,
0b11111,
0b10001,
0b11110
],
[ // C
0b01110,
0b10001,
0b10000,
0b10001,
0b01110
],
[ // D
0b11110,
0b10001,
0b10001,
0b10001,
0b11110
],
[ // E
0b11111,
0b10000,
0b11100,
0b10000,
0b11111
],
[ // F
0b11111,
0b10000,
0b11100,
0b10000,
0b10000
],
[ // G
0b01110,
0b10000,
0b10111,
0b10001,
0b01110
],
[ // H
0b10001,
0b10001,
0b11111,
0b10001,
0b10001
],
[ // I
0b01110,
0b00100,
0b00100,
0b00100,
0b01110
],
[ // J
0b00001,
0b00001,
0b00001,
0b10001,
0b01110
],
[ // K
0b10001,
0b10010,
0b11100,
0b10010,
0b10001
],
[ // L
0b10000,
0b10000,
0b10000,
0b10000,
0b11111
],
[ // M
0b01010,
0b10101,
0b10101,
0b10101,
0b10101
],
[ // N
0b10001,
0b11001,
0b10101,
0b10011,
0b10001
],
[ // O
0b01110,
0b10001,
0b10001,
0b10001,
0b01110
],
[ // P
0b11110,
0b10001,
0b11110,
0b10000,
0b10000
],
[ // Q
0b01110,
0b10001,
0b10001,
0b10011,
0b01101
],
[ // R
0b11110,
0b10001,
0b11110,
0b10001,
0b10001
],
[ // S
0b01111,
0b10000,
0b01110,
0b00001,
0b11110
],
[ // T
0b11111,
0b00100,
0b00100,
0b00100,
0b00100
],
[ // U
0b10001,
0b10001,
0b10001,
0b10001,
0b01110
],
[ // V
0b10001, //17
0b10001, //17
0b10001, //17
0b01010, //10
0b00100 //5
],
[ // W
0b10101, //21
0b10101, //21
0b10101, //21
0b10101, //21
0b01010 //10
],
[ // X
0b10001, //17
0b01010, //10
0b00100, //5
0b01010, //10
0b10001 //17
],
[ // Y
0b10001, //17
0b01010, //10
0b00100, //5
0b00100, //5
0b00100 //5
],
[ // Z
0b11111, //31
0b00010, //2
0b00100, //5
0b01000, //8
0b11111 //31
],
];
var letterL=[ // 97 - 122
[ // a
0b00110,
0b00001,
0b00111,
0b01001,
0b00111
],
[ // b
0b01000,
0b01110,
0b01001,
0b01001,
0b01110
],
[ // c
0b00000,
0b00111,
0b01000,
0b01000,
0b00111
],
[ // d
0b00001,
0b00111,
0b01001,
0b01001,
0b00111
],
[ // e
0b00110,
0b01001,
0b01111,
0b01000,
0b00110
],
[ // f
0b00011,
0b00100,
0b01111,
0b00100,
0b00100
],
[ // g
0b00111,
0b01001,
0b00111,
0b00001,
0b00110
],
[ // h
0b01000,
0b01110,
0b01001,
0b01001,
0b01001
],
[ // i
0b00100,
0b00000,
0b00100,
0b00100,
0b00100
],
[ // j
0b00010,
0b00000,
0b00010,
0b10010,
0b01100
],
[ // k
0b01000,
0b01000,
0b01010,
0b01100,
0b01010
],
[ // l
0b00100,
0b00100,
0b00100,
0b00100,
0b00100
],
[ // m
0b00000,
0b11010,
0b10101,
0b10101,
0b10101
],
[ // n
0b00000,
0b01110,
0b01001,
0b01001,
0b01001
],
[ // o
0b00000,
0b00110,
0b01001,
0b01001,
0b00110
],
[ // p
0b00000,
0b01110,
0b01001,
0b01110,
0b01000
],
[ // q
0b00000,
0b00111,
0b01001,
0b00111,
0b00001
],
[ // r
0b00000,
0b01011,
0b01100,
0b01000,
0b01000
],
[ // s
0b01111,
0b10000,
0b01110,
0b00001,
0b11110
],
[ // t
0b00100,
0b01110,
0b00100,
0b00100,
0b00010
],
[ // u
0b00000,
0b01001,
0b01001,
0b01001,
0b00111
],
[ // v
0b00000,
0b10001,
0b10001,
0b01010,
0b00100
],
[ // w
0b00000,
0b10101,
0b10101,
0b10101,
0b01010
],
[ // x
0b00000,
0b10001,
0b01110,
0b01110,
0b10001
],
[ // y
0b00000,
0b10001,
0b01010,
0b00100,
0b01000
],
[ // z
0b00000,
0b11111,
0b00100,
0b01000,
0b11111
],
];
var numbin=[ // 48 - 57
[ // 0
0b01110,
0b10001,
0b10101,
0b10001,
0b01110
],
[ // 1
0b00100,
0b01100,
0b00100,
0b00100,
0b01110
],
[ // 2
0b11110,
0b00001,
0b01110,
0b10000,
0b11111
],
[ // 3
0b01111,
0b00001,
0b01110,
0b00001,
0b01110
],
[ // 4
0b10010,
0b10010,
0b11111,
0b00010,
0b00010
],
[ // 5
0b11111,
0b10000,
0b11110,
0b00001,
0b11110
],
[ // 6
0b01110,
0b10000,
0b11110,
0b10001,
0b01110
],
[ // 7
0b11111,
0b00010,
0b00100,
0b01000,
0b10000
],
[ // 8
0b01110,
0b10001,
0b01110,
0b10001,
0b01110
],
[ // 9
0b01110,
0b10001,
0b01111,
0b00001,
0b01110
],
];
var symbol0=[ // 32 - 47
[ // blank(space) -- tab = 4 spaces
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
],
[ // !
0b00100,
0b00100,
0b00100,
0b00000,
0b00100
],
[ // "
0b01010,
0b01010,
0b00000,
0b00000,
0b00000
],
[ // # (hashtag)
0b01010,
0b11111,
0b01010,
0b11111,
0b01010
],
[ // $
0b01111,
0b10100,
0b01110,
0b00101,
0b11110
],
[ // %
0b11001,
0b11010,
0b00100,
0b01011,
0b10011
],
[ // &
0b00110,
0b01010,
0b01100,
0b10010,
0b01101
],
[ // '
0b00100,
0b00100,
0b00000,
0b00000,
0b00000
],
[ // (
0b00010,
0b00100,
0b00100,
0b00100,
0b00010
],
[ // )
0b01000,
0b00100,
0b00100,
0b00100,
0b01000
],
[ // *
0b10101,
0b01110,
0b11111,
0b01110,
0b10101
],
[ // +
0b00100,
0b00100,
0b11111,
0b00100,
0b00100
],
[ // , (comma)
0b00000,
0b00000,
0b00000,
0b00100,
0b01000
],
[ // - (dash)
0b00000,
0b00000,
0b01111,
0b00000,
0b00000
],
[ // . (dot)
0b00000,
0b00000,
0b00000,
0b00000,
0b01000
],
[ // /
0b00001,
0b00010,
0b00100,
0b01000,
0b10000
],
// --extras index 16 and 17?
[ // full block
0b11111,
0b11111,
0b11111,
0b11111,
0b11111
],
[ // square block
0b00000,
0b01110,
0b01010,
0b01110,
0b00000
],
];
var symbol1=[ // 58 - 64
[ // :
0b00000,
0b00100,
0b00000,
0b00100,
0b00000
],
[ // ;
0b00000,
0b00100,
0b00000,
0b00100,
0b00100
],
[ // <
0b00010,
0b00100,
0b01000,
0b00100,
0b00010
],
[ // =
0b00000,
0b11111,
0b00000,
0b11111,
0b00000
],
[ // >
0b01000,
0b00100,
0b00010,
0b00100,
0b01000
],
[ // ?
0b01110,
0b10010,
0b00100,
0b00000,
0b00100
],
[ // @
0b01100,
0b11010,
0b11010,
0b10111,
0b01110
],
];
var symbol2=[ // 91 - 96
[ // [
0b00110,
0b00100,
0b00100,
0b00100,
0b00110
],
[ // \
0b10000,
0b01000,
0b00100,
0b00010,
0b00001
],
[ // ]
0b01100,
0b00100,
0b00100,
0b00100,
0b01100
],
[ // ^
0b00100,
0b01010,
0b10001,
0b00000,
0b00000
],
[ // _ (underline)
0b00000,
0b00000,
0b00000,
0b00000,
0b11111
],
[ // `
0b01000,
0b00100,
0b00000,
0b00000,
0b00000
],
];
var symbol3=[ // 123 - 126
[ // {
0b00010,
0b00100,
0b01100,
0b00100,
0b00010
],
[ // |
0b00100,
0b00100,
0b00100,
0b00100,
0b00100
],
[ // }
0b01000,
0b00100,
0b00110,
0b00100,
0b01000
],
[ // ~
0b00000,
0b00000,
0b01010,
0b10100,
0b00000
],
];
var allbintodec=[ // for debug
0b00000, // 0
0b00001,
0b00010,
0b00011,
0b00100,
0b00101,
0b00110,
0b00111,
0b01000,
0b01001,
0b01010,
0b01011,
0b01100,
0b01101,
0b01110,
0b01111,
0b10000,
0b10001,
0b10010,
0b10011,
0b10100,
0b10101,
0b10110,
0b10111,
0b11000,
0b11001,
0b11010,
0b11011,
0b11100,
0b11101,
0b11110,
0b11111 //31
];
// --letters (letterC[] | letterL[])
// A-Z = 65-90 (-65 = 0-25)
// a-z = 97-122 (-97 = 0-25) [missing]
//
// --numbers (numbin[])
// 0-9 = 48-57 (-48 = 0-9)
//
// space = 32 (symbol0[0])~
// extra block = (symbol0[16])
// extra block = (symbol0[17])
var lcdpixel={
width: 4,
height: 6,
gapV: 1,
gapH: 1,
cols: 5,
rows: 5,
}
// block width = (cols * width) + (cols * gapV)
// block height = (rows * height) + (rows * gapH)
var cString="Stand-by";
var cLen=cString.length;
var cPos=0;
var csPos=0;
var lcPos=0;
var s_cPos=0;
var s_csPos=0;
var cnv,ctx;
var pixelH=5;
// fixed width
var cnvW=602;
var cnvH=52;
var pixelW=Math.floor((cnvW - lcdpixel.gapV) / (lcdpixel.width + lcdpixel.gapV));
// dynamic width
//var pixelW=60;
//var cnvW=(pixelW * (lcdpixel.width + lcdpixel.gapV)) + lcdpixel.gapV;
//var cnvH=(pixelH * (lcdpixel.height + lcdpixel.gapH)) + lcdpixel.gapH;
var maxSlot=(cnvW / ((lcdpixel.width + lcdpixel.gapV) * lcdpixel.cols));
function init() {
//var html="binary dec<br /><br />";
//for(var i=0;i<allbintodec.length;i++) {
// var abtd=allbintodec[i];
// var ab=abtd.toString(2);
// while(ab.length<5) {
// ab="0"+ab;
// }
// html+=ab+" "+abtd+"<br />";
//}
//$('log').insertAdjacentHTML('beforeend',html);
cnv=$('cnv');
ctx=cnv.getContext('2d');
cnv.width=cnvW;
cnv.height=cnvH;
cnv.style.width=cnvW+"px";
cnv.style.height=cnvH+"px";
//cnv.style.border="1px solid #f0f";
//ctx.clearRect(0,0,cnvW,cnvH);
//ctx.fillColor="#000"; // black
//ctx.fillRect(0,0,cnvW/2,cnvH); // x,y,w,h
animdraw();
}
var fps=1000/60; // render
var textfps=1000/12; // scroll (steps per second)
var showtime=0;
var holdCString="";
var fdiff=0;
var dT=null;
var ldT=null;
var adT;
var uiUpdate=5; // per sec
var uiWait=0;
var bCharLog="";
var bCharSplit=5;
function animdraw() {
clearTimeout(adT);
var delta=dT-ldT;
fdiff=delta-fps;
if(fdiff<0) fdiff=0; // sleep time is 60fps not counting
else if(fdiff>fps) fdiff=fps; // processing time, fdiff does~
lcPos-=delta;
//if(uiWait<=0) {
// //console.log("delta~"+delta);
// $('fps').innerHTML=delta+" . "+(1000/(fps+fdiff));
// $('char').innerHTML=bCharLog;
// $('lit').innerHTML="s_cPos: "+s_cPos+", s_csPos: "+s_csPos+"<br />cPos: "+cPos+", csPos: "+csPos;
// uiWait=1000/uiUpdate;
//} else {
// uiWait-=delta;
//}
ldT=dT;
dT=Date.now();
//bCharLog="";
ctx.clearRect(0,0,cnvW,cnvH);
ctx.fillStyle="#000"; // black
ctx.fillRect(0,0,cnvW,cnvH); // x,y,w,h
if(lcPos<=0) {
s_csPos++;
if(s_csPos>=5) {
s_csPos=0;
s_cPos++;
if(s_cPos>=cLen) {
s_cPos=-maxSlot; // reset
showtime++;
if(showtime>=3) { // clock show
showtime=0;
getCurrentClock();
holdCString=cString;
cString=full_date_str;
cLen=full_date_str.length;
} else {
if(next_cString!="") { // set new queue
cString=next_cString;
cLen=next_cString.length;
next_cString="";
holdCString="";
} else {
if(holdCString!="") { // set last if had
cString=holdCString;
cLen=holdCString.length;
holdCString="";
}
}
}
}
}
lcPos=textfps;
}
cPos=s_cPos;
csPos=s_csPos;
// draw grid~~
let posX=0;
let posY=0;
var bChar=[];
var blank=false;
for(var i=0;i<pixelW;i++) {
posX=(i * (lcdpixel.width + lcdpixel.gapV)) + lcdpixel.gapV;
if(!blank && cPos>=0) { // filter before and after string = empty
let charCode=cString.charCodeAt(cPos);
//let printed=0;
let selIdx=0;
if(charCode>=65 && charCode<=90) { // A-Z
selIdx=charCode-65; // starts 0
bChar=letterC[selIdx];
} else if(charCode>=97 && charCode<=122) { // a-z
selIdx=charCode-97;
bChar=letterL[selIdx];
} else if(charCode>=48 && charCode<=57) { // 0-9
selIdx=charCode-48;
bChar=numbin[selIdx];
} else if(charCode>=32 && charCode<=47) { // !"#$%&'()*+,-./
selIdx=charCode-32;
bChar=symbol0[selIdx];
} else if(charCode>=58 && charCode<=64) { // :;<=>?@
selIdx=charCode-58;
bChar=symbol1[selIdx];
} else if(charCode>=91 && charCode<=96) { // [\]^_`
selIdx=charCode-91;
bChar=symbol2[selIdx];
} else if(charCode>=123 && charCode<=126) { // {-~
selIdx=charCode-123;
bChar=symbol3[selIdx];
} else {
bChar=symbol0[17]; // square block not found
//let charC=cString.charAt(cPos);
//$('char').innerHTML=charCode+" "+charC;
//printed=1;
//switch(charCode) {
// case "-":
// selIdx=0;
// break;
// default:
//}
}
//if(!printed) {
// $('char').innerHTML=charCode+" "+selIdx;
//}
} else { // blank
//bChar=symbol0[17]; // square block not found
bChar=symbol0[0]; // empty space
}
//bCharLog+="i="+i+": "+JSON.stringify(bChar)+", ";
//bCharSplit--;
//if(bCharSplit<=0) {
// bCharLog+="<br />";
// bCharSplit=5;
//}
//if(i>=5) break;
//if(bChar.length==0) {
// bCharLog+="null";
// break;
//}
for(var j=0;j<pixelH;j++) {
posY=(j * (lcdpixel.height + lcdpixel.gapH)) + lcdpixel.gapH;
let lit=false;
if(csPos==0) {
if(bChar[j]>=16 && bChar[j]<=31) {
lit=true;
}
} else if(csPos==1) {
if((bChar[j]>=8 && bChar[j]<=15) || (bChar[j]>=24 && bChar[j]<=31)) {
lit=true;
}
} else if(csPos==2) {
if((bChar[j]>=4 && bChar[j]<=7) || (bChar[j]>=12 && bChar[j]<=15) ||
(bChar[j]>=20 && bChar[j]<=23) || (bChar[j]>=28 && bChar[j]<=31)) {
lit=true;
}
} else if(csPos==3) {
if((bChar[j]>=2 && bChar[j]<=3) || (bChar[j]>=6 && bChar[j]<=7) ||
(bChar[j]>=10 && bChar[j]<=11) || (bChar[j]>=14 && bChar[j]<=15) ||
(bChar[j]>=18 && bChar[j]<=19) || (bChar[j]>=22 && bChar[j]<=23) ||
(bChar[j]>=26 && bChar[j]<=27) || (bChar[j]>=30 && bChar[j]<=31)) {
lit=true;
}
} else if(csPos==4) {
if(isOdd(bChar[j])) {
lit=true;
}
}
if(lit) {
ctx.fillStyle="#0f0"; // green
} else {
ctx.fillStyle="#050"; // green
}
ctx.fillRect(posX,posY,lcdpixel.width,lcdpixel.height);
} // loop H
csPos++;
if(csPos>=5) {
csPos=0;
cPos++;
if(cPos>=cLen) {
blank=true;
}
}
//console.log("cPos: "+cPos+", csPos: "+csPos);
} // loop W
//console.log("new");
adT=setTimeout(function() { animdraw(); },fps-fdiff);
}
var next_cString="";
function setText(txt) {
//cString=txt;
//cLen=cString.length;
next_cString=txt;
}
function setTFps(val) {
textfps=1000/val;
//$('txttfps').innerHTML=val;
if(val>1000/fps) {
//$('rngfps').value=val;
setFps(val);
}
}
function setFps(val) {
fps=1000/val;
//$('txtfps').innerHTML=val;
if(val<1000/textfps) {
//$('rngtfps').value=val;
setTFps(val);
}
}
function updatelcd() {
cnvW=(pixelW * (lcdpixel.width + lcdpixel.gapV)) + lcdpixel.gapV;
cnvH=(pixelH * (lcdpixel.height + lcdpixel.gapH)) + lcdpixel.gapH;
maxSlot=(cnvW / ((lcdpixel.width + lcdpixel.gapV) * lcdpixel.cols));
//console.log("cnvW: "+cnvW);
//console.log("lcdpixel.width+lcdpixel.gapV: "+(lcdpixel.width + lcdpixel.gapV));
//console.log("maxSlot: "+maxSlot);
cnv.width=cnvW;
cnv.height=cnvH;
cnv.style.width=cnvW+"px";
cnv.style.height=cnvH+"px";
}
function setW(val) {
pixelW=val;
//$('txtW').innerHTML=val;
updatelcd();
}
function setPW(val) {
lcdpixel.width=parseInt(val);
//$('txtPW').innerHTML=val;
updatelcd();
}
function setPH(val) {
lcdpixel.height=parseInt(val);
//$('txtPH').innerHTML=val;
updatelcd();
}
function setGV(val) {
lcdpixel.gapV=parseInt(val);
//$('txtGV').innerHTML=val;
updatelcd();
}
function setGH(val) {
lcdpixel.gapH=parseInt(val);
//$('txtGH').innerHTML=val;
updatelcd();
}
function setWidth(val) {
cnvW=val;
//cnvH=52;
pixelW=Math.floor((cnvW - lcdpixel.gapV) / (lcdpixel.width + lcdpixel.gapV));
updatelcd();
}
function setHeight(val) {
//cnvW=val;
cnvH=val;
//pixelW=Math.floor((cnvW - lcdpixel.gapV) / (lcdpixel.width + lcdpixel.gapV));
// pixelH does not change!
updatelcd();
}
var dd;
var months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
var week=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
var dfix=["st","nd","rd","th"];
var ampm="am";
var hh,mm,ss;
var day,month,mdate,year,tzd;
var day_str,month_str,fix_clamp,date_str;
var full_date_str;
function getCurrentClock() {
dd=new Date();
hh=dd.getHours();
mm=dd.getMinutes();
ss=dd.getSeconds();
day=dd.getDay();
month=dd.getMonth();
mdate=dd.getDate();
tzd=-Math.floor(dd.getTimezoneOffset()/60);
//tzd-=1;
year=dd.getFullYear();
if(hh>=12) {
hh-=12;
ampm="PM";
} else {
ampm="AM";
}
if(hh==0) hh=12;
day_str=week[day];
month_str=months[month];
fix_clamp=mdate;
fix_clamp--;
if(fix_clamp>3) fix_clamp=3;
//date_str=mdate+dfix[fix_clamp];
date_str=mdate;
hh=(hh<10)?"0"+hh:hh;
mm=(mm<10)?"0"+mm:mm;
ss=(ss<10)?"0"+ss:ss;
tzd=(tzd>-1)?"+"+tzd:tzd;
//full_date_str=day_str+", "+month_str+" "+date_str+" "+year+", "+hh+":"+mm+":"+ss;
//full_date_str=month_str+" "+date_str+" "+day_str+" "+hh+":"+mm+" "+ampm;
//full_date_str=day_str+", "+date_str+" "+month_str+" "+year+" "+hh+":"+mm+":"+ss+" "+ampm+" (GMT"+tzd+")";
full_date_str=day_str+", "+date_str+" "+month_str+" "+year+" "+hh+":"+mm+" "+ampm+" (GMT"+tzd+")";
}
window.addEventListener('message', (event) => {
//if (event.origin === 'https://links.analiestar.com') {
console.log('Message from parent:', event.data[0]);
switch(event.data[0]) {
case "new_text":
setText(event.data[1]);
break;
case "new_width": // fixed
setWidth(event.data[1]);
break;
case "new_height": // fixed
setHeight(event.data[1]);
break;
default:
}
//}
});
</script>
</head>
<body onload="init();">
<canvas id="cnv"></canvas>
<!--<input type="text" value="" onchange="setText(this.value);" />
<br />
textFPS: <span id="txttfps">12</span> <input type="range" min="1" max="1000" value="12" step="1" onchange="setTFps(this.value);" id="rngtfps">
<br />
FPS: <span id="txtfps">60</span> <input type="range" min="1" max="1000" value="60" step="1" onchange="setFps(this.value);" id="rngfps">
<br />
stepW: <span id="txtW">60</span> <input type="range" min="0" max="255" value="60" step="1" onchange="setW(this.value);">
<br />
pixelW: <span id="txtPW">8</span> <input type="range" min="1" max="100" value="8" step="1" onchange="setPW(this.value);">
<br />
pixelH: <span id="txtPH">8</span> <input type="range" min="1" max="100" value="8" step="1" onchange="setPH(this.value);">
<br />
gapV: <span id="txtGV">2</span> <input type="range" min="0" max="100" value="2" step="1" onchange="setGV(this.value);">
<br />
gapH: <span id="txtGH">2</span> <input type="range" min="0" max="100" value="2" step="1" onchange="setGH(this.value);">-->
<!--<div id="log"></div>
<div id="fps"></div>
<div id="char"></div>
<div id="lit"></div>-->
</body>
</html>
Top