In yesterday’s Colour Wheel Size and Spoke Colour Tutorial discussion around the Javascript alert popup ideas we never actually call the “alert” (that references the window.alert) method in what we are doing. We just are using an “alert” box look of things.
But today, with those “prompt” based code off that “alert box look” code (buttons) we really make a call to this “prompt” code. Ah, but what code? Normally, it’s the “window.prompt” method, where the arrangement is a modal window, where you are stuck until you answer the question (of the prompt). But what if we change that arrangement, and allow “prompt” to swing it that you can do other work until you answer the “prompt” at your leisure?
Now what we are suggesting as one solution here, will not suit every situation, but our situation (ie. in this Colour Wheel web application) only has two simple calls to “prompt” and whatever we come up with as this solution needs to tailor its logic to cover for what the modal “prompt” logic used to do … but this is not too involved and so we are proceeding with our …
prompt method override
… idea. That way, often used in Object Oriented code whereby any one method or function can be overridden, often, there, with different argument and/or return value forms. We write this “inhouse” version of “prompt” as per …
const prompt = (blurb,defv) => {
if (!document.getElementById('ida')) {
document.getElementById('divalert').innerHTML='<p style="margin-top:-5px;">' + blurb.replace(/\./g,'.<br>') + '<br><input type="text" id="ida" data-onblur="prompt(' + "'" + blurb + "'" + ',this.value);" placeholder="' + defv + '" value="' + defv + '"></input> <input type="button" value="Cancel" onclick="prompt(' + "'" + blurb + "'" + ',null);"></input> <input type="button" value="OK" onclick="prompt(' + "'" + blurb + "'" + ',document.getElementById(' + "'ida'" + ').value);"></input>';
} else if (blurb.indexOf('radius') != -1) {
document.getElementById('divalert').innerHTML='';
document.getElementById('divalert').style.display='none';
if (defv != null) { rnum=eval(defv); return defv; } else { return null; }
} else {
document.getElementById('divalert').innerHTML='';
document.getElementById('divalert').style.display='none';
if (defv != null) { vsconetwothree=rework(defv); } else { vsconetwothree=''; }
return vsconetwothree;
}
if (('' + defv) != '') {
return defv;
}
return null; // window.prompt(blurb, defv);
};
… teamed with …
function ourdivalert(inmsg) {
var nottext=true;
if (document.getElementById('divalert')) {
if (document.getElementById('divalert').innerHTML.indexOf(' type="text"') != -1) { nottext=false; }
}
if (nottext) {
document.getElementById('divalert').style.position='absolute';
document.getElementById('divalert').style.left=('' + rectdc.left).replace('px','') + 'px';
document.getElementById('divalert').style.top='' + eval(-80 + eval(('' + rectdc.top).replace('px',''))) + 'px';
document.getElementById('divalert').style.backgroundColor='#e0e0e0';
document.getElementById('divalert').style.display='block';
document.getElementById('divalert').style.zIndex='456';
document.getElementById('divalert').style.opacity='0.8';
document.getElementById('divalert').style.padding='5px 5px 5px 5px';
document.getElementById('divalert').innerHTML=inmsg + '<br><br><input type=button value="Radius +/-" onclick=" var ppnum=prompt(' + "'Enter radius of clock.','' + rnum" + '); if (ppnum != null) { rnum=eval(ppnum); } "></input> <input type=button value="Spoke Colour(s)" onclick=" var ppnum=prompt(' + "'Enter wheel spoke colour(s) to choose from where commas separate as required. Cancel will go back to default randomized approach.','' + vsconetwothree" + '); if (ppnum != null) { vsconetwothree=rework(ppnum); } else { vsconetwothree=' + "''" + '; } "></input> <input type=button value=Close onclick=nodivalert();></input>';
}
setTimeout(nodivalert,9000);
}
function nodivalert() {
if (document.getElementById('divalert').innerHTML.indexOf(' type="text"') != -1) {
setTimeout(nodivalert, 1000);
} else {
document.getElementById('divalert').style.display='none';
document.getElementById('divalert').style.zIndex='-456';
document.getElementById('divalert').style.left=('-' + rectdc.left).replace('px','') + 'px';
document.getElementById('divalert').style.top=('-' + rectdc.top).replace('px','') + 'px';
}
}
… in our changed Colour Wheel colour_wheel.html Colour Wheel web application (also, the “Child” popup appearing via clicks of the clock parts of our SVG Network Clock web application).
Previous relevant Colour Wheel Size and Spoke Colour Tutorial is shown below.
Thinking about the “Child” Colour Wheel of yesterday’s SVG Network Clock Map Right Click Hashtagging Tutorial we wanted to add some user controllable …
- way for the user to change the Colour Wheel radius … in other words, its size … and …
- way for the user to change the spoke colour(s) of the Colour Wheel
… and wondered where to offer the Javascript prompt window logic we had in mind … when …
da, da da da da, da, da da
… we remembered our rare venturing into non-alert Javascript popup window box thinking logic that we developed when you click the wheel. Well, what a relief! It does pay, sometimes, to do the hard work of tailoring your own alert box scenario in your code, and then later, you can tailor that inhouse arrangement for future requirements, as we did, today, with our changed Colour Wheel colour_wheel.html Colour Wheel web application (also, the “Child” popup appearing via clicks of the clock parts of our SVG Network Clock web application), as per the changed spoke colour creation code snippet …
if (vsconetwothree != '' && vsarray.length == 0) {
context.strokeStyle = maybephash(vsconetwothree); //'#40FF20';
} else if (vsconetwothree != '') {
context.strokeStyle = maybephash(vsarray[Math.floor(Math.random() * vsarray.length)]); //'#40FF20';
} else {
context.strokeStyle = "#" + cone + "0" + ctwo + "0" + cthree + "0"; //'#40FF20';
}
context.stroke();
… changed helper outerers, as per …
var rnum='100';
var vsconetwothree='', vsarray=[];
function maybephash(inclr) {
var nir=false;
if (inclr.trim().indexOf('#') == -1 && inclr.trim().length == 6) {
for (var ibn=0; ibn<inclr.trim().length; ibn++) {
if (inclr.trim().substring(ibn).substring(0,1) >= '0' && inclr.trim().substring(ibn).substring(0,1) <= '9') {
nir=nir;
} else if (inclr.trim().substring(ibn).substring(0,1).toLowerCase() >= 'a' && inclr.trim().substring(ibn).substring(0,1).toLowerCase() <= 'f') {
nir=nir;
} else {
nir=true;
}
}
if (nir) {
return inclr.trim();
}
return '#' + inclr.trim();
}
return inclr.trim();
}
function rework(instis) {
var outis='[]', thiscompt='', ithis=0, comd='';
if (instis.trim() == '') { return ''; }
if (instis.indexOf(',') == -1) { return instis.trim().replace(/\"/g,"").replace(/\'/g,"").replace(/\;/g,""); }
var csl=instis.trim().toLowerCase().replace(/\;/g,"").replace(/\"/g,"'").replace(/^\[/g,'').replace(/\]$/g,'').split(',');
for (var ijk=0; ijk<csl.length; ijk++) {
if (ithis > 0) {
ithis--;
} else if (csl[ijk].indexOf('rgba(') != -1) {
ithis=3;
outis=outis.replace("[", "['" + csl[ijk].replace(/\'/g,'') + ',' + csl[eval(1 + ijk)].replace(/\'/g,'') + ',' + csl[eval(2 + ijk)].replace(/\'/g,'') + ',' + csl[eval(3 + ijk)].replace(/\'/g,'') + "'" + comd);
comd=',';
} else if (csl[ijk].indexOf('rgb(') != -1) {
ithis=2;
outis=outis.replace("[", "['" + csl[ijk].replace(/\'/g,'') + ',' + csl[eval(1 + ijk)].replace(/\'/g,'') + ',' + csl[eval(2 + ijk)].replace(/\'/g,'') + "'" + comd);
comd=',';
} else {
outis=outis.replace("[", "['" + csl[ijk].replace(/\'/g,'') + "'" + comd);
comd=',';
}
}
eval(" vsarray=" + outis);
return outis;
}
function ourdivalert(inmsg) {
document.getElementById('divalert').style.position='absolute';
document.getElementById('divalert').style.left=('' + rectdc.left).replace('px','') + 'px';
document.getElementById('divalert').style.top='' + eval(-80 + eval(('' + rectdc.top).replace('px',''))) + 'px';
document.getElementById('divalert').style.backgroundColor='#e0e0e0';
document.getElementById('divalert').style.display='block';
document.getElementById('divalert').style.zIndex='456';
document.getElementById('divalert').style.opacity='0.8';
document.getElementById('divalert').style.padding='5px 5px 5px 5px';
document.getElementById('divalert').innerHTML=inmsg + '<br><br><input type=button value="Radius +/-" onclick=" var ppnum=prompt(' + "'Enter radius of clock.','' + rnum" + '); if (ppnum != null) { rnum=eval(ppnum); } "></input> <input type=button value="Spoke Colour(s)" onclick=" var ppnum=prompt(' + "'Enter wheel spoke colour(s) to choose from where commas separate as required. Cancel will go back to default randomized approach.','' + vsconetwothree" + '); if (ppnum != null) { vsconetwothree=rework(ppnum); } else { vsconetwothree=' + "''" + '; } "></input> <input type=button value=Close onclick=nodivalert();></input>';
setTimeout(nodivalert,9000);
}
… featuring a bit of good ol’ Javascript eval based “on the fly” logic.
Previous relevant SVG Network Clock Map Right Click Hashtagging Tutorial is shown below.
Adding to yesterday’s SVG Network Clock Iframe Window Opener Tutorial we have a combination of …
- right click (Windows) or two finger gesture (macOS) event logic …
var altwo=""; //"//www.rjmprogramming.com.au/PHP/Map/map.php?title=Greenwich%20London&onclick=y&label=['Lat',&value='Lon','Name']&data=,[51.4769,-0.0005,~Greenwich~]";
var althree="//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Greenwich%20London%20Places&aregexographicals=y&aregeographicals=HTTP.From%2Chttp.To%2Chttp.Greenwich&peninfo=51.4769|-0.0005|127968_From,51.4769|-0.0005|128205_To,51.4769|-0.0005|Greenwich&width=834&height=520&country=Places&popularity=&data=%20[51.4769|-0.0005|~From~,2]%20,%20[51.4769|-0.0005|~To~,2]%20,%20[51.4769|-0.0005|~Greenwich~,2]";
if (document.addEventListener) {
document.getElementById('myhr').addEventListener('contextmenu', function(e) {
e.preventDefault();
window.open(modgeomay(althree),'_blank','top=100,left=100,width=850,height=800'); //alert('Right Click');
}, false);
document.getElementById('myh4').addEventListener('contextmenu', function(e) {
e.preventDefault();
window.open(modmapmay(altwo),'_blank','top=100,left=100,width=500,height=500'); //alert('Right Click');
}, false);
} else {
document.getElementById('myhr').attachEvent('oncontextmenu', function() {
e.preventDefault();
window.open(modgeomay(althree),'_blank','top=100,left=100,width=850,height=800'); //alert('right click');
});
document.getElementById('myh4').attachEvent('oncontextmenu', function() {
e.preventDefault();
window.open(modmapmay(altwo),'_blank','top=100,left=100,width=500,height=500'); //alert('right click');
});
}
… taking the user to … - Google Chart …
- hashtag (#) based URL information passing and processing …
var lh=('' + location.hash).replace(/\#$/g,'');
function modmapmay(inuid) {
var titleis="Greenwich London";
var latis="51.4769";
var longis="-0.0005";
var endb='';
if (lh != '' && altwo == '') {
var threes=lh.replace(/^\#/g,'').split('#')[0].split('|');
for (var ij=0; ij<threes.length; ij+=3) {
titleis=decodeURIComponent(threes[ij]);
latis=decodeURIComponent(threes[eval(1 + ij)]);
longis=decodeURIComponent(threes[eval(2 + ij)]);
if (altwo == "") {
altwo="//www.rjmprogramming.com.au/PHP/Map/map.php?title=" + encodeURIComponent(titleis) + "&onclick=y&label=['Lat',&value='Lon','Name']&data=,[" + latis + "," + longis + ",~" + encodeURIComponent(titleis) + "~]";
} else {
endb='&onclick=' + altwo.split('&onclick=')[1].replace(/\]$/g, "]%20,%20[" + latis + "," + longis + ",~" + encodeURIComponent(titleis) + "~]");
altwo="//www.rjmprogramming.com.au/PHP/Map/map.php?title=" + encodeURIComponent(titleis) + endb;
}
}
}
titleis="Greenwich London";
latis="51.4769";
longis="-0.0005";
if (document.getElementById('mysel').value != 'GMT') {
//altwo="//www.rjmprogramming.com.au/PHP/Map/map.php?title=Greenwich%20London&onclick=y&label=['Lat',&value='Lon','Name']&data=,[51.4769,-0.0005,~Greenwich~]";
//return altwo; // "//www.rjmprogramming.com.au/PHP/Map/map.php?title=Greenwich%20London&onclick=y&label=['Lat',&value='Lon','Name']&data=,[51.4769,-0.0005,~Greenwich~]";
//} else {
latis=document.getElementById('mysel').innerHTML.split(' value="' + document.getElementById('mysel').value + '"')[1].split(' data-geo="')[1].split(',')[0];
longis=document.getElementById('mysel').innerHTML.split(' value="' + document.getElementById('mysel').value + '"')[1].split(' data-geo="')[1].split(',')[1];
titleis=document.getElementById('mysel').innerHTML.replace(' value="localtime">Localtime<','').replace(' data-geo=', ' value="localtime" data-geo=').split(' value="' + document.getElementById('mysel').value + '"')[1].split('>')[1].split('<')[0];
}
if (altwo == "") {
altwo="//www.rjmprogramming.com.au/PHP/Map/map.php?title=" + encodeURIComponent(titleis) + "&onclick=y&label=['Lat',&value='Lon','Name']&data=,[" + latis + "," + longis + ",~" + encodeURIComponent(titleis) + "~]";
} else {
endb='&onclick=' + altwo.split('&onclick=')[1].replace(/\]$/g, "]%20,%20[" + latis + "," + longis + ",~" + encodeURIComponent(titleis) + "~]");
altwo="//www.rjmprogramming.com.au/PHP/Map/map.php?title=" + encodeURIComponent(titleis) + endb;
}
if (lh.replace('#','') == '') {
lh='#' + encodeURIComponent(titleis) + '|' + latis + '|' + longis;
} else {
lh+='|' + encodeURIComponent(titleis) + '|' + latis + '|' + longis;
}
return altwo; // "//www.rjmprogramming.com.au/PHP/Map/map.php?title=" + encodeURIComponent(titleis) + "&onclick=y&label=['Lat',&value='Lon','Name']&data=,[" + latis + "," + longis + ",~" + encodeURIComponent(titleis) + "~]";
//return inuid;
}
function modgeomay(inuid) {
if (document.getElementById('mysel').value == 'GMT') {
return "//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Greenwich%20London%20Places&aregexographicals=y&aregeographicals=HTTP.From%2Chttp.To%2Chttp.Greenwich&peninfo=51.4769|-0.0005|127968_From,51.4769|-0.0005|128205_To,51.4769|-0.0005|Greenwich&width=834&height=520&country=Places&popularity=&data=%20[51.4769|-0.0005|~From~,2]%20,%20[51.4769|-0.0005|~To~,2]%20,%20[51.4769|-0.0005|~Greenwich~,2]";
} else {
var latis=document.getElementById('mysel').innerHTML.split(' value="' + document.getElementById('mysel').value + '"')[1].split(' data-geo="')[1].split(',')[0];
var longis=document.getElementById('mysel').innerHTML.split(' value="' + document.getElementById('mysel').value + '"')[1].split(' data-geo="')[1].split(',')[1];
var titleis=document.getElementById('mysel').innerHTML.replace(' value="localtime">Localtime<','').replace(' data-geo=', ' value="localtime" data-geo=').split(' value="' + document.getElementById('mysel').value + '"')[1].split('>')[1].split('<')[0];
return "//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=" + encodeURIComponent(titleis) + "%20Places&aregexographicals=y&aregeographicals=HTTP.From%2Chttp.To%2Chttp." + encodeURIComponent(titleis) + "&peninfo=" + latis + "|" + longis + "|127968_From," + latis + "|" + longis + "|128205_To," + latis + "|" + longis + "|" + encodeURIComponent(titleis) + "&width=834&height=520&country=Places&popularity=&data=%20[" + latis + "|" + longis + "|~From~,2]%20,%20[" + latis + "|" + longis + "|~To~,2]%20,%20[" + latis + "|" + longis + "|~" + encodeURIComponent(titleis) + "~,2]";
}
return inuid;
}
… in the changed HTML/Javascript supervisor svg_clock.html regarding SVG Network Clock we think you should (re)try, now with the ancillary functionality …
Clock clicks popup Colour Wheel, Separator click for Timezone Info, Separator right click for Google Geo Chart Map, Flag text click for Google Maps and right click for concatenated Google Map Chart
Did you know?
Or “would you believe” is more like it, for us. Yesterday’s SVG Network Clock Iframe Window Opener Tutorial work did not amount to the popup windows being dynamic on mobile platforms. It is hard to believe, at least for us, but, we’d not set the Parent iframe’s return value to the window.open opens of the popup Child windows be stored in a var(iable (as we never used that var(iable we mistakenly thought it did not matter … but patently it does) for mobile platform Child popup window dynamics as per …
- the changed PHP (Digital Clock) content helper cldate.php …
<?php
echo "<html><head><script type='text/javascript'> var iwois=null; </script></head><body><div id=mydiv></div><script type='text/javascript'>
var asuff='" . $midbit . $csuff . "';
var adate = new Date();
var dow=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
var his=eval('' + adate.getHours());
var mis=eval('' + adate.getMinutes());
var sis=eval('' + adate.getSeconds());
var ssuff='';
if (('' + adate).indexOf(' GMT') != -1) { ssuff=' GMT' + ('' + adate).split(' GMT')[1]; }
if (1 == 1) {
document.getElementById('mydiv').innerHTML=dow[eval('' + adate.getDay())] + ' ' + ('0' + his).slice(-2) + ':' + ('0' + mis).slice(-2) + ':' + ('0' + sis).split('.')[0].slice(-2) + ' ' + ('0' + adate.getDate()).slice(-2) + ' ' + ('0' + eval(1 + eval('' + adate.getMonth()))).slice(-2).replace('01','Jan').replace('02','Feb').replace('03','Mar').replace('04','Apr').replace('05','May').replace('06','Jun').replace('07','Jul').replace('08','Aug').replace('09','Sep').replace('10','Oct').replace('11','Nov').replace('12','Dec') + ' ' + ('' + adate.getFullYear()) + ' ' + ssuff + asuff;
} else {
document.write(dow[eval('' + adate.getDay())] + ' ' + ('0' + his).slice(-2) + ':' + ('0' + mis).slice(-2) + ':' + ('0' + sis).split('.')[0].slice(-2) + ' ' + ('0' + adate.getDate()).slice(-2) + ' ' + ('0' + eval(1 + eval('' + adate.getMonth()))).slice(-2).replace('01','Jan').replace('02','Feb').replace('03','Mar').replace('04','Apr').replace('05','May').replace('06','Jun').replace('07','Jul').replace('08','Aug').replace('09','Sep').replace('10','Oct').replace('11','Nov').replace('12','Dec') + ' ' + ('' + adate.getFullYear()) + ' ' + ssuff + asuff);
}
</script></body></html>";
?>
… and … - the changed PHP helper supervisor svg_clock.php …
<?php
<a id="adigital" data-target="nextif" target="_blank" title="Click for Colour Wheel time" data-href="./colour_wheel.html<?php $modebit=''; if (isset($_GET['timezone'])) { $modebit='?mode=' . str_replace('GjunkMT','Europe/London',str_replace(' ','_',str_replace('+','_',urldecode($_GET['timezone'])))); } echo $modebit; ?>" onclick=" iwois=window.open('./colour_wheel.html<?php $modebit=''; if (isset($_GET['timezone'])) { $modebit='?mode=' . str_replace('GjunkMT','Europe/London',str_replace(' ','_',str_replace('+','_',urldecode($_GET['timezone'])))); } echo $modebit; ?>','_blank','left=600,top=30,width=700,height=800');"><text id="sclock" x="10" y="30" fill="green" class="Ggggg" text-anchor="left">
?>
Previous relevant SVG Network Clock Iframe Window Opener Tutorial is shown below.
Onto the interfacing and integration work of yesterday’s SVG Network Digital and Analogue Clock Synchronizing Tutorial, today we have a three way relationship set to achieve a more dynamic popup window that responds to changes of its window.opener, the “kicker” being (as a first for us) that that window.opener is a “child iframe” itself, and so …
Grandparent | Parent (or iframe child of Grandparent) | Child |
---|---|---|
Source | ||
svg_clock.html | cldate.php | colour_wheel.html |
Linkage Description |
||
Child can see and modify Grandparent’s document.title as window.opener.parent.document.title |
Child can see Parent’s document.getElementById(‘sclock’) contents as window.opener.document.getElementById(‘sclock’).outerHTML |
Child can read Grandparent’s document.title to detect a change of conditions when it should change its own dropdown … |
function sclooklook() {
if (window.opener) {
if (window.opener.document.getElementById('sclock')) {
if (!adt) {
oktor=false;
adt=new Date();
if (('' + window.opener.parent.document.title).indexOf(' ... ') != -1 && ('' + window.opener.parent.document.title).indexOf(' ... ') == -1) {
window.opener.parent.document.title=window.opener.parent.document.title.replace(' ... ', ' ... ').replace('Lone ','A ');
console.log('77:' + window.opener.parent.document.title);
} else if (('' + window.opener.parent.document.title).indexOf('SVG Network Clock') != -1) {
window.opener.parent.document.title='One SVG Network Clock ... ' + document.getElementById('sele').value;
console.log('777:' + window.opener.parent.document.title);
}
console.log('7:' + window.opener.parent.document.title);
}
var preadt='';
if (sioc != '') {
if (window.opener.parent.document.title.indexOf(' ... ') != -1) {
preadt=window.opener.parent.document.title.split(' ... ')[1];
console.log('222:' + preadt);
} else if (window.opener.document.getElementById('sclock').outerHTML.indexOf(' ' + adt.getFullYear() + ' ') != -1) {
preadt=window.opener.document.getElementById('sclock').outerHTML.split(' ' + adt.getFullYear() + ' ')[1].split(' ')[0];
console.log('2222:' + preadt);
}
}
if (sioc == '') {
console.log('0:' + window.opener.document.getElementById('sclock').outerHTML);
if (window.opener.document.getElementById('sclock').outerHTML.indexOf(' ' + adt.getFullYear() + ' ') != -1) {
sioc=window.opener.document.getElementById('sclock').outerHTML.split(' ' + adt.getFullYear() + ' ')[1].split(' ')[0];
console.log('1:' + sioc);
}
console.log('2:' + window.opener.document.getElementById('sclock').outerHTML);
} else if (sioc != preadt) {
document.title+=' ... ' + preadt;
console.log('2:' + preadt);
sioc=preadt;
if (1 == 11) {
location.href=document.URL.split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(sioc);
} else {
document.getElementById('stz').innerHTML='';
document.getElementById('sele').value=sioc;
document.getElementById('sele').style.cursor=inhousec('progress');
changemode(document.getElementById('sele'));
}
window.focus();
} else {
console.log('9:' + preadt);
}
} else if (sioc != '' && window.opener.parent.document.title) {
if (window.opener.parent.document.title.indexOf(' ... ') != -1) {
preadt=window.opener.parent.document.title.split(' ... ')[1];
if (sioc != preadt) {
document.title+=' ... ' + preadt;
console.log('22:' + preadt);
sioc=preadt;
if (1 == 11) {
location.href=document.URL.split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(sioc);
} else {
document.getElementById('stz').innerHTML='';
document.getElementById('sele').value=sioc;
document.getElementById('sele').style.cursor=inhousec('progress');
changemode(document.getElementById('sele'));
}
window.focus();
}
}
} else {
console.log('no go');
}
} else {
console.log('No go');
}
}
… those window.opener based relationships protected at the Grandparent level by continuing on in an overlayed “total webpage” iframe usage as per …
if (document.title.indexOf(' ... ') != -1 || document.title.indexOf('A SVG') != -1 || document.title.indexOf('One SVG') != -1) {
document.getElementById('mytd').style.opacity='0.0';
document.getElementById('botif').src=locationhref;
document.getElementById('botif').style.position='absolute';
document.getElementById('botif').style.top='0px';
document.getElementById('botif').style.left='0px';
document.getElementById('botif').style.width='100%';
document.getElementById('botif').style.height='100%';
document.getElementById('botif').style.zIndex='99';
document.getElementById('botif').style.display='block';
} else {
location.href=locationhref;
}
… for a scenario where …
- user has started up (Grandparent) SVG Network Clock …
- user clicks a Parent (iframe child of Grandparent) clock part, whether analogue or digital …
- causing Child popup window to “pop up” … and if user intends changing timezones back at the Grandparent it would be best to …
- arrange the two windows to be separated and non-overlapping (or do this manually yourself at a later date) …
- after the Child popup window settles …
- change to Grandparent timezone dropdown … will set in play …
- Child timezone dropdown will match that of Grandparent timezone dropdown (via software logic, where multiple changes may result in some Child animation of shows of these timezones)
… in …
- the changed HTML/Javascript supervisor svg_clock.html … and …
- the changed Colour Wheel colour_wheel.html web application
… regarding SVG Network Clock we think you should (re)try.
Previous relevant SVG Network Digital and Analogue Clock Synchronizing Tutorial is shown below.
The work of yesterday’s SVG Network Digital and Analogue Clock Interfacing Tutorial has moved us to improve …
- the accuracy of the Colour Wheel datetime synchronization with the SVG Network Clock … ie. it can be offputting seeing two clocks showing different times so share more information from parent window to child window within the SVG clock svg_clock.php (parent) changes …
<?php
<a id="adigital" data-target="nextif" target="_blank" title="Click for Colour Wheel time" data-href="./colour_wheel.html<?php $modebit=''; if (isset($_GET['timezone'])) { $modebit='?mode=' . str_replace('GjunkMT','Europe/London',str_replace(' ','_',str_replace('+','_',urldecode($_GET['timezone'])))); } echo $modebit; ?>" onclick="window.open('./colour_wheel.html<?php $modebit=''; if (isset($_GET['timezone'])) { $modebit='?mode=' . str_replace('GjunkMT','Europe/London',str_replace(' ','_',str_replace('+','_',urldecode($_GET['timezone'])))); } echo $modebit; ?>','_blank','left=600,top=30,width=700,height=800');"><text id="sclock" x="10" y="30" fill="green" class="Ggggg" text-anchor="left">
Time goes here
</text></a>
<g>
<a id="aanalogue" data-target="nextif" target="_blank" title="Click for Colour Wheel time" data-href="./colour_wheel.html<?php $modebit=''; if (isset($_GET['timezone'])) { $modebit='?mode=' . str_replace('GjunkMT','Europe/London',str_replace(' ','_',str_replace('+','_',urldecode($_GET['timezone'])))); } echo $modebit; ?>" onclick="window.open('./colour_wheel.html<?php $modebit=''; if (isset($_GET['timezone'])) { $modebit='?mode=' . str_replace('GjunkMT','Europe/London',str_replace(' ','_',str_replace('+','_',urldecode($_GET['timezone'])))); } echo $modebit; ?>','_blank','left=600,top=30,width=700,height=800');">
<circle id="cclock" cx="200" cy="200" r="150" fill="transparent">
<title></title>
</circle></a>
<line id="chour" title="" x1="200" y1="200" x2="200" y2="100" style="stroke:transparent;stroke-width:3" /
<line id="cminute" title="" x1="200" y1="200" x2="340" y2="200" style="stroke:transparent;stroke-width:2" />
<line id="csecond" title="" x1="200" y1="200" x2="200" y2="320" style="stroke:transparent;stroke-width:1" /
?>
… maintained via svg_clock.php …
<?php echo ”
function eachsecond(ints) {
var his=eval('' + ints.split(':')[0]);
var mis=eval('' + ints.split(':')[1]);
var sis=eval('' + ints.split(':')[2]);
if (chour) { chour.setAttribute('title', '' + his); }
if (cminute) { cminute.setAttribute('title', '' + mis); }
if (csecond) { csecond.setAttribute('title', '' + sis); }
var hang=eval(180 - eval(0 + Math.round(eval(eval(his % 12) + eval(mis / 60) + eval(sis / 3600)) * 30)) % 360);
var mang=eval(180 - eval(0 + Math.round(eval(mis + eval(sis / 60)) * 6)) % 360);
var sang=eval(180 - eval(0 + Math.round(sis * 6)) % 360);
//top.document.title=ints + ' ' + his + ':' + mis + ':' + sis + ' ' + hang + ';' + mang + ';' + sang;
var retps='', retds='';
retps+=retds + Math.round(eval(200.0 + eval('' + Math.sin(hang * Math.PI / 180.0) * 100.0)));
retds=',';
retps+=retds + Math.round(eval(200.0 + eval('' + Math.cos(hang * Math.PI / 180.0) * 100.0)));
retds=',';
retps+=retds + Math.round(eval(200.0 + eval('' + Math.sin(mang * Math.PI / 180.0) * 140.0)));
retds=',';
retps+=retds + Math.round(eval(200.0 + eval('' + Math.cos(mang * Math.PI / 180.0) * 140.0)));
retds=',';
retps+=retds + Math.round(eval(200.0 + eval('' + Math.sin(sang * Math.PI / 180.0)) * 120.0));
retds=',';
retps+=retds + Math.round(eval(200.0 + eval('' + Math.cos(sang * Math.PI / 180.0)) * 120.0));
return retps;
}
“; ?>
… but please see over at the child the “outerHTML” attribute is the safest to use and cut up for our purposes when dealing with SVG - more daylight saving time considerations … ie. do not rely on PHP, but rather Javascript, regarding GMT timezone offsets, in colour_wheel.html (child) …
const findTimeZoneOffset = (tz,date) => { // thanks to https://stackoverflow.com/questions/57837631/timezone-offset-by-timezone-name-for-a-specific-date-in-javascript
let utcDate = new Date(date.toLocaleString('en-US', { timeZone: "UTC" }));
let tzDate = new Date(date.toLocaleString('en-US', { timeZone: tz }));
let diff = ( tzDate.getTime() - utcDate.getTime() ) / 1000 / 60 / 60;
return diff;
};
- timing and priority of datetime functionalities in Colour Wheel … ie. do not wait for background images before adjusting clock time (and allowing for non-mobile (more SVG element) cursors representing Wikipedia (thanks) image background progress) …
var lastimagesetfor='', lastisfit='';
function preinhousec() {
inhousec('progress');
}
function inhousec(defcurs) {
if (defcurs == 'progress') {
if (document.getElementById('stz').innerHTML != '') {
document.getElementById('sele').style.cursor='pointer';
lastisfit='' + (document.getElementById('stz').innerText || document.getElementById('stz').contentWindow || document.getElementById('stz').contentDocument);
lastimagesetfor=document.getElementById('sele').value;
return 'pointer';
} else {
setTimeout(preinhousec, 1000);
}
} else {
setTimeout(preinhousec, 1000);
}
if (lastimagesetfor.replace('GMT','/').indexOf('/') != -1) {
lastimagesetfor=lastimagesetfor.replace('GMT','gmt').replace(/\//g,'~');
return 'url(' + "'" + 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="126" height="48" viewport="0 0 100 100" style="border-radius:15px;background-color:rgba(255,255,0,0.5);fill:black;font-family:Verdana;font-size:9px;text-shadow:white 1px 1px;"><text y="40%">Images ' + lastisfit + '</text><text y="70%">to ' + document.getElementById('sele').value + ' ...</text></svg>' + "') 16 0, progress";
} else if (lastimagesetfor.replace('gmt','GMT').replace(/\~/g,'/').indexOf('/') != -1) {
return 'url(' + "'" + 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="126" height="48" viewport="0 0 100 100" style="border-radius:15px;background-color:rgba(255,255,0,0.5);fill:black;font-family:Verdana;font-size:9px;text-shadow:white 1px 1px;"><text y="40%">Images ' + lastisfit + '</text><text y="70%">to ' + document.getElementById('sele').value + ' ...</text></svg>' + "') 16 0, progress";
}
return defcurs;
}
function changemode(selo) {
var wasaddv='';
var dq=new Date();
if (selo.value != '') {
xxmode=selo.value;
if (selo.value.indexOf('/') != -1 && selo.value.substring(0,1) == selo.value.substring(0,1).toLowerCase()) {
wasaddv=document.getElementById('addthis').value; //alert('Addthis=' + document.getElementById('addthis').value);
if (yourtzlist.indexOf('>' + document.getElementById('sele').value + '<') != -1) {
document.getElementById('stz').innerHTML='';
document.getElementById('sele').style.cursor=inhousec('progress');
if (document.getElementById('sele').value.indexOf('/') != -1) {
document.getElementById('addthis').value='' + findTimeZoneOffset(document.getElementById('sele').value, new Date(dq.getFullYear(),dq.getMonth(),dq.getDate(),dq.getHours(),dq.getMinutes(),dq.getSeconds(),0)); //yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',')[eval(-1 + yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',').length)].split('"')[0];
} else {
document.getElementById('addthis').value='' + yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',')[eval(-1 + yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',').length)].split('"')[0];
}
}
document.getElementById('tzi').src=document.getElementById('tzi').src.split('?')[0] + '?tzexact=' + encodeURIComponent(mfd(selo.value.substring(0,1).toUpperCase() + selo.value.substring(1))) + '&tznickname=' + encodeURIComponent(selo.value.split('/')[eval(-1 + selo.value.split('/').length)].replace(/_/g,' ')) + avatar_at;
} else if (xxmode == 'GMT') {
wasaddv=document.getElementById('addthis').value; //alert('AdDthis=' + document.getElementById('addthis').value);
if (yourtzlist.indexOf('>' + document.getElementById('sele').value + '<') != -1) {
document.getElementById('stz').innerHTML='';
document.getElementById('sele').style.cursor=inhousec('progress');
if (document.getElementById('sele').value.indexOf('/') != -1) {
document.getElementById('addthis').value='' + findTimeZoneOffset(document.getElementById('sele').value, new Date(dq.getFullYear(),dq.getMonth(),dq.getDate(),dq.getHours(),dq.getMinutes(),dq.getSeconds(),0)); //yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',')[eval(-1 + yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',').length)].split('"')[0];
} else {
document.getElementById('addthis').value='' + yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',')[eval(-1 + yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',').length)].split('"')[0];
}
}
document.getElementById('tzi').src=document.getElementById('tzi').src.split('?')[0] + '?tzexact=' + encodeURIComponent(mfd(selo.value)) + '&tznickname=' + encodeURIComponent(selo.value.split('/')[eval(-1 + selo.value.split('/').length)].replace(/_/g,' ')) + avatar_at;
} else {
wasaddv=document.getElementById('addthis').value; //alert('AddThis=' + document.getElementById('addthis').value + ' ' + document.getElementById('sele').value);
if (yourtzlist.indexOf('>' + document.getElementById('sele').value + '<') != -1) {
document.getElementById('stz').innerHTML='';
document.getElementById('sele').style.cursor=inhousec('progress');
if (document.getElementById('sele').value.indexOf('/') != -1) {
document.getElementById('addthis').value='' + findTimeZoneOffset(document.getElementById('sele').value, new Date(dq.getFullYear(),dq.getMonth(),dq.getDate(),dq.getHours(),dq.getMinutes(),dq.getSeconds(),0)); //yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',')[eval(-1 + yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',').length)].split('"')[0];
} else {
document.getElementById('addthis').value='' + yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',')[eval(-1 + yourtzlist.split('>' + document.getElementById('sele').value + '<')[0].split(',').length)].split('"')[0];
}
}
document.getElementById('tzi').src=document.getElementById('tzi').src.split('?')[0] + '?tzexact=' + encodeURIComponent(mfd(selo.value)) + '&tznickname=' + encodeURIComponent(selo.value.split('/')[eval(-1 + selo.value.split('/').length)].replace(/_/g,' ')) + avatar_at;
}
if (window.parent && allowed) { // maybe get_tz.php supervising
if (parent.document.getElementById('tz')) {
if (parent.document.getElementById('tz').value != selo.value.split('/')[eval(-1 + selo.value.split('/').length)].replace(/\_/g,' ')) {
parent.document.getElementById('tz').value=selo.value.split('/')[eval(-1 + selo.value.split('/').length)].replace(/\_/g,' ');
if (parent.obit) {
parent.obit();
}
}
}
}
} else if (xxmode != 'GMT' && (document.URL.indexOf('mode=') != -1 || xxmode.indexOf('/') != -1)) {
location.href=document.URL.split('?')[0].split('#')[0];
}
document.getElementById('divideo').innerHTML="";
document.getElementById('divmap').innerHTML="";
if (document.getElementById('h1s').innerHTML.indexOf('jalt') != -1) { document.getElementById('h1s').innerHTML='Colour Wheel'; }
lookforstz();
alttrydone=true;
}
function eachsecond() {
var cmlist=[];
var dow=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
setTimeout(eachsecond, 1000);
context.clearRect(0,0,elem.width,elem.height);
if (document.getElementById('addthis').value == '-0.0') {
adate=new Date();
} else {
var now = new Date();
adate=new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds());
adate.setTime(adate.getTime() + (eval(document.getElementById('addthis').value) * 60 * 60 * 1000));
}
var his=eval('' + adate.getHours());
var mis=eval('' + adate.getMinutes());
var sis=eval('' + adate.getSeconds());
if (document.getElementById('ourcanvas')) {
if (window.opener) {
if (window.opener.document.getElementById('chour') && window.opener.document.getElementById('aanalogue')) {
if (window.opener.document.getElementById('aanalogue').outerHTML.indexOf(document.getElementById('sele').value) != -1) {
his=eval('' + window.opener.document.getElementById('chour').outerHTML.split(' title="')[1].split('"')[0]);
mis=eval('' + window.opener.document.getElementById('cminute').outerHTML.split(' title="')[1].split('"')[0]);
sis=eval('' + window.opener.document.getElementById('csecond').outerHTML.split(' title="')[1].split('"')[0]);
}
} else if (window.opener.document.getElementById('chour') && window.opener.document.getElementById('adigital')) {
if (window.opener.document.getElementById('adigital').outerHTML.indexOf(document.getElementById('sele').value) != -1) {
his=eval('' + window.opener.document.getElementById('chour').outerHTML.split(' title="')[1].split('"')[0]);
mis=eval('' + window.opener.document.getElementById('cminute').outerHTML.split(' title="')[1].split('"')[0]);
sis=eval('' + window.opener.document.getElementById('csecond').outerHTML.split(' title="')[1].split('"')[0]);
}
} else if (window.opener.document.getElementById('sclock')) {
if (window.opener.document.getElementById('sclock').outerHTML.indexOf(document.getElementById('sele').value) != -1) {
cmlist=window.opener.document.getElementById('sclock').outerHTML.replace(':/','').split(':');
if (eval('' + cmlist.length) >= 3) {
his=eval('' + cmlist[0].slice(-2));
mis=eval('' + cmlist[1]);
sis=eval('' + cmlist[2].substring(0,2));
}
}
}
}
if (his >= 0 && his < 12) {
if (('' + document.getElementById('ourcanvas').style.backgroundColor) != 'white') {
document.getElementById('ourcanvas').style.backgroundColor='white';
}
} else {
if (('' + document.getElementById('ourcanvas').style.backgroundColor) != 'darkblue') {
document.getElementById('ourcanvas').style.backgroundColor='darkblue';
}
}
}
var ssuff='';
if (('' + sis).indexOf('.') != -1) { ssuff='.' + ('' + sis).split('.')[1]; }
hang=eval(eval(270 + Math.round(eval(eval(his % 12) + eval(mis / 60) + eval(sis / 3600)) * 30)) % 360);
mang=eval(eval(270 + Math.round(eval(mis + eval(sis / 60)) * 6)) % 360);
sang=eval(eval(270 + Math.round(sis * 6)) % 360);
elem.title=dow[eval('' + adate.getDay())] + ', ' + ('0' + adate.getDate()).slice(-2) + '-' + ('0' + eval(1 + eval('' + adate.getMonth()))).slice(-2) + '-' + ('' + adate.getFullYear()) + ' ' + ('0' + his).slice(-2) + ':' + ('0' + mis).slice(-2) + ':' + ('0' + sis).split('.')[0].slice(-2) + ssuff;
document.getElementById('dc').title=elem.title; //dow[eval('' + adate.getDay())] + ', ' + ('0' + adate.getDate()).slice(-2) + '-' + ('0' + eval(1 + eval('' + adate.getMonth()))).slice(-2) + '-' + ('' + adate.getFullYear()) + ' ' + ('0' + his).slice(-2) + ':' + ('0' + mis).slice(-2) + ':' + ('0' + sis).split('.')[0].slice(-2) + ssuff;
//document.title='' + his + ':' + mis + ':' + sis + ' ' + hang + ';' + mang + ';' + sang;
if (document.getElementById('sele').value != '' && paths.length == 0) {
for (var ii=0; ii<360; ii++) { //360
paths.push(new Path2D());
}
}
if (avatar_at == '') {
context.globalAlpha = 1.0;
} else {
context.globalAlpha = 0.6;
}
context.beginPath();
context.arc(Math.round(eval(25 + eval(cwidth / 2))), Math.round(eval(25 + eval(cheight / 2))), eval(rnum * Math.abs(factor)), 0, alldegree);
//context.fillStyle = "#ffffff"; //'#40FF20';
if (his >= 12) {
context.fillStyle = "#f2f2f2"; //'#40FF20';
} else {
context.fillStyle = "#f9f9f9"; //'#40FF20';
}
context.fill();
//alert('' + context.lineWidth);
context.lineCap = "round";
context.lineJoin = "round";
for (var i=0; i<360; i++) { //360
//context.font = cf;
//context.strokeStyle = '#FF0000';
cone=letter[Math.floor(Math.random() * letter.length)];
ctwo=letter[Math.floor(Math.random() * letter.length)];
cthree=letter[Math.floor(Math.random() * letter.length)];
//context.fillStyle = "#" + cone + "0" + ctwo + "0" + cthree + "0"; //'#40FF20';
//context.fill();
if (i == hang || i == mang || i == sang) {
if (i == hang) {
context.beginPath();
context.moveTo(Math.round(eval(25 + eval(cwidth / 2))), Math.round(eval(25 + eval(cheight / 2))));
context.globalAlpha = 1.0;
context.strokeStyle = "#000000"; //'#40FF20';
context.lineWidth=eval(2 + eval(bthickness));
context.lineTo(Math.round(eval(25 + eval(cwidth / 2)) + eval(eval(rnum * Math.abs(hfactor)) * (Math.cos(onedegree * i)))), Math.round(eval(25 + eval(cheight / 2)) + eval(eval(rnum * Math.abs(hfactor)) * (Math.sin(onedegree * i)))));
}
if (i == sang) {
context.beginPath();
context.moveTo(Math.round(eval(25 + eval(cwidth / 2))), Math.round(eval(25 + eval(cheight / 2))));
context.globalAlpha = 1.0;
context.strokeStyle = "#ff0000"; //'#40FF20';
context.lineWidth=eval(bthickness);
context.lineTo(Math.round(eval(25 + eval(cwidth / 2)) + eval(eval(rnum * Math.abs(sfactor)) * (Math.cos(onedegree * i)))), Math.round(eval(25 + eval(cheight / 2)) + eval(eval(rnum * Math.abs(sfactor)) * (Math.sin(onedegree * i)))));
}
if (i == mang) {
context.beginPath();
context.moveTo(Math.round(eval(25 + eval(cwidth / 2))), Math.round(eval(25 + eval(cheight / 2))));
context.globalAlpha = 1.0;
context.strokeStyle = "#000000"; //'#40FF20';
context.lineWidth=eval(1 + eval(bthickness));
context.lineTo(Math.round(eval(25 + eval(cwidth / 2)) + eval(eval(rnum * Math.abs(mfactor)) * (Math.cos(onedegree * i)))), Math.round(eval(25 + eval(cheight / 2)) + eval(eval(rnum * Math.abs(mfactor)) * (Math.sin(onedegree * i)))));
}
context.closePath();
context.stroke();
//alert('' + cone + ctwo + cthree);
context.beginPath();
context.lineWidth=eval(bthickness);
context.moveTo(Math.round(eval(25 + eval(cwidth / 2))), Math.round(eval(25 + eval(cheight / 2))));
context.lineTo(Math.round(eval(25 + eval(cwidth / 2)) + eval(eval(rnum * Math.abs(factor)) * (Math.cos(onedegree * i)))), Math.round(eval(25 + eval(cheight / 2)) + eval(eval(rnum * Math.abs(factor)) * (Math.sin(onedegree * i)))));
context.closePath();
if (eval((i + 1) % 30) == 1) {
context.globalAlpha = 0.5;
} else {
context.globalAlpha = 0.2;
}
context.strokeStyle = "#" + cone + "0" + ctwo + "0" + cthree + "0"; //'#40FF20';
context.stroke();
} else {
//alert('' + cone + ctwo + cthree);
context.beginPath();
context.lineWidth=eval(bthickness);
context.moveTo(Math.round(eval(25 + eval(cwidth / 2))), Math.round(eval(25 + eval(cheight / 2))));
context.lineTo(Math.round(eval(25 + eval(cwidth / 2)) + eval(eval(rnum * Math.abs(factor)) * (Math.cos(onedegree * i)))), Math.round(eval(25 + eval(cheight / 2)) + eval(eval(rnum * Math.abs(factor)) * (Math.sin(onedegree * i)))));
context.closePath();
if (eval((i + 1) % 30) == 1) {
context.globalAlpha = 0.5;
} else {
context.globalAlpha = 0.2;
}
context.strokeStyle = "#" + cone + "0" + ctwo + "0" + cthree + "0"; //'#40FF20';
context.stroke();
}
}
context.globalAlpha = 1.0;
context.beginPath();
context.arc(Math.round(eval(25 + eval(cwidth / 2))), Math.round(eval(25 + eval(cheight / 2))), eval(rnum * Math.abs(factor)), 0, alldegree);
if (his >= 12) {
context.strokeStyle = "#000000"; //'#40FF20';
} else {
context.strokeStyle = "#ffff00"; //'#40FF20';
}
context.stroke();
//setTimeout(eachsecond, 1000);
}
… in …
- the changed PHP helper supervisor svg_clock.php … and …
- the changed Colour Wheel colour_wheel.html web application
… regarding SVG Network Clock we think you should (re)try.
Previous relevant SVG Network Digital and Analogue Clock Interfacing Tutorial is shown below.
We’re making use of an SVG “a” (tag) link methodology to interface …
- SVG Network Digital and Analogue Clocks Tutorial‘s SVG digital and/or analogue clock web application … now interfacing to …
… timezone friendly, including the GMT timezone, improved product.
New to us, as previously mentioned, was the use of SVG “a” links in …
- the changed PHP helper supervisor svg_clock.php use of SVG snippet …
<a data-target="nextif" target="_blank" title="Click for Colour Wheel time" data-href="//www.rjmprogramming.com.au/HTMLCSS/colour_wheel.html<?php $modebit=''; if (isset($_GET['timezone'])) { $modebit='?mode=' . str_replace('GjunkMT','Europe/London',str_replace(' ','_',str_replace('+','_',urldecode($_GET['timezone'])))); } echo $modebit; ?>" onclick="window.open('//www.rjmprogramming.com.au/HTMLCSS/colour_wheel.html<?php $modebit=''; if (isset($_GET['timezone'])) { $modebit='?mode=' . str_replace('GjunkMT','Europe/London',str_replace(' ','_',str_replace('+','_',urldecode($_GET['timezone'])))); } echo $modebit; ?>','_blank','left=600,top=30,width=700,height=800');"><text id="sclock" x="10" y="30" fill="green" class="Ggggg" text-anchor="left">
Time goes here
</text></a>
<g>
<a data-target="nextif" target="_blank" title="Click for Colour Wheel time" data-href="//www.rjmprogramming.com.au/HTMLCSS/colour_wheel.html<?php $modebit=''; if (isset($_GET['timezone'])) { $modebit='?mode=' . str_replace('GjunkMT','Europe/London',str_replace(' ','_',str_replace('+','_',urldecode($_GET['timezone'])))); } echo $modebit; ?>" onclick="window.open('//www.rjmprogramming.com.au/HTMLCSS/colour_wheel.html<?php $modebit=''; if (isset($_GET['timezone'])) { $modebit='?mode=' . str_replace('GjunkMT','Europe/London',str_replace(' ','_',str_replace('+','_',urldecode($_GET['timezone'])))); } echo $modebit; ?>','_blank','left=600,top=30,width=700,height=800');">
<circle id="cclock" cx="200" cy="200" r="150" fill="transparent">
<title></title>
</circle></a>
- the changed HTML supervisor svg_clock.html live run … of …
- the changed PHP (Digital Clock) content helper cldate.php
- >the changed Colour Wheel colour_wheel.html web application
… that we hope you try.
Previous relevant SVG Network Digital and Analogue Clocks Tutorial is shown below.
The SVG based clock of SVG Network Digital and Analogue Clock Local Time Tutorial days was all fine and good, but on a revisit, we felt compelled to make this changed HTML supervisor svg_clock.html live run be capable of tabular side by side “clocks” so that you can get that feeling with the web application of the comparison of timezones, perhaps in a …
- timezone time of set off point … compared, and next to a clock with …
- timezone time of destination point
… which might be useful before ringing somebody or getting your stomach ready for the jetlag to come!
Once there getting this going, yes, we felt compelled to want to offer the user the chance to ( given global var scalar=1.0; ) …
- toggle visibility of left hand clock …
function disappearmy(obis) {
var disp='none';
if (obis.innerHTML != 'X') { disp='table-cell'; obis.innerHTML='X'; } else { obis.innerHTML='O'; }
document.getElementById('mytd').style.display=disp;
}
function tdisappearmy(obis) {
var disp='none';
if (obis.innerHTML != 'X') { disp='table-cell'; obis.innerHTML='X'; } else { obis.innerHTML='O'; }
document.getElementById('mytd').style.display=disp;
}
… - allow table cell widths to lessen …
function lessw() {
var rectis=document.getElementById('mytd').getBoundingClientRect();
document.getElementById('mytd').style.width='' + eval(-5 + eval('' + ('' + rectis.width).replace('px',''))) + 'px';
document.getElementById('nexttd').style.width='' + eval(-5 + eval('' + ('' + rectis.width).replace('px',''))) + 'px';
}
function tlessw() {
var rectis=top.document.getElementById('mytd').getBoundingClientRect();
document.getElementById('mytd').style.width='' + eval(-5 + eval('' + ('' + rectis.width).replace('px',''))) + 'px';
document.getElementById('nexttd').style.width='' + eval(-5 + eval('' + ('' + rectis.width).replace('px',''))) + 'px';
scalar-=0.1;
top.document.body.style.transform='scale(' + scalar + ')';
}
… - allow table cell widths to expand …
function morew() {
//alert(1);
var rectis=document.getElementById('mytd').getBoundingClientRect();
document.getElementById('mytd').style.width='' + eval(5 + eval('' + ('' + rectis.width).replace('px',''))) + 'px';
document.getElementById('nexttd').style.width='' + eval(5 + eval('' + ('' + rectis.width).replace('px',''))) + 'px';
}
function tmorew() {
//alert(11);
var rectis=document.getElementById('mytd').getBoundingClientRect();
document.getElementById('mytd').style.width='' + eval(5 + eval('' + ('' + rectis.width).replace('px',''))) + 'px';
document.getElementById('nexttd').style.width='' + eval(5 + eval('' + ('' + rectis.width).replace('px',''))) + 'px';
//alert(document.getElementById('mytd').style.width);
scalar+=0.1;
top.document.body.style.transform='scale(' + scalar + ')';
}
… - toggle visibility of right hand clock …
function disappearnext(obis) {
var disp='none';
if (obis.innerHTML != 'X') { disp='table-cell'; obis.innerHTML='X'; } else { obis.innerHTML='O'; }
document.getElementById('nexttd').style.display=disp;
}
function tdisappearnext(obis) {
var disp='none';
if (obis.innerHTML != 'X') { disp='table-cell'; obis.innerHTML='X'; } else { obis.innerHTML='O'; }
document.getElementById('nexttd').style.display=disp;
}
… as you would, if you’re “watching the clock”?!
Previous relevant SVG Network Digital and Analogue Clock Local Time Tutorial is shown below.
Off the list of TimeZones we offered on the first dropdown of SVG Network Digital and Analogue Clock Daylight Saving Tutorial‘s web application, you may have noticed one glaring omission. That’s right, we were missing …
- local time … and today we remedy that, as well as …
- improve a loading logic weakness that could result in our SVG object element returning null … and …
- add an onhover Country Name piece of display data
Leaving out the fairly straightforward last change above, let’s go into more detail regarding those other improvements.
- local time …
the issue here being that a “local time” is awkward, but possible (thanks to this useful link) in serverside PHP …
<?php
if (strpos(('' . $_SERVER['QUERY_STRING']), "localtime") !== false) {
echo "<html><body><div id=mydiv></div><script type='text/javascript'>
var asuff='" . $midbit . $csuff . "';
var adate = new Date();
var dow=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
var his=eval('' + adate.getHours());
var mis=eval('' + adate.getMinutes());
var sis=eval('' + adate.getSeconds());
var ssuff='';
if (('' + adate).indexOf(' GMT') != -1) { ssuff=' GMT' + ('' + adate).split(' GMT')[1]; }
if (1 == 1) {
document.getElementById('mydiv').innerHTML=dow[eval('' + adate.getDay())] + ' ' + ('0' + his).slice(-2) + ':' + ('0' + mis).slice(-2) + ':' + ('0' + sis).split('.')[0].slice(-2) + ' ' + ('0' + adate.getDate()).slice(-2) + ' ' + ('0' + eval(1 + eval('' + adate.getMonth()))).slice(-2).replace('01','Jan').replace('02','Feb').replace('03','Mar').replace('04','Apr').replace('05','May').replace('06','Jun').replace('07','Jul').replace('08','Aug').replace('09','Sep').replace('10','Oct').replace('11','Nov').replace('12','Dec') + ' ' + ('' + adate.getFullYear()) + ' ' + ssuff + asuff;
} else {
document.write(dow[eval('' + adate.getDay())] + ' ' + ('0' + his).slice(-2) + ':' + ('0' + mis).slice(-2) + ':' + ('0' + sis).split('.')[0].slice(-2) + ' ' + ('0' + adate.getDate()).slice(-2) + ' ' + ('0' + eval(1 + eval('' + adate.getMonth()))).slice(-2).replace('01','Jan').replace('02','Feb').replace('03','Mar').replace('04','Apr').replace('05','May').replace('06','Jun').replace('07','Jul').replace('08','Aug').replace('09','Sep').replace('10','Oct').replace('11','Nov').replace('12','Dec') + ' ' + ('' + adate.getFullYear()) + ' ' + ssuff + asuff);
}
</script></body></html>";
}
?>
… but patently more suited to the Javascript available to us with the “HTML supervisor” client facing web application component as per …
var loct='';
var adate = new Date();
var dow=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
var his=eval('' + adate.getHours());
var mis=eval('' + adate.getMinutes());
var sis=eval('' + adate.getSeconds());
var ssuff='';
if (('' + adate).indexOf(' GMT') != -1) { ssuff=' GMT' + ('' + adate).split(' GMT')[1]; }
var curts=dow[eval('' + adate.getDay())] + ' ' + ('0' + his).slice(-2) + ':' + ('0' + mis).slice(-2) + ':' + ('0' + sis).split('.')[0].slice(-2) + ' ' + ('0' + adate.getDate()).slice(-2) + ' ' + ('0' + eval(1 + eval('' + adate.getMonth()))).slice(-2).replace('01','Jan').replace('02','Feb').replace('03','Mar').replace('04','Apr').replace('05','May').replace('06','Jun').replace('07','Jul').replace('08','Aug').replace('09','Sep').replace('10','Oct').replace('11','Nov').replace('12','Dec') + ' ' + ('' + adate.getFullYear()) + ' ' + ssuff;
var loct='';
if (tz.indexOf('localtime') != -1) { loct=curts; }
… and, as such, to continue the process every second to update our clock, we set in play a navigational technique we’d never put into play before that we can remember, that being …
// Rather than reloading content in an HTML iframe element via [iFrameElementObject].src=[URLtoUseAsContentForTheIframe]; ... for SVG object ID=myclock we ...
function getmelt(iois) {
if (iois != null) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
if (tz.indexOf('localtime') != -1) {
if (aconto.body.innerHTML.indexOf('</div>') != -1) {
loct=aconto.body.innerHTML.split('</div>')[0].split('>')[eval(-1 + aconto.body.innerHTML.split('</div>')[0].split('>').length)];
} else {
loct=aconto.body.innerHTML;
}
if (uprefix.indexOf('&both=') > 0) {
uprefix='&both=' + uprefix.split('&both=')[1];
} else if (uprefix.indexOf('&analogue=') > 0) {
uprefix='&analogue=' + uprefix.split('&analogue=')[1];
} else if (uprefix.indexOf('&y=') > 0) {
uprefix='&y=' + uprefix.split('&y=')[1];
}
document.getElementById('myclock').data="svg_clock.php?timezone=" + encodeURIComponent(tz + loct) + uprefix;
setTimeout(morelt, 1000);
}
}
}
}
}
function morelt() {
document.getElementById('loces').src='cldate.php?localtime=' + Math.floor(Math.random() * 198765433);
}
// ... in an onload event function for an HTML iframe element, presenting "enough of a flag" to tell the other web application components we are wanting local time
… the downside being that the SVG tends to flash a bit (with activity) - improve a loading logic weakness that could result in our SVG object element returning null …
we actually had flawed code up until today not doing its job, but today the “HTML Supervisor”‘s “setTimeout(checkmyobject,4000);” checker of existence of the SVG object is better for …
function checkmyobject() {
if (!document.getElementById('myclock')) {
window.location.reload(true);
} else {
var t=document.querySelector("#myclock");
var htmlDocument=t.contentDocument;
if (('' + htmlDocument).replace(/\<p\>/g,'').replace(/\<\/p\>/g,'').replace(String.fromCharCode(10),'').replace('null','') == '') { window.location.reload(true); }
}
}
… in its approach to, for the first time we can remember doing, refreshing the webpage programmatically via “window.location.reload(true);” to eventually get such failed initially loaded SVG object data to succeed
… again, you can see within …
- SVG graphics display … calling on …
- the changed HTML supervisor svg_clock.html live run … of …
- the changed PHP helper supervisor svg_clock.php … of …
- the changed PHP (Digital Clock) content helper cldate.php
Previous relevant SVG Network Digital and Analogue Clock Daylight Saving Tutorial is shown below.
We were pondering how best to “value add” onto the web application of our recent SVG Network Digital and Analogue Clock Tutorial when we remembered that the “star codeline” of that project’s “PHP (Digital Clock) content helper” was …
<?php
$thedate=date('l H:i:s d M Y e');
?>
… and we leave this to be …
<?php
$thedate=date('l H:i:s d M Y e I~') . $emflag;
?>
… after today’s two streams of work …
- flag Daylight Saving clock times having noticed researching PHP date function’s “date ( string $format [, int $timestamp = time() ] ) : string” first format parameter the interesting switch …
format character Description Example returned values I (capital i) Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise. … we could use …
<?php
$midbit="";
if (isset($_GET['timezone'])) {
if (str_replace("+"," ",urldecode($_GET['timezone'])) == "") {
date_default_timezone_set("UTC");
} else {
$midbit="http://www.timezoneconverter.com/cgi-bin/zoneinfo?tz=" . urlencode(str_replace("+","_",urldecode($_GET['timezone'])));
date_default_timezone_set(str_replace("+"," ",urldecode($_GET['timezone'])));
}
} else {
date_default_timezone_set("UTC");
}
$thedate=date('l H:i:s d M Y e I~') . $emflag;
if (strpos($thedate, " 1~") !== false) {
$thedate=str_replace(" 1~", " ", $thedate);
} else if (strpos($thedate, " 0~") !== false) {
$midbit="";
$thedate=str_replace(" 0~", " ", $thedate);
}
if (isset($_GET['both'])) {
echo $thedate . $midbit . '</text>' . $midbit . '<circle id="cclock" cx="200" cy="200" r="150" fill="navy"/><text>';
} else if (isset($_GET['analogue'])) {
echo $thedate . $midbit . '</text>' . $midbit . '<circle id="cclock" cx="200" cy="200" r="150" fill="navy"/><text>';
} else {
echo $thedate . $midbit;
}
?>… as a means by which its compadre web application components can be helped out recognizing Daylight Saving clock (time) scenarios
- add some Internationalization improvement by adding some emoji flag improvements getting to this project’s “PHP (Digital Clock) content helper” as that $emflag variable as per …
<?php
$emflag="";
if (isset($_GET['emflag'])) {
$emflag=" " . urldecode($_GET['emflag']);
}
?>… and instigated back at the HTML supervisor as per …
if (!String.fromCodePoint) { // thanks to http://xahlee.info/js/js_unicode_code_point.html
// ES6 Unicode Shims 0.1 , © 2012 Steven Levithan , MIT License
String.fromCodePoint = function fromCodePoint () {
var chars = [], point, offset, units, i;
for (i = 0; i < arguments.length; ++i) {
point = arguments[i];
offset = point - 0x10000;
units = point > 0xFFFF ? [0xD800 + (offset >> 10), 0xDC00 + (offset & 0x3FF)] : [point];
chars.push(String.fromCharCode.apply(null, units));
}
return chars.join("");
}
}
// Thanks to https://stackoverflow.com/questions/35948102/how-to-create-a-border-bottom-in-css-using-a-text-character-such-as-a-dash-lett
var es="<style> " + String.fromCharCode(10);
es+="h4 { " + String.fromCharCode(10);
es+="position:relative; " + String.fromCharCode(10);
es+="overflow:hidden; " + String.fromCharCode(10);
es+=" padding-bottom:0.5em; " + String.fromCharCode(10);
es+=" } " + String.fromCharCode(10);
es+="h4:after { " + String.fromCharCode(10);
es+=" position:absolute; " + String.fromCharCode(10);
es+=" line-height:0.5em; " + String.fromCharCode(10);
es+=" bottom:0; " + String.fromCharCode(10);
es+=" left:0; " + String.fromCharCode(10);
es+=" right:0; " + String.fromCharCode(10);
es+=" white-space:pre; " + String.fromCharCode(10);
es+=" content:'- - - - - - - - - - - - - - - - '; " + String.fromCharCode(10);
es+=" text-shadow: 0.7em 0 transparent, 1.4em 0 transparent; " + String.fromCharCode(10);
es+=" } " + String.fromCharCode(10);
es+=" " + String.fromCharCode(10);
es+=" hr + h4:after { " + String.fromCharCode(10);
es+=" text-shadow: 0.7em 0.2em transparent, 1.4em -0.2em transparent; " + String.fromCharCode(10);
es+=" } " + String.fromCharCode(10);
es+=" </style> " + String.fromCharCode(10);
var froms='youllneverfindthis';
var tos='';
var prevfromefs='youllneverfindthis';
var fromefs='youllneverfindthis';
var toefs='';
var isotwois='';
var flagbit='';
var lri="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var dri=["127462","127463","127464","127465","127466","127467","127468","127469","127470","127471","127472","127473","127474","127475","127476","127477","127478","127479","127480","127481","127482","127483","127484","127485","127486","127487"];
var ourtzlist="<option value=\"Africa/Abidjan\" data-geo=\"5.31666,-4.03334,GMT,CI,+0\">Africa/Abidjan</option><option value=\"Africa/Accra\" data-geo=\"5.55,-0.21667,GMT,GH,+0\">Africa/Accra</option><option value=\"Africa/Addis_Ababa\" data-geo=\"9.03333,38.7,EAT,ET,+3\">Africa/Addis_Ababa</option><option value=\"Africa/Algiers\" data-geo=\"36.78333,3.05,CET,DZ,+1\">Africa/Algiers</option><option value=\"Africa/Asmara\" data-geo=\"15.33333,38.88333,EAT,ER,+3\">Africa/Asmara</option><option value=\"Africa/Bamako\" data-geo=\"12.65,-8,GMT,ML,+0\">Africa/Bamako</option>"]; // etcetera etcetera etcetera
var parts;
var tz=location.search.split('timezone=')[1] ? decodeURIComponent(location.search.split('timezone=')[1].split('&')[0]).replace(/\+/g,' ') : '';
if (tz != '') { froms=location.search.split('timezone=')[1].split('&')[0]; parts=ourtzlist.split(decodeURIComponent(froms)); if (parts.length > 1) { isotwois=parts[1].split(',')[3]; if (isotwois.replace(/\?/g,'').length == 2) { if (document.URL.indexOf('?') != -1) { fromefs=encodeURIComponent(orccflag(isotwois.toUpperCase())); flagbit='&emflag=' + fromefs; } else { fromefs=encodeURIComponent(orccflag(isotwois.toUpperCase())); flagbit='?emflag=' + fromefs; } } } }
var uprefix=('?' + (document.URL + flagbit + '?#').split('#')[0].split('?')[1]).replace('?','&').replace('timezone=','prtimezoneev=').replace('emflag=','premflagev=').replace(froms,tos).replace(fromefs,toefs).replace('prtimezoneev=&','').replace('premflagev=&','');
function orccflag(thiscc) {
var ccsuff='', ccchar=' ', cde='', sfcp='';
for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
sfcp+=String.fromCodePoint(eval('' + dri[eval('' + lri.indexOf(ccchar))]));
ccsuff+=cde + ('' + dri[eval('' + lri.indexOf(ccchar))]); //'' + dri[eval('' + lri.indexOf(ccchar))] + ';';
cde='.';
}
es=es.replace(/\-\ \ \ \ \ /g, sfcp + ' ');
return sfcp; //ccsuff;
}
… and then later within the document.body part of the webpage that global variable es (helping create an emoji (flag) border) comes into play …
<script type='text/javascript'>
if (tz != "") {
document.write("<h1 id=myh1>SVG Network Clock</h1><h3>RJM Programming - January, 2020</h3><h4>Thanks to The PHP Anthology Volume II: Applications by Harry Fuecks</h4><p>The <select id=mysel onchange=gonext(this.value);>" + ("<option value=''>GMT</option>" + tzlist).replace('>' + tz + '<',' selected>' + tz + '<') + "</select> <select style='display:inline-block;' onchange=\"location.href=(document.URL.replace('analogue=','x=').replace('both=','y=') + ('&' + this.value + '=y').replace('&=y','')).replace('.html&','.html?');\"><option value=''>digital clock</option><option value=analogue" + analoguesuffix + ">analogue clock</option><option value=both" + bothsuffix + ">digital and analogue clock</option></select> sponsored by SVG is<br><hr style='height:3px;' title='Click here for any Daylight Saving Time information' onclick=\"window.open('http://www.timezoneconverter.com/cgi-bin/zoneinfo?tz=" + encodeURIComponent(tz) + "','_blank','top=50,left=50,width=500,height=500');\"><br><object id=myclock data='svg_clock.php?timezone=" + encodeURIComponent(tz) + uprefix + "' width='1200' height='530' type='image/svg+xml' /></p>" + es);
}
</script>
… you can see within …
- SVG graphics display … calling on …
- the changed HTML supervisor svg_clock.html live run … of …
- the changed PHP helper supervisor svg_clock.php … of …
- the changed PHP (Digital Clock) content helper cldate.php
Previous relevant SVG Network Digital and Analogue Clock Tutorial is shown below.
The recent SVG Network Clock Primer Tutorial work created …
- an SVG (text element) based network Digital clock … and today we extend functionality to add …
- an SVG (circle and line element) based network Analogue clock
… and allow for the SVG text element content also be a tooltip for the SVG circle element via SVG title subelement …
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt);">
<defs>
<radialGradient id="navyGradient"
cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
<stop offset="0%" stop-color="navy"/>
<stop offset="100%" stop-color="purple"/>
</radialGradient>
<radialGradient id="yellowGradient"
cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
<stop offset="0%" stop-color="yellow"/>
<stop offset="100%" stop-color="orange"/>
</radialGradient>
</defs>
<text id="sclock" x="30" y="30" fill="green" class="Rrrrr" text-anchor="left">
Time goes here
</text>
<g>
<circle id="cclock" cx="200" cy="200" r="150" fill="transparent">
<title></title>
</circle>
<line id="chour" x1="200" y1="200" x2="200" y2="100" style="stroke:transparent;stroke-width:3" />
<line id="cminute" x1="200" y1="200" x2="340" y2="200" style="stroke:transparent;stroke-width:2" />
<line id="csecond" x1="200" y1="200" x2="200" y2="320" style="stroke:transparent;stroke-width:1" />
</g>
</svg>
… referenced via …
var sclock;
var cclock, cclocktitle;
var chour;
var cminute;
var csecond;
function init(evt) {
if (window.svgDocument == null) {
svgDocument = evt.target.ownerDocument;
}
sclock = svgDocument.getElementById("sclock").firstChild;
cclock = svgDocument.getElementById("cclock");
cclocktitle = svgDocument.getElementById("cclock").firstElementChild;
chour = svgDocument.getElementById("chour");
cminute = svgDocument.getElementById("cminute");
csecond = svgDocument.getElementById("csecond");
gettime();
}
function gettime() {
getURL('<?php echo $turl; ?>', showtime);
}
function showtime(rsp) {
var tstmp=rsp.content.split('<')[0];
var hmsbit='';
if (rsp.content.indexOf('<circle') != -1) {
cclocktitle.innerHTML=tstmp;
hmsbit=eachsecond(tstmp.split(' ')[1]);
if (eval(tstmp.split(' ')[1].split(':')[0]) >= 12) {
cclock.style.fill = 'url(#navyGradient)'; // 'navy';
chour.style.stroke = 'white';
cminute.style.stroke = 'white';
csecond.style.stroke = 'white';
} else {
cclock.style.fill = 'url(#yellowGradient)'; // 'yellow';
chour.style.stroke = 'navy';
cminute.style.stroke = 'navy';
csecond.style.stroke = 'navy';
}
chour.setAttribute('x2', hmsbit.split(',')[0]);
chour.setAttribute('y2', hmsbit.split(',')[1]);
cminute.setAttribute('x2', hmsbit.split(',')[2]);
cminute.setAttribute('y2', hmsbit.split(',')[3]);
csecond.setAttribute('x2', hmsbit.split(',')[4]);
csecond.setAttribute('y2', hmsbit.split(',')[5]);
}
if (document.URL.indexOf('analogue=') != -1) {
sclock.data = ''; //rsp.content.split('<')[0];
} else {
sclock.data = tstmp; //rsp.content.split('<')[0];
}
setTimeout('gettime()', 1000);
}
… all changes regarding the svg_clock.php of SVG Network Clock web application of …
- SVG graphics display … calling on …
- the changed HTML supervisor svg_clock.html live run … of …
- the changed PHP helper supervisor svg_clock.php … of …
- the changed PHP (Digital Clock) content helper cldate.php
Previous relevant SVG Network Clock Primer Tutorial is shown below.
Another approach to a Digital Clock web application is off and running today, reminiscent of some of the concepts in Digital Clock Styling for Daylight Saving Tutorial. Today’s difference though is a significant one involving …
- SVG graphics display … calling on …
- HTML supervisor svg_clock.html … of …
- PHP helper supervisor svg_clock.php … of …
- PHP (Digital Clock) content helper cldate.php
… and we’d like to thank The PHP Anthology (Volume II: Applications) by Harry Fuecks (ISBN: 0-9579218-4-5) for the inspiration of methodologies used. We are encouraged to move on from this “proof of concept” beginning because we are enthusiastic to build on the very simple SVG text element beginnings with more advanced work in future blogs.
Feel free to try it yourself here or look below at (initially) a GMT digital clock …
Previous relevant Digital Clock Styling for Daylight Saving Tutorial is shown below.
The Daylight Saving Time web application we talked about with Daylight Saving Time TimeZone Emoji Tutorial starts out showing a digital clock displaying the time at various Timezone Places around the world. It occurred to us, this morning, looking over at the alarm clock (also digital) that it would be interesting to recreate that look, at least a bit. But what immediately seemed appealing was not any photography or media based work, but the really simple CSS idea to make use of …
- HTML table elements containing …
- two tr row elements per numeral (or digit) of time to define … each row containing a …
- single td cell with the content (ie. non-breaking space) … but working to define the numbers via the correct combinations of use of …
- style=’border-top:28px solid red;’
- style=’border-bottom:28px solid red;’
- style=’border-left:28px solid red;’
- style=’border-right:28px solid red;’
… for all the td cells involved
… reminding me of how incredible it is that just a few lines can be used by artists to have a viewer know exactly what they were depicting. More with faces, mind you, but even so, is an interesting part of how our brains work.
The code changes just involve a new array in the Javascript as per …
var dcborder=[
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-left:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid red;border-left:28px solid red;border-right:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid transparent;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid transparent;border-right:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid red;border-top:28px solid red;border-left:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-top:28px solid red;border-right:28px solid red;border-bottom:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid transparent;border-left:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid transparent;border-right:28px solid red;border-top:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-left:28px solid red;'> </td></tr><tr><td style='border-right:28px solid red;border-top:28px solid red;border-bottom:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-left:28px solid red;'> </td></tr><tr><td style='border-right:28px solid red;border-top:28px solid red;border-bottom:28px solid red;border-left:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-right:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-left:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid red;border-top:28px solid red;border-left:28px solid red;border-right:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-left:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid red;border-top:28px solid red;border-right:28px solid red;'> </td></tr></table>"
];
… and modified code that writes out the digital clock numerals …
function dc(chuh, subclass) {
var retval="";
if (subclass == 'hour' && chuh.length == 1) chuh='0' + chuh;
for (var iy=0; iy<chuh.length; iy++) {
if (document.URL.indexOf('dcviaborder=') != -1) {
retval+='<td>' + dcborder[eval('' + chuh.substring(iy, eval(1 + iy)))] + '</td>';
} else {
retval+='<td><h1 class="a' + chuh.substring(iy, eval(1 + iy)) + ' ' + subclass + '"></h1></td>';
}
}
return retval;
}
… and the HTML means by which the user can toggle between the two digital clock looks …
<h1 align='center'>Daylight Saving Time Information <a style='text-decoration:underline;cursor:pointer;' onclick=" if (document.URL.indexOf('dcviaborder=') != -1) { location.href=document.URL.replace('dcviaborder=','dcviaXborder='); } else { location.href=(document.URL + '&dcviaborder=y').replace('.html&','.html?'); }" title="Toggle look of Digital Clock">💞</a> RJM Programming - September, 2015</h1>
You can see this new digital clock look and contrast it to the old digital clock look with the changes we made to daylight_saving_time.html for your perusal.
Previous relevant Daylight Saving Time TimeZone Emoji Tutorial is shown below.
The last time we added a change to our Daylight Saving TimeZone Information web application was during our Other Side of the World Google Chart Tutorial work, and then, so many things were going on with interfacing and integration we didn’t really revisit the Daylight Saving TimeZone Information web application for itself, as it is so good to do every now and then to …
- incorporate new things you’ve learnt
- check on functionality that has fallen by the wayside (or, sin of all sins, never got to the wayside)
Our recent perusals around the “wooooooooorrrrllldd” of CSS3 reminded us of the power of CSS Selectors, especially the ones that came in with CSS3. The “two out of three” that we use today are described on today’s tutorial picture as well as we’d want to do here … so here goes …
Featuring
CSS3 Selectors for element attributes
^= (starts with)
*= (contains)
$= (ends with … not used)
Thanks to
When you try to memorize syntax do you look for “linkages”? Yes, you can find anything on the net. But seriously, this CSS syntax can be remembered because it uses the characters of a lot of RegEx wildcarding systems. Another kind of “linkage” we saw between this CSS(3) Selector functionality, and where it would be useful, was that we’d noted that TimeZone identifiers have a name, and generally they take a form …
Region/Placename
… and that Region (plus or minus the “/“) felt to us like a good candidate for functionality enhancement via the CSS(3) Selectors above. You can judge for yourself way below, or by clicking today’s tutorial picture.
Three other “popular” items around here, featuring, today, are …
- emojis (some of which were multiple and so we wish to rethank Iemoji (multiple HTML entity information) and FileFormat Information (normal HTML entity information) and Emojipedia (finding them) for these emoji lookups, as well as the CSS syntax help from this webpage (needed, because, unbelievable to us, we’d only ever done this with Javascript, in the past)), and their role to help internationalization of your web applications, and to add a bit of colour, and cuteness
- HTML element alt attribute when a data busy HTML select element option tag (the tag that we get most satisfaction from, making busy … it has to be said) is already using …
- title
- value
- text (or innerHTML)
… and you come along later not wanting to clobber any good logic looking for another “data place” to populate with your new “data item” (of interest) … well, that could be the “oft neglected except perhaps with the HTML img tag” alt attribute
- CSS selector :before
Apart from that alt logic above the changes we made to daylight_saving_time.html amounted to changes adding in new CSS(3) Selectors (that just happen … the joy of CSS, we guess) …
<style>
a[title*="Africa/"]:before { content: '\01f30d' }
a[title*="Europe/"]:before { content: '\01f4b6' }
a[title*="America/"]:before { content: '\01f30e' }
a[title*="Asia/"]:before { content: '\01f30f' }
a[title*="Australia/"]:before { content: '\01f1e6\01f1fa' }
a[title*="Indian/"]:before { content: '\01f1ee\01f1f3' }
a[title*="Pacific/"]:before { content: '\01f3dd' }
a[title*="Arctic/"]:before { content: '\01f1ec\01f1f1' }
a[title*="Antarctica/"]:before { content: '\01f1e6\01f1f6' }
a[title*="Atlantic/"]:before { content: '\01f30a' }
option[value*="Africa"]:before { content: '\01f30d' }
option[value*="Europe"]:before { content: '\01f4b6' }
option[value*="America"]:before { content: '\01f30e' }
option[value*="Asia"]:before { content: '\01f30f' }
option[value*="Australia"]:before { content: '\01f1e6\01f1fa' }
option[value*="Indian"]:before { content: '\01f1ee\01f1f3' }
option[value*="Pacific"]:before { content: '\01f3dd' }
option[value*="Arctic"]:before { content: '\01f1ec\01f1f1' }
option[value*="Antarctica"]:before { content: '\01f1e6\01f1f6' }
option[value*="Atlantic"]:before { content: '\01f30a' }
option[alt^="Africa/"]:before { content: '\01f30d' }
option[alt^="Europe/"]:before { content: '\01f4b6' }
option[alt^="America/"]:before { content: '\01f30e' }
option[alt^="Asia/"]:before { content: '\01f30f' }
option[alt^="Australia/"]:before { content: '\01f1e6\01f1fa' }
option[alt^="Indian/"]:before { content: '\01f1ee\01f1f3' }
option[alt^="Pacific/"]:before { content: '\01f3dd' }
option[alt^="Arctic/"]:before { content: '\01f1ec\01f1f1' }
option[alt^="Antarctica/"]:before { content: '\01f1e6\01f1f6' }
option[alt^="Atlantic/"]:before { content: '\01f30a' }
</style>
You can see these predominantly CSS styling changes for yourself at this live run link.
Previous relevant Other Side of the World Google Chart Tutorial is shown below.
Google Charts provides great chart tools for various purposes. We already use the Map Chart heavily with our “Other Side of the World” recent web application we last talked about below with Other Side of the World Continents and Countries Tutorial. This is no surprise given the geolocation and positioning and mapping aspects to the project. But also apt is the …
- Geo Chart which displays nominated countries and/or regions on a world map … and we also thought it would be good to call on a …
- Bar Chart can display Great Circle distances between places the user identifies during an execution of the “Other Side of the World” web application session
Over time you get a feeling for what Google Chart suits what scenario of data arrangements. Perhaps, here it would be instructional to read Google’s miscellaneous examples if you are wondering what is possible with this great software suite. We interface to many of these charts here at this blog and to read through these you could visit this link.
Today, as far as this “feel” goes, we’d like to admire how the Google Chart “way” of being housed in an HTML div element leads itself to scaling ready for smaller format devices, so long as you, the coder above, “play the game” so to speak, trying to specify percentage values for HTML element width properties where possible. This came to play with today’s Google Chart Bar Chart “fitting in” with right column table cell (td) widths with today’s “Other Side of the World” web application.
These two code files were involved in these changes …
- other_side_of_the_world.htm (changed in this way) … and you can try a live run or Seattle live run
- tz_places.php (changed this way)
As per usual, we encourage you to try the web application, and compare the goings on with code, and a good web inspector tool.
Previous relevant Other Side of the World Continents and Countries Tutorial is shown below.
Today, as with WordPress 4.1.1’s Other Side of the World Continents and Countries Tutorial, we came across a scenario where there was a tiny advantage being Australian, in that our “Continent Name” equals our “Country Name” … which I suppose you could argue for Antarctica, maybe?!
We were amused by this at school, and now have the first real world “application” of this in that today’s task, much harder than we thought it would be, was, with our “Other Side of the World” web application (we last talked about with Other Side of the World Timezone Tutorial as shown below) to link the two bigger data sets up the top of the list of three datasets going on with our application …
- Weather Underground database via its API … thanks
- PHP TimeZone functionality … why thank you, kind Open Sourcers (and the plates as well)
- the useful webpage … thank you again
The Weather Underground tends to talk about Placenames and their Country Names whereas the PHP TimeZones tend to link Placenames with Continent (or region) Names … and the missing link between these two talking to each other a good percentage of the time involves the PHP’s getLocation() functionality we’ve talked about before as a method for the DateTimeZone class, along with some 2 character ISO Country code information you can read more about at //stackoverflow.com/questions/17842003/php-intl-country-code-2-chars-to-country-name.
Making this link has lots of benefits …
- our “closest to” lists now have more data to call on (supplementing the last of those datasets above) … and …
- we can now allow for searches by Country on that top HTML select (dropdown) element …
- we can fill in more specified places now that we can add in a Country so often and often reach a point with the Weather Underground scrutiny where there is only one returned value, at which point, some days ago, we added logic to say just go and display this on the Map Chart and the rest straight away to save some time
- people tend to think of a Country when they think of a place, at least on dry land, that is.
An unusual code threesome were involved in these changes …
- other_side_of_the_world.htm (changed in this way) … and you can try a live run or Johannesburg live run
- daylight_saving_time.html (changed this way)
- tz_places.php (changed this way)
… that last one getting a new calling method just for this purpose of …
- take a placename
- take its inputted Continent (or region) Name … and …
- have the supervisory codes send to tz_places.php a $_GET[] call for the purpose of …
- using getLocation() functionality find a 2 character ISO Country Code … and …
- link this to a full Country Name via various arrays we have in the PHP … and finish off by …
- sign off the PHP (in an HTML iframe element) by changing relevant fields in top.document or parent.document DOM HTML elements via a simple HTML body onload event method of making those changes and exiting the called PHP … allowing for …
- supervisors pick up their usual logic flows once we have a Placename,CountryName textbox scenario going
Of course “Australia” the continent name being the same as “Australia” the country name saves so much time I’ll think I’ll have that cup of coffee now. See ya!
Previous relevant Other Side of the World Timezone Tutorial is shown below.
We’ve got a lot of “where” functionality mixed in with “when” functionality with our “Other Side of the World” web application. To us, the easiest way to link “where” and “when” in the world is the concept of Earth’s timezones. We spent a lot of time looking into this with the blog thread ending with TimeZone Country Places Data Tutorial and then it went through another makeover when we tackled its integration into the Weather Underground API inspired blog postings culminating in Weather API via Iframe jQuery Ajax AutoComplete Tutorial
Reading down that first blog posting thread to its “Primer Tutorial” …
Into the mix of the logic here, we need to venture into the world of two letter ISO Country Codes, and we work this with help from //php.net/manual/en/datetimezone.getlocation.php and //stackoverflow.com/questions/17842003/php-intl-country-code-2-chars-to-country-name and //php.net/manual/en/function.timezone-identifiers-list.php and //www.timezoneconverter.com/ to “hardcode” our HTML select “dropdown” elements we create in the process, and offer TimeZone information HTML select “dropdown” elements as well.
… you can see how good PHP is, natively, with timezones, and how approachable all this is for all PHP programmers … exciting stuff!
And there’s another series of blog postings culminating in HTML/PHP Timezone Feed Function Keys Tutorial involved in this same realm of thinking, that we use today (as with WordPress 4.1.1’s Other Side of the World Timezone Tutorial), along with the … you guessed it … Client Pre-emptive Iframe technique approaches to making use of what it helps with. Integrating “what it helps with” is quite interesting, and quite “Ajax”y in its ways. We call its supervisory web application into a new HTML iframe element of our “Other Side of the World” web application and pluck out only its initial “Digital Clock” HTML table display, and transfer that HTML table and its modified CSS styling over into a new HTML div element within the “Other Side of the World” web application, initially style “display:none;” but capable of being called into play via the user selecting an “Hour Time of the Day” value of interest, that causes the iframed daylight_saving_time.html (changed this way).
What the user sees/does to use this new functionality looks like …
- they see the “Hour of the Day” dropdown
- they select an “Hour of the Day” value of interest … in today’s tutorial picture, here in AEST Australia (around about 8pm) we chose “07am”
- the “Digital Clock” flashes random current times of day from around the “TimeZone Places World” and when it lobs onto the first matching time between 07am and 08am (exclusive) …
- that matching “TimeZone Place” is copied into the “Other Side of the World” Place textbox … and …
- the “Weather Underground” (autocomplete) database is scrutinized for a match, and if so …
- the Map Chart shows the matched place as the base position along with its “Other Side of the World” counterpart, allowing for Google Chart click/touch (its “select”) event logic to allow for other functionalities that include a Weather link and TimeZone information (with a current time of day) … along with the …
- usual “packdrill” for TimeZone Places iframe table cell and YouTube API Embedded iframe table cell in the (now) bottom row of the “Other Side of the World” (big) table element
The code for these TimeZone integration changes, building on yesterday’s Other Side of the World Map Chart Styling Tutorial, remains as just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.htm (changed in this minor way for our HTML supervisor of additional TimeZone functionalities today) if you like, or want to try out (or try out for a specific (argument) location, such as Tokyo try out), again. The Client Pre-emptive Iframe reading and use of PHP continues today, making great use of its TimeZone code talents.
Previous relevant Other Side of the World Map Chart Styling Tutorial is shown below.
You’ll have noticed with our “Other Side of the World” web application of recent days … or maybe not, if you were dozing off … how much use we make of the Google Charts Map Chart functionality. Can’t do without it … thanks, Google.
Now if you go to read about the Google Chart Map Chart you may end up at this very interesting webpage, and even if it was some time back you were last there, it is always worth checking back in every now and then for information on changes, or to reread this functionality rich software suite documentation. We only touch the “tip of the iceberg” with the way we interface to Google Charts, but today we want to take some small steps to improving on that. Even taking small steps, when dealing with a third-party product so rich in possibilities, we try to be generic and be able to offer more to those adventurous users out there, both laptop and mobile (at least iPad only at this stage) users.
So we have set up a way for iPad users using the mobile app to be able to save their comma prefixed …
- localized Google Chart Map Chart styling ideas from here when they interactively enter Map Chart criteria … and for …
- all users of our “Other Side of the World” web application get an additional non-default Google Chart Map Chart “Styled Map” tab (in addition to their default “Map” and “Satellite” tabs), and some non-default Google Chart Map Chart icons … thanks to Icons-Land here
The new icons for that latter scenario also feature a different icon showing after a “pin” icon is selected (ie. the Google Chart click/touch “select” event is called into play).
The code for these Map Chart changes remains as just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.htm (changed in this minor way for our HTML supervisor of Google Chart Map Chart purposes today) if you like, or want to try out (or try out for a specific (argument) location, such as Beijing try out), again. The major changes related to in the Google Chart Map Chart web application PHP you could call map.php, and which changed in this way, starting down our long path towards more Map Chart styling possibilities.
Previous relevant Other Side of the World Iframe Tutorial is shown below.
Our “Other Side of the World” web application we’ve been developing lately has made extensive use of the HTML iframe element, mainly as a “reader” of data in that Client Pre-emptive Iframe technique way. But the HTML iframe element is probably better known for its data integration and display talents, and it is these that we call upon today, to (software) integrate two other existing sources of data so that, display-wise we have four table (td) cells in play now those being the original …
- top left cell where the user interacts to show latitude and longitudes and placenames of interest
- top right cell showing these “latitude and longitudes and placenames of interest” paired with their “Other Side of the World” counterparts within a Google Charts Map Chart (software) integration … and, as of today we add into the equation …
- bottom left cell where depending on whether we’ve derived our “latitude and longitudes and placenames of interest” from …
- the Weather Underground HTML select (dropdown) element results in an HTML iframe element hosting a Weather API via Iframe jQuery Ajax Autocomplete Tutorial‘s TimeZone Places dataset … or …
- the useful webpage (thanks) HTML select (dropdown) element results in an HTML iframe element hosting a YouTube Embedded Video in Iframe API RegEx Tutorial ‘s YouTube (embedded) video integrator
- bottom right cell where the user’s “latitude and longitudes and placenames of interest”‘s “Other Side of the World” interfaces to the useful webpage (thanks) HTML select (dropdown) element results in an HTML iframe element hosting a YouTube Embedded Video in Iframe API RegEx Tutorial ‘s YouTube (embedded) video integrator
We now think the use of all this can have you hopping around the world discovering lots of geographical based, video based and timezone based information about lots of places around the world, lots of which you may never have known much about.
We’ve software integrated today, as well as integrated “where” web application thoughts with “when” web application thoughts.
Another feature of today’s changes involves the geolocation features of the Javascript …
navigator.geolocation.getCurrentPosition(success[, error[, options]])
… syntax method of allowing Location Services, if allowed by the user, return a latitude and longitude position of the user themselves, information used at the instigation of the web application, and which we also used with HTML/Javascript Where Does It Get Me To Primer Tutorial and Google Chart Map Chart Select Event Primer Tutorial in the past.
The code for this remains as just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.htm (changed in this way for our HTML iframe (software) integration purposes today) if you like, or want to try out (or try out for a specific (argument) location, such as Alice Springs try out), again. It also required small changes to …
- HTML of the YouTube embedded iframe video integrator’s supervisory karaoke_youtube_api.htm changed in this way and with this live run link
We hope you try it out and discover some new things!
Previous relevant Other Side of the World Onblur Tutorial is shown below.
The onblur event in web programming is a very important event regarding interactive keyboard entries made by the user. We base new functionality, today, with our “Other Side of the World” web application, by allowing a user who enters in their own “place” information, can have that information filtered through the same “autocomplete” database provided by the wonderful Weather Underground and its great API service.
When we presented the last Weather Underground related blog posting we even used this functionality also interfacing to the onkeyup keyboard event, making it look up the database after just a few characters typed into the associated HTML input type=text text box, but today we lessen the interaction, presuming the user knows a location of interest and will only want information after tabbing out of this text box … hence the onblur event, only, logic interface to new functionality that creates an additional HTML select (dropdown) element of use to populate those same …
- placename
- country … linked to …
- latitude
- longitude
… fields as talked about yesterday when we presented Other Side of the World Places Tutorial as shown below.
So that’s the idea, but making it happen involved some tweaking of the parts to the Weather Underground blog posting Weather API via Iframe jQuery Ajax AutoComplete Tutorial from some time back, the changes for which we’ll explain later.
Again we call on Client Pre-emptive Iframe techniques for this, telling us that you can just keep on adding HTML iframe elements to make this technique happen for several different sources of information, as necessary.
The code for this is just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.htm (changed in this way for our onblur event purposes today) if you like, or want to try out (or try out for a specific (argument) location, such as Darwin try out), again. It also required small changes to …
- HTML of the “parent” you could call autocomplete.htm changed in this way and with this live run link (or specific place argument calls like the one here for live run for Darwin link) … and its …
- PHP autocomplete jQuery Ajax engined helper you could call using_key.php and tweaked in this way
Previous relevant Other Side of the World Places Tutorial is shown below.
A fair while ago now we were in the midst of writing a Geographicals Suite of web applications that, given Latitude and Longitude pairs you could calculate things like …
- Sun Angle at noon
- Moon Angle at noon
- Coriolis Effect
- Distance between Geographical Locations
- Weather at Geographical Location
… and that we eventually added some “placename” capabilities to all this, introduced with PHP/Javascript/HTML Sun Angle Tutorial, which harnessed all this useful goodwill of this useful webpage (thanks) publishing some placename geographicals data.
- placename
- country … linked to …
- latitude
- longitude
… and that we “channel” today, via our beloved Client Pre-emptive Iframe techniques, so that we reuse PHP, rather than having to create new PHP, as an aid to the modularization for added “placename” functionality to our “Other Side of the World” web application we started presenting yesterday with Other Side of the World Primer Tutorial as shown below.
Another thing we are trialling today is a concept (that admittedly seems to need more work in Firefox) of an HTML select (dropdown) element having an onclick event (after an onchange event that changes that select element value to a non-nothing value) having a logic whereby that select element value is used to repopulate the …
- placename (, country) (Great Circle Distance in km away)
- latitude
- longitude
… HTML input type=text and type=number fields automatically. In the normal case of events in non-Firefox web browsers an onchange event change of value to a non-nothing value just causes that select element value to be one of the places shown on the Google Charts Map Chart that we display.
The default is to show five of the nearest placenames in the derived list, but a “+” button can increase that number of “nearest”s as required.
The code for this is just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.htm (changed in this way for our purposes today) if you like, or want to try out, again perhaps?
Previous relevant Other Side of the World Primer Tutorial is shown below.
Today we’ve written a first draft of an “Other Side of the World” web application using a Google Chart Map Chart embedded into an HTML iframe element to show the user …
- the position of the place that they enter in for their latitude and longitude … as well as …
- “the other side of the world” to the position of the place that they enter in for their latitude and longitude, calculated by imagining you take a trip from your original location through the middle of the Earth and straight through onto the other location
Is this our “sister” location? Am not sure. But somebody was telling “Porkies” to me as a child where we were told “China” as being on the other side.
The code for this is just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.html if you like, or want to try out.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.