Spotlight is macOS’s built-in, system-wide search engine. Activated by pressing Command + Spacebar, it lets you instantly find files, launch apps, perform math calculations, convert currency, check weather, and run quick system commands without leaving your current window.
… or, for the purposes of today’s tutorial’s purposes, is the bosom buddy, on macOS, of …
Keyboard Shortcuts
… because, after that initial …
Command + Spacebar
… keyboard … shortcut … to get to the Spotlight desktop application, just about everything is possible to get to, to many degrees, without relying on any clicks anywhere, as the previous Windows and macOS Hanging Useful Keyboard Shortcuts Tutorial set the scene for, too.
So, why the interest?
Well, we got into a spot of bother where it became very useful to use (just keyboard) …
Command + Spacebar
Bluetooth
Return key
Arrow down to Bluetooth File Exchange
Return key
Arrow down to (in our case) M720 Triathlon
Return key
… one day. Huh?!
Let me explain. We’ve had clicking problems with this MacBook Air’s trackpad to do with it’s clicking capabilities only (ie. swipe gestures still worked), and, as we gave a bit of the background to with Bluetooth Mouse Show Desktop Primer Tutorial the way we worked around this was to buy and install a bluetooth mouse from Logitech called the M720 Triathlon. All good for more than a year now. But one day we turned Bluetooth Off then rebooted the MacBook Air. Ouch?! Sure, we could log in to the desktop, but doing much else easily relied on …
a fully functional trackpad … or, what could of worked if we’d arranged it …
an installed USB lead based mouse … or even, perhaps, we’re not sure …
plugging in some USB lead based mouse that is plug and play
… none of which were available to me. But good ol’ Spotlight and Keyboard Shortcuts were (ie. to reconnect the bluetooth mouse)! Yayyyyyy!
Can hear some of you asking …
So, what happens when the M720 Triathlon runs out of battery? Isn’t it the same panic?
Well, it happened last week, and we were wondering too! A message comes up on the macOS screen to say the M720 Triathlon is low on battery power, and we just took that message at it’s word, changing the battery, and carried on.
Can hear some of you asking …
So, do the M720 Triathlon and what’s left of the trackpad’s functionality get in each other’s way?
No, they can either or both work at whatever they are capable of.
… it gave us that very annoying “hanging experience” to the extent that our MacBook Air rebooted itself. And so, given this, we hereby apologize if a previous version of the Dots and Boxes game has caused you any grief.
But the fix to our dots_and_boxes_game.htmlDots and Boxes game was a “one number different” fix, and rather than short change our readers … heaven forbid … we’re going to focus, today, more on what keyboard shortcuts on macOS or Windows might help you out in the bad scenario described above …
For Mac, press Option + Command + Esc to open the Force Quit window, or hold Option + Command + Shift + Esc for three seconds to force quit the active app directly. For Windows, press Alt + F4 to close the active app, or Ctrl + Shift + Esc to open Task Manager to kill processes.
Mac Force Quit Shortcuts:
Force Quit Dialog: Option + Command + Esc
Force Quit Focused App: Option + Command + Shift + Esc (hold for 3 seconds)
Standard Quit: Command + Q
Windows Force Quit Shortcuts:
Close Active App: Alt + F4
Open Task Manager (to terminate app): Ctrl + Shift + Esc
Alternative Task Manager: Ctrl + Alt + Delete then select Task Manager
Linux/Other:
Xkill: Ctrl + Alt + Esc (often used to click and destroy a window)
These may or may not help depending on the severity of the memory issue you are facing, in which case …
For Windows, use Win + X then U then R for a fast restart. Alternatively, Alt + F4 on the desktop opens a shutdown menu. For Mac, use Control + Command + Power Button to force a restart. These methods allow full system control without a mouse.
Windows Restart Shortcuts
Power User Menu (Fastest): Press Win + X, then U, then R.
Desktop Shutdown: Press Alt + F4 while on the desktop to open the shutdown dialog, then select “Restart”.
Ctrl+Alt+Del: Press Ctrl + Alt + Del, use arrow keys to reach the power icon, press Enter, and select “Restart”.
Run Command: Press Win + R, type shutdown -r -t 0, and hit Enter.
macOS Restart Shortcuts
Force Restart: Control + Command + Power button (or Touch ID button).
Standard Restart: Control + Option + Command + Power button (closes apps, then restarts).
Linux/Other
Alt+SysRq+B: Forcibly reboots the system immediately.
We hope, one day, but not too soon, you find this useful?!
Yes, that’s it for us today, simply because the “morphed into” is a lot like “the end result”, our new Dots and Boxes Game. After all, both are …
online games
on a board
with span cells
containing onclick logic
ideally for 2 or more players
And as for the onclick logic Javascript logic? We can’t remember relying on the outerHTML (ie. the entire HTML element expressed as HTML) of an HTML (span) element for the (onclick event) logic basis, as per (the plug in code different to (and the same as) yesterday’s code) …
if (document.getElementById('names')) {
if (document.getElementById('names').value == '' && document.getElementById('names').placeholder.indexOf(',') != -1) {
document.getElementById('names').value=document.getElementById('names').placeholder;
//alert(1);
document.getElementById('numsel').value='' + document.getElementById('names').value.split(',').length;
//alert(document.getElementById('numsel').value);
nparrange(document.getElementById('numsel'));
//alert(11);
document.getElementById('smore').innerHTML=notify('Your go ' + anames[curplayer]);
}
}
console.log('1');
if (spano.innerHTML.toLowerCase() == 's' || spano.innerHTML.toLowerCase() == 'o') { return true; }
console.log('2');
var rtis=spano.getBoundingClientRect();
console.log('3');
e = e || window.event;
e.preventDefault();
if (e.touches) {
if (e.touches[0].pageX) {
xx = e.touches[0].pageX;
yy = e.touches[0].pageY;
} else {
xx = e.touches[0].clientX;
yy = e.touches[0].clientY;
}
//console.log('pos3=' + pos3 + ',pos4=' + pos4);
} else if (e.clientX || e.clientY) {
xx = e.clientX;
yy = e.clientY;
} else {
xx = e.pageX;
yy = e.pageY;
}
var topm=eval(yy - rtis.top);
var bottomm=eval(rtis.bottom - yy);
var leftm=eval(xx - rtis.left);
var rightm=eval(rtis.right - xx);
var sbl=eval('' + noc(spano.outerHTML).split('border-').length);
var sbc=eval('' + spano.outerHTML.split('background-color').length);
Even though it took too long to get to yesterday’s Word Find Game Viewport Tutorial‘s Word Find Game’s level of satisfaction, for us, it was always going to be worth it, because when you overengineer it can mean cloning off that into another useful web application is a “paring down” exercise, more than anything, and this is infinitely easier than “a reinvention of the wheel” scenario, especially where it comes to “cross platform” game usage “user experience” issues.
The fun bit of such an approach, in thinking about what we end up with today is the thought that a …
Word Find Game … could be cloned or morphed into a …
SOS Game
… we remember from our days at high school, in less than a day. The memory of the SOS Game did not extend to the detail, and so we thank How to Play – SOS for reminders about the status of diagonality, while up versus down and forwards versus backwards concerns were a bit “per se” regarding “SOS”!
It was the confluence of one “onclick” type event to cover, regarding span elements set out in a grid initialized to a non-breaking space ( ie. ) …
fill in contents as “S”
fill in contents as “O”
… that set us to determining for the span “cell” click, was it positioned …
in the top half means “S” … or …
in the bottom half means “O”
? This had us converging on changes to the “clicks” mode onclick event Javascript logic …
function didclick(e, spano) {
if (document.getElementById('names')) {
if (document.getElementById('names').value == '' && document.getElementById('names').placeholder.indexOf(',') != -1) {
document.getElementById('names').value=document.getElementById('names').placeholder;
//alert(1);
document.getElementById('numsel').value='' + document.getElementById('names').value.split(',').length;
//alert(document.getElementById('numsel').value);
nparrange(document.getElementById('numsel'));
//alert(11);
document.getElementById('smore').innerHTML=notify('Your go ' + anames[curplayer]);
}
}
console.log('1');
if (spano.innerHTML.toLowerCase() == 's' || spano.innerHTML.toLowerCase() == 'o') { return true; }
console.log('2');
var rtis=spano.getBoundingClientRect();
console.log('3');
e = e || window.event;
e.preventDefault();
if (e.touches) {
if (e.touches[0].pageX) {
xx = e.touches[0].pageX;
yy = e.touches[0].pageY;
} else {
xx = e.touches[0].clientX;
yy = e.touches[0].clientY;
}
//console.log('pos3=' + pos3 + ',pos4=' + pos4);
} else if (e.clientX || e.clientY) {
xx = e.clientX;
yy = e.clientY;
} else {
xx = e.pageX;
yy = e.pageY;
}
var thislet=' ';
var locsubscore=0;
var thisi=eval(spano.id.replace('span',''));
if (eval(yy - rtis.top) <= eval(rtis.bottom - yy)) { // s
thislet='S';
spano.innerHTML=thislet;
spano.style.color='rgb(128,0,128)'; //'#000000';
} else {
thislet='O';
spano.innerHTML=thislet;
spano.style.color='#0000ff';
}
sbs=[];
if (eval(thisi % 100) >= 2) { // forwards we are at end
if ((sb(document.getElementById('span' + eval(-2 + thisi))).innerHTML + sb(document.getElementById('span' + eval(-1 + thisi))).innerHTML + sb(document.getElementById('span' + eval(thisi))).innerHTML) == 'SOS') {
sbord();
locsubscore++;
}
}
sbs=[];
if (eval(thisi % 100) >= 1 && eval(thisi % 100) <= 98) { // forwards we are in the middle
if ((sb(document.getElementById('span' + eval(-1 + thisi))).innerHTML + sb(document.getElementById('span' + eval(thisi))).innerHTML + sb(document.getElementById('span' + eval(1 + thisi))).innerHTML) == 'SOS') {
sbord();
locsubscore++;
}
}
sbs=[];
if (eval(thisi % 100) <= 97) { // forwards we are at start
if ((sb(document.getElementById('span' + eval(thisi))).innerHTML + sb(document.getElementById('span' + eval(1 + thisi))).innerHTML + sb(document.getElementById('span' + eval(2 + thisi))).innerHTML) == 'SOS') {
sbord();
locsubscore++;
}
}
if (updownallowed) {
sbs=[];
if (eval(thisi / 100) >= 2) { // down we are at end
if ((sb(document.getElementById('span' + eval(-200 + thisi))).innerHTML + sb(document.getElementById('span' + eval(-100 + thisi))).innerHTML + sb(document.getElementById('span' + eval(thisi))).innerHTML) == 'SOS') {
sbord();
locsubscore++;
}
}
sbs=[];
if (eval(thisi / 100) >= 1 && eval(thisi / 100) <= 18) { // down we are in the middle
if ((sb(document.getElementById('span' + eval(-100 + thisi))).innerHTML + sb(document.getElementById('span' + eval(thisi))).innerHTML + sb(document.getElementById('span' + eval(100 + thisi))).innerHTML) == 'SOS') {
sbord();
locsubscore++;
}
}
sbs=[];
if (eval(thisi / 100) <= 17) { // down we are at start
if ((sb(document.getElementById('span' + eval(thisi))).innerHTML + sb(document.getElementById('span' + eval(100 + thisi))).innerHTML + sb(document.getElementById('span' + eval(200 + thisi))).innerHTML) == 'SOS') {
sbord();
locsubscore++;
}
}
}
CSS styling keeps getting better for webpages, with extended functionality, as proven when CSS3 came to being. Two styling features we find quite impactive are …
CSS animation … and …
CSS linear gradients
… we use, respectively, regarding …
“selection” textarea and “click” div of span elements … helping create a colour coded border “glow” 3D effect …
<style>
Yesterday’s Word Find Game Personalization Tutorial, and the Word Find Game from versions before all had an unwieldy relationship with mobile platforms. The …
selection, via Selection API, using HTML textarea, suits non-mobile well … but we think today’s newly coded for …
click, via HTML span element onclick logics, work better on mobile platforms
… and so we’ve coded for a new dropdown to offer both modus operandi as options, with new “click” modus operandi Javascript …
Yesterday’s Word Find Game Modes of Use Tutorial gave us the means by which we could have multiple players in our “Finding the Word” game, as a number. But many users prefer “names” to “numbers”. And so …
we start asking for an optional (comma separated) user name list … that if used …
starts looking for Notifications API functionality to keep the players informed about proceedings … and …
if underlying Navigator APInavigator.platform points at an underlying macOS operating system, also offer the user the chance to turn notification wording to audio commentary, as well
… modes of use that the user(s) can control. And so, with this in mind, to improve on yesterday’s Word Find Game Underlay Tutorial we’ve set out providing ways the users can control these two concepts via two new dropdowns …
… along with a span element showing the current player number all within that topmost h1 element, and helped out by two new dropdown (ie. select element) onchange event Javascript logics …
var numplayers=1;
var curplayer=0;
var ascores=[0], agoes=[0];
var backwardsallowed=true;
var updownallowed=true;
var diagonalsallowed=true;
var zdebye='';
var zzdebye='';
var lastzdebye='';
var goutstris='';
var delayis=0;
var sofar=';';
var score=0, goes=0, subscore=0;
… but there is essentially only the difference in the control of “z-index” (and maybe “opacity”) property different about the concepts, and to deploy to improve on for the start we made with yesterday’s Word Find Game Primer Tutorial.
“Underlay” usefulness, to us, goes like this …
what you “underlay” … for us within the new CSS styling …
<style>
textarea {
font-family: Courier New;
font-size: 20px;
opacity: 0.9;
z-index: 9;
padding: 0 0 0 0;
margin: 0 0 0 0;
}
It’s lucky for us that there are so many good resources out there to help, one link of real interest, for us, being this excellent link, thanks, getting us to use this new Javascript function …
Here’s another day of testing a Javascript API today, which has that “desktop feel”, that being the Clipboard API …
The Clipboard API provides the ability to respond to clipboard commands (cut, copy, and paste) as well as to asynchronously read from and write to the system clipboard.
… our clipboard_api_test.htmlproof of concept version offering “text clipboard data” functionality from the text based clipboard into an HTML textarea element via …
append
prepend
at cursor
… modes of use, you can also try below (or get a sneakpeak at tomorrow’s ideas) …
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
Around here the hashtag means of constructing URLs, especially regarding “a” email mailto: and SMS sms: URL links, has saved the day manys the time, given our emphasis away from mail server based communication logics.
And today, it is used internally, in URLs, as well. That is because the titles for the seven songs can go beyond the ? and & get argument URL length limits for this blog’s domain Apache/PHP/MySql web server.
In this project, we’ve had the good luck to always organize the shaping of the Song Title data arguments to the end of the ? and & get argument parts of the URLs, wherever they be used. As such, the simple arrangement to not be haunted by URL length restrictions just via a …
var urlofinterest=urlofinterest.replace('&thetlist=', '#thetlist'); // hence ... doh!
… type of Javascript code arrangement. Cute, huh?!
first you have to store such a listing URL into window.localStorage …
if (('' + window.localStorage.getItem('song_list_' + decodeURIComponent(document.URL.split('thelist=')[1].split('&')[0].split('#')[0]))).replace(/^undefined/g,'').replace(/^null/g,'') == '') {
window.localStorage.setItem('song_list_' + decodeURIComponent(document.URL.split('thelist=')[1].split('&')[0].split('#')[0]), newerproposedurl.replace('?', '?subject=' + encodeURIComponent(document.getElementById('mys1').innerText) + '&'));
} else {
window.localStorage.removeItem('song_list_' + decodeURIComponent(document.URL.split('thelist=')[1].split('&')[0].split('#')[0]));
window.localStorage.setItem('song_list_' + decodeURIComponent(document.URL.split('thelist=')[1].split('&')[0].split('#')[0]), newerproposedurl.replace('?', '?subject=' + encodeURIComponent(document.getElementById('mys1').innerText) + '&'));
}
… and then …
you should recall these stored settings so that they can be reused …
function ourblurb(inurlidea) {
return String.fromCharCode(10) + decodeURIComponent(('' + inurlidea + '#thetlist=').split('thetlist=')[1].split('&')[0].split('#')[0]).replace(/\|/g,' ... then ... ' + String.fromCharCode(10));
}
function thenagain(inurlidea) {
var outurlidea=inurlidea, isokayhere=true, iuyx=0;
//alert(inurlidea + ' becomes ' + ('' + inurlidea + '#order=').split('order=')[1].trim());
if (inurlidea.indexOf('thelist=') != -1 && eval('' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0].trim().split(',').length) == 7) {
//alert(inurlidea + ' Becomes ' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0] + ' of length ' + eval('' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0].length));
if (eval('' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0].length) == 13) {
//alert(inurlidea + ' becomeS ' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0].trim());
var theseurlsare=('' + inurlidea + '#thelist=').split('thelist=')[1].split('&')[0].split('#')[0];
var newurlsare=theseurlsare;
var theurlsare=decodeURIComponent(theseurlsare.split('&')[0].split('#')[0]).split(',');
var thesetsare=('' + inurlidea + '#thetlist=').split('thetlist=')[1].split('&')[0].split('#')[0];
var newtsare=thesetsare;
var thetsare=decodeURIComponent(thesetsare.split('&')[0].split('#')[0]).split('|');
var thenumsarehere=('' + inurlidea + '#order=').split('order=')[1].split('#')[0].trim().split(',');
var minone=-1;
if ((',' + ('' + inurlidea + '#order=').split('order=')[1].trim() + ',').indexOf(',0,') != -1) {
minone=0;
}
//alert(inurlidea + ' becOmeS ' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0].trim());
You’d think we’d be done with ablutions at this blog, but noooooo wayyyy … Luna says … there’s all manner of molecular interest out there …
It’s not just H and the 2 and the O … it’s the art of the roleroll.
… or so says “The Lu” anyway!
We wanted our recent Shower Songs web application be the application of choice for URLs at RJM Programming involving our Shower Songs web application YouTube API “radio play” web application.
In a “remembering and recall” scenario …
first you have to store such a listing URL into window.localStorage …
… and then …
you should recall these stored settings so that they can be reused …
our inhouse Shower Songs project using YouTube API means to “Radio Play” some, let’s say, “theatrical pursuits by the water”
A couple of times now, we’ve used it as company in the bath via an iPhone, preparing the list ahead of ever having to tap another anything, to hear some songs in the sequence the user establishes ahead of time … ie. the purpose of this web application.
However, we made some bad colour choices, especially regarding the mobile red button overlayed by black text containing the song title. It was hard to see. It is easier now, that text being yellow.
While there, we decided on a pale green background colour to apply to the textarea user interactive input and progress displaying conduit, when it’s relevant YouTube video is playing (in audio stream only mode), and another principle of our Shower Songs logic is that you should only see one pale green textarea for any great period of time … ie. the songs play in sequence, and looping around in continuous play, like on the radio.
Believe it or not, the actual top level hierarchy Shower Songs window needs no changes for this, but …
first you have to store such a listing URL into window.localStorage …
if (('' + window.localStorage.getItem('song_list_' + decodeURIComponent(document.URL.split('thelist=')[1].split('&')[0].split('#')[0]))).replace(/^undefined/g,'').replace(/^null/g,'') == '') {
window.localStorage.setItem('song_list_' + decodeURIComponent(document.URL.split('thelist=')[1].split('&')[0].split('#')[0]), newerproposedurl.replace('?', '?subject=' + encodeURIComponent(document.getElementById('mys1').innerText) + '&'));
} else {
window.localStorage.removeItem('song_list_' + decodeURIComponent(document.URL.split('thelist=')[1].split('&')[0].split('#')[0]));
window.localStorage.setItem('song_list_' + decodeURIComponent(document.URL.split('thelist=')[1].split('&')[0].split('#')[0]), newerproposedurl.replace('?', '?subject=' + encodeURIComponent(document.getElementById('mys1').innerText) + '&'));
}
… and then …
you should recall these stored settings so that they can be reused …
function ourblurb(inurlidea) {
return String.fromCharCode(10) + decodeURIComponent(('' + inurlidea + '#thetlist=').split('thetlist=')[1].split('&')[0].split('#')[0]).replace(/\|/g,' ... then ... ' + String.fromCharCode(10));
}
function thenagain(inurlidea) {
var outurlidea=inurlidea, isokayhere=true, iuyx=0;
//alert(inurlidea + ' becomes ' + ('' + inurlidea + '#order=').split('order=')[1].trim());
if (inurlidea.indexOf('thelist=') != -1 && eval('' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0].trim().split(',').length) == 7) {
//alert(inurlidea + ' Becomes ' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0] + ' of length ' + eval('' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0].length));
if (eval('' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0].length) == 13) {
//alert(inurlidea + ' becomeS ' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0].trim());
var theseurlsare=('' + inurlidea + '#thelist=').split('thelist=')[1].split('&')[0].split('#')[0];
var newurlsare=theseurlsare;
var theurlsare=decodeURIComponent(theseurlsare.split('&')[0].split('#')[0]).split(',');
var thesetsare=('' + inurlidea + '#thetlist=').split('thetlist=')[1].split('&')[0].split('#')[0];
var newtsare=thesetsare;
var thetsare=decodeURIComponent(thesetsare.split('&')[0].split('#')[0]).split('|');
var thenumsarehere=('' + inurlidea + '#order=').split('order=')[1].split('#')[0].trim().split(',');
var minone=-1;
if ((',' + ('' + inurlidea + '#order=').split('order=')[1].trim() + ',').indexOf(',0,') != -1) {
minone=0;
}
//alert(inurlidea + ' becOmeS ' + ('' + inurlidea + '#order=').split('order=')[1].split('#')[0].trim());
You’d think we’d be done with ablutions at this blog, but noooooo wayyyy … Luna says … there’s all manner of molecular interest out there …
It’s not just H and the 2 and the O … it’s the art of the roleroll.
… or so says “The Lu” anyway!
We wanted our recent Shower Songs web application be the application of choice for URLs at RJM Programming involving our Shower Songs web application YouTube API “radio play” web application.
In a “remembering and recall” scenario …
first you have to store such a listing URL into window.localStorage …
… and then …
you should recall these stored settings so that they can be reused …
our inhouse Shower Songs project using YouTube API means to “Radio Play” some, let’s say, “theatrical pursuits by the water”
A couple of times now, we’ve used it as company in the bath via an iPhone, preparing the list ahead of ever having to tap another anything, to hear some songs in the sequence the user establishes ahead of time … ie. the purpose of this web application.
However, we made some bad colour choices, especially regarding the mobile red button overlayed by black text containing the song title. It was hard to see. It is easier now, that text being yellow.
While there, we decided on a pale green background colour to apply to the textarea user interactive input and progress displaying conduit, when it’s relevant YouTube video is playing (in audio stream only mode), and another principle of our Shower Songs logic is that you should only see one pale green textarea for any great period of time … ie. the songs play in sequence, and looping around in continuous play, like on the radio.
Believe it or not, the actual top level hierarchy Shower Songs window needs no changes for this, but …
our YouTube video identifier code tests ( ie. end in a particular character within AEIMQUYcgkosw048 and encodeURIComponent([thisCode]) == [thisCode] ) … else, other comma separated lists might be passed onto Tabular Single Row Image Gallery
our inhouse Shower Songs project using YouTube API means to “Radio Play” some, let’s say, “theatrical pursuits by the water”
A couple of times now, we’ve used it as company in the bath via an iPhone, preparing the list ahead of ever having to tap another anything, to hear some songs in the sequence the user establishes ahead of time … ie. the purpose of this web application.
However, we made some bad colour choices, especially regarding the mobile red button overlayed by black text containing the song title. It was hard to see. It is easier now, that text being yellow.
While there, we decided on a pale green background colour to apply to the textarea user interactive input and progress displaying conduit, when it’s relevant YouTube video is playing (in audio stream only mode), and another principle of our Shower Songs logic is that you should only see one pale green textarea for any great period of time … ie. the songs play in sequence, and looping around in continuous play, like on the radio.
Believe it or not, the actual top level hierarchy Shower Songs window needs no changes for this, but …
Command Line ImageMagick HEIC to JPEG Image Creation Tutorial
Lately, we’ve been finding that the image format of photographs taken by our iPad’s Camera mobile application come out in …
IMG_9999.HEIC
… HEIC format (and file naming style of convention) back downloaded into this MacBook Air’s “realm of interest” (and we base a lot of work, here, in MAMP‘s Document Root folder, as a place to base ourselves in). When browsing for these image/heic such files there are known issues, which we do not feel like addressing directly, just now at least.
But we do have a workaround for it, for now … and just maybe forevvvvvvvvvvvveeeeeerrrrr?! Who knows?
And that solution adds another “layer” to the way the recent crontab/curl scheduled macOS PHP command line approach last talked about with Command Line ImageMagick JPEG Image Creation Tutorial set up it’s solution, so that …
on top of it’s existant “PaintBrush macOS can’t do *.jpeg” so we’ll get the PHP to ImageMagickconvert *.png (recent) to *.jpeg and *.jpg … today “this other layer” goes …
“Local File Browsing’s FileReader fails, natively, regarding File type image/heic files” so then we’ll get the PHP to ImageMagick convert *.HEIC (recent) to *.jpeG and *.jpG
Kludge ☇alert☇ for Windows! Sorry, Windows, macOS has case sensitivity, but last time we looked Windows cannot differentiate this way?!
And what do we do up at the local file browsing FileReader File object created interception point, in the Javascript? Code like …
// Globally ...
var lastreject='';
// ... then, near the top of it's function readBlob(opt_startByte, opt_stopByte) { } ...
if (files[0].type.indexOf("image/") != -1 && files[0].name.indexOf(".HEIC") != -1) {
if (lastreject != files[0].name.replace(".HEIC", ".jpeG")) {
lastreject=files[0].name.replace(".HEIC", ".jpeG");
alert('Please reselect using ' + files[0].name.replace(".HEIC", ".jpeG") + ' assuming you have PHP paintbrush_png_jpg.php active in your scheduling');
}
return;
}
The kludges keep coming?! But we’re pretty happy for now and might see about a better solution down the line. Meanwhile the changedpaintbrush_png_jpg.php saves our bacon, for now!
Stop Press
Since, we’ve realized out of the iOS Camera app Photos app downloading, you can end up with *.heic (ie. lowercase) files, which we cater for with a further changedpaintbrush_png_jpg.php PHP macOS (via Terminal app) command line application.
Command Line ImageMagick JPEG Image Creation Tutorial
For a while now, on macOS, we’ve been putting up with a scenario with our beloved macOS Paintbrush desktop application version whereby it will not save images in …
JPEG format … any more, so we have been saving in …
PNG format
… for some time now. Is this a big deal? Well, that is the question? We got a bit of a surprise in aspects of the solution we came up with.
With that, pretty obvious to us, first aim of smaller sized output image media files to start producing, we decided to involve …
… via this PHP ( where we thank this useful link for great help ) …
<?php
// paintbrush_png_jpg.php
// August, 2025
// crontab php command line called way to backup Paintbrush created *.png to reduced size *.jpg
$it = new GlobIterator(__DIR__ . "/*.png");
$last2mis = 9020;
foreach ( $it as $file ) {
if ((time() - $file->getMTime()) <= $last2mis) {
if (!file_exists(str_replace('.png','.jpg',$file)) && !file_exists(str_replace('.png','.jpeg',$file))) {
exec("cd " . __DIR__ . '; /usr/local/bin/convert -quality 30 ' . $file . ' ' . str_replace('.png','.jpeg',$file));
}
}
}
?>
… which achieves it’s objective, for the most part, because we are always saving these PNG files to MAMP‘s Document Root ( ie. /Applications/MAMP/htdocs for us ).
All good, smaller image JPEG files do result, but the twist for us came when we assembled our first JPEG vs PNG sets …
$ ls -l mamp_p*.*g*
-rw-r--r-- 1 user admin 459400 3 Aug 15:15 mamp_paintbrush_job-15.jpeg
-rw-r--r--@ 1 user admin 1857056 3 Aug 14:39 mamp_paintbrush_job-15.png
-rw-r--r-- 1 user admin 413477 3 Aug 15:14 mamp_paintbrush_job-17.jpeg
-rw-r--r--@ 1 user admin 1816410 3 Aug 14:47 mamp_paintbrush_job-17.png
-rw-r--r--@ 1 user admin 246569 3 Aug 15:08 mamp_paintbrush_job-21.jpeg
-rw-r--r--@ 1 user admin 1959028 3 Aug 15:08 mamp_paintbrush_job-21.png
-rw-r--r-- 1 user admin 264874 3 Aug 15:10 mamp_paintbrush_job-23.jpeg
-rw-r--r--@ 1 user admin 2555260 3 Aug 15:09 mamp_paintbrush_job-23.png
-rw-r--r-- 1 user admin 249117 3 Aug 15:11 mamp_paintbrush_job-25.jpeg
-rw-r--r--@ 1 user admin 2704233 3 Aug 15:11 mamp_paintbrush_job-25.png
-rw-r--r-- 1 user admin 230524 3 Aug 15:16 mamp_paintbrush_job-27.jpeg
-rw-r--r--@ 1 user admin 1962296 3 Aug 15:15 mamp_paintbrush_job-27.png
-rw-r--r-- 1 user admin 280417 3 Aug 15:17 mamp_paintbrush_job-29.jpeg
-rw-r--r--@ 1 user admin 2677561 3 Aug 15:16 mamp_paintbrush_job-29.png
$
… into two animated GIF images ( with PNG based one called paintbrush_crontab_png_to_jpeg.gif ) …
So, in “full flow debugging style awareness” what is the “key phrase” in the description of the issue, above?
We’d say “iPad users only” definitely, because no matter what debugging we do with Apple white leads joining up Safari browser iPad and MacBook Air debugging windows we do (and don’t get me wrong, this did help get the outerHTML of an img element in question, which was useful) clear thinking would reask (the “platform” and “environment” related) …
Why only on iPad (when it doesn’t happen on iPhone)?
… question because, in our experience …
That’s the unusual thing about the issue. And if we’d been on the ultimate ball we’d have noted that that discovery we outline below was made using an iPad!
… our changes being helped out by the discovery that our previous …
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
// is identified around here as a mobile platform
}
… was a bit unreliable identifying mobile iOS platform Safari web browser usage, but this useful link got us to refine that thinking to …
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) || eval(String.fromCharCode(32).trim() + navigator.maxTouchPoints) > 0) {
// is better identified around here as a mobile platform
}
… with more success. Yayyyyy!
… so we bit the bullet and applied this discovery’s changes to the good ol’ header.php of our TwentyTen themed WordPress blog “go to” piece of code. Yes, good to do, but we found, still no Havana cigar!
So then, relook at the outerHTML of the img element in question. It looked like …
… and that ontouchend=”imgedit(event);” is a clue to follow. Indeed, it took us to the “image right click logics” contained in the changedonrightclick.js external Javascript logic designed for right click analysis. What if it’s “mobile check booleans” need this updating too? And yes, that fixed the issue.
mobile platform chance to have three finger gestures help with scrolling functionality … today we have it so that …
mobile platforms are better suited creating Image Maps via canvas and image based inhouse web application (looking out for 🗺️🖼️ emoji button means to create Image Map when ready, as a double click on the canvas can do as well)
… our changes being helped out by the discovery that our previous …
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
// is identified around here as a mobile platform
}
… was a bit unreliable identifying mobile iOS platform Safari web browser usage, but this useful link got us to refine that thinking to …
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) || eval(String.fromCharCode(32).trim() + navigator.maxTouchPoints) > 0) {
// is better identified around here as a mobile platform
}
… with more success. Yayyyyy!
Along the way the HTML textarea elements used to identify Image Map subelement area rectangular limits have their disabled attribute set, which has the benefit …
that there is no need to allow any focus to these textarea elements when nothing any user can enter into them would make any difference anyway … and yet …
at least on non-mobile platforms the useful resizing talents of textarea elements are not stopped because of the disabled attribute being set
… had become a little obsolete (at least, regarding the emoji button workflow), in the sense that, like with the canvas ondblclick event (ie. double click) functionality, why not, when clicking that 🗺️🖼️ Image Map creator emoji button grab the contents of the canvas already displaying as the default content presented to the “potential” (ie. it depends, sometimes, whether you double click that canvas element the next time) Image Map creation session?
Relevant to Random Background Image Map Area Polygons Tutorial and the decision then regarding non-mobile platforms to use an initial click followed by right clicks to enable Image Map area element shape=poly components, today, thinking with respect to mobile platforms, we’ve decided Image Map area element shape=poly components can be created via an initial click followed by double click sequences and going back to the polygon start, with either platform type, ending the polygon with two separated clicks. Also relevant to that same tutorial and it’s pointer-events:none; discovery, today’s mobile work regarding the textarea elements plotted to show the rectangular limits of user defined areas already created we found “real world relevance” to applying this to mobile such textarea elements. That is because on some mobile platforms these textarea elements will never be able to be resized out of the way, but if we apply pointer-events:none; to these, it does not matter, as the user can, as required, click/touch through these overlayed elements that have a huge z-index and semi-transparency applied to them.
Again, perhaps on a mobile platform web browser, feel free to try …
There are known Safari mobile web browser textarea resizing limitations as we discovered trying a Google search of allow textarea resizing on mobile safari web browser, thanks, that we gleaned from the use of …
Solution 2: Standard JavaScript Auto-Grow
If you need to support older versions of iOS Safari that lack the newest CSS specs, you can dynamically update the box height using a tiny JavaScript event listener. This removes the scrollbar and expands the container vertically as they type:
HTML: html
<textarea id=”mobile-textarea” rows=”3″ oninput=”autoGrow(this)”></textarea>
Canvas Interfacer Three Finger Gesture Usage Tutorial
There’s more research needed around here regarding mobile platform usage to the HTML5canvas based ideas swirling around yesterday’s Random Background Image Map Area Polygons Tutorial‘s work, and one issue we came across was …
on mobile platforms you can get to gesture results whereby the canvas is all you see on the screen (eg. of an iPhone) …
but what if you are in “scribble mode” at that point? …
before today, we were having trouble using …
two finger “pinch” gesture to zoom out … or …
one finger “swipe” to reveal more to the right (where, if we could have reached it, that right hand menu of annotation options has none of these “scribble mode” oddities) … because …
before today, that last idea just drew a “scribble” “free drawing” line to the canvas
… to reach the menu or any other non-canvas element not in “scribble mode” (ie. scrolling could not be achieved, at least in a way we could immediately access)
If you are building this for a website or web app, you can use the touchstart and touchmove events to capture finger coordinates, check if exactly three fingers are on the screen, and then calculate the direction.
… to (start with global … var isthree=false; and) end up with …
… near the top of our function toptouchHandler(event) Javascript code in our changedsignature_signature.js external Javascript canvas interfacer helper.
Image Map only allowing for area subelements with shape=rect … today we also allow for …
Image Map now allowing for area subelements with shape=poly …
… via …
Right clicks after an initial click are the means by which you can define area shape=poly ( as distinct from the default shape=rect ) elements where to finish a polygon two click back close to the start point.
… as a modus operandi for the user to cater for more complex shape definitions in their Image Maps.
That doesn’t mean the rectangle around such a polygon is not also significant. Do you know why?
Yes, a hosting HTML div of a specific width and height and positioned absolutely at a precise left and top screen position allows SVG innerHTML like …
<svg xmlns="http://w3.org" width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet"><polyline points="0,67,56,7,100,0,150,17,0,67"></polyline></svg> ... be showing a polygonal user clicked shape, scaled appropriately, yet responsively, and allowing for those % unit definitions above making all this methodology useful here. Notice the zero co-ordinates? That is no accident. We make the co-ordinates relative to the minimum x and minimum y "datum" to the co-ordinating.
To pass events down through a higher z-index element, add pointer-events: none; to the top element. This tells the browser to ignore the overlay for mouse events, allowing clicks and hovers to "fall through" to the element stacked beneath it.
... to learn a whole new technique we've been looking for for quite some time now ... now, where did we put that "Overlay Disappointments File"?! ... bye bye!
... and allowing users using our inhouse Random Background interfacer the chance to create some Image Maps using incarnations of these images as the visual basis to them.
We've chosen ...
the oncontextmenu (ie. right click) as an intervention point to facilitate this ... or ...
if using a macOS operating system a ...
control-command-shift-3
control-command-shift-5
...
document.addEventListener('keydown', (event) => { // thanks to https://www.google.com/search?q=javascript+detecting+control-command-shift-3&rlz=1C5OZZY_en&oq=javascript+detecting+control-command-shift-3&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQIRigATIHCAIQIRigATIHCAMQIRigATIHCAQQIRigATIHCAUQIRiPAjIHCAYQIRiPAjIHCAcQIRiPAtIBCTE3NzMyajBqN6gCALACAA&sourceid=chrome&ie=UTF-8
// Check if Control, Command (metaKey), and Shift are all held down
// AND the key pressed is the number 3
if (
event.ctrlKey &&
event.metaKey &&
event.shiftKey &&
event.code === 'Digit5'
) {
// Prevent the default browser action if necessary
//event.preventDefault();
established a URL means by which a single URL call from the canvas residing Inhouse Image Map Creator and Canvas Annotation web application via a data URI hashtag conduit ... and today just ...
allowing for an absolute URL in that hashtag is the relatively simple change needed so that, using this, our WordPress "right click over an img image element" functionality can be tweaked ...
var huhifs=prompt('Optionally, please, any CSS for images ... append 3 spaces to be able to edit this ' + (gthing == 'image' ? gthing + ' (and answer of #imagemap will use this image as basis for creation of an image map in a new window)' : gthing) + ' in a canvas ... ref. https://www.w3schools.com/cssref/css3_pr_filter.php ... eg. ' + egblurb + usuff + ' ', defblurb);
if (huhifs == null) {
huhifs='';
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
if (event.target.outerHTML.indexOf('<a ') == 0) {
console.log(6);
ggurl=event.target.href;
} else {
console.log(66);
ggurl=document.body.innerHTML.split(event.target.outerHTML)[0].split(' href="')[eval(-1 + document.body.innerHTML.split(event.target.outerHTML)[0].split(' href="').length)].split('"')[0];
}
if (6 == 6) {
console.log(ggurl);
window.open(ggurl,'_blank'); ggurl='';
// huhifs=window.prompt('Optionally, please, any CSS for images ... append three spaces to be able to edit this ' + gthing + ' in a canvas ... ref. https://www.w3schools.com/cssref/css3_pr_filter.php ... eg. ' + egblurb + usuff + ' ', defblurb);
} else {
setTimeout(function(){ window.open(ggurl,'_blank'); ggurl=''; }, 5000); //alert(event.currentTarget.outerHTML); //event.currentTarget.click();
}
}
}
if (huhifs.toLowerCase() == '#imagemap') {
event.preventDefault();
event.stopPropagation();
ggurl=event.target.src;
window.open('//www.rjmprogramming.com.au/HTMLCSS/user_of_signature_signature.htm?imagemap=url#' + (ggurl.indexOf('//') != -1 ? '//' + ggurl.split('//')[1] : (ggurl.replace(/^\.\//g,'/').indexOf('/') == 0 ? '//www.rjmprogramming.com.au/' + ggurl.substring(1).replace(/^\//g,'ITblog/') : (ggurl.indexOf('../') == 0 ? '//www.rjmprogramming.com.au/' + ggurl.substring(3) : ggurl))),'_blank','top=40,left=40,width=' + eval(-80 + screen.width) + ',height=' + eval(-80 + screen.height));
ggurl='';
} else if (huhifs.indexOf('data:image/') == 0) {
if (document.getElementById('imgcopycheck') && usuff != '') { //if (document.URL.indexOf('/streetart/') != -1) {
uplitc(huhifs); //alert(document.URL);
}
return '';
}
... as an excerpt from the changedonrightclick.js external Javascript called by WordPress, and calling ...
... good, now, again ... an image is a canvas is an image ...
an image is a canvas is an image
... excellent, now, backwards ... egami na si savnac a si egami na ...
egami na si savnac a si egami na
... wow! ... Now, lastly … I want my mamma! Now! ...
I want my mamma! Now!
Mamma! Thank god you’re here! But it's true. Our thinking behind allowing browsed for image files become data URIs that can be the img element "image" part of the "image map", further to yesterday's Inhouse Image Map Creator Mobile Debug Tutorial, we can now create using our inhouse Image Map Creator capable web application uses the "an image via [canvasContext].drawImage() is a canvas via [canvas].toDataURL() is an image" concept that can save us heaps of time with this project. Instead of intervening at each dropdown option mentioning "Browse" to make this design change, we, instead, introduce to the HTML5canvas element a new ondblclick event ...
<canvas ondblclick="qwowo=window.open(document.URL.split('?')[0].split('#')[0] + '?imagemap=url#' + this.toDataURL('image/jpeg',0.4),'_blank','top=40,left=40,width=' + eval(-80 + screen.width) + ',height=' + eval(-80 + screen.height) + '');" ondragstart="dragstart(event);" draggable="false" title="Ready for you to create your canvas 🎨 content above any signature 💳 panel ... keys U for Undo and R for Redo can work after a discrete click ending any scribble mode of use. Double click can facilitate turning this canvas content into an image map, and this canvas content can be populated by so many of the options in the menu to the right, which includes many local image file browsing choices." id="topcanvas" width=850 height=600 style="background-color:white; position: absolute; top:0; left:0; border-bottom:5px solid yellow; border-right:5px solid blue;"></canvas>
... allowing that "on double click" result in the web application turning into an Image Map Creator where now ...
Image Map ( ie. <img src="[image URL as entered by user or data URI browsed for by the user, or, come to think of it, from a couple of days back, entered in by the 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
... is that very pithy redefinition of our web application's view of what an Image Map can be! Though?!
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%);
... talking about the three appended spaces needed.
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 ...
... (we figured after a day of tinkering ... so sad).
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.
Did you read the recent Responsive Web Design Landing Page Image Map Tutorial? Its core takeaway was the linking of One Image Website functionalities. In these One Image Websites we've picked out a guinea pig ...
... 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 ...
Mobile apps “out of the box” are quite likely to change with each, in our case, iOS, upgrade. Sometimes nuanced changes pass you by, unless you are into reading the “fine print” on each upgrade’s documentation, that is.
For that reason, we occasionally revisit the big such “out of the box” apps and …
99% of the time that is just to use them in the usual way … but yesterday …
we did it for the “more intense peruse” to take notice of what might be new to us, which we do … ah, let’s see … 100 – 99 = ? … 1% of the time
… as might have been the case when we presented Camera Pinch Tutorial talking specifically about the great iPhone iOS Camera app.
The iOS Camera app’s top right “six dots” menu …
… suboptions caught our eye …
filter
styles
aspect
… which we played around with, and are presenting our findings with today’s animated GIF presentation. In amongst all that we thought we’d like to hone in on iOS Camera app’s …
Noir Cool (smallest aspect)
… sticking to the order above, and see whether we can get at all close using …
… which was also helpful thanks, and then we constructed a web application for you to try out the concepts we are getting at here with a first draftNoir Cool (small aspect) simulation web application …
We saw our first stink bug of the summer season! Yayyyyy! Now, we know we may have offended some gardeners out there, but we find it comforting seeing any of …
Stink Bugs … the sighting was of a Bronze Orange Bug sulciventris
… as a reminder of our eastern Australian summers and that they are still around! Yayyyyy! Because it is a little concerning how little happens on the car windscreen these days insect wise compared to the nineties and into the noughties.
Huh?! Thanks, Nala, Luna! You’ve finished in the summer grasses?! And yes, you want to get to the point? Yes, and you’ve been watching Skippy …
… summer reruns, perhaps?! Huh?!
Yes … well … there you go. Yes, we wanted to … um … point out … in terms of photographic technique … in terms of the digital realm … shall we say …
Okay, Skip … getting there
… let’s just say …
Isn’t the pinch gesture on the Camera app just “the bee’s knees”?
And yes, Skip, bees have knees … before you complain! Sheeesshhh!
Photographing insects …
has to have gotten more convenient being out and about with a Camera app, whether that be iOS or Android or whattevvvvvvvveeeerrrr … with the ease of pinch gesture usage when shaping to take the photo … and yet …
in the Single Lens Reflex dominance days (of Photography) we’d have had …
much much longer telephoto and/or zoom lenses
tripods
shutter clickers (from a distance)
perhaps more patience
perhaps darkroom enlargement opportunities
… counteracting that convenience … but yes, you can accessorize?!
One thing is for sure, and that is that you should not feel alone delving into the Citizen Science scene. It is growing … and practising fiercely .
Yes, this transitioning from /tmp to /home/rjmprogr has us trying not to rush, because rushing can be associated with places where you assume …
… rather than prepare and study. Besides, Akela said no!
Why choose /home/rjmprogr ?
it can be read and written to by the RJM Programming web server username … and yet …
cannot be referenced by users surfing the net … being lower down the directory tree than the /home/rjmprogr/public_html which corresponds to our Apache Document Root folder
it can be read and written to by the cPanel username … meaning …
New Temporary Folder Arrangements Tidying Tutorial
We’ve had one public and three private dedicated virtual servers running our Apache/PHP/MySql web server here at RJM Programming. The last two have us transitioning from one AlmaLinux web server to another. What could be different? Well (readers who resist reading blog posting titles) security measures move on with a lot of upgrades and migrations in web server “land” these days. On ours, the use of …
/tmp
… as per …
# df -k /
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda1 103019024 58818836 38940980 61% /
# df -k /tmp
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/loop0 4054752 1108 3843932 1% /tmp
#
… have in the last AlmaLinux web server incarnation become more contentious in that the RJM Programming web server username (as distinct from the administrator of cPanel username) is unable to write to this /tmp for the first time. This is a little bit of a peeve for us, as we have written quite a bit of PHP that uses it to read and write from, as it’s temporary storage “place of choice”.
There’s no way we are going to rush to remedy this, but, today, after self-ruling out, after discussion with our web hosters, Crazy Domains, the thought of changing any file permissions here, we’re starting, sort of at the back end of the issue, fixing for the future …
change the minutes field 10 less for all such records
copy this into a buffer
back at RJM Programming cPanel’s Terminal window …
crontab -e
… ours uses the great vi editor where we get to the end character and type “i” for insert in order to Paste (via top menu) into the crontab file … followed by “wq” to save (with all being well will result in …
crontab: installing new crontab
)
readying ourselves for either “tidying up” requirement into the future
Over to you … PHP!
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
our inhouse Shower Songs project using YouTube API means to “Radio Play” some, let’s say, “theatrical pursuits by the water”
A couple of times now, we’ve used it as company in the bath via an iPhone, preparing the list ahead of ever having to tap another anything, to hear some songs in the sequence the user establishes ahead of time … ie. the purpose of this web application.
However, we made some bad colour choices, especially regarding the mobile red button overlayed by black text containing the song title. It was hard to see. It is easier now, that text being yellow.
While there, we decided on a pale green background colour to apply to the textarea user interactive input and progress displaying conduit, when it’s relevant YouTube video is playing (in audio stream only mode), and another principle of our Shower Songs logic is that you should only see one pale green textarea for any great period of time … ie. the songs play in sequence, and looping around in continuous play, like on the radio.
Believe it or not, the actual top level hierarchy Shower Songs window needs no changes for this, but …