Temporal Gradient Backgrounds


Background gradients are usually done in space; the color gradually changes from one part of the screen to another. These gradients are done in time.

Since images only show the screen at one moment, it is better to view a demo:

Click to View

To start a new gradient, just click the screen.

This 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>Temporal Gradients</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 { }

</style>
</head>
<body>
<select id=”s1″ onchange=’init();’>
<option>Choose Gradient</option>
<option>Blue to Red</option>
<option>Green to Red</option>
<option>Blue to Green</option>
<option>Darker to Lighter Blue</option>
</select>
<div id=”grad” style = “position:absolute;left:0;top:0;width:100%;height:100%; visibility: hidden” onclick=’document.getElementById(“grad”).style.visibility = “hidden”;’></div>

<script type=”text/javascript”>
var r; var b; var clr; var si; var cnt = 0; var g; var binc = true;

function init() {
if (document.getElementById(“s1”).value == “Blue to Red”) {
g = 0;
r = 0;
b = 255;
}
if (document.getElementById(“s1”).value == “Green to Red”) {
b = 0
r = 0;
g = 255;
}
if (document.getElementById(“s1”).value == “Blue to Green”) {
g = 0;
r = 0;
b = 255;
}

if (document.getElementById(“s1”).value == “Darker to Lighter Blue”) {
g = 0;
r = 0;
b = 80;
}
clearInterval(si);
cnt = 0;
document.getElementById(“grad”).style.visibility = “visible”;
si = setInterval(“tgrad2()”,100);
}

function tgrad2() {
if (document.getElementById(“s1”).value == “Blue to Red”) {
if (cnt % 2 == 0) {
r += 5;
if (r > 255) r = 255;
if (r == 255 && b > 0) {
b -= 5;
}
if (b == 0) cnt ++;
}

if (cnt % 2 == 1) {
b += 5;
if (b > 255) b = 255;
if (b == 255 && r > 0) {
r -= 5;
}
if (r == 0) cnt ++;
}
}

if (document.getElementById(“s1”).value == “Green to Red”) {
if (cnt % 2 == 0) {
r += 5;
if (r > 255) r = 255;
if (r == 255 && g > 0) {
g -= 5;
}
if (g == 0) cnt ++;
}

if (cnt % 2 == 1) {
g += 5;
if (g > 255) g = 255;
if (g == 255 && r > 0) {
r -= 5;
}
if (r == 0) cnt ++;
}
}

if (document.getElementById(“s1”).value == “Blue to Green”) {
if (cnt % 2 == 0) {
g += 5;
if (g > 255) g = 255;
if (g == 255 && b > 0) {
b -= 5;
}
if (b == 0) cnt ++;
}

if (cnt % 2 == 1) {
b += 5;
if (b > 255) b = 255;
if (b == 255 && g > 0) {
g -= 5;
}
if (g == 0) cnt ++;
}
}

if (document.getElementById(“s1”).value == “Darker to Lighter Blue”) {
if (binc) {
b += 2;
if (b > 210) {
binc = false;
b = 210;
}
}
if (! binc) {
b -= 2;
if (b < 80) {
binc = true;
b = 80;
}
}
}

clr = “rgb(” + r + “,” + g + “,” + b + “)”;
document.getElementById(“grad”).style.backgroundColor = clr;
//alert(document.getElementById(“grad”).style.backgroundColor + ” ” + cnt ) ;

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


The code for a typical two color gradient is as follows:
if (document.getElementById(“s1”).value == “Blue to Red”) {
if (cnt % 2 == 0) {
r += 5;
if (r > 255) r = 255;
if (r == 255 && b > 0) {
b -= 5;
}
if (b == 0) cnt ++;
}

if (cnt % 2 == 1) {
b += 5;
if (b > 255) b = 255;
if (b == 255 && r > 0) {
r -= 5;
}
if (r == 0) cnt ++;
}
}

This gradient starts with blue already at maximum value and red at minimum.
A counter cnt is at 0;
A timer calls the function at 100 ms intervals, at which the red value is increased.
When the red reaches maximum, the blue is decreased.
When the blue reaches minimum, the counter is incremented.
This causes a reverse, with first the blue increasing and then the red decreasing.
When red reaches minimum the counter is incremented again.
The result is whenever the counter is even red increases and then blue decreases, and when it is odd blue increases and then red decreases.

Making a gradient within a single color is even simpler:
f (document.getElementById(“s1”).value == “Darker to Lighter Blue”) {
if (binc) {
b += 2;
if (b > 210) {
binc = false;
b = 210;
}
}
if (! binc) {
b -= 2;
if (b < 80) {
binc = true;
b = 80;
}
}

A boolean binc is initially true and the blue value is increased.
When the blue value reaches 210 binc is set to false and the value decreases.
When it drops to 80, binc is reset to true and the value increases until it reaches 210, at which time it starts decreasing again.

Updated HTML Beveled Text


This is an expansion of a previous post in which just about everything is made adjustable, background image, font size and color, text background and position.

This is a view:

This 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>Beveled Text</title>
<style>
body {margin-left:0;margin-right:0;font:italic normal 900 86px Georgia;}
a{ text-decoration: }:link { color: rgb(0, 0, 255) }:visited {color :rgb(100, 0,100) }:hover { }:active { }
#frame{position: relative; width: 96%; height:600px; left: 2%; border: 1px solid}

</style>
</head>
<body>
<center><select id=”s1″ name=”s1″ onchange=’setColor();’ ><option >To Color</option><option >Text</option><option >Background</option></select> <input type=’color’ id=’cl’ value= simple color /> <select id=”s3″ name=”s3″ ><option >Style</option><option >Normal</option><option >Italic</option><option >Oblique</option></select> <select id=”s2″ name=”s2″ ><option >Font</option><option >Arial</option><option >Arial Black</option><option >Comic Sans MS</option><option >Courier New</option><option >Georgia</option><option >Impact</option><option >Times New Roman</option><option >Verbana</option></select> <input type=”file” id=”fil” name=”files” onchange=’addImage();’ /> <select id=”s4″ name=”s4″><option>Choose Folder</option><option></option><option>A-E/</option><option>F-J/</option><option>K-O/</option><option>P-R/</option><option>S-T/</option><option>SVG/</option></select> <input type=”button” id=”b2″ name=”b2″ value=”Save” onclick=’sve();’/> <input type=”button” id=”b1″ name=”b1″ value=”New” onclick=’location.reload();’/></center>
<di id=”frame”>
<di id=”txt1″ style = “position: absolute; top: 0; padding: 0 10px 0 0″ >
</di>
</di>
<script type=”text/javascript”>
var posX;var posY; var r; var g; var b; var txt; var inc; var a; var cnt = 0; var el = []; var clr = []; var fs = []; var sze = 0; var clr2 = “”; var sze2 = 0; var fnt; var styl; var oldURL = “tmp.html”;
sze = prompt(“font size”, “”);
sze2 = sze;
document.onclick = getMouse;
document.onkeypress = getKey;

function getMouse(e) {

fs[1] = sze2;

for (var i = 2; i <= 5; i ++) {
if (sze2 – sze > 7) {
break;
}
sze -= 2;
fs[i] = sze;
}

if (sze < 20) {
inc = 1;
} else {
inc = 2;
}

fnt = document.getElementById(“s2”).value;
styl = document.getElementById(“s3”).value;

posX = e.pageX – 30;
posY = e.pageY – 120;
if (posY > 30) {
document.getElementById(“txt1”).style.top = posY + “px”;
document.getElementById(“txt1”).style.left = posX + “px”;
}
}

function getKey(e) {
cnt ++;
el[1] = “d” + cnt;
txt = String.fromCharCode(e.keyCode);
document.getElementById(“txt1”).innerHTML += ‘<di id= “‘ + el[1] + ‘” style = “position: relative; display: inline; font:’ + styl + ‘ normal 900 ‘ + fs[1] + ‘px ‘ + fnt + ‘; color: ‘ + clr[1] + ‘”></di>’;
document.getElementById(el[1]).innerHTML = txt;
for (var i = 2; i <= 5; i ++) {
cnt ++;
el[i] = “d” + cnt;
document.getElementById(el[i – 1]).innerHTML += ‘<di id= “‘ + el[i] + ‘” style = “position: absolute; left: ‘ + inc + ‘px; top: ‘ + inc + ‘px; display: inline; font:’ + styl + ‘ normal 900 ‘ + fs[i] + ‘px ‘+ fnt + ‘; color: ‘ + clr[i] + ‘”></dv>’;
document.getElementById(el[i]).innerHTML = txt;
//alert(document.getElementById(“txt1”).innerHTML);
}
}

function setColor() {
if (document.getElementById(“s1”).value == “Background”) {
document.getElementById(“txt1”).style.backgroundColor = document.getElementById(“cl”).value;
} else {
var c = document.getElementById(“cl”).value;
r = parseInt(c.substr(1,2),16);
g = parseInt(c.substr(3,2),16);
b = parseInt(c.substr(5,2),16);
clr[1] = “rgb(” + r + “,” + g + “,” + b + “)”;
for (var i = 2; i <= 5; i ++) {
r += 17;
if (r > 255) r = 255;
g += 17;
if (g > 255) g = 255;
b += 17;
if (b > 255) b = 255;
clr[i] = “rgb(” + r + “,” + g + “,” + b + “)”;
}
}
}

function addImage() {
var fldr = document.getElementById(“s4”).value;
var fname = document.getElementById(“fil”).value;
fname = fldr + fname.substr(fname.lastIndexOf(“\\”) + 1);
document.getElementById(“frame”).innerHTML = ‘<img id = “im1” src= “../My Pictures/’ + fname + ‘” style=”position: absolute; display: inline; left: 30px; top: 0; height:600px” /> ‘ + document.getElementById(“frame”).innerHTML;
}

function sve() {
var textToSave = ‘<html><di id = “frame” style = “position: relative; width: 96%; height:600px; left: 2%; “>’ + document.getElementById(“frame”).innerHTML + ‘</di></html>’;
alert(textToSave);
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 basic concept has been diuscussed in a previous post. Where everything in that post was fixed, this one allow nearly everything to be changed.
The background image can be set with addImage():
function addImage() {
var fldr = document.getElementById(“s4”).value;
var fname = document.getElementById(“fil”).value;
fname = fldr + fname.substr(fname.lastIndexOf(“\\”) + 1);
document.getElementById(“frame”).innerHTML = ‘<img id = “im1” src= “../My Pictures/’ + fname + ‘” style=”position: absolute; display: inline; left: 30px; top: 0; height:600px” /> ‘ + document.getElementById(“frame”).innerHTML;
}

Either the text background or text color can be set:
function setColor() {
if (document.getElementById(“s1”).value == “Background”) {
document.getElementById(“txt1”).style.backgroundColor = document.getElementById(“cl”).value;
} else {
var c = document.getElementById(“cl”).value;
r = parseInt(c.substr(1,2),16);
g = parseInt(c.substr(3,2),16);
b = parseInt(c.substr(5,2),16);
clr[1] = “rgb(” + r + “,” + g + “,” + b + “)”;

On loading a prompt sets the font siaze:
sze = prompt(“font size”, “”);
sze2 = sze;

The font and style are set from selects:
fnt = document.getElementById(“s2”).value;
styl = document.getElementById(“s3”).value;

The position or the text can be moved by means of a mouse listener:
function getMouse(e) {
posX = e.pageX – 30;
posY = e.pageY – 120;
if (posY > 30) {
document.getElementById(“txt1”).style.top = posY + “px”;
document.getElementById(“txt1”).style.left = posX + “px”;

A HTML “Photoshop” Like Effect


This html app creates a Photoshop like effect in which a part of one image is placed on a second image.

Here is the source image:

Here is the background image:

and the resulting composite:

Additionally, the placed object can be positioned on the background by means of the arrow keys.

It can be saved either as an image by screen capture, or a file.

The app consists of a html file and a js file.

This is the html:

<!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>PathGen</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 { }
</style>
</head>
<body>
<div id=”page”></div>
http://pathGen.js
<script type=”text/javascript”>
var fll = “blue”; var op = “.4”; var cont = false; var si2; var cnt2 = 0; var l = 0 ; var u = 50;
document.onkeydown = mv;

function mv(e) {
if (e.keyCode == 37) l -= 2;
if (e.keyCode == 39) l += 2;
if (e.keyCode == 38) u -= 2;
if (e.keyCode == 40) u += 2;
if (e.keyCode == 83) sve();
document.getElementById(“svg1”).style.left = l + “px”;
document.getElementById(“svg1”).style.top = u + “px”;
document.getElementById(“svg1”).style.height = b2 + “px”;
}

function sve() {
var savstr = ‘<html><div id=”frame” style=”position: absolute; width: 100%; height: 520px; left: 0; top: 50px”>’ + document.getElementById(“frame”).innerHTML + ‘</div> <svg id=”svg1″ style=”position: absolute; width: 100%; height: 520px; left: ‘+ document.getElementById(“svg1”).style.left + ‘; top: ‘ + document.getElementById(“svg1”).style.top + ‘; “>’ + document.getElementById(“svg1”).innerHTML + ‘</svg></html>’;
document.getElementById(“page”).innerHTML += ‘<textarea id=”ta” style = “position: absolute; width: 90%; height: 100%; left: 0; top: 0” >’ + savstr + ‘</textarea>’;
setTimeout(“sve2()”,1000);
}

function sve2() {
document.getElementById(“ta”).focus();
document.getElementById(“ta”).select();
success = document.execCommand(“copy”);
}

function contin(par) {
document.getElementById(“svg1″).innerHTML = ‘<defs><clipPath id=”clp” >’ + document.getElementById(“svg1”).innerHTML + ‘</clipPath></defs>’;
document.getElementById(“svg1″).innerHTML += ‘<image x=”0″ y=”0″ height=”500″ href=”‘ + par + ‘” style = “clip-path: url(#clp)” />’ ;
document.getElementById(“frame”).innerHTML = ‘<img id = “im2” src= “A-E/DSCI0008.jpg” height=”500px” />’;
setTimeout(“ld3()”,1000);
}

function ld3() {
document.getElementById(“frame”).style.width = im2.clientWidth;
document.getElementById(“frame”).style.height = im2.clientHeight;
}

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


This is the js:

var wd; var ht; var tempX = 0; var tempY = 0; var cnt = -1; var px = []; var py = []; var str = “”; var str2 = “”; var str3 = “”;
var tp; var fname; var w; var h; var fil = “blue”; var op = .4;

document.getElementById(“page”).innerHTML = ‘<div id=”frame” style=”position: absolute; width: 100%; height: 520px; left: 0; top: 50px”></div> <svg id=”svg1″ style=”position: absolute; width: 100%; height: 520px; left: 0; top: 50px; “></svg> <select id=”s1″ name=”s1″><option >Folder</option><option ></option><option >A-E/</option><option >F-J/</option><option >K-Q/</option><option >P-R/</option><option >S-T/</option></select> <input type=”file” id=”fle” name=”files” onchange=”ld();”/> <input type=”button” id=”b1″ name=”b1″ value=”Create” onclick=”go();” /> <input type=”button” id=”b2″ name=”b2″ value=”Continue” onclick=”contin(fname);” />’;

document.getElementById(“svg1”).onclick = getMouse;

function getMouse(e) {
tempX = e.pageX;
tempY = e.pageY;
if (tempY > tp ) {
cnt ++;
document.getElementById(“svg1″).innerHTML += ‘<ellipse cx=”‘ + tempX + ‘” cy=”‘ + (tempY – 50) + ‘” rx=”4″ ry=”4″ fill = “blue” /> ‘;
px[cnt] = tempX; py[cnt] = tempY;
if ( cnt == 0) {
str2 += ‘<path id = “path1” style = “position: absolute; fill: ‘ + fll + ‘; fill-opacity:’ + op + ‘” transform = “translate(0, -50)” d = “M ‘ + px[0] + ‘,’ + py[0] + ‘ C ‘ ;
}

if (cnt > 0) str2 = str2 + px[cnt] + ‘,’ + py[cnt] + ‘ ‘ ;
}
}

function ld(el) {
var fldr = document.getElementById(“s1”).value;
fname = document.getElementById(“fle”).value;
fname = fldr + fname.substr(fname.lastIndexOf(“\\”) + 1);
document.getElementById(“frame”).innerHTML += ‘<img id=”img1″ src= “‘ + fname + ‘” height=”500px” />’;
setTimeout(“ld2()”,1000);
}

function ld2() {
document.getElementById(“frame”).style.height = img1.clientHeight;
document.getElementById(“svg1”).style.height = img1.clientHeight;
document.getElementById(“frame”).style.width = img1.clientWidth;
document.getElementById(“svg1”).style.width = img1.clientWidth;
tp = parseInt(document.getElementById(“svg1”).style.top.substr(0,document.getElementById(“svg1”).style.top.length – 2 ));
w = parseInt(document.getElementById(“svg1”).style.width.substr(0,document.getElementById(“svg1”).style.width.length – 2 ));
h = parseInt(document.getElementById(“svg1”).style.height.substr(0,document.getElementById(“svg1”).style.height.length – 2 ));
}

function go(e) {
document.getElementById(“svg1”).innerHTML = “”;
str2 = str2 + px[cnt] + ‘,’ + py[cnt]+ ‘ ‘ + px[cnt] + ‘,’ + py[cnt] + ‘ ‘ + px[cnt] + ‘,’ + py[cnt] + ‘ ‘ + px[cnt] + ‘,’ + py[cnt] + ‘ ‘ + px[cnt] + ‘,’ + py[cnt] + ‘ Z” />’;
if (str3 != “”) str2 = str3 + ” ” + str2;
document.getElementById(“svg1”).innerHTML += str2;
str3 = str2;
cnt = -1;
px = [];
py = [];
}


The interface is created dynamically by the script:
document.getElementById(“page”).innerHTML = ‘<div id=”frame” style=”position: absolute; width: 100%; height: 520px; left: 0; top: 50px”></div> <svg id=”svg1″ style=”position: absolute; width: 100%; height: 520px; left: 0; top: 50px; “></svg> <select id=”s1″ name=”s1″><option >Folder</option><option ></option><option >A-E/</option><option >F-J/</option><option >K-Q/</option><option >P-R/</option><option >S-T/</option></select> <input type=”file” id=”fle” name=”files” onchange=”ld();”/> <input type=”button” id=”b1″ name=”b1″ value=”Create” onclick=”go();” /> <input type=”button” id=”b2″ name=”b2″ value=”Continue” onclick=”contin(fname);” />’;

The creation of the path has been described before, by clicking a selection.

The loading of the source image is triggered by a change in the file input. A time delay is set in to allow it to load before obtaining the dimensions. This has been previously described.

Clicking Continue transfers control to the html file:
function contin(par) {
document.getElementById(“svg1″).innerHTML = ‘<defs><clipPath id=”clp” >’ + document.getElementById(“svg1”).innerHTML + ‘</clipPath></defs>’;
document.getElementById(“svg1″).innerHTML += ‘<image x=”0″ y=”0″ height=”500″ href=”‘ + par + ‘” style = “clip-path: url(#clp)” />’ ;
document.getElementById(“frame”).innerHTML = ‘<img id = “im2” src= “A-E/DSCI0008.jpg” height=”500px” />’;
setTimeout(“ld3()”,1000);
}

A Clip Path is created from the path and placed on the source image which is then placed on the background image.

After a time delay, the background image is resized:
function ld3() {
document.getElementById(“frame”).style.width = im2.clientWidth;
document.getElementById(“frame”).style.height = im2.clientHeight;
}

The object is not really cut from the source image and placed on the background image.

The entire source image is on top, but all but the clipped path is transparent.

In this case the background image is fixed but future posts will have interactive background images.

Installing Linux on a Chromebook

Although I use Windows based computers for many things, for certain reasons I restrict my online experience to a Chromebook.

The Chromebook I was using was showing signs of wear, so I decided to get a new one while the old one was still working.

The new one has access to Android apps. However, I found them to be practically worthless on a laptop. They would install, but they either would not run or they were designed for touchscreens and were not convenient for machines with a keyboard.

This Chromebook also has the ability to install a version of Linux, which so far has been fruitful. This is only in Beta but so far I have not found any problems.

Linux allows me to use powerful applications such as the Libre Office Suite and especially Gimp, offline

By default this is disabled but can be enabled in Settings.
It takes a few minutes to install and creates a terminal as in this image:

After installation the Linux apps appear on the Chrome taskbar the same as Chrome apps:


The four icons on the right are Nautilus, Gimp, Libre Office and Terminal. Toward the middle is an icon of a brain, which is the Linux game GBrainy.

It is also possible to share Chromebook files with Linux. In this case my Chromebook data is on a SD Card, so I made those files available to the Linux apps:

On creation of the Linux a folder is inserted in the files app:

Subfolders can be added to this, the same as any other folders.

The installation of apps such as Gimp was relatively straightforward.
sudo apt-get update to get the most recent package
sudo apt-get install gimp

After it is installed, it can be started just as any chrome app.

This is the Open File dialog:

The files on the SD Card are available.

By default linux makes most files readable and writable only to the owner, so the permissions for files may have to be changed to be used by third parties.

Changing to a directory and entering sudo chmod -R 777 will make every file in the folder readable, writable and executable.

Libre Office was a little different.

A file on the SD Card could not be opened directly. Instead, the file had to be copied to the Downloads subfolder of Linux files, from where it could be edited, returned and then copied back to the SD Card.

The installation of Xampp was a little more complex. I basically followed the directions in the following link:
View at Medium.com

The only real change I made was I downloaded the installation file to the Downloads subfolder rather to Linux files.

The installation file must be made executable:
sudo chmod +x xampp-linux-x64-8.0.1-0-installer.run

For some reason, the URL is not localhost, but penguin-linux-test and the root folder is /opt/lampp.htdocs/dashboard.
There is an index.html file in that folder, so it will have to be renamed to something that is not automatically loaded to run your own files.
All files to load must be placed in subfolders in the direct path of dashboard.

The path that shares the SD Card files is /mnt/chromeos/removable/SD Card, so when selecting files to be uploaded to the “site” with the file input, that must be taken into account.