Apologies to any mobile users wanting to access this new inhouse Image Map creator web application last talked about with yesterday’s Inhouse Image Map Creator Interactive Drill Down Tutorial before today, that is, but we were leaving the issue until a proper hardware …
Mac Book Air
Apple white lead
iPhone
… that once the middle one plugs into the top and bottom allows for …
iPhone Safari web browser call of the inhouse Image Map creator … could tee up with (ie. attain a “connection” with) …
Mac Book Air Safari web browser Develop -> (in our case) Robert’s iPhone -> user_of_signature_signature.htm
… online debugging session, could be arranged and a block of time set aside to concentrate on, because “concentrate” is the name of the game here!
Luckily, the issue was straightforward, where many are not. In the overseeing code, we had …
… ba bow … because in the external Javascript we got pulled up by the debugging of the iPhone execution attempt at a codeline, where the user decides to take on an Image Map creation task …
Inhouse Image Map Creator Interactive Drill Down Tutorial
It might be the case, often, with Image Map creations, as with our recent web application featuring in yesterday’s Inhouse Image Map Creator Drill Down Tutorial that the user needs to …
strike while the iron is hot
… regarding having the event logic be nuanced as the image map area subelements are created in terms of …
area subelement inline event logic definitions (pointing at, perhaps, local Javascript functions) … as well as …
the content of those local Javascript functions
… in such a way that, if you come back to “flesh out” the image map HTML coding the next day, say, there are enough clues you’ve left that you do not have to go and match the “coords” attribute values to a screen position to get some context. That takes a lot longer we find.
And so, today, we now offer …
Enter an Image URL (append space to create Image Maps where click/tap pairs can define rectangle corners … cursor is a crosshair for lower left click/tap, first, then cursor is pointer top right … append another one space to prompt for tailored event logic each time and two spaces to also review the default Javascript used for double click logic image map testing purposes … we are going to discourage scrolling here, but you can still zoom out or in)
… Javascript prompt windows “on the fly” to allow for this to be a possibility for the Image Map creator using …
Onto yesterday’s Inhouse Image Map Creator Tutorial we’ve decided today’s work should stay within non-mobile realms but flesh out more user available functionality to help with “stage two” thinking. With that in mind …
the image map HTML containing textarea created (with yesterday’s efforts using the Canvas and Image Map web application (now featuring a new emoji button 🗺️🖼️ to allow for a non-dropdown usage approach)) has an ondblclick event logic added so that when double clicking, at any stage of the image map creation processing, it …
opens a new popup window where that HTML you have so far is surrounded by a default “rest of webpage” scenario as the HTML that goes into making up that popup window HTML content, and where you can test out it’s workings … as well as …
that popup window image map, itself, is given an ondblclick event logic whereby a double click there can create below that image map within the same popup window a new textarea element containing all that HTML (default “rest of webpage” and all) which can be copied into a clipboard buffer as required … and …
if that textarea within the popup window is edited and the user double clicks that textarea element, a new popup window reflecting your changes is opened above that … etcetera etcetera etcetera
All this can be used to either/both validate your image map and follow through further to incorporating the image map into a functional HTML webpage, using the changedsignature_signature.js external Javascript to make all this possible. Within that changed external Javascript we allow the user to cancel the proposed area subelement currently embarked upon between where the user has clicked/tapped the bottom left and before they shape to click/tap the top right rectangle definition, via a right click, so as to reset back to the click/tap using the crosshair cursor back at a bottom left area shape=rect subelement definition.
The “largely canvas” using web application last talked about with WordPress Blog Image Editing Media Tutorial, today, we’re excited to announce, has been given an “on first draft just image URL” using new …
Image Map ( ie. <img src=”[image URL as entered by user]” usemap=’#htblah’ blah /><map name=’htblah’ id=htblah><area shape=rect coords=’tlx,tly,brx,bry’ blah> … more area elements blah … blah … blah … <area shape=default nohref alt=”” /></map> ) creator
… arrangement inhouse means to construct image maps, so far, just via an image URL.
Why hook into the largely canvas savvy web application? Well, it is that basic positional mouse event logic that is needed to create image maps, and here, it is a dominant theme, and useful, even though the rearrangement of data needed is quite substantial, still, that is where we think this new functionality appears most at home, being a new suboption (“Image 🖼 Canvas Matches Actual URL or Image Map rectangle area creations“) off a dropdown option means of deploying.
No tests on mobile, yet, but on non-mobile, we’re happy, once the user chooses to create Image Maps, so long as …
we stop user web page scrolling … while still allowing …
webpage zooming out or in
… in conjunction with …
replacing the webpage table’s left cell content, which used to contain a canvas element, with the user defined image, via it’s URL …
replacing the webpage table’s right cell content, which used to contain an canvas annotation menu, with the image map URL HTML built up from user lower left and upper right rectangle defining click/taps
… we have the wherewithal to create image map HTML code the user can copy and use, with “stage two” fleshing out!
… to allow for this image map inhouse functionality. The talents of HTML textarea elements, with their resizing abilities, helps out here, allowing these overlayed textarea elements …
containing image map HTML … and/or …
overlaying semi-transparentally to see what has been clicked already
… also be able to be resized “out of the way” should that be needed perhaps regarding overlapping scenarios, without having to resort to any other type of event logic to allow for. The other big and relevant talent of textarea elements is their ability to contain HTML code and be editable with that HTML code, perhaps user amended, and to be able to Select All then Copy into a clipboard buffer, via it’s right click web browser menu, ready to paste somewhere else, that HTML content ready for any required “stage two” embellishment and usage.
… to add to our recent WordPress Blog Image Editing functionality, extending it’s capabilities to be able to optionally create either/both …
Video
Animated GIF
… media presentations off this should the user pick more than one image, to be edited, in any one web browser tab (via window.sessionStorage) session. So far, we’re creating …
window.open
background image
background-size: contain
… “Video” and “Animated GIF” presentations, and see this as a shareable commodity, into the future, especially as the image slide data ends up being an HTML canvas [canvas].toDataURL() data URI that represents …
lots of data
but understood everywhere
… and content wise has included within it, any canvas manipulations and annotating and reworking the user has applied plus, at least for Google Chrome, any image filtering CSS the user has requested, into that canvas. We shape to involve the cowsayactual web server disk based media creating interfacing, but not for now. We’ll see, because WordPress Visual Synopsis Media Tutorial methodologies also ended up presentation wise, with “inhouse” “Video” and “Animated GIF” presentations.
How does the user make this happen? Well, at the opportune call of our Canvas Image Editor web application some “Mantissa MadnessMagic” takes place using …
… to help create, within the blog posting webpage content, the HTML skeletal necessaries modelled on how WordPress Visual Synopsis Media Tutorial worked it for Visual Synopsis (Slideshows) functionality which included inhouse “Video” and/or “Animated GIF” media presentations.
WordPress Blog Posting Feature Image Editing Tutorial we’re using a hosted HTML iframe window within the blog posting webpage of interest
And that should be a lot easier to handle, yes?! Well, yes, maybe, but not that much easier. A little bit “easier” because the logic is largely funnelled into code that is common to both modus operandi.
In amongst the commonalities, thankfully, the means to get to the “image editing and annotating” and/or “image styling” functionality remains …
Non-mobile right click or spread/pinch mobile gesture on most blog posting images can lead to image editing and annotating functionality, where for animated GIFs first slide is chosen.
We learnt a bit making the mobile ontouchend spread/pinch detection more bulletproof …
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
setTimeout(function(){
document.ontouchend=function(e){
if (document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') != -1) {
lastsp=eval(e.touches.length);
}
if (eval('' + e.touches.length) >= 1) {
if (document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') == -1) {
onrightclickask();
} else if (e.touches[0].target.outerHTML.split('>')[0].indexOf('<img ') == 0 && e.touches[0].target.outerHTML.split('>')[0].indexOf(' tabindex=') != -1) {
onrightclickask(); //document.title=':' + e.touches[0].target.outerHTML.split('>')[0].substring(1);
}
}
};
}, 4000);
}
… but ahead of this, for the TwentyTen theme changes to codex webpage structure we predominantly do with a good ol’ tailored header.php the most effective modified (which is new) codeline now goes …
Running against us regarding One Image Website design ..
Running for us regarding One Image Website design …
the programmatical scrolling means embedded iframe hosting will not work
way window.prompt freezes all Javascript at a snapshot of time …
hashtag navigation can be the conduit to pass data onto inhouse Canvas Editor of Image Data
[canvasContext].drawImage has a variety of useful calls (in that OOP method feel) allowing for dynamic cropping
That “one against” stopped how we envisaged the work at the start of the day. We thought we’d use window.sessionStorage (or maybe window.localStorage) as the only data conduit needed, and we’ll be continuing that idea with another approach into the future, but back to today, hashtagging provided that conduit means, even if we were using data URIs (though all we need today are image absolute URLs).
And then there was “the unknown factor” …
Can [canvasContext].drawImage draw that image with CSS filter styling applied?
Well, we found using Javascript DOM ahead of the new Image() call …
xcelem=document.getElementById('topcanvas');
xccontext = xcelem.getContext("2d");
xcimg=new Image;
xcimg.onload = function(){
var mysx=('' + window.sessionStorage.getItem('user_of_signature_signature_sx')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sx')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The x coordinate where to start clipping
var mysy=('' + window.sessionStorage.getItem('user_of_signature_signature_sy')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sy')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The y coordinate where to start clipping
var myswidth=('' + window.sessionStorage.getItem('user_of_signature_signature_swidth')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_swidth')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The width of the clipped image
var mysheight=('' + window.sessionStorage.getItem('user_of_signature_signature_sheight')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sheight')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The height of the clipped image
var myx=('' + window.sessionStorage.getItem('user_of_signature_signature_x')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_x')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // The x coordinate where to place the image on the canvas
var myy=('' + window.sessionStorage.getItem('user_of_signature_signature_y')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_y')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // The y coordinate where to place the image on the canvas
var mywidth=('' + window.sessionStorage.getItem('user_of_signature_signature_width')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_width')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The width of the image to use (stretch or reduce the image)
var myheight=('' + window.sessionStorage.getItem('user_of_signature_signature_height')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_height')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The height of the image to use (stretch or reduce the image)
if (mywidth != '' && myheight != '') {
xcelem.width=eval('' + mywidth);
xcelem.height=eval('' + myheight);
if (('' + xcimg.style.filter).replace(/^undefined/g,'').replace(/^null/g,'').trim() != '') {
xccontext.filter=xcimg.style.filter;
}
if (myx != '' && myy != '' && myswidth == '' && mysheight == '') {
xccontext.drawImage(xcimg,eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight));
setTimeout(function(){ xccontext.drawImage(xcimg,eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight)); }, 3000);
window.sessionStorage.removeItem('user_of_signature_signature_x');
window.sessionStorage.removeItem('user_of_signature_signature_y');
window.sessionStorage.removeItem('user_of_signature_signature_width');
window.sessionStorage.removeItem('user_of_signature_signature_height');
} else {
xccontext.drawImage(xcimg,eval('' + mysx),eval('' + mysy),eval('' + myswidth),eval('' + mysheight),eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight));
setTimeout(function(){ xccontext.drawImage(xcimg,eval('' + mysx),eval('' + mysy),eval('' + myswidth),eval('' + mysheight),eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight)); }, 3000);
window.sessionStorage.removeItem('user_of_signature_signature_sx');
window.sessionStorage.removeItem('user_of_signature_signature_sy');
window.sessionStorage.removeItem('user_of_signature_signature_swidth');
window.sessionStorage.removeItem('user_of_signature_signature_sheight');
window.sessionStorage.removeItem('user_of_signature_signature_x');
window.sessionStorage.removeItem('user_of_signature_signature_y');
window.sessionStorage.removeItem('user_of_signature_signature_width');
window.sessionStorage.removeItem('user_of_signature_signature_height');
}
} else {
xcelem.width=xcimg.width;
xcelem.height=xcimg.height;
if (('' + xcimg.style.filter).replace(/^undefined/g,'').replace(/^null/g,'').trim() != '') {
xccontext.filter=xcimg.style.filter;
}
xccontext.drawImage(xcimg,0,0);
setTimeout(function(){ xccontext.drawImage(xcimg,0,0); }, 3000);
}
if (window.parent) {
if (parent.document.getElementById('if_image_canvas')) {
if (('' + parent.document.getElementById('if_image_canvas').style.height).replace('px','').trim() != '') {
if (eval('' + ('' + parent.document.getElementById('if_image_canvas').style.height).replace('px','').trim()) < eval(200 + eval('' + xcelem.height))) {
parent.document.getElementById('if_image_canvas').style.height='' + eval(200 + eval('' + xcelem.height)) + 'px';
}
} else {
parent.document.getElementById('if_image_canvas').style.height='' + eval(200 + eval('' + xcelem.height)) + 'px';
}
parent.document.getElementById('if_image_canvas').style.display='block';
if (parent.document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') != -1) {
parent.document.getElementById('if_image_canvas').scrollIntoView();
}
}
}
};
var incomings=('' + window.sessionStorage.getItem('user_of_signature_signature_filter')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_filter')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The image filter CSS styling to apply
if ((incomings.indexOf('%20') != -1 || 7 == 7) && incomings.replace(':',')').indexOf(')') != -1 && incomings.indexOf('style=') != -1) {
incomings='style=' + encodeURIComponent((incomings.split('style=')[1].split('&')[0].split('#')[0]).replace(/\%20/g,' ').replace(/\+/g,' '));
}
var relincomings=incomings.split('style=')[1] ? decodeURIComponent(incomings.split('style=')[1].split('&')[0].split('#')[0]).replace(/\%20/g,' ').replace(/\+/g,' ') : '';
if (relincomings.indexOf('filter:') != -1) {
xcimg.style.filter=relincomings.split('filter:')[1].split(';')[0].split('}')[0];
}
xcimg.src=xcont;
… didn’t help, and then we asked the online woooorrrrrllllddd to come across this very useful link, thanks to teach us …
… with the user able to make this happen with those right click (non-mobile) or pinch or swipe gesture (mobile) actions (talked about with yesterday’s One Image Website SessionStorage Image Filtering Tutorial) getting the user to a prompt window with the modified “blurb” …
Optionally, please, any CSS for images … append three spaces to be able to edit this screenshot in a canvas … ref. https://www.w3schools.com/cssref/css3_pr_filter.php … eg. filter: grayscale(100%);
clientside image filtering functionality to offer …
almost exclusively using window.sessionStorage ideas (rather than our usual window.localStorage (ie. like Cookies) usage)
Why is that last point any big deal? Well, programmers will tell you, often the tidy up of a new arrangement involves as much, or more, coding to do than the instigation. And a lot of programmers, am sure, will agree that that is a pain in the neck, often. But the use of window.sessionStorage at the expense of window.localStorage allows the programmer to go …
Aaaaaahhhhh
There is so much less to tidy up. Using window.sessionStorage it is only data on that web browser tab that comes into play, and as soon as that web browser tab no longer exists, nor does the window.sessionStorage data you stored. Yayyyyyyy!
We found we couldn’t quite make it exclusively with window.sessionStorage because in the One Image Website paradigm of offering music playing we lost window.sessionStorage data for one of the two web browser tabs that become involved to start the music rolling. So sad. Nevertheless, we transferred some controllable temporary window.localStorage data storage over to window.sessionStorage data storage at the opportune time …
How can the non-mobile user access these new aesthetic settings? Via a right click, as our new unfettered layer of functionality option, encapsulated by onrightclick.js external Javascript “proof of concept” effort, on the way to a Javascript prompt window, is the way we’ve gone about it. From there, the user can enter CSS non-selector actions such as the use of CSS filter property.
And as such, it’s worth a revisit of one or all of our reworked One Image Website web applications …
Normal Run …
Run for All Platforms that Presents an Audio Element You Can Play Immmediately
Today, we’ve bitten the bullet, and decided to shore up the webpage scrolling issues that could occur in yesterday’s One Image Website VTT Tracks Tutorial, and before, with our set of One Image Websites. They represent, perhaps, a slightly unusual scenario whereby the image data is allowed to be itself, and being bigger than the dimensions of the webpage (straight from its digital source), in all probability. Hence, the randomized document.body scrolling that occurs.
But up until today our randomized range of scrollLeft and scrollTop positioning that could occur ranged over the entire width and height of the underlying image, while we think we should only be scrolling over the range ([imageWidth] – window.innerWidth (screen width)) x ([imageHeight] – window.innerHeight (screen height)). This could lead to white bands to the right and/or bottom of the webpage, in its presentation. And so we’ve fixed all the Javascript code to replace the old with the new in all the One Image Website codesets …
… and, am sorry, but cannot award any points to those who chose the former, because … well … it’s doubtful we’d mention the second unless we’d done it. And so the answer is … the former … down Nala … the latter!
Today’s blog posting is also a little story about the benefits of what we like to call client pre-emptive iframe logic, whereby we open an HTML iframe element, blazing away with its src attribute pointing at a URL that may or may not exist, and if it does, we do something about its content, usually, in the HTML iframe onload event logic. In our case the URL is a VTT file suiting the One Image Website of relevance given the upload and renaming of the VTTs created using yesterday’s PHP ffmpeg log to VTT file creator web application.
As a programmer who would like to pursue true track cue Javascript coding, develop the function tracks in the One Image Website index-ssmhalf.html you could View -> Page Source from your favourite web browser, for any of …
Normal Run …
Run for All Platforms that Presents an Audio Element You Can Play Immmediately
… where, now, where the user plays music, perhaps continuously (like a radio) with an HTML audio element play button press, the currently playing song, thanks to Royalty Free Music For Video, help you keep in touch with the song playing up at the web browser tab and the image title.
This amounted to Javascript changes, as per …
index.htm …
var foreground=null; // and get rid of var in var foreground below
var plusstuff='';
function ftchange(tob) {
plusstuff=' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
if (document.getElementById('place').title.indexOf(' Playing ') == -1) {
document.getElementById('place').title+=' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
} else {
document.getElementById('place').title=document.getElementById('place').title.split(' Playing ')[0] + ' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
}
}
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i) && document.URL.indexOf('?audio=') == -1) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.body.innerHTML+='<iframe id=ifmusicone title="Play http://www.freesoundtrackmusic.com (thanks) Music Set on Loop Here" src="./index-ssmhalf.html?justmusic=00" style="opacity:0.5;z-index:345;position:absolute;width:140px;height:100px;left:' + eval(-140 + eval('' + window.innerWidth)) + 'px;top:0px;"></iframe>';
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
function FadeInImage()
{ var foreground=document.getElementById("place");
window.clearTimeout("FadeInImage('" + "place" + "')");
rotateImage("place");
}
function rotateImage(place) {
while (number_of_image == 0)
{
place = place;
}
xplace=place;
//alert('yay2');
anotherNew();
var foreground=document.getElementById(place);
//alert(place);
var thedivlink=document.getElementById("thedivlink");
var thediv=document.getElementById("thediv");
if (foreground.width > 0) {
thedivlink.style.display = "none";
thediv.style.display = "none";
if (document.getElementById('ifmusicone')) {
document.getElementById('ifmusicone').style.display='none';
}
//alert('yay2a');
var alink=document.getElementById("alink");
var xxxx=alink.href;
if (xxxx.indexOf("mp3") != -1)
{
//alink.href="index-ssm.html";
//alink.onclick="javascript:void(0);";
alink.href="filewrite.php?id=session&name="+bigrandnumber+"&ext=txt&rand="+bigrandnumber;
alink.onclick="javascript:void(0);";
foreground.onclick="javascript:hasBeenClicked();";
foreground.title="Click for Bamboozled provided by http://www.freesoundtrackmusic.com" + plusstuff;
ffmpeg … with its great logging and media concatenation talents, thanks …
macOS Terminal desktop app … regarding its great GUI design feature allowing you to gather up actions of the past into a copy buffer via its Edit -> Find functionality, thanks
Don’t know about you, but have always found the creation of track data VTT files (and their predecessor SRT files) one of the most tedious jobs in programming?
But the work of the day before yesterday’s One Image Website iOS Radio Music Tutorial and its audio concatenation via ffmpeg themes had us looking back, wistfully, back up our (macOS) Terminal (desktop apps) logging of a few days past, hoping for an escape from VTT file manual text editing for our wish to enhance our One Image Website work of recent days. Wow, the ffmpeg logging was brilliant!
There was enough there to program the creation of VTT files from the ffmpeg, and our “cd”ing and “ls”ing and other stuff, in the (let’s more accurately say, Terminal) logging. Yayyyyy!
If you click the light green form submit button, in the iframe way below, yourself, it will reveal, in details/summary (revealing) tags, both the input and output (VTT files) for you to see this more clearly, or to have it clicked for you in a new window, click this button clicker incarnation. In the works of the HTML form below, for the first time we can remember, and because the defaults are so arcane, we developed HTML form onsubmit logic as per …
… as a way to deal with arcane defaults, where the encouragement is there for an interested programmer to download PHP code (perhaps to a MAMP local Apache/PHP/mySql web server environment) and tweak to their purposes. Note that you can paste your own logging into the textarea as a way this PHP application can be useful even up at the RJM Programming domain …
For tomorrow, we offer an optional “one less click”, “one less window” methodology improvement on the work above, as we transition the other “One Image Websites” over to the new iOS music paradigm.
… and so, it being tomorrow we’re here starting our discussion starting with the “one less window” thought. Have a look at this table outlining some (off the top of the head) clientside navigation techniques in two categories …
No new window created …
New window created …
window.open([URL],’_self’)
window.open([URL],’_blank’)
location.href=[URL]
window.open([URL],’_top’)
window.location=[URL]
top.window.location=[URL]; // if in an iframe
Ajax (with or without new FormData()) whether ‘GET’ or ‘POST’
form target=_blank action=[URL]
form target=_self action=[URL]
form target=_top action=[URL] // if in an iframe
iframe srcdoc=[webpageHTML]
form target=_parent action=[URL] // if in an iframe
iframe src=[URL]
parent.window.location=[URL]; // if in an iframe
… and it’s that last left hand column iframe src=[URL] we like for the purposes of these changes today. That new HTML iframe in the “One Image Website” index.htm supervisories is now worked via …
function rotateImage(place) {
while (number_of_image == 0)
{
place = place;
}
xplace=place;
anotherNew();
var foreground=document.getElementById(place);
var thedivlink=document.getElementById("thedivlink");
var thediv=document.getElementById("thediv");
if (foreground.width > 0) {
thedivlink.style.display = "none";
thediv.style.display = "none";
if (document.getElementById('ifmusicone')) {
document.getElementById('ifmusicone').style.display='none';
}
//
// more rotateImage code follows ...
//
}
//
// more rotateImage code follows ...
//
}
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i)) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.body.innerHTML+='<iframe id=ifmusicone title="Play http://www.freesoundtrackmusic.com (thanks) Music Set on Loop Here" src="./index-ssmhalf.html?justmusic=0" style="opacity:0.5;z-index:345;position:absolute;width:140px;height:100px;left:' + eval(-140 + eval('' + window.innerWidth)) + 'px;top:0px;"></iframe>';
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
… up towards the top right of the index.htm webpage when using an iOS platform. It is optional whether the user …
clicks Play button of that new top right audio element for continuous “looped audio track sets” mode of use with no new second window required (and so, no window focus changes and no second click required either)
clicks blue link for continuous “looped audio track sets” mode of use with a new second window’s audio element that the user clicks the Play button of
clicks none of those modes of use above that are offered for a short time to then click appropriately to start up music, optionally, as required, at a later date as possible
So feel free to try a One Image Website in the list below …
… where this new iOS music arrangement logic has been incorporated.
Stop Press
The Webpage Meta Refresh Primer Tutorial has reminded us of another left hand “No new window created” navigation methodology using the HTML meta “refresh” tag.
… to have a day’s worth of experimenting trialling a solution to the “chestnut of a” problem getting iOS music to play continuously without supervision, like a radio program, albeit on a cycle of repeated content (set (such as the oneoffive.mp3 twooffive.mp3 threeoffive.mp3 fouroffive.mp3 fiveoffive.mp3 set of 5 tracks in example below)). Years ago Apple‘s iOS started requiring a user click to validate the playing of media, hence the interest in today’s topic.
The ingredients for the solution, and testing thereof, are …
optionally, (we’re just suggesting this headphone idea if you want to keep the music to yourself) via Bluetooth, with a set up involving a connection to a set of AirPods (and connected to your ears) … are chosen as …
click the blue link up the top that appears for a short time … then …
in the resultant new music window click the Audio play button presented (the point of interest being that this could be the last click required for continuous music playing, in that audio loop) … music should play continuously and …
if more interesting visuals are also required focus back to calling window
And given that the iPhone and AirPods are charged, and you don’t charge out of Bluetooth range with the iPhone, you could get that “radio feeling” out of an iOS user experience!
Code changes, all just clientside HTML and Javascript, went …
calling window‘s index.htm changes around the document.body onload event area of interest 🎶 …
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i)) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
For tomorrow, we offer an optional “one less click”, “one less window” methodology improvement on the work above, as we transition the other “One Image Websites” over to the new iOS music paradigm.
So, why keep the old way? Well, we packed the “old way” with content rich functionality, and do not want to ditch that yet, but maybe over time?!
We’re just over time, aren’t you?! And so, we arrive at a long planned for tilt at Image Map functionality that we often turn to Mobilefish.Com and its excellent Image Map Creation to help us out … but not today?! Why not? We have a funny set of needs, they being …
our Image Map’s image will have a variable set of width x height dimensions …
our Image Map’s image will be transparent
our Image Map needs to have a hole left aside inside it where the functionality that originally existed (and pointed to WordPress Blog content like you are reading), is still working
… the last condition of which we realized, down the track, required us to create four Image Maps. But … but … Nala hears you say?!
Yes, we can reference the one image, in its data URL guise, as a smaller, or not, version of itself, by specifying CSS properties …
position:absolute; (our usual for overlay scenarios)
z-index:56; (for both transparent image and its associated Image Map … more on this later)
left (to appropriately position in X to be in the relevant section of dark green Image Map overlaying in the Landing Page)
top (to appropriately position in Y to be in the relevant section of dark green Image Map overlaying in the Landing Page)
width (which will be up to the transparent image width)
height (which will be up to the transparent image height)
… and no concern about opacity given the transparent image and z-index considerations, here.
So, how can we involve a transparent image here? Well, that is where the new Responsive Web Design Landing Page being PHP, though up to today it had contained no PHP, is in our favour. We can use PHP’s GD to create one, grab its associated data URL and tidy up, and constructing the four image and associated Image Map HTML elements populated, in its “child iframe”, and sending back up into the “parent webpage’s” new …
function ouralert(innum) {
var ans='';
switch ('' + innum) {
case '1':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '2':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '3':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '4':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.) Eg. https://www.rjmprogramming.com.au/slideshow.html', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '5':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '6':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.) Eg. https://www.rjmprogramming.com.au/plus/', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '7':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '8':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', '');
}
break;
case '9':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', '');
}
break;
default:
break;
}
if (!ans) { ans=''; }
if (ans != '') {
window.open(ans.trim(), '_blank');
if (ans != ans.trim()) {
window.localStorage.setItem('area' + innum + 'url', encodeURIComponent(ans.trim()));
}
}
}
function imbit() {
//if (document.getElementById('myimg')) {
// document.getElementById('myimg').style.border='5px dashed purple';
//}
if (('' + window.localStorage.getItem('area4url')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
urls[3]=decodeURIComponent('' + window.localStorage.getItem('area4url'));
document.getElementById('area4').title=decodeURIComponent('' + window.localStorage.getItem('area4url')) + '# ... long hover of at least 8 seconds for chance to change';
document.getElementById('area4').href=decodeURIComponent('' + window.localStorage.getItem('area4url'));
document.getElementById('area4').onclick=function(){ omoiset=-1; urls[3]=urls[3]; }
//document.getElementById('area4').ondblclick=function(){ ouralert(4); }
}
if (('' + window.localStorage.getItem('area6url')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
urls[5]=decodeURIComponent('' + window.localStorage.getItem('area6url'));
document.getElementById('area6').title=decodeURIComponent('' + window.localStorage.getItem('area6url')) + '# ... long hover of at least 8 seconds for chance to change';
document.getElementById('area6').href=decodeURIComponent('' + window.localStorage.getItem('area6url'));
document.getElementById('area6').onclick=function(){ omoiset=-1; urls[5]=urls[5]; }
//document.getElementById('area6').ondblclick=function(){ ouralert(6); }
}
}
separating out totally “uninvolved” Landing Page calls hooked up with a new index.php (actually just HTML) Landing Page incarnation that has better Responsive Design credentials … from …
any other call of any complexity or having a query string etcetera, reverting to the “old way”
… new paradigm? So, why keep the old way? Well, we packed the “old way” with content rich functionality, and do not want to ditch that yet, but maybe over time?!
Responsive web design (RWD) is an approach to web design that makes web pages render well on a variety of devices and window or screen sizes from minimum to maximum display size. Recent work also considers the viewer proximity as part of the viewing context as an extension for RWD.[1] Content, design and performance are necessary across all devices to ensure usability and satisfaction.[2][3][4][5]
honing in on our “Landing Page and friends” set of unresponsively designed webpages …
honing in on iPhone sized devices (ie. not iPads nor laptops) …
host web browser address bar calls of “Landing Page and friends” set of unresponsively designed webpages within a caller.htmlresponsively web designed shell supervisory webpage and start using some of that …
Inhouse Image Map Creator Interactive Drill Down Tutorial
It might be the case, often, with Image Map creations, as with our recent web application featuring in yesterday’s Inhouse Image Map Creator Drill Down Tutorial that the user needs to …
strike while the iron is hot
… regarding having the event logic be nuanced as the image map area subelements are created in terms of …
area subelement inline event logic definitions (pointing at, perhaps, local Javascript functions) … as well as …
the content of those local Javascript functions
… in such a way that, if you come back to “flesh out” the image map HTML coding the next day, say, there are enough clues you’ve left that you do not have to go and match the “coords” attribute values to a screen position to get some context. That takes a lot longer we find.
And so, today, we now offer …
Enter an Image URL (append space to create Image Maps where click/tap pairs can define rectangle corners … cursor is a crosshair for lower left click/tap, first, then cursor is pointer top right … append another one space to prompt for tailored event logic each time and two spaces to also review the default Javascript used for double click logic image map testing purposes … we are going to discourage scrolling here, but you can still zoom out or in)
… Javascript prompt windows “on the fly” to allow for this to be a possibility for the Image Map creator using …
Onto yesterday’s Inhouse Image Map Creator Tutorial we’ve decided today’s work should stay within non-mobile realms but flesh out more user available functionality to help with “stage two” thinking. With that in mind …
the image map HTML containing textarea created (with yesterday’s efforts using the Canvas and Image Map web application (now featuring a new emoji button 🗺️🖼️ to allow for a non-dropdown usage approach)) has an ondblclick event logic added so that when double clicking, at any stage of the image map creation processing, it …
opens a new popup window where that HTML you have so far is surrounded by a default “rest of webpage” scenario as the HTML that goes into making up that popup window HTML content, and where you can test out it’s workings … as well as …
that popup window image map, itself, is given an ondblclick event logic whereby a double click there can create below that image map within the same popup window a new textarea element containing all that HTML (default “rest of webpage” and all) which can be copied into a clipboard buffer as required … and …
if that textarea within the popup window is edited and the user double clicks that textarea element, a new popup window reflecting your changes is opened above that … etcetera etcetera etcetera
All this can be used to either/both validate your image map and follow through further to incorporating the image map into a functional HTML webpage, using the changedsignature_signature.js external Javascript to make all this possible. Within that changed external Javascript we allow the user to cancel the proposed area subelement currently embarked upon between where the user has clicked/tapped the bottom left and before they shape to click/tap the top right rectangle definition, via a right click, so as to reset back to the click/tap using the crosshair cursor back at a bottom left area shape=rect subelement definition.
The “largely canvas” using web application last talked about with WordPress Blog Image Editing Media Tutorial, today, we’re excited to announce, has been given an “on first draft just image URL” using new …
Image Map ( ie. <img src=”[image URL as entered by user]” usemap=’#htblah’ blah /><map name=’htblah’ id=htblah><area shape=rect coords=’tlx,tly,brx,bry’ blah> … more area elements blah … blah … blah … <area shape=default nohref alt=”” /></map> ) creator
… arrangement inhouse means to construct image maps, so far, just via an image URL.
Why hook into the largely canvas savvy web application? Well, it is that basic positional mouse event logic that is needed to create image maps, and here, it is a dominant theme, and useful, even though the rearrangement of data needed is quite substantial, still, that is where we think this new functionality appears most at home, being a new suboption (“Image 🖼 Canvas Matches Actual URL or Image Map rectangle area creations“) off a dropdown option means of deploying.
No tests on mobile, yet, but on non-mobile, we’re happy, once the user chooses to create Image Maps, so long as …
we stop user web page scrolling … while still allowing …
webpage zooming out or in
… in conjunction with …
replacing the webpage table’s left cell content, which used to contain a canvas element, with the user defined image, via it’s URL …
replacing the webpage table’s right cell content, which used to contain an canvas annotation menu, with the image map URL HTML built up from user lower left and upper right rectangle defining click/taps
… we have the wherewithal to create image map HTML code the user can copy and use, with “stage two” fleshing out!
… to allow for this image map inhouse functionality. The talents of HTML textarea elements, with their resizing abilities, helps out here, allowing these overlayed textarea elements …
containing image map HTML … and/or …
overlaying semi-transparentally to see what has been clicked already
… also be able to be resized “out of the way” should that be needed perhaps regarding overlapping scenarios, without having to resort to any other type of event logic to allow for. The other big and relevant talent of textarea elements is their ability to contain HTML code and be editable with that HTML code, perhaps user amended, and to be able to Select All then Copy into a clipboard buffer, via it’s right click web browser menu, ready to paste somewhere else, that HTML content ready for any required “stage two” embellishment and usage.
… to add to our recent WordPress Blog Image Editing functionality, extending it’s capabilities to be able to optionally create either/both …
Video
Animated GIF
… media presentations off this should the user pick more than one image, to be edited, in any one web browser tab (via window.sessionStorage) session. So far, we’re creating …
window.open
background image
background-size: contain
… “Video” and “Animated GIF” presentations, and see this as a shareable commodity, into the future, especially as the image slide data ends up being an HTML canvas [canvas].toDataURL() data URI that represents …
lots of data
but understood everywhere
… and content wise has included within it, any canvas manipulations and annotating and reworking the user has applied plus, at least for Google Chrome, any image filtering CSS the user has requested, into that canvas. We shape to involve the cowsayactual web server disk based media creating interfacing, but not for now. We’ll see, because WordPress Visual Synopsis Media Tutorial methodologies also ended up presentation wise, with “inhouse” “Video” and “Animated GIF” presentations.
How does the user make this happen? Well, at the opportune call of our Canvas Image Editor web application some “Mantissa MadnessMagic” takes place using …
… to help create, within the blog posting webpage content, the HTML skeletal necessaries modelled on how WordPress Visual Synopsis Media Tutorial worked it for Visual Synopsis (Slideshows) functionality which included inhouse “Video” and/or “Animated GIF” media presentations.
WordPress Blog Posting Feature Image Editing Tutorial we’re using a hosted HTML iframe window within the blog posting webpage of interest
And that should be a lot easier to handle, yes?! Well, yes, maybe, but not that much easier. A little bit “easier” because the logic is largely funnelled into code that is common to both modus operandi.
In amongst the commonalities, thankfully, the means to get to the “image editing and annotating” and/or “image styling” functionality remains …
Non-mobile right click or spread/pinch mobile gesture on most blog posting images can lead to image editing and annotating functionality, where for animated GIFs first slide is chosen.
We learnt a bit making the mobile ontouchend spread/pinch detection more bulletproof …
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
setTimeout(function(){
document.ontouchend=function(e){
if (document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') != -1) {
lastsp=eval(e.touches.length);
}
if (eval('' + e.touches.length) >= 1) {
if (document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') == -1) {
onrightclickask();
} else if (e.touches[0].target.outerHTML.split('>')[0].indexOf('<img ') == 0 && e.touches[0].target.outerHTML.split('>')[0].indexOf(' tabindex=') != -1) {
onrightclickask(); //document.title=':' + e.touches[0].target.outerHTML.split('>')[0].substring(1);
}
}
};
}, 4000);
}
… but ahead of this, for the TwentyTen theme changes to codex webpage structure we predominantly do with a good ol’ tailored header.php the most effective modified (which is new) codeline now goes …
Running against us regarding One Image Website design ..
Running for us regarding One Image Website design …
the programmatical scrolling means embedded iframe hosting will not work
way window.prompt freezes all Javascript at a snapshot of time …
hashtag navigation can be the conduit to pass data onto inhouse Canvas Editor of Image Data
[canvasContext].drawImage has a variety of useful calls (in that OOP method feel) allowing for dynamic cropping
That “one against” stopped how we envisaged the work at the start of the day. We thought we’d use window.sessionStorage (or maybe window.localStorage) as the only data conduit needed, and we’ll be continuing that idea with another approach into the future, but back to today, hashtagging provided that conduit means, even if we were using data URIs (though all we need today are image absolute URLs).
And then there was “the unknown factor” …
Can [canvasContext].drawImage draw that image with CSS filter styling applied?
Well, we found using Javascript DOM ahead of the new Image() call …
xcelem=document.getElementById('topcanvas');
xccontext = xcelem.getContext("2d");
xcimg=new Image;
xcimg.onload = function(){
var mysx=('' + window.sessionStorage.getItem('user_of_signature_signature_sx')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sx')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The x coordinate where to start clipping
var mysy=('' + window.sessionStorage.getItem('user_of_signature_signature_sy')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sy')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The y coordinate where to start clipping
var myswidth=('' + window.sessionStorage.getItem('user_of_signature_signature_swidth')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_swidth')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The width of the clipped image
var mysheight=('' + window.sessionStorage.getItem('user_of_signature_signature_sheight')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sheight')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The height of the clipped image
var myx=('' + window.sessionStorage.getItem('user_of_signature_signature_x')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_x')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // The x coordinate where to place the image on the canvas
var myy=('' + window.sessionStorage.getItem('user_of_signature_signature_y')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_y')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // The y coordinate where to place the image on the canvas
var mywidth=('' + window.sessionStorage.getItem('user_of_signature_signature_width')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_width')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The width of the image to use (stretch or reduce the image)
var myheight=('' + window.sessionStorage.getItem('user_of_signature_signature_height')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_height')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The height of the image to use (stretch or reduce the image)
if (mywidth != '' && myheight != '') {
xcelem.width=eval('' + mywidth);
xcelem.height=eval('' + myheight);
if (('' + xcimg.style.filter).replace(/^undefined/g,'').replace(/^null/g,'').trim() != '') {
xccontext.filter=xcimg.style.filter;
}
if (myx != '' && myy != '' && myswidth == '' && mysheight == '') {
xccontext.drawImage(xcimg,eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight));
setTimeout(function(){ xccontext.drawImage(xcimg,eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight)); }, 3000);
window.sessionStorage.removeItem('user_of_signature_signature_x');
window.sessionStorage.removeItem('user_of_signature_signature_y');
window.sessionStorage.removeItem('user_of_signature_signature_width');
window.sessionStorage.removeItem('user_of_signature_signature_height');
} else {
xccontext.drawImage(xcimg,eval('' + mysx),eval('' + mysy),eval('' + myswidth),eval('' + mysheight),eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight));
setTimeout(function(){ xccontext.drawImage(xcimg,eval('' + mysx),eval('' + mysy),eval('' + myswidth),eval('' + mysheight),eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight)); }, 3000);
window.sessionStorage.removeItem('user_of_signature_signature_sx');
window.sessionStorage.removeItem('user_of_signature_signature_sy');
window.sessionStorage.removeItem('user_of_signature_signature_swidth');
window.sessionStorage.removeItem('user_of_signature_signature_sheight');
window.sessionStorage.removeItem('user_of_signature_signature_x');
window.sessionStorage.removeItem('user_of_signature_signature_y');
window.sessionStorage.removeItem('user_of_signature_signature_width');
window.sessionStorage.removeItem('user_of_signature_signature_height');
}
} else {
xcelem.width=xcimg.width;
xcelem.height=xcimg.height;
if (('' + xcimg.style.filter).replace(/^undefined/g,'').replace(/^null/g,'').trim() != '') {
xccontext.filter=xcimg.style.filter;
}
xccontext.drawImage(xcimg,0,0);
setTimeout(function(){ xccontext.drawImage(xcimg,0,0); }, 3000);
}
if (window.parent) {
if (parent.document.getElementById('if_image_canvas')) {
if (('' + parent.document.getElementById('if_image_canvas').style.height).replace('px','').trim() != '') {
if (eval('' + ('' + parent.document.getElementById('if_image_canvas').style.height).replace('px','').trim()) < eval(200 + eval('' + xcelem.height))) {
parent.document.getElementById('if_image_canvas').style.height='' + eval(200 + eval('' + xcelem.height)) + 'px';
}
} else {
parent.document.getElementById('if_image_canvas').style.height='' + eval(200 + eval('' + xcelem.height)) + 'px';
}
parent.document.getElementById('if_image_canvas').style.display='block';
if (parent.document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') != -1) {
parent.document.getElementById('if_image_canvas').scrollIntoView();
}
}
}
};
var incomings=('' + window.sessionStorage.getItem('user_of_signature_signature_filter')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_filter')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The image filter CSS styling to apply
if ((incomings.indexOf('%20') != -1 || 7 == 7) && incomings.replace(':',')').indexOf(')') != -1 && incomings.indexOf('style=') != -1) {
incomings='style=' + encodeURIComponent((incomings.split('style=')[1].split('&')[0].split('#')[0]).replace(/\%20/g,' ').replace(/\+/g,' '));
}
var relincomings=incomings.split('style=')[1] ? decodeURIComponent(incomings.split('style=')[1].split('&')[0].split('#')[0]).replace(/\%20/g,' ').replace(/\+/g,' ') : '';
if (relincomings.indexOf('filter:') != -1) {
xcimg.style.filter=relincomings.split('filter:')[1].split(';')[0].split('}')[0];
}
xcimg.src=xcont;
… didn’t help, and then we asked the online woooorrrrrllllddd to come across this very useful link, thanks to teach us …
… with the user able to make this happen with those right click (non-mobile) or pinch or swipe gesture (mobile) actions (talked about with yesterday’s One Image Website SessionStorage Image Filtering Tutorial) getting the user to a prompt window with the modified “blurb” …
Optionally, please, any CSS for images … append three spaces to be able to edit this screenshot in a canvas … ref. https://www.w3schools.com/cssref/css3_pr_filter.php … eg. filter: grayscale(100%);
clientside image filtering functionality to offer …
almost exclusively using window.sessionStorage ideas (rather than our usual window.localStorage (ie. like Cookies) usage)
Why is that last point any big deal? Well, programmers will tell you, often the tidy up of a new arrangement involves as much, or more, coding to do than the instigation. And a lot of programmers, am sure, will agree that that is a pain in the neck, often. But the use of window.sessionStorage at the expense of window.localStorage allows the programmer to go …
Aaaaaahhhhh
There is so much less to tidy up. Using window.sessionStorage it is only data on that web browser tab that comes into play, and as soon as that web browser tab no longer exists, nor does the window.sessionStorage data you stored. Yayyyyyyy!
We found we couldn’t quite make it exclusively with window.sessionStorage because in the One Image Website paradigm of offering music playing we lost window.sessionStorage data for one of the two web browser tabs that become involved to start the music rolling. So sad. Nevertheless, we transferred some controllable temporary window.localStorage data storage over to window.sessionStorage data storage at the opportune time …
How can the non-mobile user access these new aesthetic settings? Via a right click, as our new unfettered layer of functionality option, encapsulated by onrightclick.js external Javascript “proof of concept” effort, on the way to a Javascript prompt window, is the way we’ve gone about it. From there, the user can enter CSS non-selector actions such as the use of CSS filter property.
And as such, it’s worth a revisit of one or all of our reworked One Image Website web applications …
Normal Run …
Run for All Platforms that Presents an Audio Element You Can Play Immmediately
Today, we’ve bitten the bullet, and decided to shore up the webpage scrolling issues that could occur in yesterday’s One Image Website VTT Tracks Tutorial, and before, with our set of One Image Websites. They represent, perhaps, a slightly unusual scenario whereby the image data is allowed to be itself, and being bigger than the dimensions of the webpage (straight from its digital source), in all probability. Hence, the randomized document.body scrolling that occurs.
But up until today our randomized range of scrollLeft and scrollTop positioning that could occur ranged over the entire width and height of the underlying image, while we think we should only be scrolling over the range ([imageWidth] – window.innerWidth (screen width)) x ([imageHeight] – window.innerHeight (screen height)). This could lead to white bands to the right and/or bottom of the webpage, in its presentation. And so we’ve fixed all the Javascript code to replace the old with the new in all the One Image Website codesets …
… and, am sorry, but cannot award any points to those who chose the former, because … well … it’s doubtful we’d mention the second unless we’d done it. And so the answer is … the former … down Nala … the latter!
Today’s blog posting is also a little story about the benefits of what we like to call client pre-emptive iframe logic, whereby we open an HTML iframe element, blazing away with its src attribute pointing at a URL that may or may not exist, and if it does, we do something about its content, usually, in the HTML iframe onload event logic. In our case the URL is a VTT file suiting the One Image Website of relevance given the upload and renaming of the VTTs created using yesterday’s PHP ffmpeg log to VTT file creator web application.
As a programmer who would like to pursue true track cue Javascript coding, develop the function tracks in the One Image Website index-ssmhalf.html you could View -> Page Source from your favourite web browser, for any of …
Normal Run …
Run for All Platforms that Presents an Audio Element You Can Play Immmediately
… where, now, where the user plays music, perhaps continuously (like a radio) with an HTML audio element play button press, the currently playing song, thanks to Royalty Free Music For Video, help you keep in touch with the song playing up at the web browser tab and the image title.
This amounted to Javascript changes, as per …
index.htm …
var foreground=null; // and get rid of var in var foreground below
var plusstuff='';
function ftchange(tob) {
plusstuff=' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
if (document.getElementById('place').title.indexOf(' Playing ') == -1) {
document.getElementById('place').title+=' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
} else {
document.getElementById('place').title=document.getElementById('place').title.split(' Playing ')[0] + ' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
}
}
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i) && document.URL.indexOf('?audio=') == -1) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.body.innerHTML+='<iframe id=ifmusicone title="Play http://www.freesoundtrackmusic.com (thanks) Music Set on Loop Here" src="./index-ssmhalf.html?justmusic=00" style="opacity:0.5;z-index:345;position:absolute;width:140px;height:100px;left:' + eval(-140 + eval('' + window.innerWidth)) + 'px;top:0px;"></iframe>';
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
function FadeInImage()
{ var foreground=document.getElementById("place");
window.clearTimeout("FadeInImage('" + "place" + "')");
rotateImage("place");
}
function rotateImage(place) {
while (number_of_image == 0)
{
place = place;
}
xplace=place;
//alert('yay2');
anotherNew();
var foreground=document.getElementById(place);
//alert(place);
var thedivlink=document.getElementById("thedivlink");
var thediv=document.getElementById("thediv");
if (foreground.width > 0) {
thedivlink.style.display = "none";
thediv.style.display = "none";
if (document.getElementById('ifmusicone')) {
document.getElementById('ifmusicone').style.display='none';
}
//alert('yay2a');
var alink=document.getElementById("alink");
var xxxx=alink.href;
if (xxxx.indexOf("mp3") != -1)
{
//alink.href="index-ssm.html";
//alink.onclick="javascript:void(0);";
alink.href="filewrite.php?id=session&name="+bigrandnumber+"&ext=txt&rand="+bigrandnumber;
alink.onclick="javascript:void(0);";
foreground.onclick="javascript:hasBeenClicked();";
foreground.title="Click for Bamboozled provided by http://www.freesoundtrackmusic.com" + plusstuff;
ffmpeg … with its great logging and media concatenation talents, thanks …
macOS Terminal desktop app … regarding its great GUI design feature allowing you to gather up actions of the past into a copy buffer via its Edit -> Find functionality, thanks
Don’t know about you, but have always found the creation of track data VTT files (and their predecessor SRT files) one of the most tedious jobs in programming?
But the work of the day before yesterday’s One Image Website iOS Radio Music Tutorial and its audio concatenation via ffmpeg themes had us looking back, wistfully, back up our (macOS) Terminal (desktop apps) logging of a few days past, hoping for an escape from VTT file manual text editing for our wish to enhance our One Image Website work of recent days. Wow, the ffmpeg logging was brilliant!
There was enough there to program the creation of VTT files from the ffmpeg, and our “cd”ing and “ls”ing and other stuff, in the (let’s more accurately say, Terminal) logging. Yayyyyy!
If you click the light green form submit button, in the iframe way below, yourself, it will reveal, in details/summary (revealing) tags, both the input and output (VTT files) for you to see this more clearly, or to have it clicked for you in a new window, click this button clicker incarnation. In the works of the HTML form below, for the first time we can remember, and because the defaults are so arcane, we developed HTML form onsubmit logic as per …
… as a way to deal with arcane defaults, where the encouragement is there for an interested programmer to download PHP code (perhaps to a MAMP local Apache/PHP/mySql web server environment) and tweak to their purposes. Note that you can paste your own logging into the textarea as a way this PHP application can be useful even up at the RJM Programming domain …
For tomorrow, we offer an optional “one less click”, “one less window” methodology improvement on the work above, as we transition the other “One Image Websites” over to the new iOS music paradigm.
… and so, it being tomorrow we’re here starting our discussion starting with the “one less window” thought. Have a look at this table outlining some (off the top of the head) clientside navigation techniques in two categories …
No new window created …
New window created …
window.open([URL],’_self’)
window.open([URL],’_blank’)
location.href=[URL]
window.open([URL],’_top’)
window.location=[URL]
top.window.location=[URL]; // if in an iframe
Ajax (with or without new FormData()) whether ‘GET’ or ‘POST’
form target=_blank action=[URL]
form target=_self action=[URL]
form target=_top action=[URL] // if in an iframe
iframe srcdoc=[webpageHTML]
form target=_parent action=[URL] // if in an iframe
iframe src=[URL]
parent.window.location=[URL]; // if in an iframe
… and it’s that last left hand column iframe src=[URL] we like for the purposes of these changes today. That new HTML iframe in the “One Image Website” index.htm supervisories is now worked via …
function rotateImage(place) {
while (number_of_image == 0)
{
place = place;
}
xplace=place;
anotherNew();
var foreground=document.getElementById(place);
var thedivlink=document.getElementById("thedivlink");
var thediv=document.getElementById("thediv");
if (foreground.width > 0) {
thedivlink.style.display = "none";
thediv.style.display = "none";
if (document.getElementById('ifmusicone')) {
document.getElementById('ifmusicone').style.display='none';
}
//
// more rotateImage code follows ...
//
}
//
// more rotateImage code follows ...
//
}
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i)) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.body.innerHTML+='<iframe id=ifmusicone title="Play http://www.freesoundtrackmusic.com (thanks) Music Set on Loop Here" src="./index-ssmhalf.html?justmusic=0" style="opacity:0.5;z-index:345;position:absolute;width:140px;height:100px;left:' + eval(-140 + eval('' + window.innerWidth)) + 'px;top:0px;"></iframe>';
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
… up towards the top right of the index.htm webpage when using an iOS platform. It is optional whether the user …
clicks Play button of that new top right audio element for continuous “looped audio track sets” mode of use with no new second window required (and so, no window focus changes and no second click required either)
clicks blue link for continuous “looped audio track sets” mode of use with a new second window’s audio element that the user clicks the Play button of
clicks none of those modes of use above that are offered for a short time to then click appropriately to start up music, optionally, as required, at a later date as possible
So feel free to try a One Image Website in the list below …
… where this new iOS music arrangement logic has been incorporated.
Stop Press
The Webpage Meta Refresh Primer Tutorial has reminded us of another left hand “No new window created” navigation methodology using the HTML meta “refresh” tag.
… to have a day’s worth of experimenting trialling a solution to the “chestnut of a” problem getting iOS music to play continuously without supervision, like a radio program, albeit on a cycle of repeated content (set (such as the oneoffive.mp3 twooffive.mp3 threeoffive.mp3 fouroffive.mp3 fiveoffive.mp3 set of 5 tracks in example below)). Years ago Apple‘s iOS started requiring a user click to validate the playing of media, hence the interest in today’s topic.
The ingredients for the solution, and testing thereof, are …
optionally, (we’re just suggesting this headphone idea if you want to keep the music to yourself) via Bluetooth, with a set up involving a connection to a set of AirPods (and connected to your ears) … are chosen as …
click the blue link up the top that appears for a short time … then …
in the resultant new music window click the Audio play button presented (the point of interest being that this could be the last click required for continuous music playing, in that audio loop) … music should play continuously and …
if more interesting visuals are also required focus back to calling window
And given that the iPhone and AirPods are charged, and you don’t charge out of Bluetooth range with the iPhone, you could get that “radio feeling” out of an iOS user experience!
Code changes, all just clientside HTML and Javascript, went …
calling window‘s index.htm changes around the document.body onload event area of interest 🎶 …
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i)) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
For tomorrow, we offer an optional “one less click”, “one less window” methodology improvement on the work above, as we transition the other “One Image Websites” over to the new iOS music paradigm.
So, why keep the old way? Well, we packed the “old way” with content rich functionality, and do not want to ditch that yet, but maybe over time?!
We’re just over time, aren’t you?! And so, we arrive at a long planned for tilt at Image Map functionality that we often turn to Mobilefish.Com and its excellent Image Map Creation to help us out … but not today?! Why not? We have a funny set of needs, they being …
our Image Map’s image will have a variable set of width x height dimensions …
our Image Map’s image will be transparent
our Image Map needs to have a hole left aside inside it where the functionality that originally existed (and pointed to WordPress Blog content like you are reading), is still working
… the last condition of which we realized, down the track, required us to create four Image Maps. But … but … Nala hears you say?!
Yes, we can reference the one image, in its data URL guise, as a smaller, or not, version of itself, by specifying CSS properties …
position:absolute; (our usual for overlay scenarios)
z-index:56; (for both transparent image and its associated Image Map … more on this later)
left (to appropriately position in X to be in the relevant section of dark green Image Map overlaying in the Landing Page)
top (to appropriately position in Y to be in the relevant section of dark green Image Map overlaying in the Landing Page)
width (which will be up to the transparent image width)
height (which will be up to the transparent image height)
… and no concern about opacity given the transparent image and z-index considerations, here.
So, how can we involve a transparent image here? Well, that is where the new Responsive Web Design Landing Page being PHP, though up to today it had contained no PHP, is in our favour. We can use PHP’s GD to create one, grab its associated data URL and tidy up, and constructing the four image and associated Image Map HTML elements populated, in its “child iframe”, and sending back up into the “parent webpage’s” new …
function ouralert(innum) {
var ans='';
switch ('' + innum) {
case '1':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '2':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '3':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '4':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.) Eg. https://www.rjmprogramming.com.au/slideshow.html', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '5':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '6':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.) Eg. https://www.rjmprogramming.com.au/plus/', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '7':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '8':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', '');
}
break;
case '9':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', '');
}
break;
default:
break;
}
if (!ans) { ans=''; }
if (ans != '') {
window.open(ans.trim(), '_blank');
if (ans != ans.trim()) {
window.localStorage.setItem('area' + innum + 'url', encodeURIComponent(ans.trim()));
}
}
}
function imbit() {
//if (document.getElementById('myimg')) {
// document.getElementById('myimg').style.border='5px dashed purple';
//}
if (('' + window.localStorage.getItem('area4url')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
urls[3]=decodeURIComponent('' + window.localStorage.getItem('area4url'));
document.getElementById('area4').title=decodeURIComponent('' + window.localStorage.getItem('area4url')) + '# ... long hover of at least 8 seconds for chance to change';
document.getElementById('area4').href=decodeURIComponent('' + window.localStorage.getItem('area4url'));
document.getElementById('area4').onclick=function(){ omoiset=-1; urls[3]=urls[3]; }
//document.getElementById('area4').ondblclick=function(){ ouralert(4); }
}
if (('' + window.localStorage.getItem('area6url')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
urls[5]=decodeURIComponent('' + window.localStorage.getItem('area6url'));
document.getElementById('area6').title=decodeURIComponent('' + window.localStorage.getItem('area6url')) + '# ... long hover of at least 8 seconds for chance to change';
document.getElementById('area6').href=decodeURIComponent('' + window.localStorage.getItem('area6url'));
document.getElementById('area6').onclick=function(){ omoiset=-1; urls[5]=urls[5]; }
//document.getElementById('area6').ondblclick=function(){ ouralert(6); }
}
}
separating out totally “uninvolved” Landing Page calls hooked up with a new index.php (actually just HTML) Landing Page incarnation that has better Responsive Design credentials … from …
any other call of any complexity or having a query string etcetera, reverting to the “old way”
… new paradigm? So, why keep the old way? Well, we packed the “old way” with content rich functionality, and do not want to ditch that yet, but maybe over time?!
Responsive web design (RWD) is an approach to web design that makes web pages render well on a variety of devices and window or screen sizes from minimum to maximum display size. Recent work also considers the viewer proximity as part of the viewing context as an extension for RWD.[1] Content, design and performance are necessary across all devices to ensure usability and satisfaction.[2][3][4][5]
honing in on our “Landing Page and friends” set of unresponsively designed webpages …
honing in on iPhone sized devices (ie. not iPads nor laptops) …
host web browser address bar calls of “Landing Page and friends” set of unresponsively designed webpages within a caller.htmlresponsively web designed shell supervisory webpage and start using some of that …
Onto yesterday’s Inhouse Image Map Creator Tutorial we’ve decided today’s work should stay within non-mobile realms but flesh out more user available functionality to help with “stage two” thinking. With that in mind …
the image map HTML containing textarea created (with yesterday’s efforts using the Canvas and Image Map web application (now featuring a new emoji button 🗺️🖼️ to allow for a non-dropdown usage approach)) has an ondblclick event logic added so that when double clicking, at any stage of the image map creation processing, it …
opens a new popup window where that HTML you have so far is surrounded by a default “rest of webpage” scenario as the HTML that goes into making up that popup window HTML content, and where you can test out it’s workings … as well as …
that popup window image map, itself, is given an ondblclick event logic whereby a double click there can create below that image map within the same popup window a new textarea element containing all that HTML (default “rest of webpage” and all) which can be copied into a clipboard buffer as required … and …
if that textarea within the popup window is edited and the user double clicks that textarea element, a new popup window reflecting your changes is opened above that … etcetera etcetera etcetera
All this can be used to either/both validate your image map and follow through further to incorporating the image map into a functional HTML webpage, using the changedsignature_signature.js external Javascript to make all this possible. Within that changed external Javascript we allow the user to cancel the proposed area subelement currently embarked upon between where the user has clicked/tapped the bottom left and before they shape to click/tap the top right rectangle definition, via a right click, so as to reset back to the click/tap using the crosshair cursor back at a bottom left area shape=rect subelement definition.
The “largely canvas” using web application last talked about with WordPress Blog Image Editing Media Tutorial, today, we’re excited to announce, has been given an “on first draft just image URL” using new …
Image Map ( ie. <img src=”[image URL as entered by user]” usemap=’#htblah’ blah /><map name=’htblah’ id=htblah><area shape=rect coords=’tlx,tly,brx,bry’ blah> … more area elements blah … blah … blah … <area shape=default nohref alt=”” /></map> ) creator
… arrangement inhouse means to construct image maps, so far, just via an image URL.
Why hook into the largely canvas savvy web application? Well, it is that basic positional mouse event logic that is needed to create image maps, and here, it is a dominant theme, and useful, even though the rearrangement of data needed is quite substantial, still, that is where we think this new functionality appears most at home, being a new suboption (“Image 🖼 Canvas Matches Actual URL or Image Map rectangle area creations“) off a dropdown option means of deploying.
No tests on mobile, yet, but on non-mobile, we’re happy, once the user chooses to create Image Maps, so long as …
we stop user web page scrolling … while still allowing …
webpage zooming out or in
… in conjunction with …
replacing the webpage table’s left cell content, which used to contain a canvas element, with the user defined image, via it’s URL …
replacing the webpage table’s right cell content, which used to contain an canvas annotation menu, with the image map URL HTML built up from user lower left and upper right rectangle defining click/taps
… we have the wherewithal to create image map HTML code the user can copy and use, with “stage two” fleshing out!
… to allow for this image map inhouse functionality. The talents of HTML textarea elements, with their resizing abilities, helps out here, allowing these overlayed textarea elements …
containing image map HTML … and/or …
overlaying semi-transparentally to see what has been clicked already
… also be able to be resized “out of the way” should that be needed perhaps regarding overlapping scenarios, without having to resort to any other type of event logic to allow for. The other big and relevant talent of textarea elements is their ability to contain HTML code and be editable with that HTML code, perhaps user amended, and to be able to Select All then Copy into a clipboard buffer, via it’s right click web browser menu, ready to paste somewhere else, that HTML content ready for any required “stage two” embellishment and usage.
… to add to our recent WordPress Blog Image Editing functionality, extending it’s capabilities to be able to optionally create either/both …
Video
Animated GIF
… media presentations off this should the user pick more than one image, to be edited, in any one web browser tab (via window.sessionStorage) session. So far, we’re creating …
window.open
background image
background-size: contain
… “Video” and “Animated GIF” presentations, and see this as a shareable commodity, into the future, especially as the image slide data ends up being an HTML canvas [canvas].toDataURL() data URI that represents …
lots of data
but understood everywhere
… and content wise has included within it, any canvas manipulations and annotating and reworking the user has applied plus, at least for Google Chrome, any image filtering CSS the user has requested, into that canvas. We shape to involve the cowsayactual web server disk based media creating interfacing, but not for now. We’ll see, because WordPress Visual Synopsis Media Tutorial methodologies also ended up presentation wise, with “inhouse” “Video” and “Animated GIF” presentations.
How does the user make this happen? Well, at the opportune call of our Canvas Image Editor web application some “Mantissa MadnessMagic” takes place using …
… to help create, within the blog posting webpage content, the HTML skeletal necessaries modelled on how WordPress Visual Synopsis Media Tutorial worked it for Visual Synopsis (Slideshows) functionality which included inhouse “Video” and/or “Animated GIF” media presentations.
WordPress Blog Posting Feature Image Editing Tutorial we’re using a hosted HTML iframe window within the blog posting webpage of interest
And that should be a lot easier to handle, yes?! Well, yes, maybe, but not that much easier. A little bit “easier” because the logic is largely funnelled into code that is common to both modus operandi.
In amongst the commonalities, thankfully, the means to get to the “image editing and annotating” and/or “image styling” functionality remains …
Non-mobile right click or spread/pinch mobile gesture on most blog posting images can lead to image editing and annotating functionality, where for animated GIFs first slide is chosen.
We learnt a bit making the mobile ontouchend spread/pinch detection more bulletproof …
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
setTimeout(function(){
document.ontouchend=function(e){
if (document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') != -1) {
lastsp=eval(e.touches.length);
}
if (eval('' + e.touches.length) >= 1) {
if (document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') == -1) {
onrightclickask();
} else if (e.touches[0].target.outerHTML.split('>')[0].indexOf('<img ') == 0 && e.touches[0].target.outerHTML.split('>')[0].indexOf(' tabindex=') != -1) {
onrightclickask(); //document.title=':' + e.touches[0].target.outerHTML.split('>')[0].substring(1);
}
}
};
}, 4000);
}
… but ahead of this, for the TwentyTen theme changes to codex webpage structure we predominantly do with a good ol’ tailored header.php the most effective modified (which is new) codeline now goes …
Running against us regarding One Image Website design ..
Running for us regarding One Image Website design …
the programmatical scrolling means embedded iframe hosting will not work
way window.prompt freezes all Javascript at a snapshot of time …
hashtag navigation can be the conduit to pass data onto inhouse Canvas Editor of Image Data
[canvasContext].drawImage has a variety of useful calls (in that OOP method feel) allowing for dynamic cropping
That “one against” stopped how we envisaged the work at the start of the day. We thought we’d use window.sessionStorage (or maybe window.localStorage) as the only data conduit needed, and we’ll be continuing that idea with another approach into the future, but back to today, hashtagging provided that conduit means, even if we were using data URIs (though all we need today are image absolute URLs).
And then there was “the unknown factor” …
Can [canvasContext].drawImage draw that image with CSS filter styling applied?
Well, we found using Javascript DOM ahead of the new Image() call …
xcelem=document.getElementById('topcanvas');
xccontext = xcelem.getContext("2d");
xcimg=new Image;
xcimg.onload = function(){
var mysx=('' + window.sessionStorage.getItem('user_of_signature_signature_sx')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sx')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The x coordinate where to start clipping
var mysy=('' + window.sessionStorage.getItem('user_of_signature_signature_sy')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sy')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The y coordinate where to start clipping
var myswidth=('' + window.sessionStorage.getItem('user_of_signature_signature_swidth')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_swidth')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The width of the clipped image
var mysheight=('' + window.sessionStorage.getItem('user_of_signature_signature_sheight')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sheight')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The height of the clipped image
var myx=('' + window.sessionStorage.getItem('user_of_signature_signature_x')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_x')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // The x coordinate where to place the image on the canvas
var myy=('' + window.sessionStorage.getItem('user_of_signature_signature_y')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_y')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // The y coordinate where to place the image on the canvas
var mywidth=('' + window.sessionStorage.getItem('user_of_signature_signature_width')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_width')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The width of the image to use (stretch or reduce the image)
var myheight=('' + window.sessionStorage.getItem('user_of_signature_signature_height')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_height')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The height of the image to use (stretch or reduce the image)
if (mywidth != '' && myheight != '') {
xcelem.width=eval('' + mywidth);
xcelem.height=eval('' + myheight);
if (('' + xcimg.style.filter).replace(/^undefined/g,'').replace(/^null/g,'').trim() != '') {
xccontext.filter=xcimg.style.filter;
}
if (myx != '' && myy != '' && myswidth == '' && mysheight == '') {
xccontext.drawImage(xcimg,eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight));
setTimeout(function(){ xccontext.drawImage(xcimg,eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight)); }, 3000);
window.sessionStorage.removeItem('user_of_signature_signature_x');
window.sessionStorage.removeItem('user_of_signature_signature_y');
window.sessionStorage.removeItem('user_of_signature_signature_width');
window.sessionStorage.removeItem('user_of_signature_signature_height');
} else {
xccontext.drawImage(xcimg,eval('' + mysx),eval('' + mysy),eval('' + myswidth),eval('' + mysheight),eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight));
setTimeout(function(){ xccontext.drawImage(xcimg,eval('' + mysx),eval('' + mysy),eval('' + myswidth),eval('' + mysheight),eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight)); }, 3000);
window.sessionStorage.removeItem('user_of_signature_signature_sx');
window.sessionStorage.removeItem('user_of_signature_signature_sy');
window.sessionStorage.removeItem('user_of_signature_signature_swidth');
window.sessionStorage.removeItem('user_of_signature_signature_sheight');
window.sessionStorage.removeItem('user_of_signature_signature_x');
window.sessionStorage.removeItem('user_of_signature_signature_y');
window.sessionStorage.removeItem('user_of_signature_signature_width');
window.sessionStorage.removeItem('user_of_signature_signature_height');
}
} else {
xcelem.width=xcimg.width;
xcelem.height=xcimg.height;
if (('' + xcimg.style.filter).replace(/^undefined/g,'').replace(/^null/g,'').trim() != '') {
xccontext.filter=xcimg.style.filter;
}
xccontext.drawImage(xcimg,0,0);
setTimeout(function(){ xccontext.drawImage(xcimg,0,0); }, 3000);
}
if (window.parent) {
if (parent.document.getElementById('if_image_canvas')) {
if (('' + parent.document.getElementById('if_image_canvas').style.height).replace('px','').trim() != '') {
if (eval('' + ('' + parent.document.getElementById('if_image_canvas').style.height).replace('px','').trim()) < eval(200 + eval('' + xcelem.height))) {
parent.document.getElementById('if_image_canvas').style.height='' + eval(200 + eval('' + xcelem.height)) + 'px';
}
} else {
parent.document.getElementById('if_image_canvas').style.height='' + eval(200 + eval('' + xcelem.height)) + 'px';
}
parent.document.getElementById('if_image_canvas').style.display='block';
if (parent.document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') != -1) {
parent.document.getElementById('if_image_canvas').scrollIntoView();
}
}
}
};
var incomings=('' + window.sessionStorage.getItem('user_of_signature_signature_filter')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_filter')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The image filter CSS styling to apply
if ((incomings.indexOf('%20') != -1 || 7 == 7) && incomings.replace(':',')').indexOf(')') != -1 && incomings.indexOf('style=') != -1) {
incomings='style=' + encodeURIComponent((incomings.split('style=')[1].split('&')[0].split('#')[0]).replace(/\%20/g,' ').replace(/\+/g,' '));
}
var relincomings=incomings.split('style=')[1] ? decodeURIComponent(incomings.split('style=')[1].split('&')[0].split('#')[0]).replace(/\%20/g,' ').replace(/\+/g,' ') : '';
if (relincomings.indexOf('filter:') != -1) {
xcimg.style.filter=relincomings.split('filter:')[1].split(';')[0].split('}')[0];
}
xcimg.src=xcont;
… didn’t help, and then we asked the online woooorrrrrllllddd to come across this very useful link, thanks to teach us …
… with the user able to make this happen with those right click (non-mobile) or pinch or swipe gesture (mobile) actions (talked about with yesterday’s One Image Website SessionStorage Image Filtering Tutorial) getting the user to a prompt window with the modified “blurb” …
Optionally, please, any CSS for images … append three spaces to be able to edit this screenshot in a canvas … ref. https://www.w3schools.com/cssref/css3_pr_filter.php … eg. filter: grayscale(100%);
clientside image filtering functionality to offer …
almost exclusively using window.sessionStorage ideas (rather than our usual window.localStorage (ie. like Cookies) usage)
Why is that last point any big deal? Well, programmers will tell you, often the tidy up of a new arrangement involves as much, or more, coding to do than the instigation. And a lot of programmers, am sure, will agree that that is a pain in the neck, often. But the use of window.sessionStorage at the expense of window.localStorage allows the programmer to go …
Aaaaaahhhhh
There is so much less to tidy up. Using window.sessionStorage it is only data on that web browser tab that comes into play, and as soon as that web browser tab no longer exists, nor does the window.sessionStorage data you stored. Yayyyyyyy!
We found we couldn’t quite make it exclusively with window.sessionStorage because in the One Image Website paradigm of offering music playing we lost window.sessionStorage data for one of the two web browser tabs that become involved to start the music rolling. So sad. Nevertheless, we transferred some controllable temporary window.localStorage data storage over to window.sessionStorage data storage at the opportune time …
How can the non-mobile user access these new aesthetic settings? Via a right click, as our new unfettered layer of functionality option, encapsulated by onrightclick.js external Javascript “proof of concept” effort, on the way to a Javascript prompt window, is the way we’ve gone about it. From there, the user can enter CSS non-selector actions such as the use of CSS filter property.
And as such, it’s worth a revisit of one or all of our reworked One Image Website web applications …
Normal Run …
Run for All Platforms that Presents an Audio Element You Can Play Immmediately
Today, we’ve bitten the bullet, and decided to shore up the webpage scrolling issues that could occur in yesterday’s One Image Website VTT Tracks Tutorial, and before, with our set of One Image Websites. They represent, perhaps, a slightly unusual scenario whereby the image data is allowed to be itself, and being bigger than the dimensions of the webpage (straight from its digital source), in all probability. Hence, the randomized document.body scrolling that occurs.
But up until today our randomized range of scrollLeft and scrollTop positioning that could occur ranged over the entire width and height of the underlying image, while we think we should only be scrolling over the range ([imageWidth] – window.innerWidth (screen width)) x ([imageHeight] – window.innerHeight (screen height)). This could lead to white bands to the right and/or bottom of the webpage, in its presentation. And so we’ve fixed all the Javascript code to replace the old with the new in all the One Image Website codesets …
… and, am sorry, but cannot award any points to those who chose the former, because … well … it’s doubtful we’d mention the second unless we’d done it. And so the answer is … the former … down Nala … the latter!
Today’s blog posting is also a little story about the benefits of what we like to call client pre-emptive iframe logic, whereby we open an HTML iframe element, blazing away with its src attribute pointing at a URL that may or may not exist, and if it does, we do something about its content, usually, in the HTML iframe onload event logic. In our case the URL is a VTT file suiting the One Image Website of relevance given the upload and renaming of the VTTs created using yesterday’s PHP ffmpeg log to VTT file creator web application.
As a programmer who would like to pursue true track cue Javascript coding, develop the function tracks in the One Image Website index-ssmhalf.html you could View -> Page Source from your favourite web browser, for any of …
Normal Run …
Run for All Platforms that Presents an Audio Element You Can Play Immmediately
… where, now, where the user plays music, perhaps continuously (like a radio) with an HTML audio element play button press, the currently playing song, thanks to Royalty Free Music For Video, help you keep in touch with the song playing up at the web browser tab and the image title.
This amounted to Javascript changes, as per …
index.htm …
var foreground=null; // and get rid of var in var foreground below
var plusstuff='';
function ftchange(tob) {
plusstuff=' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
if (document.getElementById('place').title.indexOf(' Playing ') == -1) {
document.getElementById('place').title+=' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
} else {
document.getElementById('place').title=document.getElementById('place').title.split(' Playing ')[0] + ' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
}
}
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i) && document.URL.indexOf('?audio=') == -1) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.body.innerHTML+='<iframe id=ifmusicone title="Play http://www.freesoundtrackmusic.com (thanks) Music Set on Loop Here" src="./index-ssmhalf.html?justmusic=00" style="opacity:0.5;z-index:345;position:absolute;width:140px;height:100px;left:' + eval(-140 + eval('' + window.innerWidth)) + 'px;top:0px;"></iframe>';
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
function FadeInImage()
{ var foreground=document.getElementById("place");
window.clearTimeout("FadeInImage('" + "place" + "')");
rotateImage("place");
}
function rotateImage(place) {
while (number_of_image == 0)
{
place = place;
}
xplace=place;
//alert('yay2');
anotherNew();
var foreground=document.getElementById(place);
//alert(place);
var thedivlink=document.getElementById("thedivlink");
var thediv=document.getElementById("thediv");
if (foreground.width > 0) {
thedivlink.style.display = "none";
thediv.style.display = "none";
if (document.getElementById('ifmusicone')) {
document.getElementById('ifmusicone').style.display='none';
}
//alert('yay2a');
var alink=document.getElementById("alink");
var xxxx=alink.href;
if (xxxx.indexOf("mp3") != -1)
{
//alink.href="index-ssm.html";
//alink.onclick="javascript:void(0);";
alink.href="filewrite.php?id=session&name="+bigrandnumber+"&ext=txt&rand="+bigrandnumber;
alink.onclick="javascript:void(0);";
foreground.onclick="javascript:hasBeenClicked();";
foreground.title="Click for Bamboozled provided by http://www.freesoundtrackmusic.com" + plusstuff;
ffmpeg … with its great logging and media concatenation talents, thanks …
macOS Terminal desktop app … regarding its great GUI design feature allowing you to gather up actions of the past into a copy buffer via its Edit -> Find functionality, thanks
Don’t know about you, but have always found the creation of track data VTT files (and their predecessor SRT files) one of the most tedious jobs in programming?
But the work of the day before yesterday’s One Image Website iOS Radio Music Tutorial and its audio concatenation via ffmpeg themes had us looking back, wistfully, back up our (macOS) Terminal (desktop apps) logging of a few days past, hoping for an escape from VTT file manual text editing for our wish to enhance our One Image Website work of recent days. Wow, the ffmpeg logging was brilliant!
There was enough there to program the creation of VTT files from the ffmpeg, and our “cd”ing and “ls”ing and other stuff, in the (let’s more accurately say, Terminal) logging. Yayyyyy!
If you click the light green form submit button, in the iframe way below, yourself, it will reveal, in details/summary (revealing) tags, both the input and output (VTT files) for you to see this more clearly, or to have it clicked for you in a new window, click this button clicker incarnation. In the works of the HTML form below, for the first time we can remember, and because the defaults are so arcane, we developed HTML form onsubmit logic as per …
… as a way to deal with arcane defaults, where the encouragement is there for an interested programmer to download PHP code (perhaps to a MAMP local Apache/PHP/mySql web server environment) and tweak to their purposes. Note that you can paste your own logging into the textarea as a way this PHP application can be useful even up at the RJM Programming domain …
For tomorrow, we offer an optional “one less click”, “one less window” methodology improvement on the work above, as we transition the other “One Image Websites” over to the new iOS music paradigm.
… and so, it being tomorrow we’re here starting our discussion starting with the “one less window” thought. Have a look at this table outlining some (off the top of the head) clientside navigation techniques in two categories …
No new window created …
New window created …
window.open([URL],’_self’)
window.open([URL],’_blank’)
location.href=[URL]
window.open([URL],’_top’)
window.location=[URL]
top.window.location=[URL]; // if in an iframe
Ajax (with or without new FormData()) whether ‘GET’ or ‘POST’
form target=_blank action=[URL]
form target=_self action=[URL]
form target=_top action=[URL] // if in an iframe
iframe srcdoc=[webpageHTML]
form target=_parent action=[URL] // if in an iframe
iframe src=[URL]
parent.window.location=[URL]; // if in an iframe
… and it’s that last left hand column iframe src=[URL] we like for the purposes of these changes today. That new HTML iframe in the “One Image Website” index.htm supervisories is now worked via …
function rotateImage(place) {
while (number_of_image == 0)
{
place = place;
}
xplace=place;
anotherNew();
var foreground=document.getElementById(place);
var thedivlink=document.getElementById("thedivlink");
var thediv=document.getElementById("thediv");
if (foreground.width > 0) {
thedivlink.style.display = "none";
thediv.style.display = "none";
if (document.getElementById('ifmusicone')) {
document.getElementById('ifmusicone').style.display='none';
}
//
// more rotateImage code follows ...
//
}
//
// more rotateImage code follows ...
//
}
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i)) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.body.innerHTML+='<iframe id=ifmusicone title="Play http://www.freesoundtrackmusic.com (thanks) Music Set on Loop Here" src="./index-ssmhalf.html?justmusic=0" style="opacity:0.5;z-index:345;position:absolute;width:140px;height:100px;left:' + eval(-140 + eval('' + window.innerWidth)) + 'px;top:0px;"></iframe>';
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
… up towards the top right of the index.htm webpage when using an iOS platform. It is optional whether the user …
clicks Play button of that new top right audio element for continuous “looped audio track sets” mode of use with no new second window required (and so, no window focus changes and no second click required either)
clicks blue link for continuous “looped audio track sets” mode of use with a new second window’s audio element that the user clicks the Play button of
clicks none of those modes of use above that are offered for a short time to then click appropriately to start up music, optionally, as required, at a later date as possible
So feel free to try a One Image Website in the list below …
… where this new iOS music arrangement logic has been incorporated.
Stop Press
The Webpage Meta Refresh Primer Tutorial has reminded us of another left hand “No new window created” navigation methodology using the HTML meta “refresh” tag.
… to have a day’s worth of experimenting trialling a solution to the “chestnut of a” problem getting iOS music to play continuously without supervision, like a radio program, albeit on a cycle of repeated content (set (such as the oneoffive.mp3 twooffive.mp3 threeoffive.mp3 fouroffive.mp3 fiveoffive.mp3 set of 5 tracks in example below)). Years ago Apple‘s iOS started requiring a user click to validate the playing of media, hence the interest in today’s topic.
The ingredients for the solution, and testing thereof, are …
optionally, (we’re just suggesting this headphone idea if you want to keep the music to yourself) via Bluetooth, with a set up involving a connection to a set of AirPods (and connected to your ears) … are chosen as …
click the blue link up the top that appears for a short time … then …
in the resultant new music window click the Audio play button presented (the point of interest being that this could be the last click required for continuous music playing, in that audio loop) … music should play continuously and …
if more interesting visuals are also required focus back to calling window
And given that the iPhone and AirPods are charged, and you don’t charge out of Bluetooth range with the iPhone, you could get that “radio feeling” out of an iOS user experience!
Code changes, all just clientside HTML and Javascript, went …
calling window‘s index.htm changes around the document.body onload event area of interest 🎶 …
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i)) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
For tomorrow, we offer an optional “one less click”, “one less window” methodology improvement on the work above, as we transition the other “One Image Websites” over to the new iOS music paradigm.
So, why keep the old way? Well, we packed the “old way” with content rich functionality, and do not want to ditch that yet, but maybe over time?!
We’re just over time, aren’t you?! And so, we arrive at a long planned for tilt at Image Map functionality that we often turn to Mobilefish.Com and its excellent Image Map Creation to help us out … but not today?! Why not? We have a funny set of needs, they being …
our Image Map’s image will have a variable set of width x height dimensions …
our Image Map’s image will be transparent
our Image Map needs to have a hole left aside inside it where the functionality that originally existed (and pointed to WordPress Blog content like you are reading), is still working
… the last condition of which we realized, down the track, required us to create four Image Maps. But … but … Nala hears you say?!
Yes, we can reference the one image, in its data URL guise, as a smaller, or not, version of itself, by specifying CSS properties …
position:absolute; (our usual for overlay scenarios)
z-index:56; (for both transparent image and its associated Image Map … more on this later)
left (to appropriately position in X to be in the relevant section of dark green Image Map overlaying in the Landing Page)
top (to appropriately position in Y to be in the relevant section of dark green Image Map overlaying in the Landing Page)
width (which will be up to the transparent image width)
height (which will be up to the transparent image height)
… and no concern about opacity given the transparent image and z-index considerations, here.
So, how can we involve a transparent image here? Well, that is where the new Responsive Web Design Landing Page being PHP, though up to today it had contained no PHP, is in our favour. We can use PHP’s GD to create one, grab its associated data URL and tidy up, and constructing the four image and associated Image Map HTML elements populated, in its “child iframe”, and sending back up into the “parent webpage’s” new …
function ouralert(innum) {
var ans='';
switch ('' + innum) {
case '1':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '2':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '3':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '4':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.) Eg. https://www.rjmprogramming.com.au/slideshow.html', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '5':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '6':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.) Eg. https://www.rjmprogramming.com.au/plus/', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '7':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '8':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', '');
}
break;
case '9':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', '');
}
break;
default:
break;
}
if (!ans) { ans=''; }
if (ans != '') {
window.open(ans.trim(), '_blank');
if (ans != ans.trim()) {
window.localStorage.setItem('area' + innum + 'url', encodeURIComponent(ans.trim()));
}
}
}
function imbit() {
//if (document.getElementById('myimg')) {
// document.getElementById('myimg').style.border='5px dashed purple';
//}
if (('' + window.localStorage.getItem('area4url')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
urls[3]=decodeURIComponent('' + window.localStorage.getItem('area4url'));
document.getElementById('area4').title=decodeURIComponent('' + window.localStorage.getItem('area4url')) + '# ... long hover of at least 8 seconds for chance to change';
document.getElementById('area4').href=decodeURIComponent('' + window.localStorage.getItem('area4url'));
document.getElementById('area4').onclick=function(){ omoiset=-1; urls[3]=urls[3]; }
//document.getElementById('area4').ondblclick=function(){ ouralert(4); }
}
if (('' + window.localStorage.getItem('area6url')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
urls[5]=decodeURIComponent('' + window.localStorage.getItem('area6url'));
document.getElementById('area6').title=decodeURIComponent('' + window.localStorage.getItem('area6url')) + '# ... long hover of at least 8 seconds for chance to change';
document.getElementById('area6').href=decodeURIComponent('' + window.localStorage.getItem('area6url'));
document.getElementById('area6').onclick=function(){ omoiset=-1; urls[5]=urls[5]; }
//document.getElementById('area6').ondblclick=function(){ ouralert(6); }
}
}
separating out totally “uninvolved” Landing Page calls hooked up with a new index.php (actually just HTML) Landing Page incarnation that has better Responsive Design credentials … from …
any other call of any complexity or having a query string etcetera, reverting to the “old way”
… new paradigm? So, why keep the old way? Well, we packed the “old way” with content rich functionality, and do not want to ditch that yet, but maybe over time?!
Responsive web design (RWD) is an approach to web design that makes web pages render well on a variety of devices and window or screen sizes from minimum to maximum display size. Recent work also considers the viewer proximity as part of the viewing context as an extension for RWD.[1] Content, design and performance are necessary across all devices to ensure usability and satisfaction.[2][3][4][5]
honing in on our “Landing Page and friends” set of unresponsively designed webpages …
honing in on iPhone sized devices (ie. not iPads nor laptops) …
host web browser address bar calls of “Landing Page and friends” set of unresponsively designed webpages within a caller.htmlresponsively web designed shell supervisory webpage and start using some of that …
The “largely canvas” using web application last talked about with WordPress Blog Image Editing Media Tutorial, today, we’re excited to announce, has been given an “on first draft just image URL” using new …
Image Map ( ie. <img src=”[image URL as entered by user]” usemap=’#htblah’ blah /><map name=’htblah’ id=htblah><area shape=rect coords=’tlx,tly,brx,bry’ blah> … more area elements blah … blah … blah … <area shape=default nohref alt=”” /></map> ) creator
… arrangement inhouse means to construct image maps, so far, just via an image URL.
Why hook into the largely canvas savvy web application? Well, it is that basic positional mouse event logic that is needed to create image maps, and here, it is a dominant theme, and useful, even though the rearrangement of data needed is quite substantial, still, that is where we think this new functionality appears most at home, being a new suboption (“Image 🖼 Canvas Matches Actual URL or Image Map rectangle area creations“) off a dropdown option means of deploying.
No tests on mobile, yet, but on non-mobile, we’re happy, once the user chooses to create Image Maps, so long as …
we stop user web page scrolling … while still allowing …
webpage zooming out or in
… in conjunction with …
replacing the webpage table’s left cell content, which used to contain a canvas element, with the user defined image, via it’s URL …
replacing the webpage table’s right cell content, which used to contain an canvas annotation menu, with the image map URL HTML built up from user lower left and upper right rectangle defining click/taps
… we have the wherewithal to create image map HTML code the user can copy and use, with “stage two” fleshing out!
… to allow for this image map inhouse functionality. The talents of HTML textarea elements, with their resizing abilities, helps out here, allowing these overlayed textarea elements …
containing image map HTML … and/or …
overlaying semi-transparentally to see what has been clicked already
… also be able to be resized “out of the way” should that be needed perhaps regarding overlapping scenarios, without having to resort to any other type of event logic to allow for. The other big and relevant talent of textarea elements is their ability to contain HTML code and be editable with that HTML code, perhaps user amended, and to be able to Select All then Copy into a clipboard buffer, via it’s right click web browser menu, ready to paste somewhere else, that HTML content ready for any required “stage two” embellishment and usage.
… to add to our recent WordPress Blog Image Editing functionality, extending it’s capabilities to be able to optionally create either/both …
Video
Animated GIF
… media presentations off this should the user pick more than one image, to be edited, in any one web browser tab (via window.sessionStorage) session. So far, we’re creating …
window.open
background image
background-size: contain
… “Video” and “Animated GIF” presentations, and see this as a shareable commodity, into the future, especially as the image slide data ends up being an HTML canvas [canvas].toDataURL() data URI that represents …
lots of data
but understood everywhere
… and content wise has included within it, any canvas manipulations and annotating and reworking the user has applied plus, at least for Google Chrome, any image filtering CSS the user has requested, into that canvas. We shape to involve the cowsayactual web server disk based media creating interfacing, but not for now. We’ll see, because WordPress Visual Synopsis Media Tutorial methodologies also ended up presentation wise, with “inhouse” “Video” and “Animated GIF” presentations.
How does the user make this happen? Well, at the opportune call of our Canvas Image Editor web application some “Mantissa MadnessMagic” takes place using …
… to help create, within the blog posting webpage content, the HTML skeletal necessaries modelled on how WordPress Visual Synopsis Media Tutorial worked it for Visual Synopsis (Slideshows) functionality which included inhouse “Video” and/or “Animated GIF” media presentations.
WordPress Blog Posting Feature Image Editing Tutorial we’re using a hosted HTML iframe window within the blog posting webpage of interest
And that should be a lot easier to handle, yes?! Well, yes, maybe, but not that much easier. A little bit “easier” because the logic is largely funnelled into code that is common to both modus operandi.
In amongst the commonalities, thankfully, the means to get to the “image editing and annotating” and/or “image styling” functionality remains …
Non-mobile right click or spread/pinch mobile gesture on most blog posting images can lead to image editing and annotating functionality, where for animated GIFs first slide is chosen.
We learnt a bit making the mobile ontouchend spread/pinch detection more bulletproof …
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
setTimeout(function(){
document.ontouchend=function(e){
if (document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') != -1) {
lastsp=eval(e.touches.length);
}
if (eval('' + e.touches.length) >= 1) {
if (document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') == -1) {
onrightclickask();
} else if (e.touches[0].target.outerHTML.split('>')[0].indexOf('<img ') == 0 && e.touches[0].target.outerHTML.split('>')[0].indexOf(' tabindex=') != -1) {
onrightclickask(); //document.title=':' + e.touches[0].target.outerHTML.split('>')[0].substring(1);
}
}
};
}, 4000);
}
… but ahead of this, for the TwentyTen theme changes to codex webpage structure we predominantly do with a good ol’ tailored header.php the most effective modified (which is new) codeline now goes …
Running against us regarding One Image Website design ..
Running for us regarding One Image Website design …
the programmatical scrolling means embedded iframe hosting will not work
way window.prompt freezes all Javascript at a snapshot of time …
hashtag navigation can be the conduit to pass data onto inhouse Canvas Editor of Image Data
[canvasContext].drawImage has a variety of useful calls (in that OOP method feel) allowing for dynamic cropping
That “one against” stopped how we envisaged the work at the start of the day. We thought we’d use window.sessionStorage (or maybe window.localStorage) as the only data conduit needed, and we’ll be continuing that idea with another approach into the future, but back to today, hashtagging provided that conduit means, even if we were using data URIs (though all we need today are image absolute URLs).
And then there was “the unknown factor” …
Can [canvasContext].drawImage draw that image with CSS filter styling applied?
Well, we found using Javascript DOM ahead of the new Image() call …
xcelem=document.getElementById('topcanvas');
xccontext = xcelem.getContext("2d");
xcimg=new Image;
xcimg.onload = function(){
var mysx=('' + window.sessionStorage.getItem('user_of_signature_signature_sx')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sx')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The x coordinate where to start clipping
var mysy=('' + window.sessionStorage.getItem('user_of_signature_signature_sy')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sy')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The y coordinate where to start clipping
var myswidth=('' + window.sessionStorage.getItem('user_of_signature_signature_swidth')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_swidth')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The width of the clipped image
var mysheight=('' + window.sessionStorage.getItem('user_of_signature_signature_sheight')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_sheight')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The height of the clipped image
var myx=('' + window.sessionStorage.getItem('user_of_signature_signature_x')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_x')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // The x coordinate where to place the image on the canvas
var myy=('' + window.sessionStorage.getItem('user_of_signature_signature_y')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_y')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // The y coordinate where to place the image on the canvas
var mywidth=('' + window.sessionStorage.getItem('user_of_signature_signature_width')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_width')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The width of the image to use (stretch or reduce the image)
var myheight=('' + window.sessionStorage.getItem('user_of_signature_signature_height')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_height')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The height of the image to use (stretch or reduce the image)
if (mywidth != '' && myheight != '') {
xcelem.width=eval('' + mywidth);
xcelem.height=eval('' + myheight);
if (('' + xcimg.style.filter).replace(/^undefined/g,'').replace(/^null/g,'').trim() != '') {
xccontext.filter=xcimg.style.filter;
}
if (myx != '' && myy != '' && myswidth == '' && mysheight == '') {
xccontext.drawImage(xcimg,eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight));
setTimeout(function(){ xccontext.drawImage(xcimg,eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight)); }, 3000);
window.sessionStorage.removeItem('user_of_signature_signature_x');
window.sessionStorage.removeItem('user_of_signature_signature_y');
window.sessionStorage.removeItem('user_of_signature_signature_width');
window.sessionStorage.removeItem('user_of_signature_signature_height');
} else {
xccontext.drawImage(xcimg,eval('' + mysx),eval('' + mysy),eval('' + myswidth),eval('' + mysheight),eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight));
setTimeout(function(){ xccontext.drawImage(xcimg,eval('' + mysx),eval('' + mysy),eval('' + myswidth),eval('' + mysheight),eval('' + myx),eval('' + myy),eval('' + mywidth),eval('' + myheight)); }, 3000);
window.sessionStorage.removeItem('user_of_signature_signature_sx');
window.sessionStorage.removeItem('user_of_signature_signature_sy');
window.sessionStorage.removeItem('user_of_signature_signature_swidth');
window.sessionStorage.removeItem('user_of_signature_signature_sheight');
window.sessionStorage.removeItem('user_of_signature_signature_x');
window.sessionStorage.removeItem('user_of_signature_signature_y');
window.sessionStorage.removeItem('user_of_signature_signature_width');
window.sessionStorage.removeItem('user_of_signature_signature_height');
}
} else {
xcelem.width=xcimg.width;
xcelem.height=xcimg.height;
if (('' + xcimg.style.filter).replace(/^undefined/g,'').replace(/^null/g,'').trim() != '') {
xccontext.filter=xcimg.style.filter;
}
xccontext.drawImage(xcimg,0,0);
setTimeout(function(){ xccontext.drawImage(xcimg,0,0); }, 3000);
}
if (window.parent) {
if (parent.document.getElementById('if_image_canvas')) {
if (('' + parent.document.getElementById('if_image_canvas').style.height).replace('px','').trim() != '') {
if (eval('' + ('' + parent.document.getElementById('if_image_canvas').style.height).replace('px','').trim()) < eval(200 + eval('' + xcelem.height))) {
parent.document.getElementById('if_image_canvas').style.height='' + eval(200 + eval('' + xcelem.height)) + 'px';
}
} else {
parent.document.getElementById('if_image_canvas').style.height='' + eval(200 + eval('' + xcelem.height)) + 'px';
}
parent.document.getElementById('if_image_canvas').style.display='block';
if (parent.document.URL.replace('/wordpress','/ITblog').indexOf('/ITblog') != -1) {
parent.document.getElementById('if_image_canvas').scrollIntoView();
}
}
}
};
var incomings=('' + window.sessionStorage.getItem('user_of_signature_signature_filter')).replace(/^undefined/g,'').replace(/^null/g,'') != '' ? ('' + window.sessionStorage.getItem('user_of_signature_signature_filter')).replace(/^undefined/g,'').replace(/^null/g,'') : ''; // Optional. The image filter CSS styling to apply
if ((incomings.indexOf('%20') != -1 || 7 == 7) && incomings.replace(':',')').indexOf(')') != -1 && incomings.indexOf('style=') != -1) {
incomings='style=' + encodeURIComponent((incomings.split('style=')[1].split('&')[0].split('#')[0]).replace(/\%20/g,' ').replace(/\+/g,' '));
}
var relincomings=incomings.split('style=')[1] ? decodeURIComponent(incomings.split('style=')[1].split('&')[0].split('#')[0]).replace(/\%20/g,' ').replace(/\+/g,' ') : '';
if (relincomings.indexOf('filter:') != -1) {
xcimg.style.filter=relincomings.split('filter:')[1].split(';')[0].split('}')[0];
}
xcimg.src=xcont;
… didn’t help, and then we asked the online woooorrrrrllllddd to come across this very useful link, thanks to teach us …
… with the user able to make this happen with those right click (non-mobile) or pinch or swipe gesture (mobile) actions (talked about with yesterday’s One Image Website SessionStorage Image Filtering Tutorial) getting the user to a prompt window with the modified “blurb” …
Optionally, please, any CSS for images … append three spaces to be able to edit this screenshot in a canvas … ref. https://www.w3schools.com/cssref/css3_pr_filter.php … eg. filter: grayscale(100%);
clientside image filtering functionality to offer …
almost exclusively using window.sessionStorage ideas (rather than our usual window.localStorage (ie. like Cookies) usage)
Why is that last point any big deal? Well, programmers will tell you, often the tidy up of a new arrangement involves as much, or more, coding to do than the instigation. And a lot of programmers, am sure, will agree that that is a pain in the neck, often. But the use of window.sessionStorage at the expense of window.localStorage allows the programmer to go …
Aaaaaahhhhh
There is so much less to tidy up. Using window.sessionStorage it is only data on that web browser tab that comes into play, and as soon as that web browser tab no longer exists, nor does the window.sessionStorage data you stored. Yayyyyyyy!
We found we couldn’t quite make it exclusively with window.sessionStorage because in the One Image Website paradigm of offering music playing we lost window.sessionStorage data for one of the two web browser tabs that become involved to start the music rolling. So sad. Nevertheless, we transferred some controllable temporary window.localStorage data storage over to window.sessionStorage data storage at the opportune time …
How can the non-mobile user access these new aesthetic settings? Via a right click, as our new unfettered layer of functionality option, encapsulated by onrightclick.js external Javascript “proof of concept” effort, on the way to a Javascript prompt window, is the way we’ve gone about it. From there, the user can enter CSS non-selector actions such as the use of CSS filter property.
And as such, it’s worth a revisit of one or all of our reworked One Image Website web applications …
Normal Run …
Run for All Platforms that Presents an Audio Element You Can Play Immmediately
Today, we’ve bitten the bullet, and decided to shore up the webpage scrolling issues that could occur in yesterday’s One Image Website VTT Tracks Tutorial, and before, with our set of One Image Websites. They represent, perhaps, a slightly unusual scenario whereby the image data is allowed to be itself, and being bigger than the dimensions of the webpage (straight from its digital source), in all probability. Hence, the randomized document.body scrolling that occurs.
But up until today our randomized range of scrollLeft and scrollTop positioning that could occur ranged over the entire width and height of the underlying image, while we think we should only be scrolling over the range ([imageWidth] – window.innerWidth (screen width)) x ([imageHeight] – window.innerHeight (screen height)). This could lead to white bands to the right and/or bottom of the webpage, in its presentation. And so we’ve fixed all the Javascript code to replace the old with the new in all the One Image Website codesets …
… and, am sorry, but cannot award any points to those who chose the former, because … well … it’s doubtful we’d mention the second unless we’d done it. And so the answer is … the former … down Nala … the latter!
Today’s blog posting is also a little story about the benefits of what we like to call client pre-emptive iframe logic, whereby we open an HTML iframe element, blazing away with its src attribute pointing at a URL that may or may not exist, and if it does, we do something about its content, usually, in the HTML iframe onload event logic. In our case the URL is a VTT file suiting the One Image Website of relevance given the upload and renaming of the VTTs created using yesterday’s PHP ffmpeg log to VTT file creator web application.
As a programmer who would like to pursue true track cue Javascript coding, develop the function tracks in the One Image Website index-ssmhalf.html you could View -> Page Source from your favourite web browser, for any of …
Normal Run …
Run for All Platforms that Presents an Audio Element You Can Play Immmediately
… where, now, where the user plays music, perhaps continuously (like a radio) with an HTML audio element play button press, the currently playing song, thanks to Royalty Free Music For Video, help you keep in touch with the song playing up at the web browser tab and the image title.
This amounted to Javascript changes, as per …
index.htm …
var foreground=null; // and get rid of var in var foreground below
var plusstuff='';
function ftchange(tob) {
plusstuff=' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
if (document.getElementById('place').title.indexOf(' Playing ') == -1) {
document.getElementById('place').title+=' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
} else {
document.getElementById('place').title=document.getElementById('place').title.split(' Playing ')[0] + ' Playing ' + tob + ' thanks to http://www.freesoundtrackmusic.com ';
}
}
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i) && document.URL.indexOf('?audio=') == -1) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.body.innerHTML+='<iframe id=ifmusicone title="Play http://www.freesoundtrackmusic.com (thanks) Music Set on Loop Here" src="./index-ssmhalf.html?justmusic=00" style="opacity:0.5;z-index:345;position:absolute;width:140px;height:100px;left:' + eval(-140 + eval('' + window.innerWidth)) + 'px;top:0px;"></iframe>';
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
function FadeInImage()
{ var foreground=document.getElementById("place");
window.clearTimeout("FadeInImage('" + "place" + "')");
rotateImage("place");
}
function rotateImage(place) {
while (number_of_image == 0)
{
place = place;
}
xplace=place;
//alert('yay2');
anotherNew();
var foreground=document.getElementById(place);
//alert(place);
var thedivlink=document.getElementById("thedivlink");
var thediv=document.getElementById("thediv");
if (foreground.width > 0) {
thedivlink.style.display = "none";
thediv.style.display = "none";
if (document.getElementById('ifmusicone')) {
document.getElementById('ifmusicone').style.display='none';
}
//alert('yay2a');
var alink=document.getElementById("alink");
var xxxx=alink.href;
if (xxxx.indexOf("mp3") != -1)
{
//alink.href="index-ssm.html";
//alink.onclick="javascript:void(0);";
alink.href="filewrite.php?id=session&name="+bigrandnumber+"&ext=txt&rand="+bigrandnumber;
alink.onclick="javascript:void(0);";
foreground.onclick="javascript:hasBeenClicked();";
foreground.title="Click for Bamboozled provided by http://www.freesoundtrackmusic.com" + plusstuff;
ffmpeg … with its great logging and media concatenation talents, thanks …
macOS Terminal desktop app … regarding its great GUI design feature allowing you to gather up actions of the past into a copy buffer via its Edit -> Find functionality, thanks
Don’t know about you, but have always found the creation of track data VTT files (and their predecessor SRT files) one of the most tedious jobs in programming?
But the work of the day before yesterday’s One Image Website iOS Radio Music Tutorial and its audio concatenation via ffmpeg themes had us looking back, wistfully, back up our (macOS) Terminal (desktop apps) logging of a few days past, hoping for an escape from VTT file manual text editing for our wish to enhance our One Image Website work of recent days. Wow, the ffmpeg logging was brilliant!
There was enough there to program the creation of VTT files from the ffmpeg, and our “cd”ing and “ls”ing and other stuff, in the (let’s more accurately say, Terminal) logging. Yayyyyy!
If you click the light green form submit button, in the iframe way below, yourself, it will reveal, in details/summary (revealing) tags, both the input and output (VTT files) for you to see this more clearly, or to have it clicked for you in a new window, click this button clicker incarnation. In the works of the HTML form below, for the first time we can remember, and because the defaults are so arcane, we developed HTML form onsubmit logic as per …
… as a way to deal with arcane defaults, where the encouragement is there for an interested programmer to download PHP code (perhaps to a MAMP local Apache/PHP/mySql web server environment) and tweak to their purposes. Note that you can paste your own logging into the textarea as a way this PHP application can be useful even up at the RJM Programming domain …
For tomorrow, we offer an optional “one less click”, “one less window” methodology improvement on the work above, as we transition the other “One Image Websites” over to the new iOS music paradigm.
… and so, it being tomorrow we’re here starting our discussion starting with the “one less window” thought. Have a look at this table outlining some (off the top of the head) clientside navigation techniques in two categories …
No new window created …
New window created …
window.open([URL],’_self’)
window.open([URL],’_blank’)
location.href=[URL]
window.open([URL],’_top’)
window.location=[URL]
top.window.location=[URL]; // if in an iframe
Ajax (with or without new FormData()) whether ‘GET’ or ‘POST’
form target=_blank action=[URL]
form target=_self action=[URL]
form target=_top action=[URL] // if in an iframe
iframe srcdoc=[webpageHTML]
form target=_parent action=[URL] // if in an iframe
iframe src=[URL]
parent.window.location=[URL]; // if in an iframe
… and it’s that last left hand column iframe src=[URL] we like for the purposes of these changes today. That new HTML iframe in the “One Image Website” index.htm supervisories is now worked via …
function rotateImage(place) {
while (number_of_image == 0)
{
place = place;
}
xplace=place;
anotherNew();
var foreground=document.getElementById(place);
var thedivlink=document.getElementById("thedivlink");
var thediv=document.getElementById("thediv");
if (foreground.width > 0) {
thedivlink.style.display = "none";
thediv.style.display = "none";
if (document.getElementById('ifmusicone')) {
document.getElementById('ifmusicone').style.display='none';
}
//
// more rotateImage code follows ...
//
}
//
// more rotateImage code follows ...
//
}
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i)) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.body.innerHTML+='<iframe id=ifmusicone title="Play http://www.freesoundtrackmusic.com (thanks) Music Set on Loop Here" src="./index-ssmhalf.html?justmusic=0" style="opacity:0.5;z-index:345;position:absolute;width:140px;height:100px;left:' + eval(-140 + eval('' + window.innerWidth)) + 'px;top:0px;"></iframe>';
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
… up towards the top right of the index.htm webpage when using an iOS platform. It is optional whether the user …
clicks Play button of that new top right audio element for continuous “looped audio track sets” mode of use with no new second window required (and so, no window focus changes and no second click required either)
clicks blue link for continuous “looped audio track sets” mode of use with a new second window’s audio element that the user clicks the Play button of
clicks none of those modes of use above that are offered for a short time to then click appropriately to start up music, optionally, as required, at a later date as possible
So feel free to try a One Image Website in the list below …
… where this new iOS music arrangement logic has been incorporated.
Stop Press
The Webpage Meta Refresh Primer Tutorial has reminded us of another left hand “No new window created” navigation methodology using the HTML meta “refresh” tag.
… to have a day’s worth of experimenting trialling a solution to the “chestnut of a” problem getting iOS music to play continuously without supervision, like a radio program, albeit on a cycle of repeated content (set (such as the oneoffive.mp3 twooffive.mp3 threeoffive.mp3 fouroffive.mp3 fiveoffive.mp3 set of 5 tracks in example below)). Years ago Apple‘s iOS started requiring a user click to validate the playing of media, hence the interest in today’s topic.
The ingredients for the solution, and testing thereof, are …
optionally, (we’re just suggesting this headphone idea if you want to keep the music to yourself) via Bluetooth, with a set up involving a connection to a set of AirPods (and connected to your ears) … are chosen as …
click the blue link up the top that appears for a short time … then …
in the resultant new music window click the Audio play button presented (the point of interest being that this could be the last click required for continuous music playing, in that audio loop) … music should play continuously and …
if more interesting visuals are also required focus back to calling window
And given that the iPhone and AirPods are charged, and you don’t charge out of Bluetooth range with the iPhone, you could get that “radio feeling” out of an iOS user experience!
Code changes, all just clientside HTML and Javascript, went …
calling window‘s index.htm changes around the document.body onload event area of interest 🎶 …
function xonl() {
if (!navigator.userAgent.match(/iPhone|iPod|iPad/i)) {
document.getElementById('thedivlink').href=document.getElementById('thedivlink').getAttribute('data-href');
} else {
document.getElementById('thedivlink').href='index-ssmhalf.html?justmusic=';
document.getElementById('thedivlink').onclick=function() { document.getElementById('thedivlink').href=document.getElementById('thedivlink').href; };
document.getElementById('thedivlink').target='_blank';
}
}
For tomorrow, we offer an optional “one less click”, “one less window” methodology improvement on the work above, as we transition the other “One Image Websites” over to the new iOS music paradigm.
So, why keep the old way? Well, we packed the “old way” with content rich functionality, and do not want to ditch that yet, but maybe over time?!
We’re just over time, aren’t you?! And so, we arrive at a long planned for tilt at Image Map functionality that we often turn to Mobilefish.Com and its excellent Image Map Creation to help us out … but not today?! Why not? We have a funny set of needs, they being …
our Image Map’s image will have a variable set of width x height dimensions …
our Image Map’s image will be transparent
our Image Map needs to have a hole left aside inside it where the functionality that originally existed (and pointed to WordPress Blog content like you are reading), is still working
… the last condition of which we realized, down the track, required us to create four Image Maps. But … but … Nala hears you say?!
Yes, we can reference the one image, in its data URL guise, as a smaller, or not, version of itself, by specifying CSS properties …
position:absolute; (our usual for overlay scenarios)
z-index:56; (for both transparent image and its associated Image Map … more on this later)
left (to appropriately position in X to be in the relevant section of dark green Image Map overlaying in the Landing Page)
top (to appropriately position in Y to be in the relevant section of dark green Image Map overlaying in the Landing Page)
width (which will be up to the transparent image width)
height (which will be up to the transparent image height)
… and no concern about opacity given the transparent image and z-index considerations, here.
So, how can we involve a transparent image here? Well, that is where the new Responsive Web Design Landing Page being PHP, though up to today it had contained no PHP, is in our favour. We can use PHP’s GD to create one, grab its associated data URL and tidy up, and constructing the four image and associated Image Map HTML elements populated, in its “child iframe”, and sending back up into the “parent webpage’s” new …
function ouralert(innum) {
var ans='';
switch ('' + innum) {
case '1':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '2':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '3':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '4':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.) Eg. https://www.rjmprogramming.com.au/slideshow.html', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '5':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '6':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.) Eg. https://www.rjmprogramming.com.au/plus/', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '7':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', urls[eval(-1 + eval('' + innum))].trim());
}
break;
case '8':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', '');
}
break;
case '9':
if (urls[eval(-1 + eval('' + innum))] != '') {
ans=prompt('Want to go anywhere? (To save for future append a blank.)', '');
}
break;
default:
break;
}
if (!ans) { ans=''; }
if (ans != '') {
window.open(ans.trim(), '_blank');
if (ans != ans.trim()) {
window.localStorage.setItem('area' + innum + 'url', encodeURIComponent(ans.trim()));
}
}
}
function imbit() {
//if (document.getElementById('myimg')) {
// document.getElementById('myimg').style.border='5px dashed purple';
//}
if (('' + window.localStorage.getItem('area4url')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
urls[3]=decodeURIComponent('' + window.localStorage.getItem('area4url'));
document.getElementById('area4').title=decodeURIComponent('' + window.localStorage.getItem('area4url')) + '# ... long hover of at least 8 seconds for chance to change';
document.getElementById('area4').href=decodeURIComponent('' + window.localStorage.getItem('area4url'));
document.getElementById('area4').onclick=function(){ omoiset=-1; urls[3]=urls[3]; }
//document.getElementById('area4').ondblclick=function(){ ouralert(4); }
}
if (('' + window.localStorage.getItem('area6url')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
urls[5]=decodeURIComponent('' + window.localStorage.getItem('area6url'));
document.getElementById('area6').title=decodeURIComponent('' + window.localStorage.getItem('area6url')) + '# ... long hover of at least 8 seconds for chance to change';
document.getElementById('area6').href=decodeURIComponent('' + window.localStorage.getItem('area6url'));
document.getElementById('area6').onclick=function(){ omoiset=-1; urls[5]=urls[5]; }
//document.getElementById('area6').ondblclick=function(){ ouralert(6); }
}
}
separating out totally “uninvolved” Landing Page calls hooked up with a new index.php (actually just HTML) Landing Page incarnation that has better Responsive Design credentials … from …
any other call of any complexity or having a query string etcetera, reverting to the “old way”
… new paradigm? So, why keep the old way? Well, we packed the “old way” with content rich functionality, and do not want to ditch that yet, but maybe over time?!
Responsive web design (RWD) is an approach to web design that makes web pages render well on a variety of devices and window or screen sizes from minimum to maximum display size. Recent work also considers the viewer proximity as part of the viewing context as an extension for RWD.[1] Content, design and performance are necessary across all devices to ensure usability and satisfaction.[2][3][4][5]
honing in on our “Landing Page and friends” set of unresponsively designed webpages …
honing in on iPhone sized devices (ie. not iPads nor laptops) …
host web browser address bar calls of “Landing Page and friends” set of unresponsively designed webpages within a caller.htmlresponsively web designed shell supervisory webpage and start using some of that …
And yes, we have plans for “phase three” better scoped than three out of four functionality changes in “phase two”, but we’re not sure these “phase three” ideas are possible/feasible yet, so we’ll see, in days to come?!
… into reality, and yes, it does look like integrating the Where Is Quiz to form a game incarnation in the Clairvoyance++ Game series is possible. To bed it down may take longer, but on this first day of integration …
after some time some Region names will appear where the emoji counting buttons are placed temporarily … and …
a right click on one of these five Region names can provide an incarnation of the Where Is Quiz where a double click on the lightgreen textbox there, can provide the user with a hint
That’s it on this first pass of integration, and interplay with another player integration follows over day(s) to come. Perhaps some interesting event twists and turns will provide even greater integration, but, as you may surmise with all this, it means the communication framework of the Clairvoyance++ Game IP address logics can help the changedthird draftWhere Is Quiz be shared and collaborated with more widely, we figure, with this line of thinking.
latitude and longitude geographical basis to optional dropdown option additional functionalities …
“Do you see what I see?” email or SMS sharing functionality …
Google Translate based translation functionality (just for explanatory purposes)
double click event functionality added to “answer textbox” to facilitate the giving of hints
… the last three of which we did not envisage, or have “a mind’s eye” to, at the start of the working day. That says to me, it is important sometimes, to just get in and chip away at a project, and previous experiences may help a lot to imagine the “broadening of scope” you might be able to achieve when designing an online web application.
Definitely when it comes to a web application involving …
users
generic world concepts
… you can benefit from wondering in that …
Do you see what I see?
… way, from putting yourself in the shoes of a user curious about the quiz, but not benefitting or following through regarding, perhaps because of …
language barriers
unclear quiz explanations
lack or interest in the subject matter behind the web application
Can your web application cut through to such users? Am not necessarily talking about aesthetics here, though that helps, but more to do with “how at home” you can make it feel for such users.
And so, today’s work is like “phase two” with the changedsecond draftWhere Is Quiz we invite you to play. And yes, we have plans for “phase three” better scoped than three out of four functionality changes in “phase two”, but we’re not sure these “phase three” ideas are possible/feasible yet, so we’ll see, in days to come?!
We’re back into “Quiz Territory” (and geography interests) today, we’re thinking a bit like with the recent Clairvoyance Game Chat Tutorial (albeit, we’re not sure we’ve seen “the last word on”) how it is a bit “quizzy”.
It’s the return to “where of life” thinking that got us thinking of creating, effectively, a …
Regions of the World
… online quiz we’re going to call …
Where Is Quiz
… and which leans heavily on the excellent Wikipedia for the information.
Any quiz asking for “country names” has parallels in my mind, to that database adage, regarding “indexing” …
Try to index with a number or short defined length character string.
Pithy, huh?! Yes, well … perhaps you had to be there … huh?!! Anyway, what we are getting at is that a “country name” is “too subjective” a concept to be the “only basis of asking” because …
it is human language dependent in it’s spelling and form …
can involve lots of variants …
can involve politics
… and so, in our quiz, though we welcome attempts to match a “country name” via a user guess, we also accept as a correct answer, that country’s …
… to get back into that short defined length character string realm of “better ask” basis for the quiz.
So that’s it. Pretty simple really …
load, at last count, 3703 regional pieces of data …
randomly hone in on one of those regions …
form a (readonly input type=text element) question sentence to ask …
in the background, as optional, and if in time, try to glean a regional place’s latitude,longitude (and if in time, flag it in the question, and offer as a bonus scoring idea) …
user answers with a country name or country ISO-3166-2 country code (with or without any latitude,longitude appendages) …
quiz web application, via an input type=text element onblur event function, assesses that answer (updating the quiz scoring) and display findings of that assessment …
back to step 2 for another question where the last answer is cleared
Stepping back from the Clairvoyance++ Game project, of recent times, further to the recent Clairvoyance Game IP Address Links Tutorial it occurred to us just this morning how similar …
… and so we may as well build on the “connection work” already there, and bedded down, to also offer a two user Chat conversation set of functionalities, as a new dropdown option the user can choose.
New ideas are all fine and good, as long as it is not a pain in the neck to organize, fitting in with other dropdown option functionalities, and with this in mind, invented a new argument “itype” value of zero, it not having been used yet, and not interfering with window.localStorage “starting itype value” considerations.
We’re not here, today, to in any way criticize the Javascript prompt window, and it’s (harkening back to the desktop application wooooorrrrrllldd in it’s feel) interactive talents, that wee bit removed and independent from webpage goings on. In fact, it is modal (ie. is capable of freezing the Javascript) and this talent needs to be used in the apt place, but is the easiest “modal means” when that is required.
Where it is not as useful, in it’s operating system origins, is it’s lack of colour coding possibilities, and it happens, today, that our work to improve on yesterday’s Clairvoyance Game Textarea Onblur Tutorial regarding creating IP Address Other Player links, can be all the more useful with some colour coding. We have these “colour modes of operation” going, today, as per …
IP Address Other Player comma separated links list alternates among …
flash of yellow background on first showing, else white background
blue font … for IP Address of current player … else …
black font … alternating with …
white fonts … shortly after window.prompt answer made … except for …
orange background is given to users “just arrived on the scene since last black/blue font incarnation” … and can persist through white fonts and pushed to start of links list
… perhaps helping users “hook up” with other users they are in contact with, and can invite, via these “just logged in” identifications.
Further to the day before yesterday’s Clairvoyance Game Element Type Tutorial it’s in that form allowing users to design their own Clairvoyance Game style of game we harness …
… that great event to intervene with when processing the content of …
many input type elements
textarea
myriad of innerHTML friendly elements involving global attribute contenteditable=true
… via …
<textarea onblur=maybeif(this); title="Double click to populate with default suggestion" ondblclick="this.value=this.placeholder.split(String.fromCharCode(10))[eval(-1 + this.placeholder.split(String.fromCharCode(10)).length)]; document.getElementById('one').value='House'; document.getElementById('two').value='Thing'; " rows=2 style=width:90%; type=text placeholder='Image Map HTML URL eg. https://www.rjmprogramming.com.au/HTMLCSS/livingroom.htm' value='' name=three id=three></textarea><br><span> ... or ...</span><br>
<textarea onblur=numdotsonly(this); title="Double click to populate with default suggestion" ondblclick="this.value=this.placeholder.split(String.fromCharCode(10))[eval(-1 + this.placeholder.split(String.fromCharCode(10)).length)]; document.getElementById('one').value='Counting Number'; document.getElementById('two').value='Number'; " rows=3 style=width:90%; type=text placeholder='Comma separated list of 5 Emoji Decimal HTML Entity Values eg. for Game Name Words value of Counting Number (where . can facilitate complex emojis and the #span creates span elements) could be 49.65039.8419,50.65039.8419,51.65039.8419,52.65039.8419,53.65039.8419#span' value='' name=four id=four></textarea><br><span> ... or ...</span><br>
<textarea onblur=perhapsiframes(this); title="Double click to populate with default suggestion" ondblclick="this.value=this.placeholder.split(String.fromCharCode(10))[eval(-1 + this.placeholder.split(String.fromCharCode(10)).length)]; document.getElementById('one').value='Fish'; document.getElementById('two').value='Fish'; " rows=3 style=width:90%; type=text placeholder='Comma separated list of 5 Image URLs eg. for Game Name Words value of Fish could be //fishesofaustralia.net.au/images/thumbnailimage/NarcetesErimelasAlcock.jpg,//fishesofaustralia.net.au/images/thumbnailimage/LutjansuBengalensisuwkwaj.jpg,//fishesofaustralia.net.au/images/thumbnailimage/GobiodonSpadix2Holotype.jpg,//fishesofaustralia.net.au/images/thumbnailimage/SebastapistesMonospinaRandallHolotype.jpg,//fishesofaustralia.net.au/images/thumbnailimage/AmblyeleotrisBellicaudaRandall.jpg' value='' name=five id=five></textarea><br><br>
… to allow for many more scenarios a user might apply entering in various URLs or text data or hashtagging “switches”, as per …
… sometimes resorting to QR Codes as a representation of a URL should we not be able to extract any data from that URL, in a changedlatest draftClairvoyance++ Game.
… to make those User Bonus Score questions and answer default suggestions have lots more variety.
Also, today, we use the oninput event means by which we can stop the user entering particular delimiter characters we hope they do not use defining Game Names and Game Nouns …
And, today, we allow the user to hashtag enter an HTML element type as the output element type output within the five table cells of the game, exemplified by …
When a game scores and it’s got a non-aspirational feel about it, it can turn off some potential players. And so, with this in mind, onto yesterday’s Clairvoyance Game User Definitions Tutorial we now offer some optional bonus scoring functionality to also involve either …
Maths questions
User created questions
Either player can ask for this additional challenge involving …
… within the realms of the web browser being used. Then that newly created user defined game can be shared when invoking email or SMS invitations, and can get added to in that Game type dropdown, where another “Your Own …” suboption brings up the HTML form (and there, some textarea element double click logics might help with the filling out, and/or “modelling the filling out” for you) where the user can create and control these definitions.
… can be referenced to fill in new Clairvoyance++ Game looking incarnations as well as a means, via background image of a newly “top part of webpage” HTML div element, clicking means by which the original image map action item can be reopened, as well.
We think, at this stage, that we want to offer the user some “own incarnation” functionality eventually, and we’d like to add this image map idea into the mix. We’ll see about that later, but for now we have the modelled new dropdown options below …
var zener_cards=['/circle_yellow.jpg#circle_yellow','/cross_red.jpg#cross_red','/waves_blue.jpg#waves_blue','/square_black.jpg#square_black','/star_green.jpg#star_green'];
var sideas=['Awaiting Other Player Choosing a ' + thenouns[theiw] + ' to Guess','Select the ' + thenouns[theiw] + ' Your Player Partner Selected','Select a ' + thenouns[theiw] + ' You Are Asking Your Player Partner to Guess','Awaiting Guess from Your Player Partner','Awaiting a ' + thenouns[theiw] + ' Selection from Your Playing Partner'];
… working with the cropping and resizing smarts the HTML canvas element is capable of …
… when the user enters a “player name” (looking a lot like an IP address) from that list of “potential players online” that is not any form of their own IP address player name. It will be apparent to regular readers that this methodology was intended to be the “usual methodology” at the beginning of our project, and so “we’ll allow a leave pass” for you to ask …
So what do we mean by “implied invitations”? Well, in between a user “Wait” answer and the next, any other user can ask to play that waiting user, and the next time out of the prompt window they may find they’re in the midst of a game of some sort, invited by another player. We hope this does not offend?!
The concept of a “formal invitation” still exists for the email or SMS collaboration conduits, we hasten to add.
And so “day ?whatevvvvvvvvvvveeeeerrrrrrrr” got us to …
Extending yesterday’s Clairvoyance Game Sharing Scores Tutorial, it’s not exactly OOP (Object Oriented Programming) we are doing, but what we’d describe as “objectify” the proceedings we’re attending to today. Take a look at the following Javascript initialization code (now versus before) …
var zener_cards=['/circle_yellow.jpg#circle_yellow','/cross_red.jpg#cross_red','/waves_blue.jpg#waves_blue','/square_black.jpg#square_black','/star_green.jpg#star_green'];
var theword='Clairvoyance';
var thenoun='Zener Card';
var theelem="<img style='object-fit:contain;' src=";
var thewords=['Clairvoyance', 'Fruit', 'Food'];
var theelems=["<img style='object-fit:contain;' src=", "<img style='object-fit:contain;' src=", "<img style='object-fit:contain;' src="];
var theihs=[">", ">", ">"];
var thenouns=['Zener Card', 'Fruit', 'Food'];
var theiw=(document.URL.indexOf('itype=') != -1 ? eval(-1 + eval('' + document.URL.split('itype=')[1].split('&')[0].split('#'))) : 0);
var ppsuff='';
var youare='';
var otheris='';
var score=0, goes=0;
var woois=null;
var pick=-1, awaiting=false, holdon=false;
var bihnull=true;
var anchor=null;
var initval='';
var lastafterscore='';
var wherewrong=false;
var sharemyscore=false, allowsdone=false;
var zcblurb=' You can enter ? to find out more about the history of Zener Cards. ';
var sideas=['Awaiting Other Player Choosing a ' + thenouns[theiw] + ' to Guess','Select the ' + thenouns[theiw] + ' Your Player Partner Selected','Select a ' + thenouns[theiw] + ' You Are Asking Your Player Partner to Guess','Awaiting Guess from Your Player Partner','Awaiting a ' + thenouns[theiw] + ' Selection from Your Playing Partner'];
… helping build up HTML for a new dropdown (versus what was there before) …
<script type=text/javascript>
document.write("<h1 id=muh1>" + thewords[theiw] + " Game " + multimaybe() + "<input type=checkbox id=allows style=display:none; onchange=chscal(this);><font size=1 id=fshare style=display:none;>Share Score</font></input> <input type=checkbox id=allowstwo style=display:none; onchange=chscaltwo(this);><font size=1 id=fsharetwo style=display:none;>Be Told Where You Went Wrong</font></input></h1>");
</script>
… and am sure you can see where an initial “Clairvoyance” noun “hardcoding” feel of logic gets expanded to an “array of nouns” (where lots of programmers will immediately shout “objects”), as an alternative way of thinking to the ways our Javascript functions are like “verbs”. If you “abstract” the “what was a hardcoding” into “a dynamically selectable list of nouns” this objectifying process can be quite useful.
Be Told Where You Went Wrong … guessing within our two player Clairvoyance Game … easy peasy … but …
Share Your Score … was really difficult … go figure …
… though the latter did ask a lot regarding timing and the sleep patterns of the PHP interlocutor … ?
Let’s just “move on” … shall we?!
Also on the agenda was some colour coding … and who doesn’t like a bit of colour coding! We purloined CSS into play, with “the kind of kludgy / kind of cute (well, you had to be there)” introduction of a title attribute to the status wording element and then apply that CSS …
<style>
#tdstatus[title^='Awaiting Other '] {
border: 3px solid red;
}
#tdstatus[title^='Awaiting a '] {
border: 3px solid rgb(127,0,0);
}
#tdstatus[title^='Select the '] {
border: 6px solid lightgreen;
}
#tdstatus[title^='Select a '] {
border: 6px solid green;
}
$tdstatus { padding: 5 5 5 5; }
</style>
We often find it the way, when it comes to colour coding, we borrow from “the traffic light creed” regarding the colours used, where a reddish colour means “hang on” and a greenish colour is an invitation to the user. One could also think of “beeps” or “notifications” here, but not with us here, as of yet.
In yesterday’s Clairvoyance Game Tutorial, with our Clairvoyance Game, really a game for two, downplayed invitations to the end of the blog posting blurb. But really, invitations are the “be all and end all” for a two player game shared over the Internet and just using a “PHP and HTML/Javascript” level of sophistication.
And, of course, two days later (when we think it should have only been “one day later”), it might be me, but making this work for email or SMS invitations was not trivial, partly because …
we launched into this “phase two public invitational sharing” on a false premise … our “phase one window.open and window.opener” Javascript logics were flawed (further into the logic than the first foray, shall we say) … bad news … we reckon one out of two days “getting there” would have to be put down to the lack of testing on day one … whereas …
our thought that “phase two” is just phase one window.open and window.opener transfers to PHP writes Javascript equivalents was “more or less” true, but we all know “programming life” throws up unexpected roadblocks
… and that is the excuse today, which we are sticking to … so there, ngaaahhhh!
This calls into play the importance, often, of “project planning”, and the compartmentalizing of testing, including really tight unit testing, especially if your software plan has so much dependency in “day two” on the “day one” quality. As far as that goes, in our defence, regarding a networking web application, that this Clairvoyance Game “more or less is” (though yesterday’s work simplistically pared that down so that we never needed more than our local MAMP Apache/PHP web server involved) sometimes you find it is hard to recognize “units” within the big picture.
And so “day two” and “day three” were all about “online invitation” logic for email or SMS invitations in …
Are you sixth sensical? Can you read tea leaves? If it’s one out of two, that will do.
We’re starting down the road to a new …
Clairvoyance Game
… today, that on today’s first draft, as a design for two players …
starts you playing yourself, or a nearby other player willing to share windows on your one common web browser incarnation …
kind of ludicrous on this day one but the building blocks are there, they being …
HTML and Javascript parent … talking to …
PHP interlocutor
… which we’re going to extend, on day two, simulating what a window.open and window.opener (just on client) can do, just with a few more calls, and sleeping
Two players take it in turns …
selecting a Zener Card the other player is asked to guess
other player trying to guess that Zener Card selected
latitude and longitude geographical basis to optional dropdown option additional functionalities …
“Do you see what I see?” email or SMS sharing functionality …
Google Translate based translation functionality (just for explanatory purposes)
double click event functionality added to “answer textbox” to facilitate the giving of hints
… the last three of which we did not envisage, or have “a mind’s eye” to, at the start of the working day. That says to me, it is important sometimes, to just get in and chip away at a project, and previous experiences may help a lot to imagine the “broadening of scope” you might be able to achieve when designing an online web application.
Definitely when it comes to a web application involving …
users
generic world concepts
… you can benefit from wondering in that …
Do you see what I see?
… way, from putting yourself in the shoes of a user curious about the quiz, but not benefitting or following through regarding, perhaps because of …
language barriers
unclear quiz explanations
lack or interest in the subject matter behind the web application
Can your web application cut through to such users? Am not necessarily talking about aesthetics here, though that helps, but more to do with “how at home” you can make it feel for such users.
And so, today’s work is like “phase two” with the changedsecond draftWhere Is Quiz we invite you to play. And yes, we have plans for “phase three” better scoped than three out of four functionality changes in “phase two”, but we’re not sure these “phase three” ideas are possible/feasible yet, so we’ll see, in days to come?!
We’re back into “Quiz Territory” (and geography interests) today, we’re thinking a bit like with the recent Clairvoyance Game Chat Tutorial (albeit, we’re not sure we’ve seen “the last word on”) how it is a bit “quizzy”.
It’s the return to “where of life” thinking that got us thinking of creating, effectively, a …
Regions of the World
… online quiz we’re going to call …
Where Is Quiz
… and which leans heavily on the excellent Wikipedia for the information.
Any quiz asking for “country names” has parallels in my mind, to that database adage, regarding “indexing” …
Try to index with a number or short defined length character string.
Pithy, huh?! Yes, well … perhaps you had to be there … huh?!! Anyway, what we are getting at is that a “country name” is “too subjective” a concept to be the “only basis of asking” because …
it is human language dependent in it’s spelling and form …
can involve lots of variants …
can involve politics
… and so, in our quiz, though we welcome attempts to match a “country name” via a user guess, we also accept as a correct answer, that country’s …
… to get back into that short defined length character string realm of “better ask” basis for the quiz.
So that’s it. Pretty simple really …
load, at last count, 3703 regional pieces of data …
randomly hone in on one of those regions …
form a (readonly input type=text element) question sentence to ask …
in the background, as optional, and if in time, try to glean a regional place’s latitude,longitude (and if in time, flag it in the question, and offer as a bonus scoring idea) …
user answers with a country name or country ISO-3166-2 country code (with or without any latitude,longitude appendages) …
quiz web application, via an input type=text element onblur event function, assesses that answer (updating the quiz scoring) and display findings of that assessment …
back to step 2 for another question where the last answer is cleared
Stepping back from the Clairvoyance++ Game project, of recent times, further to the recent Clairvoyance Game IP Address Links Tutorial it occurred to us just this morning how similar …
… and so we may as well build on the “connection work” already there, and bedded down, to also offer a two user Chat conversation set of functionalities, as a new dropdown option the user can choose.
New ideas are all fine and good, as long as it is not a pain in the neck to organize, fitting in with other dropdown option functionalities, and with this in mind, invented a new argument “itype” value of zero, it not having been used yet, and not interfering with window.localStorage “starting itype value” considerations.
We’re not here, today, to in any way criticize the Javascript prompt window, and it’s (harkening back to the desktop application wooooorrrrrllldd in it’s feel) interactive talents, that wee bit removed and independent from webpage goings on. In fact, it is modal (ie. is capable of freezing the Javascript) and this talent needs to be used in the apt place, but is the easiest “modal means” when that is required.
Where it is not as useful, in it’s operating system origins, is it’s lack of colour coding possibilities, and it happens, today, that our work to improve on yesterday’s Clairvoyance Game Textarea Onblur Tutorial regarding creating IP Address Other Player links, can be all the more useful with some colour coding. We have these “colour modes of operation” going, today, as per …
IP Address Other Player comma separated links list alternates among …
flash of yellow background on first showing, else white background
blue font … for IP Address of current player … else …
black font … alternating with …
white fonts … shortly after window.prompt answer made … except for …
orange background is given to users “just arrived on the scene since last black/blue font incarnation” … and can persist through white fonts and pushed to start of links list
… perhaps helping users “hook up” with other users they are in contact with, and can invite, via these “just logged in” identifications.
Further to the day before yesterday’s Clairvoyance Game Element Type Tutorial it’s in that form allowing users to design their own Clairvoyance Game style of game we harness …
… that great event to intervene with when processing the content of …
many input type elements
textarea
myriad of innerHTML friendly elements involving global attribute contenteditable=true
… via …
<textarea onblur=maybeif(this); title="Double click to populate with default suggestion" ondblclick="this.value=this.placeholder.split(String.fromCharCode(10))[eval(-1 + this.placeholder.split(String.fromCharCode(10)).length)]; document.getElementById('one').value='House'; document.getElementById('two').value='Thing'; " rows=2 style=width:90%; type=text placeholder='Image Map HTML URL eg. https://www.rjmprogramming.com.au/HTMLCSS/livingroom.htm' value='' name=three id=three></textarea><br><span> ... or ...</span><br>
<textarea onblur=numdotsonly(this); title="Double click to populate with default suggestion" ondblclick="this.value=this.placeholder.split(String.fromCharCode(10))[eval(-1 + this.placeholder.split(String.fromCharCode(10)).length)]; document.getElementById('one').value='Counting Number'; document.getElementById('two').value='Number'; " rows=3 style=width:90%; type=text placeholder='Comma separated list of 5 Emoji Decimal HTML Entity Values eg. for Game Name Words value of Counting Number (where . can facilitate complex emojis and the #span creates span elements) could be 49.65039.8419,50.65039.8419,51.65039.8419,52.65039.8419,53.65039.8419#span' value='' name=four id=four></textarea><br><span> ... or ...</span><br>
<textarea onblur=perhapsiframes(this); title="Double click to populate with default suggestion" ondblclick="this.value=this.placeholder.split(String.fromCharCode(10))[eval(-1 + this.placeholder.split(String.fromCharCode(10)).length)]; document.getElementById('one').value='Fish'; document.getElementById('two').value='Fish'; " rows=3 style=width:90%; type=text placeholder='Comma separated list of 5 Image URLs eg. for Game Name Words value of Fish could be //fishesofaustralia.net.au/images/thumbnailimage/NarcetesErimelasAlcock.jpg,//fishesofaustralia.net.au/images/thumbnailimage/LutjansuBengalensisuwkwaj.jpg,//fishesofaustralia.net.au/images/thumbnailimage/GobiodonSpadix2Holotype.jpg,//fishesofaustralia.net.au/images/thumbnailimage/SebastapistesMonospinaRandallHolotype.jpg,//fishesofaustralia.net.au/images/thumbnailimage/AmblyeleotrisBellicaudaRandall.jpg' value='' name=five id=five></textarea><br><br>
… to allow for many more scenarios a user might apply entering in various URLs or text data or hashtagging “switches”, as per …
… sometimes resorting to QR Codes as a representation of a URL should we not be able to extract any data from that URL, in a changedlatest draftClairvoyance++ Game.
… to make those User Bonus Score questions and answer default suggestions have lots more variety.
Also, today, we use the oninput event means by which we can stop the user entering particular delimiter characters we hope they do not use defining Game Names and Game Nouns …
And, today, we allow the user to hashtag enter an HTML element type as the output element type output within the five table cells of the game, exemplified by …
When a game scores and it’s got a non-aspirational feel about it, it can turn off some potential players. And so, with this in mind, onto yesterday’s Clairvoyance Game User Definitions Tutorial we now offer some optional bonus scoring functionality to also involve either …
Maths questions
User created questions
Either player can ask for this additional challenge involving …
… within the realms of the web browser being used. Then that newly created user defined game can be shared when invoking email or SMS invitations, and can get added to in that Game type dropdown, where another “Your Own …” suboption brings up the HTML form (and there, some textarea element double click logics might help with the filling out, and/or “modelling the filling out” for you) where the user can create and control these definitions.
… can be referenced to fill in new Clairvoyance++ Game looking incarnations as well as a means, via background image of a newly “top part of webpage” HTML div element, clicking means by which the original image map action item can be reopened, as well.
We think, at this stage, that we want to offer the user some “own incarnation” functionality eventually, and we’d like to add this image map idea into the mix. We’ll see about that later, but for now we have the modelled new dropdown options below …
var zener_cards=['/circle_yellow.jpg#circle_yellow','/cross_red.jpg#cross_red','/waves_blue.jpg#waves_blue','/square_black.jpg#square_black','/star_green.jpg#star_green'];
var sideas=['Awaiting Other Player Choosing a ' + thenouns[theiw] + ' to Guess','Select the ' + thenouns[theiw] + ' Your Player Partner Selected','Select a ' + thenouns[theiw] + ' You Are Asking Your Player Partner to Guess','Awaiting Guess from Your Player Partner','Awaiting a ' + thenouns[theiw] + ' Selection from Your Playing Partner'];
… working with the cropping and resizing smarts the HTML canvas element is capable of …
… when the user enters a “player name” (looking a lot like an IP address) from that list of “potential players online” that is not any form of their own IP address player name. It will be apparent to regular readers that this methodology was intended to be the “usual methodology” at the beginning of our project, and so “we’ll allow a leave pass” for you to ask …
So what do we mean by “implied invitations”? Well, in between a user “Wait” answer and the next, any other user can ask to play that waiting user, and the next time out of the prompt window they may find they’re in the midst of a game of some sort, invited by another player. We hope this does not offend?!
The concept of a “formal invitation” still exists for the email or SMS collaboration conduits, we hasten to add.
And so “day ?whatevvvvvvvvvvveeeeerrrrrrrr” got us to …
Extending yesterday’s Clairvoyance Game Sharing Scores Tutorial, it’s not exactly OOP (Object Oriented Programming) we are doing, but what we’d describe as “objectify” the proceedings we’re attending to today. Take a look at the following Javascript initialization code (now versus before) …
var zener_cards=['/circle_yellow.jpg#circle_yellow','/cross_red.jpg#cross_red','/waves_blue.jpg#waves_blue','/square_black.jpg#square_black','/star_green.jpg#star_green'];
var theword='Clairvoyance';
var thenoun='Zener Card';
var theelem="<img style='object-fit:contain;' src=";
var thewords=['Clairvoyance', 'Fruit', 'Food'];
var theelems=["<img style='object-fit:contain;' src=", "<img style='object-fit:contain;' src=", "<img style='object-fit:contain;' src="];
var theihs=[">", ">", ">"];
var thenouns=['Zener Card', 'Fruit', 'Food'];
var theiw=(document.URL.indexOf('itype=') != -1 ? eval(-1 + eval('' + document.URL.split('itype=')[1].split('&')[0].split('#'))) : 0);
var ppsuff='';
var youare='';
var otheris='';
var score=0, goes=0;
var woois=null;
var pick=-1, awaiting=false, holdon=false;
var bihnull=true;
var anchor=null;
var initval='';
var lastafterscore='';
var wherewrong=false;
var sharemyscore=false, allowsdone=false;
var zcblurb=' You can enter ? to find out more about the history of Zener Cards. ';
var sideas=['Awaiting Other Player Choosing a ' + thenouns[theiw] + ' to Guess','Select the ' + thenouns[theiw] + ' Your Player Partner Selected','Select a ' + thenouns[theiw] + ' You Are Asking Your Player Partner to Guess','Awaiting Guess from Your Player Partner','Awaiting a ' + thenouns[theiw] + ' Selection from Your Playing Partner'];
… helping build up HTML for a new dropdown (versus what was there before) …
<script type=text/javascript>
document.write("<h1 id=muh1>" + thewords[theiw] + " Game " + multimaybe() + "<input type=checkbox id=allows style=display:none; onchange=chscal(this);><font size=1 id=fshare style=display:none;>Share Score</font></input> <input type=checkbox id=allowstwo style=display:none; onchange=chscaltwo(this);><font size=1 id=fsharetwo style=display:none;>Be Told Where You Went Wrong</font></input></h1>");
</script>
… and am sure you can see where an initial “Clairvoyance” noun “hardcoding” feel of logic gets expanded to an “array of nouns” (where lots of programmers will immediately shout “objects”), as an alternative way of thinking to the ways our Javascript functions are like “verbs”. If you “abstract” the “what was a hardcoding” into “a dynamically selectable list of nouns” this objectifying process can be quite useful.
Be Told Where You Went Wrong … guessing within our two player Clairvoyance Game … easy peasy … but …
Share Your Score … was really difficult … go figure …
… though the latter did ask a lot regarding timing and the sleep patterns of the PHP interlocutor … ?
Let’s just “move on” … shall we?!
Also on the agenda was some colour coding … and who doesn’t like a bit of colour coding! We purloined CSS into play, with “the kind of kludgy / kind of cute (well, you had to be there)” introduction of a title attribute to the status wording element and then apply that CSS …
<style>
#tdstatus[title^='Awaiting Other '] {
border: 3px solid red;
}
#tdstatus[title^='Awaiting a '] {
border: 3px solid rgb(127,0,0);
}
#tdstatus[title^='Select the '] {
border: 6px solid lightgreen;
}
#tdstatus[title^='Select a '] {
border: 6px solid green;
}
$tdstatus { padding: 5 5 5 5; }
</style>
We often find it the way, when it comes to colour coding, we borrow from “the traffic light creed” regarding the colours used, where a reddish colour means “hang on” and a greenish colour is an invitation to the user. One could also think of “beeps” or “notifications” here, but not with us here, as of yet.
In yesterday’s Clairvoyance Game Tutorial, with our Clairvoyance Game, really a game for two, downplayed invitations to the end of the blog posting blurb. But really, invitations are the “be all and end all” for a two player game shared over the Internet and just using a “PHP and HTML/Javascript” level of sophistication.
And, of course, two days later (when we think it should have only been “one day later”), it might be me, but making this work for email or SMS invitations was not trivial, partly because …
we launched into this “phase two public invitational sharing” on a false premise … our “phase one window.open and window.opener” Javascript logics were flawed (further into the logic than the first foray, shall we say) … bad news … we reckon one out of two days “getting there” would have to be put down to the lack of testing on day one … whereas …
our thought that “phase two” is just phase one window.open and window.opener transfers to PHP writes Javascript equivalents was “more or less” true, but we all know “programming life” throws up unexpected roadblocks
… and that is the excuse today, which we are sticking to … so there, ngaaahhhh!
This calls into play the importance, often, of “project planning”, and the compartmentalizing of testing, including really tight unit testing, especially if your software plan has so much dependency in “day two” on the “day one” quality. As far as that goes, in our defence, regarding a networking web application, that this Clairvoyance Game “more or less is” (though yesterday’s work simplistically pared that down so that we never needed more than our local MAMP Apache/PHP web server involved) sometimes you find it is hard to recognize “units” within the big picture.
And so “day two” and “day three” were all about “online invitation” logic for email or SMS invitations in …
Are you sixth sensical? Can you read tea leaves? If it’s one out of two, that will do.
We’re starting down the road to a new …
Clairvoyance Game
… today, that on today’s first draft, as a design for two players …
starts you playing yourself, or a nearby other player willing to share windows on your one common web browser incarnation …
kind of ludicrous on this day one but the building blocks are there, they being …
HTML and Javascript parent … talking to …
PHP interlocutor
… which we’re going to extend, on day two, simulating what a window.open and window.opener (just on client) can do, just with a few more calls, and sleeping
Two players take it in turns …
selecting a Zener Card the other player is asked to guess
other player trying to guess that Zener Card selected
We’re back into “Quiz Territory” (and geography interests) today, we’re thinking a bit like with the recent Clairvoyance Game Chat Tutorial (albeit, we’re not sure we’ve seen “the last word on”) how it is a bit “quizzy”.
It’s the return to “where of life” thinking that got us thinking of creating, effectively, a …
Regions of the World
… online quiz we’re going to call …
Where Is Quiz
… and which leans heavily on the excellent Wikipedia for the information.
Any quiz asking for “country names” has parallels in my mind, to that database adage, regarding “indexing” …
Try to index with a number or short defined length character string.
Pithy, huh?! Yes, well … perhaps you had to be there … huh?!! Anyway, what we are getting at is that a “country name” is “too subjective” a concept to be the “only basis of asking” because …
it is human language dependent in it’s spelling and form …
can involve lots of variants …
can involve politics
… and so, in our quiz, though we welcome attempts to match a “country name” via a user guess, we also accept as a correct answer, that country’s …
… to get back into that short defined length character string realm of “better ask” basis for the quiz.
So that’s it. Pretty simple really …
load, at last count, 3703 regional pieces of data …
randomly hone in on one of those regions …
form a (readonly input type=text element) question sentence to ask …
in the background, as optional, and if in time, try to glean a regional place’s latitude,longitude (and if in time, flag it in the question, and offer as a bonus scoring idea) …
user answers with a country name or country ISO-3166-2 country code (with or without any latitude,longitude appendages) …
quiz web application, via an input type=text element onblur event function, assesses that answer (updating the quiz scoring) and display findings of that assessment …
back to step 2 for another question where the last answer is cleared
Stepping back from the Clairvoyance++ Game project, of recent times, further to the recent Clairvoyance Game IP Address Links Tutorial it occurred to us just this morning how similar …
… and so we may as well build on the “connection work” already there, and bedded down, to also offer a two user Chat conversation set of functionalities, as a new dropdown option the user can choose.
New ideas are all fine and good, as long as it is not a pain in the neck to organize, fitting in with other dropdown option functionalities, and with this in mind, invented a new argument “itype” value of zero, it not having been used yet, and not interfering with window.localStorage “starting itype value” considerations.
We’re not here, today, to in any way criticize the Javascript prompt window, and it’s (harkening back to the desktop application wooooorrrrrllldd in it’s feel) interactive talents, that wee bit removed and independent from webpage goings on. In fact, it is modal (ie. is capable of freezing the Javascript) and this talent needs to be used in the apt place, but is the easiest “modal means” when that is required.
Where it is not as useful, in it’s operating system origins, is it’s lack of colour coding possibilities, and it happens, today, that our work to improve on yesterday’s Clairvoyance Game Textarea Onblur Tutorial regarding creating IP Address Other Player links, can be all the more useful with some colour coding. We have these “colour modes of operation” going, today, as per …
IP Address Other Player comma separated links list alternates among …
flash of yellow background on first showing, else white background
blue font … for IP Address of current player … else …
black font … alternating with …
white fonts … shortly after window.prompt answer made … except for …
orange background is given to users “just arrived on the scene since last black/blue font incarnation” … and can persist through white fonts and pushed to start of links list
… perhaps helping users “hook up” with other users they are in contact with, and can invite, via these “just logged in” identifications.
Further to the day before yesterday’s Clairvoyance Game Element Type Tutorial it’s in that form allowing users to design their own Clairvoyance Game style of game we harness …
… that great event to intervene with when processing the content of …
many input type elements
textarea
myriad of innerHTML friendly elements involving global attribute contenteditable=true
… via …
<textarea onblur=maybeif(this); title="Double click to populate with default suggestion" ondblclick="this.value=this.placeholder.split(String.fromCharCode(10))[eval(-1 + this.placeholder.split(String.fromCharCode(10)).length)]; document.getElementById('one').value='House'; document.getElementById('two').value='Thing'; " rows=2 style=width:90%; type=text placeholder='Image Map HTML URL eg. https://www.rjmprogramming.com.au/HTMLCSS/livingroom.htm' value='' name=three id=three></textarea><br><span> ... or ...</span><br>
<textarea onblur=numdotsonly(this); title="Double click to populate with default suggestion" ondblclick="this.value=this.placeholder.split(String.fromCharCode(10))[eval(-1 + this.placeholder.split(String.fromCharCode(10)).length)]; document.getElementById('one').value='Counting Number'; document.getElementById('two').value='Number'; " rows=3 style=width:90%; type=text placeholder='Comma separated list of 5 Emoji Decimal HTML Entity Values eg. for Game Name Words value of Counting Number (where . can facilitate complex emojis and the #span creates span elements) could be 49.65039.8419,50.65039.8419,51.65039.8419,52.65039.8419,53.65039.8419#span' value='' name=four id=four></textarea><br><span> ... or ...</span><br>
<textarea onblur=perhapsiframes(this); title="Double click to populate with default suggestion" ondblclick="this.value=this.placeholder.split(String.fromCharCode(10))[eval(-1 + this.placeholder.split(String.fromCharCode(10)).length)]; document.getElementById('one').value='Fish'; document.getElementById('two').value='Fish'; " rows=3 style=width:90%; type=text placeholder='Comma separated list of 5 Image URLs eg. for Game Name Words value of Fish could be //fishesofaustralia.net.au/images/thumbnailimage/NarcetesErimelasAlcock.jpg,//fishesofaustralia.net.au/images/thumbnailimage/LutjansuBengalensisuwkwaj.jpg,//fishesofaustralia.net.au/images/thumbnailimage/GobiodonSpadix2Holotype.jpg,//fishesofaustralia.net.au/images/thumbnailimage/SebastapistesMonospinaRandallHolotype.jpg,//fishesofaustralia.net.au/images/thumbnailimage/AmblyeleotrisBellicaudaRandall.jpg' value='' name=five id=five></textarea><br><br>
… to allow for many more scenarios a user might apply entering in various URLs or text data or hashtagging “switches”, as per …
… sometimes resorting to QR Codes as a representation of a URL should we not be able to extract any data from that URL, in a changedlatest draftClairvoyance++ Game.
… to make those User Bonus Score questions and answer default suggestions have lots more variety.
Also, today, we use the oninput event means by which we can stop the user entering particular delimiter characters we hope they do not use defining Game Names and Game Nouns …
And, today, we allow the user to hashtag enter an HTML element type as the output element type output within the five table cells of the game, exemplified by …
When a game scores and it’s got a non-aspirational feel about it, it can turn off some potential players. And so, with this in mind, onto yesterday’s Clairvoyance Game User Definitions Tutorial we now offer some optional bonus scoring functionality to also involve either …
Maths questions
User created questions
Either player can ask for this additional challenge involving …
… within the realms of the web browser being used. Then that newly created user defined game can be shared when invoking email or SMS invitations, and can get added to in that Game type dropdown, where another “Your Own …” suboption brings up the HTML form (and there, some textarea element double click logics might help with the filling out, and/or “modelling the filling out” for you) where the user can create and control these definitions.
… can be referenced to fill in new Clairvoyance++ Game looking incarnations as well as a means, via background image of a newly “top part of webpage” HTML div element, clicking means by which the original image map action item can be reopened, as well.
We think, at this stage, that we want to offer the user some “own incarnation” functionality eventually, and we’d like to add this image map idea into the mix. We’ll see about that later, but for now we have the modelled new dropdown options below …
var zener_cards=['/circle_yellow.jpg#circle_yellow','/cross_red.jpg#cross_red','/waves_blue.jpg#waves_blue','/square_black.jpg#square_black','/star_green.jpg#star_green'];
var sideas=['Awaiting Other Player Choosing a ' + thenouns[theiw] + ' to Guess','Select the ' + thenouns[theiw] + ' Your Player Partner Selected','Select a ' + thenouns[theiw] + ' You Are Asking Your Player Partner to Guess','Awaiting Guess from Your Player Partner','Awaiting a ' + thenouns[theiw] + ' Selection from Your Playing Partner'];
… working with the cropping and resizing smarts the HTML canvas element is capable of …
… when the user enters a “player name” (looking a lot like an IP address) from that list of “potential players online” that is not any form of their own IP address player name. It will be apparent to regular readers that this methodology was intended to be the “usual methodology” at the beginning of our project, and so “we’ll allow a leave pass” for you to ask …
So what do we mean by “implied invitations”? Well, in between a user “Wait” answer and the next, any other user can ask to play that waiting user, and the next time out of the prompt window they may find they’re in the midst of a game of some sort, invited by another player. We hope this does not offend?!
The concept of a “formal invitation” still exists for the email or SMS collaboration conduits, we hasten to add.
And so “day ?whatevvvvvvvvvvveeeeerrrrrrrr” got us to …
Extending yesterday’s Clairvoyance Game Sharing Scores Tutorial, it’s not exactly OOP (Object Oriented Programming) we are doing, but what we’d describe as “objectify” the proceedings we’re attending to today. Take a look at the following Javascript initialization code (now versus before) …
var zener_cards=['/circle_yellow.jpg#circle_yellow','/cross_red.jpg#cross_red','/waves_blue.jpg#waves_blue','/square_black.jpg#square_black','/star_green.jpg#star_green'];
var theword='Clairvoyance';
var thenoun='Zener Card';
var theelem="<img style='object-fit:contain;' src=";
var thewords=['Clairvoyance', 'Fruit', 'Food'];
var theelems=["<img style='object-fit:contain;' src=", "<img style='object-fit:contain;' src=", "<img style='object-fit:contain;' src="];
var theihs=[">", ">", ">"];
var thenouns=['Zener Card', 'Fruit', 'Food'];
var theiw=(document.URL.indexOf('itype=') != -1 ? eval(-1 + eval('' + document.URL.split('itype=')[1].split('&')[0].split('#'))) : 0);
var ppsuff='';
var youare='';
var otheris='';
var score=0, goes=0;
var woois=null;
var pick=-1, awaiting=false, holdon=false;
var bihnull=true;
var anchor=null;
var initval='';
var lastafterscore='';
var wherewrong=false;
var sharemyscore=false, allowsdone=false;
var zcblurb=' You can enter ? to find out more about the history of Zener Cards. ';
var sideas=['Awaiting Other Player Choosing a ' + thenouns[theiw] + ' to Guess','Select the ' + thenouns[theiw] + ' Your Player Partner Selected','Select a ' + thenouns[theiw] + ' You Are Asking Your Player Partner to Guess','Awaiting Guess from Your Player Partner','Awaiting a ' + thenouns[theiw] + ' Selection from Your Playing Partner'];
… helping build up HTML for a new dropdown (versus what was there before) …
<script type=text/javascript>
document.write("<h1 id=muh1>" + thewords[theiw] + " Game " + multimaybe() + "<input type=checkbox id=allows style=display:none; onchange=chscal(this);><font size=1 id=fshare style=display:none;>Share Score</font></input> <input type=checkbox id=allowstwo style=display:none; onchange=chscaltwo(this);><font size=1 id=fsharetwo style=display:none;>Be Told Where You Went Wrong</font></input></h1>");
</script>
… and am sure you can see where an initial “Clairvoyance” noun “hardcoding” feel of logic gets expanded to an “array of nouns” (where lots of programmers will immediately shout “objects”), as an alternative way of thinking to the ways our Javascript functions are like “verbs”. If you “abstract” the “what was a hardcoding” into “a dynamically selectable list of nouns” this objectifying process can be quite useful.
Be Told Where You Went Wrong … guessing within our two player Clairvoyance Game … easy peasy … but …
Share Your Score … was really difficult … go figure …
… though the latter did ask a lot regarding timing and the sleep patterns of the PHP interlocutor … ?
Let’s just “move on” … shall we?!
Also on the agenda was some colour coding … and who doesn’t like a bit of colour coding! We purloined CSS into play, with “the kind of kludgy / kind of cute (well, you had to be there)” introduction of a title attribute to the status wording element and then apply that CSS …
<style>
#tdstatus[title^='Awaiting Other '] {
border: 3px solid red;
}
#tdstatus[title^='Awaiting a '] {
border: 3px solid rgb(127,0,0);
}
#tdstatus[title^='Select the '] {
border: 6px solid lightgreen;
}
#tdstatus[title^='Select a '] {
border: 6px solid green;
}
$tdstatus { padding: 5 5 5 5; }
</style>
We often find it the way, when it comes to colour coding, we borrow from “the traffic light creed” regarding the colours used, where a reddish colour means “hang on” and a greenish colour is an invitation to the user. One could also think of “beeps” or “notifications” here, but not with us here, as of yet.
In yesterday’s Clairvoyance Game Tutorial, with our Clairvoyance Game, really a game for two, downplayed invitations to the end of the blog posting blurb. But really, invitations are the “be all and end all” for a two player game shared over the Internet and just using a “PHP and HTML/Javascript” level of sophistication.
And, of course, two days later (when we think it should have only been “one day later”), it might be me, but making this work for email or SMS invitations was not trivial, partly because …
we launched into this “phase two public invitational sharing” on a false premise … our “phase one window.open and window.opener” Javascript logics were flawed (further into the logic than the first foray, shall we say) … bad news … we reckon one out of two days “getting there” would have to be put down to the lack of testing on day one … whereas …
our thought that “phase two” is just phase one window.open and window.opener transfers to PHP writes Javascript equivalents was “more or less” true, but we all know “programming life” throws up unexpected roadblocks
… and that is the excuse today, which we are sticking to … so there, ngaaahhhh!
This calls into play the importance, often, of “project planning”, and the compartmentalizing of testing, including really tight unit testing, especially if your software plan has so much dependency in “day two” on the “day one” quality. As far as that goes, in our defence, regarding a networking web application, that this Clairvoyance Game “more or less is” (though yesterday’s work simplistically pared that down so that we never needed more than our local MAMP Apache/PHP web server involved) sometimes you find it is hard to recognize “units” within the big picture.
And so “day two” and “day three” were all about “online invitation” logic for email or SMS invitations in …
Are you sixth sensical? Can you read tea leaves? If it’s one out of two, that will do.
We’re starting down the road to a new …
Clairvoyance Game
… today, that on today’s first draft, as a design for two players …
starts you playing yourself, or a nearby other player willing to share windows on your one common web browser incarnation …
kind of ludicrous on this day one but the building blocks are there, they being …
HTML and Javascript parent … talking to …
PHP interlocutor
… which we’re going to extend, on day two, simulating what a window.open and window.opener (just on client) can do, just with a few more calls, and sleeping
Two players take it in turns …
selecting a Zener Card the other player is asked to guess
other player trying to guess that Zener Card selected
… caching speed improvements to this blog?! Well, here we are on June 12, 2026 …
able to see and navigate to all the usual WordPress.org published blog posts … but …
not able to login to the Admin backend area where we create the content … no refusal of Username/Password entered, but, rather, just redirects to the Home Blog Page rather than the Admin Dashboard Page …
… huh?! Never seen this happening, in this way, before! Tried clearing the cache, tried several browsers … all the same issue!
So, how can we shape a question to Google? Let’s try …
… getting us to, try restarting WHM cPanel service PHP-FPM (to no avail), and then onto the great advice of https://www.liquidweb.com/wordpress/errors/there-has-been-a-critical-error-on-this-website/ as steps on a wordpress.org WordPress Blog, without needing the backend, but using the WHM cPanel means to get to the relevant wp-config.php we can, temporarily, redefine from, to …
… to make happen, and then to methodically, and calmly, and non-judgementally debug, after we recreated the WordPress Admin login procedure again, logging into a wp-content/debug.log file (we downloaded via FileZilla) what might be causing the issue.
And … surprise, surprise?!
[12-Jun-2026 00:37:40 UTC] WordPress database error Table 'wps_usermeta' is marked as crashed and last (automatic?) repair failed for query SELECT user_id, meta_key, meta_value FROM wps_usermeta WHERE user_id IN (1) ORDER BY umeta_id ASC made by require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/twentyten/tag.php'), get_template_part, locate_template, load_template, require('/themes/twentyten/loop.php'), the_post, WP_Query->the_post, update_post_author_caches, cache_users, update_meta_cache
Opcache was not the cause, at least this time! It was corruption in the wps_usermeta MySql database table that the debug.log error messages indicated to us that was the problem. We’d seen table corruptions before. Let’s …
locate the relevant WordPress Blog database and click to see the table list …
confirm that wps_usermeta was “in use” … the telltale sign regarding WordPress MySql tables that have a problem … and then invoke a step which we’ve never seen fail (and we hope we never will see fail, ever?!) going, off clicking the affected table, then clicking the Sql link …
REPAIR TABLE wps_usermeta
… then clicking Go button to repair
Voila! Success! And so we can login and everything now looks like normal, so, remember to undo the wp-config.php temporary debugging idea, but perhaps leave in some comments …
It took a Sydney Metro train station ride from Sydenham to Chatswood (20 odd minutes … very odd!) to wake up! We hadn’t looked “under the hood” so to speak, since, perhaps the very old “ob_start(‘ob_gzhandler’)” concepts mentioned in WordPress Blog PHP mod_deflate Speed Improvement Tutorial (way back in 2015 … ouch … not always, but this time … ouch), to look into more Speed Improvements for this PHP written WordPress Blog.
Please, at the very least, consider, in terms of WordPress.org Blog caching smarts …
… by a WordPress.org admin login Tools->Site Health “System Health” WordPress Blog report …
… that a page speed over 1 second for relatively static data is not good enough … and as my under 8’s coach used to say …
Give it a bit of oompha!
… springs to mind as pertinent, and just that littleitsy bitsy bit concerning?$%@!
But back to the initial premise, we know the timestamps of today’s animated GIF prove otherwise, but setting that aside, the “actual Collingwood running through the corridor” minute …
php -m | grep -i opcache # is opcache already installed ... no
php -i | grep -i opcache # is opcache potentially active ... yes
dnf search php-opcache # finds you most apt version to install, ours being a PHP version 8.1 one ( Don't know? ... try php -v )
dnf install ea-php81-php-opcache.x86_64 # install opcache ... and that's it because we found, above, that opcache could be potentially active
php -m | grep -i opcache # is opcache installed ... yes ... yay!!!!!!!!! oops ... iswas that Chatswood on the left hand side in "WordPress Blog land"?
… it took on AlmaLinux to arrange opcache to be involved with the environment of the PHP running behind this WordPress Blog (and we think it might have been on platform 9¾ of Gadigal
🤺
) was a “highlight minute” spent. This blog is a lot faster now, would you not agree?
WordPress Blog PHP mod_deflate Speed Improvement Tutorial
Our “quest” for speed continues, man person. This WordPress Blog (from WordPress.org (not WordPress.com)) is now using the PHP mod_deflate module to zip up the traffic going out on the web, in exchange for a higher CPU load for our web server here at the www.rjmprogramming.com.au domain.
And how do we know? We put it through the sanity check gzip checker website here.
And what methods can implement this functionality? …
fix http.conf as the configuration file of an Apache/PHP/MySql web server … for advice here read here
fix the document root .htaccess file … for advice here read here
as applicable fix the .htaccess file at the root directory of the website of interest
add (the bold bit) <?php ob_start('ob_gzhandler'); // rest of code ... // ... // ... end of rest of code ?> // at top of the root directory index.php of the PHP website of interest … read more about this from WordPress here
We’ve decided to use that last method, and you can see how simple this is here. This tutorial also shows the improvement reflected with a speed test at Google Page Speed. Our “quest” continues. To see where we have come from, take a look at EasyApache in cPanel Primer Tutorial as shown below. Hope to see you again soon.
This is not a Monty Python skit (though?) and there is a thought process to say that the previous relevant Google Page Speed Image Optimization Follow Up Tutorial as shown below is relevant to “EasyApache on cPanel Primer Tutorial” … but I’m hoping that if you run an Apache/PHP/MySql domain you may be more advanced than we were here, seeking a “gzip” solution to speeding our website up.
These days (actually for some time) a “gzip” solution is now referred to as a “deflate” solution, and requires, on an Apache/PHP/MySql CentOS web hosting arrangement, the installation into your Apache of the module “mod_deflate” … it is FAR from deflating chortle, chortle.
Your first question regarding this, for yourself, might be … “How can I tell if gzip and/or mod_deflate is already making things faster on a URL of interest?” … use this testing website (thanks manpeepholes people). If the answer is no, as it was for this WordPress blog, please read on.
Finished reading … okay, so EasyApache is a means by which, on our Linux web server we can rebuild Apache and PHP (we go to PHP 5.4 from PHP 5.3 … and there are some repercussions to talk about another time) and MySql, and with the rebuild we make sure “mod_deflate” is selected this time.
If you are undertaking this, may I say it is good to, before you start …
backup the webserver … (though my first run did have an issue (see “cPanel gurus” below) and it reverted to a working Apache correctly, and, by the by, doesn’t stop your website working as it builds (for about 30 minutes))
“cPanel gurus” … know that if the whole thing sounds trepidatious, there is a great support website for cPanel with great experts at the ready, and if there is an issue, at least with my CentOS WHM vps arrangement any issue hooks into cPanel support (with an email) should you want some advice, and perhaps give feedback
Tomorrow we show making the “gzip” solution happen via “mod_deflate” for WordPress PHP website in a generic approach applicable to many other PHP website scenarios.
Google Page Speed Image Optimization Follow Up Tutorial
Do you remember a few days back talking about the Google Page Speed functionality with FFmpeg Image Optimization Primer Tutorial, as shown below, and also with Google PageSpeed and Firebug Mobile Friendly Primer Tutorial earlier on? We talked about image optimization … well, today, we are going to do some more … it is one of those jobs you could probably keep visiting … and practice helps, methinks. Why is image optimization important? It helps you win SEO “brownie points” with the search engines.
On the WordPress blog you are reading at the moment there is no doubt that some image optimization could be done, so we do this today, concentrating on content above the fold, using a desktop Mac application Paintbrush (and saving as a jpeg with about 25% quality as per this example), though we could have used Pixillion or Gimp (see Gimp Batch Image Manipulation Primer Tutorial) to do this job. The Paintbrush method is used because it is not every file I want to change whereas the other methods suit a “do-all-folder” approach.
You’ll see with the tutorial lots of (s)ftp transferring using the Firefox web browser with its brilliant FireFTP add-on, and you’ll see reduced file sizes and that the Google PageSpeed results improve as a result.
You may be surprised what tomorrow brings, consolidating the thoughts of today, to continue on our “quest” to speed up this WordPress blog. Hope you can join us then.
The Linux FFmpeg command is so useful, and so modest. In its “man ffmpeg” it just describes itself as a video converter, but it does (eg. scaling) images as well …. guess the modesty could be that it thinks of one image as a very short video … subliminal advertising perhaps?! We found it invaluable in the “end game” part of the creation of our “Make Your Own Charts” iOS (iPad) mobile application, and you can read more about this here.
The Google PageSpeed Insight tools not only measure a webpage’s speed but can also give a report on the Mobile (or Desktop, for that matter) friendliness of that webpage, giving a score out of 100.
… well, today, we turn our attention to the Google PageSpeed talent for showing you how to speed up your webpages, and so, get in the better books with the search engines, and your users, probably. The use of Google PageSpeed on the Landing Page clone pointed out the speed savings that could be achieved by some image optimization (preferably lossless compression) and there is a pretty obvious one here … let’s make these images 105px wide (at least for when they just load “above the fold”).
You’ll see that this is only a minor improvement from 33 to 34 score with Google PageSpeed, but has moved the Optimizing Images out of the critical section. Obviously there is such a lot to do in this area, as an ongoing project.
Did you know?
There are quite a few things to like about the Jpeg image file format, and one of the most pleasing one to implement is its peculiarity that a file extension of .jpg is totally equivalent to a file extension of .jpeg as far as the understanding of web browsers, and their rendering rules, goes. This gives a lot of scope to programmers to be able to have unusual arrangements with Jpeg files with their dual extension possibilities (the same data can have two operating system “guises”) … here we use the ability to have two different image sizes and Javascript DOM can handle the onmouseover event nonetheless by reverting to the bigger (size) version when a zooming operation is required, but none of this impacts the “above the fold” initial loading with the smaller (size) version.
Jpeg allows percentage file filtering when saving in various image editors … does one have to go on and on and on and on … or do you give up now?!
A few days back we decided to revisit (WordPress Recent Post Image Follow Up Tutorial) in order to (software) integrate it with the www.rjmprogramming.com.au domain’s Landing Page. We did this for two reasons. It was probably a good visual cue for users, who may be more inclined to click an icon, than a link, these days (… am not sure yet …) and because support for Flash is becoming too difficult with the Flash we had going on the Landing Page.
As such we decided to replace the contents within the iWebposition:absolutediv (that iWeb loves to use) that had Flash with new home-grown HTML iframe webpage that shows those latest 8 recent posts as referred to below.
The change did pan out to involve the “few times a day code”. Do you remember, below …
Why would this job have “a few times a day” functionality? … Well, the images change when a blog posting goes live, and at this blog this happens once a day, so there is no need to slow functionality down getting these images together more often than during that time the new blog posting is scheduled. So this “a few times a day” functionality uses (the web server Linux) crontab/curl … what a team … and we wrote recent-posts-2.php to be the PHP run with a curl … chortle, chortle.
… well, all that still applies, but what if we were to intervene in that code to write out HTML that suits that proposed iframe we talked about, above.
That leaves a good zero.html arrangement that is dynamic with those “few times a day” arrangements we already had in place, and which you can read more about below, as you wish. Alas, one speaks too soon, as there is something else needed for zero.html to be user-friendly enough for mobile usage … the scrolling is not as “truncaty” (is this a word?) on mobile devices as on non-mobile devices and we have decided here to just show the two most recent icons where the platform is mobile … and how was this done? After reading this brilliant advice … thanks … we did some Javascript onload functionality (in zero.html) as below …
<script type='text/javascript'> var one_o_five=600; function ol() { if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { one_o_five=105; for (var j=3; j<=8; j++) { document.getElementById(j).style.display='none'; } } } </script>
All that is left is to wipe out the iWeb div Landing Page functionality that was Flash and put in, instead …
<iframe style="width:264px;" title="Recent Blog Posts" src="PHP/zero.html"></iframe>
… all okay? You can see it at the www.rjmprogramming.com.au Landing Page a little bit down at the left hand edge of (usual) functionality.
A couple of days back (WordPress Recent Post Image Primer Tutorial) we did some functionality work on this WordPress Blog’s Recent Posts menu, and left it more functional for sure and very much “okay” … but is “okay” okay? … well, OK, it might be “okay” for a while, but think we seek more functionality:
think quite often users expect that an image on a website will have some underlying functionality, so think that would be an improvement
would like to include online contextual Ajax help for these newly included images
To move forward from where we were regarding these improvements we could proceed on 3 logic fronts methinks:
use the ul->li hierarchy to do one thing with the new images and other blog posting specific things for all the links … this may be possible, but it didn’t work (after some time) so …
change the logic so that those new CSS created background-url images are turned into real images … but we prefer to try …
add a real image superimposed over the new background-url images with a higher z-index but totally transparent (via techniques of Gimp Transparency Primer Tutorial) and add event logic to these, separate to the link event logics … this worked, and simplified code ideas as well
Our old favourite WordPress blog PHP header.php changed as in bold below:
function rptwo() {
var tworp=document.getElementById('recent-posts-2');
if (tworp != null) {
if (tworp.innerHTML.indexOf('<u' + 'l>') != -1) {
tworp.innerHTML = tworp.innerHTML.replace('<u' + 'l>', '<u' + 'l class="iconlist">');
var eight=new Array("one", "two", "three", "four", "five", "six", "seven", "eight");
var ieight;
tworp.innerHTML = tworp.innerHTML.replace(/</a>/g, "</a><img class='iiconlist' src='http://www.rjmprogramming.com.au/wordpress/transparent.png' style='z-index:3;margin-left:0px;margin-top:0px;opacity:0.2;width:140px;height:100px;box-shadow:rgba(0,0,255,0.2) 2px 2px 2px 2px inset;' onmouseover='getRpnow();' onmouseout='yehbut();' ontouchstart='getRpnow();' ontouchend='yehbut();' title=' ... welcome to the long hover functionality that shows Blog Post regarding Recent Post images'>");
Sometimes CSS meets Javascript meets “a few times a day” functionality, to get a job done, in this case a CSS styling job on this WordPress blog (continuing on with tutorials like WordPress Blog Code Tag CSS Primer Tutorial as shown below). The job is to put small images below the links in the Recent Posts menu on this WordPress blog. Figure this would help … and it is good to have a reason … it would add images or pictures to content below the field of vision … this makes the blog more user-friendly we think … but, again, as with many styling issues, this is subjective.
Why would this job have “a few times a day” functionality? … Well, the images change when a blog posting goes live, and at this blog this happens once a day, so there is no need to slow functionality down getting these images together more often than during that time the new blog posting is scheduled. So this “a few times a day” functionality uses (the web server Linux) crontab/curl … what a team … and we wrote recent-posts-2.php to be the PHP run with a curl … chortle, chortle.
Then our old favourite WordPress PHP header.php gets modified as with the bold code below for CSS (part 1 change of 2) …
Explanations of software code are so many and varied these days because there are so many platforms and programming languages to get your head around, that it would be advantageous, (lazy me finally admits), that as you scan down a blog posting in that fast scan we do as we surf the net, something stands out recognizably as “a piece of code”, apart from the default WordPress theme TwentyTen styling of the <code> tag used in our blog here (use <blockquote> for non-code quotes … by the by, all this is subjective).
Today we settle on a CSS <code> tag styling definition that mixes a few ideas:
it is important “code” line breaks where the writer of the “code” said it should
… conflictingly (is this a word?) sometimes, you want to see everything, so allow line breaking if the line overshoots at the right hand side
use a background colour to make the “code” text stand out differently
use an unusual dashed border to catch the user’s scanning eye
don’t scare the living daylights (out of the living day lights … chortle, chortle) … make the border a non-jittery colour … like … blue
So let’s see what made this happen (for itself) with our old favourite header.php (what would we do without it!) in bold: