A HTML Color Format Converter


There are three main types of color notation, rgb or rgba, hex and a single number where the r value is multiplied by 256×256, the g by 256 and the three numbers summed. Sometimes it is necessary to convert from one to another, which can be tedious. This app converts a value inserted in one format to the other two. I found it invaluable when I had to convert a table of colors to an array of a different format.

Here is how it looks:

To try Click Here

Here is the code:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head profile=”http://gmpg.org/xfn/11″&gt;
<title>HTML Editor</title>
<style>
body {margin-left:0;margin-right:0;font:normal normal 700 20px Arial;}
a{ text-decoration: }:link { color: rgb(0, 0, 255) }:visited {color :rgb(100, 0,100) }:hover { }:active { }
input{text-align: center;font:normal normal 700 24px Arial}
</style>
</head>
<body>
<center><input type=”text” id=”t1″ name=”t1″ value=”rgb(,,)” ondblclick=’convclr(“1″);’ /><br /><br /> <input type=”text” id=”t2″ name=”t2″ value=”#” ondblclick=’convclr(“2″);’ /><br /><br /> <input type=”text” id=”t3″ name=”t3″ value=”16777215″ ondblclick=’convclr(“3″);’ /></center>

<script type=”text/javascript”>
var a = 0; var b = 4; var hx = “#”; var tot = 0;
function convclr(f) {
a = 0; b = 4; tot = 0; hx = “#”;

if (f == “1”) {
var v1 = document.getElementById(“t1”).value;
a = v1.indexOf(“,”,b);
if ( parseInt(v1.substr(b,a-b)).toString(16).length == 1 ) hx += “0”;
hx += parseInt(v1.substr(b,a-b)).toString(16);
tot += 256 * 256 * parseInt(v1.substr(b,a-b));
b = a + 1;
a = v1.indexOf(“,”,b);
if ( parseInt(v1.substr(b,a-b)).toString(16).length == 1 ) hx += “0”;
hx += parseInt(v1.substr(b,a-b)).toString(16);
tot += 256 * parseInt(v1.substr(b,a-b));
b = a + 1;
a = v1.indexOf(“)”,b);
if ( parseInt(v1.substr(b,a-b)).toString(16).length == 1 ) hx += “0”;
hx += parseInt(v1.substr(b,a-b)).toString(16);
tot += parseInt(v1.substr(b,a-b));
document.getElementById(“t2”).value = hx.toUpperCase();
document.getElementById(“t3”).value = tot;
} else if (f == “2”) {
var v2 = document.getElementById(“t2”).value;
document.getElementById(“t1”).value = “rgb(” + parseInt(v2.substr(1,2),16) + “,” + parseInt(v2.substr(3,2),16) + “,” + parseInt(v2.substr(5,2),16) + “)”;
document.getElementById(“t3”).value = 256 * 256 * parseInt(v2.substr(1,2),16) + 256 * parseInt(v2.substr(3,2),16) + parseInt(v2.substr(5,2),16);
} else if (f == “3”) {
tot = parseInt(document.getElementById(“t3”).value);
var r = Math.floor(tot / (256 * 256));
tot -= (r * 256 * 256);
var g = Math.floor(tot/256);
tot -= g * 256;
b = tot;
document.getElementById(“t1”).value = “rgb(” + r + “,” + g + “,” + b + “)”;
r = r.toString(16).toUpperCase();
if (r.length == 1) r = “0” + r;
g = g.toString(16).toUpperCase();
if (g.length == 1) g = “0” + g;
b = b.toString(16).toUpperCase();
if (b.length == 1) b = “0” + b;
document.getElementById(“t2”).value = “#” + r + g + b;
}

}
</script>
</body></html>


Converting from rgb is the following:
if (f == “1”) {
var v1 = document.getElementById(“t1”).value;
a = v1.indexOf(“,”,b);
if ( parseInt(v1.substr(b,a-b)).toString(16).length == 1 ) hx += “0”;
hx += parseInt(v1.substr(b,a-b)).toString(16);
tot += 256 * 256 * parseInt(v1.substr(b,a-b));
b = a + 1;
a = v1.indexOf(“,”,b);
if ( parseInt(v1.substr(b,a-b)).toString(16).length == 1 ) hx += “0”;
hx += parseInt(v1.substr(b,a-b)).toString(16);
tot += 256 * parseInt(v1.substr(b,a-b));
b = a + 1;
a = v1.indexOf(“)”,b);
if ( parseInt(v1.substr(b,a-b)).toString(16).length == 1 ) hx += “0”;
hx += parseInt(v1.substr(b,a-b)).toString(16);
tot += parseInt(v1.substr(b,a-b));
document.getElementById(“t2”).value = hx.toUpperCase();
document.getElementById(“t3”).value = tot;
}

The rgb value is parsed for r between the opening parenthesis and the first comma, g between the commas and b between the second comma and the close parenthesis. :

toString(16) does not include a preceding 0 if the hex value is a single digit. This can lead to confusion, as it is not always clear which hex color has the single digit. I therefore precede the single digit with a 0 before listing it:
if ( parseInt(v1.substr(b,a-b)).toString(16).length == 1 ) hx += “0”;

The variable hx is then appended:

hx += parseInt(v1.substr(b,a-b)).toString(16);

Finally, the full hex value is posted in the text input:
document.getElementById(“t2”).value = hx.toUpperCase();

It is not necessary but aesthetically, I prefer the letters to be upper case.

The third format is made by appending a variable tot, first by multiplying by 256 twice, then by 256 and then just the number:
tot += 256 * 256 * parseInt(v1.substr(b,a-b));
tot += 256 * parseInt(v1.substr(b,a-b));
tot += parseInt(v1.substr(b,a-b));

Converting from hex is easier.
Since red green and blue values are made two digit, sequential two digit reading can be used:
document.getElementById(“t1”).value = “rgb(” + parseInt(v2.substr(1,2),16) + “,” + parseInt(v2.substr(3,2),16) + “,” + parseInt(v2.substr(5,2),16) + “)”;

The same values can be used for the third format:
document.getElementById(“t3”).value = 256 * 256 * parseInt(v2.substr(1,2),16) + 256 * parseInt(v2.substr(3,2),16) + parseInt(v2.substr(5,2),16);

In converting from the third format, r,g, and b values are created by the reverse of conversion from rgb:
var r = Math.floor(tot / (256 * 256));
tot -= (r * 256 * 256);
var g = Math.floor(tot/256);
tot -= g * 256;
b = tot;

These values are used for rgb:
document.getElementById(“t1”).value = “rgb(” + r + “,” + g + “,” + b + “)”;

They are also used for hex:
r = r.toString(16).toUpperCase();
if (r.length == 1) r = “0” + r;
g = g.toString(16).toUpperCase();
if (g.length == 1) g = “0” + g;
b = b.toString(16).toUpperCase();
if (b.length == 1) b = “0” + b;
document.getElementById(“t2”).value = “#” + r + g + b;

Returning multiple values from a function


It is common knowledge that functions return a single value.
However, this is not strictly true.
This simple example demonstrates that with the use of arrays, multiple values can both be inserted with a single argument and returned.

Here is the code:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head profile=”http://gmpg.org/xfn/11″&gt;
<title>HTML Editor</title>
<style>
body {margin-left:0;margin-right:0;font:normal normal normal 15px Arial;}
a{ text-decoration: }:link { color: rgb(0, 0, 255) }:visited {color :rgb(100, 0,100) }:hover { }:active { }
#t1{width: 400px; text-align:center; font:normal normal 700 18px Arial}
</style>
</head>
<body onload=’init();’>
<center><input type=”text” id=”t1″ name=”t1″ value=”” /></center>
<script type=”text/javascript”>

function init() {
var arr = [];
arr[0] = Math.PI;
arr[1] = Math.E;
arr = tst(arr);
document.getElementById(“t1”).value = “arr[0] (pi) * 2 = ” + arr[0].toFixed(4) + ” arr[1] (e) + 3 = ” + arr[1].toFixed(4);
}

function tst(v) {
var res = [];
res[0] = v[0] * 2;
res[1] = v[1] + 3;
return res
}
</script>
</body></html>


A function init() is created and a blank array, arr inserted,so arr is not a global variable.
I then inserted pi and e as the values of the first two cells of the array.
The function tst(arr) was called to do operations on the cell values.
A blank array, res is created inside tst(arr) to provide a return.
The cells of res were given the results of the operations, and res was returned to the array arr of init().
The results were summarized in a text input

Thus, multiple values were returned with a single function call.

Simple HTML Pointillism Canvas


There is a style of art called Pointillism. This simple app allows you to create your own “Masterpieces”.
I am no artist, but I think it could be fun for children to mix colors and make patterns.
Clicking a point on the canvas puts a dot with chosen size, color and transparency.

Here is an example with first a single color superimposed with varying opacities to create a sort of gradient, and varied colors making a sort of worm.:

To Try Click Here

Here is the code:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head profile=”http://gmpg.org/xfn/11″&gt;
<title>HTML Editor</title>
<style>
body {margin-left:0;margin-right:0;font:normal normal normal 15px Arial;}
a{ text-decoration: }:link { color: rgb(0, 0, 255) }:visited {color :rgb(100, 0,100) }:hover { }:active { }
#svg1{position: relative; width: 600px; height: 500px; border: 20px inset tan; background: black}
</style>
</head>
<body>
<center>
<input type=’color’ id=’clr’ value= simple color /> <input type=”text” id=”t1″ name=”t1″ value=”Brush Size” onclick = ‘clr(“t1″);’ /> <input type=”text” id=”t2″ name=”t2″ value=”Opacity” onclick = ‘clr(“t2″);’ /> <input type=”checkbox” id=”c1″ name=”c1″ value=”” />Mobile<br /><br />
<svg xmlns=”http://www.w3.org/2000/svg&#8221; version=”1.1″ id=”svg1″></svg></center>

<script type=”text/javascript”>
var posX;var posY; var sz; var colr; var opac; var mp = screen.width/2;
var IE = document.all?true:false;
document.onclick = getMouse2;

function getMouse2(e) {
colr = document.getElementById(“clr”).value;
sz = document.getElementById(“t1”).value;
opac = document.getElementById(“t2”).value;
if (IE) {
posX = event.clientX + document.body.scrollLeft;
posY = event.clientY + document.body.scrollTop;
}
else {
posX = e.pageX – mp + 300;
if (document.getElementById(“c1”).checked) mp -= 300;
posY = e.pageY – 72;
}

if (posY > 50) document.getElementById(“svg1″).innerHTML += ‘<ellipse cx=”‘ + posX + ‘” cy=”‘ + posY + ‘” rx= ‘ + sz + ‘ ry= ‘ + sz + ‘ style=”fill:’ + colr + ‘ ; stroke: none; opacity: ‘ + opac + ‘” />’;
}

function clr(el) {
document.getElementById(el).value = “”;
}
</script>
</body></html>


I used a black background but it can be made in any color.
The canvas is a SVG element with an inset border.

A mouse listener is established:
document.onclick = getMouse2;

getMouse2(e) sets variables with the color, size and transparency:
colr = document.getElementById(“clr”).value;
sz = document.getElementById(“t1”).value;
opac = document.getElementById(“t2”).value;

The clicked position is obtained and a circle placed on the canvas:
posX = e.pageX – mp + 300;
posY = e.pageY – 72;
}

if (posY > 50) document.getElementById(“svg1″).innerHTML += ‘<ellipse cx=”‘ + posX + ‘” cy=”‘ + posY + ‘” rx= ‘ + sz + ‘ ry= ‘ + sz + ‘ style=”fill:’ + colr + ‘ ; stroke: none; opacity: ‘ + opac + ‘” />’;

The x position is different if a phone is used:
if (document.getElementById(“c1”).checked) mp -= 300;

HTML Word Puzzle Creator


There is a puzzle in which words are hidden in a mass of random letters. This app assists in their creation.
The actual words must be created by hand, but this is not difficult. This app uses an 8 x 8 matrix, but any size could be used, so long as the words are no longer than the matrix size. Any words that cross each other must do so at a common letter. Here is an example:

Clicking Create then adds the random letters:

Clicking Play and then clicking a box with a letter highlights that box and changes the button to Undo:

Repeating the procedure when it says Undo reverses the procedure to correct errors.

Here is the code:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head profile=”http://gmpg.org/xfn/11″&gt;
<title>Game</title>
<style>
body {margin-left:0;margin-right:0;font:normal normal normal 15px Arial;}
a{ text-decoration: }:link { color: rgb(0, 0, 255) }:visited {color :rgb(100, 0,100) }:hover { }:active { }
#ta1{position: relative; border-collapse: collapse; text-align: center}
td{ width: 30px; height: 30px; border: 1px solid black}
</style>
</head>
<body>
<center><input type=”button” id=”b1″ name=”b1″ value=”Create” onclick=’crte();’ /> <input type=”button” id=”b2″ name=”b1″ value=”Play” onclick=’prmt();’ /> <input type=”button” id=”b3″ name=”b3″ value=”Save” onclick=’sve();’ /> <select id=”s1″ name=”s1″ onchange = ‘opn();’><option>Choose Game</option></select><br /><br />
<table id= “ta1” ></table></center>
http://hiddenText.js
<script type=”text/javascript”>
var str = “”; var char; var cnt = 0; var let; var pla = false; var oldURL = “hiddenText.js”; var oldstr = ”;

for (var i = 1; i <= puzzlecnt; i ++) {
document.getElementById(“s1”).innerHTML += ‘<option>puzzle’ + i + ‘</option>’;
}

str +='<tr>’;
for (var i = 0; i <= 63; i ++) {
str += ‘<td id = “td’ + i + ‘” contenteditable = “true” onclick=\’chgclr(id);\’ ></td>’;
if (i == 7 || i == 15 || i == 23 || i == 31 || i == 39 || i == 47 || i == 55) str +='</tr><tr>’;
}
str +='</tr>’;
document.getElementById(“ta1”).innerHTML = str;

function opn() {
document.getElementById(“ta1”).innerHTML = puzzle[document.getElementById(“s1”).selectedIndex];
}

function prmt() {
if (! pla) {
pla = true;
document.getElementById(“b2”).value = “Undo”;
} else {
document.getElementById(“b2”).value = “Play”;
pla = false;
}
}

function chgclr(el) {
if (pla) {
document.getElementById(el).style.backgroundColor = “#dddddd”;
} else {
document.getElementById(el).style.backgroundColor = “white”;
}
}

function crte() {
if (puzzlecnt > 0) {
for (var i = 1; i <= puzzlecnt; i ++) {
oldstr += ‘puzzle[‘ + i + ‘] = \” + puzzle[i] + ‘\’;\n’;
}
}
puzzlecnt ++;
for (var j = 0; j <= 63; j ++) {
for (var i = 0; i <= 16; i ++) {
char = Math.floor(90 * Math.random()) + 1;
if (char > 64) {
cnt ++;
if (cnt > 0) let = String.fromCharCode(char).toLowerCase();
if (document.getElementById(“td” + j).innerHTML == “”) document.getElementById(“td” + j).innerHTML = let;
}
}
}
}

function sve() {
var textToSave = ‘var puzzlecnt = 0;\nvar puzzle = [];\npuzzle[0] = \’\’;\n’ + oldstr + ‘\npuzzle[‘ + puzzlecnt + ‘] = \” + document.getElementById(“ta1″).innerHTML + ‘\’;\npuzzlecnt = ‘ + puzzlecnt + ‘;\n’;
var textToSaveAsBlob = new Blob([textToSave], {type:”text/plain”});
var textToSaveAsURL = window.URL.createObjectURL(textToSaveAsBlob);
fileNameToSaveAs = prompt(“FileName to save as”,oldURL);
oldURL = fileNameToSaveAs;
var downloadLink = document.createElement(“a”);
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = “Download File”;
downloadLink.href = textToSaveAsURL;
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = “none”;
document.body.appendChild(downloadLink);
downloadLink.click();
}

function destroyClickedElement(event) {
document.body.removeChild(event.target);
}
</script>
</body></html>


The puzzle is a table created by a script:
str +='<tr>’;
for (var i = 0; i <= 63; i ++) {
str += ‘<td id = “td’ + i + ‘” contenteditable = “true” onclick=\’chgclr(id);\’ ></td>’;
if (i == 7 || i == 15 || i == 23 || i == 31 || i == 39 || i == 47 || i == 55) str +='</tr><tr>’;
}
str +='</tr>’;
document.getElementById(“ta1″).innerHTML = str;

Clicking Create calls the function crte():
function crte() {
if (puzzlecnt > 0) {
for (var i = 1; i <= puzzlecnt; i ++) {
oldstr += ‘puzzle[‘ + i + ‘] = \” + puzzle[i] + ‘\’;\n’;
}
}
puzzlecnt ++;
for (var j = 0; j <= 63; j ++) {
for (var i = 0; i <= 16; i ++) {
char = Math.floor(90 * Math.random()) + 1;
if (char > 64) {
cnt ++;
if (cnt > 0) let = String.fromCharCode(char).toLowerCase();
if (document.getElementById(“td” + j).innerHTML == “”) document.getElementById(“td” + j).innerHTML = let;
}
}
}
}

Since there are 64 boxes, random values have to created for up to 64 key codes, minus the number of boxes already occupied.
the key codes for letters go from 65 to 90 so random values up to 90 have to be created and used if 64 or higher:
char = Math.floor(90 * Math.random()) + 1;
if (char > 64) {

These are converted to lower case and inserted if the box is empty:
if (cnt > 0) let = String.fromCharCode(char).toLowerCase();
if (document.getElementById(“td” + j).innerHTML == “”) document.getElementById(“td” + j).innerHTML = let;

Since all characters below 64 must be rejected, the generation must be looped until enough letters are created, or blank boxes will be left:
for (var i = 0; i <= 16; i ++) {

Clicking Play calls prmt():
function prmt() {
if (! pla) {
pla = true;
document.getElementById(“b2”).value = “Undo”;
} else {
document.getElementById(“b2”).value = “Play”;
pla = false;
}
}

This is a toggle which changes the boolean variable ply.

Clicking a box then calls chngclr(el), where el is the id of the cell:
function chgclr(el) {
if (pla) {
document.getElementById(el).style.backgroundColor = “#dddddd”;
} else {
document.getElementById(el).style.backgroundColor = “white”;
}
}

Clicking Save calls sve(), which saves the puzzle for future recall, using a js file. This is as before, with the textToSave being the following:
var textToSave = ‘var puzzlecnt = 0;\nvar puzzle = [];\npuzzle[0] = \’\’;\n’ + oldstr + ‘\npuzzle[‘ + puzzlecnt + ‘] = \” + document.getElementById(“ta1”).innerHTML + ‘\’;\npuzzlecnt = ‘ + puzzlecnt + ‘;\n’;

On opening the names of saved puzzles are inserted into a select element:
for (var i = 1; i <= puzzlecnt; i ++) {
document.getElementById(“s1”).innerHTML += ‘<option>puzzle’ + i + ‘</option>’;
}

Clicking an option loads the selected puzzle:
function opn() {
document.getElementById(“ta1”).innerHTML = puzzle[document.getElementById(“s1”).selectedIndex];
}