Walking Trip …

Walking Trip

Walking Trip

Offenbach's Suite ... Warts 'n All

Offenbach's Suite ... Warts 'n All

 📅  

If this was interesting you may be interested in this too.

Posted in Photography, Trips | Tagged , , | 34 Comments

Dominoes Horizontal Block Game User Experience Tutorial

Dominoes Horizontal Block Game User Experience Tutorial

Dominoes Horizontal Block Game User Experience Tutorial

To improve yesterday’s Dominoes Horizontal Block Game Tutorial

Turn Away From

… paradigm whereby two players can play a Dominoes Game sharing the one device, that game may benefit by a user instigated “beep paradigm” in play (but be aware if you have dogs in the house like “The Lu” she gets put off by this optional beeping).

We can deploy this mainly through the external Javascript we talked about at Country Quizzes Beep Tutorial via …


<script type=text/javascript src='//www.rjmprogramming.com.au/beep.js?iam=song_lyric_faux_pas.html&rand=76576533' data-defer=defer></script>

That placement of one beep (for player 1 “turn away”) or two beeps (for player 2 “turn away”) can both tell players …

  • when they should turn away … as well as …
  • when they should re-engage

… regarding our changed third draft Dominoes Block Game you can try below.


Previous relevant Dominoes Horizontal Block Game Tutorial is shown below.

Dominoes Horizontal Block Game Tutorial

Dominoes Horizontal Block Game Tutorial

After yesterday’s Dominoes Game Sections Tutorial we have a …

Dominoes Horizontal Block Game

… initially coded for. Why the “Horizontal” here? Well, to allow “vertical roaming” we need to think a bit more, on it.

This ask of Google … css flip image‘s …

To flip an image using CSS, use the transform property with either the scaleX() or scaleY() function.

Quick Reference

Horizontal Flip (Mirror):
transform: scaleX(-1);

Vertical Flip (Upside Down):
transform: scaleY(-1);

Both (180-degree rotation):
transform: scale(-1, -1);

transform: scaleX(-1) idea was useful, thanks, as was css filter to blacken image out‘s …

To completely blacken an image out using a CSS filter, use filter: brightness(0);.

Quick Reference

css.blackout-image {
filter: brightness(0);
}

… this idea, thanks applied to our changed second draft Dominoes Block Game you can try below.


Previous relevant Dominoes Game Sections Tutorial is shown below.

Dominoes Game Sections Tutorial

Dominoes Game Sections Tutorial

Further to yesterday’s Dominoes Game Resources Tutorial‘s start to our Dominoes online game quest, and reading more about the rules of play regarding a Block Game version we’ve settled for the following sections on this game’s webpage designed for two players sharing the one screen (so far) …

  • header parts
  • playing area … where the tiles players play are placed
  • left and right player areas … show player names and score and current button of applicability …
  • left and right player tiles area … sometimes showing individual player tiles, sometimes showing underside of tile, with an honour system in play that the player whose turn it is not, turns away when asked …
  • stock area … contains the rest of the 28 dominoes not yet in play, showing underside of tile

Our strategy will be the first player to play is determined by whether left or right button is first selected, and from there in the game the order of play proceeds as per the rules of the Dominoes Block Game.

So far we think we’ll rewrite button content constantly according to what the status of the game at any given time. We can do that because the button elements are hosted by span hosting HTML elements.

And so, that is the plan regarding our first draft sections showing of proposed Dominoes Block Game, today.


Previous relevant Dominoes Game Resources Tutorial is shown below.

Dominoes Game Resources Tutorial

Dominoes Game Resources Tutorial

When creating an online web application game, like Animated Plane and Coconut Hunt Game Nuances Tutorial‘s Animated Plane and Coconut Hunt Game or games like playing card games, they involve “things” or …

nouns

… you can think of in programming (and many IDE) parlance as “resources”, and such games can lend themselves towards Object Oriented Programming (ie. OOP) code design, perhaps, and a set aside block of time preparing resources ahead of starting any coding. So it is with today’s start, for us, in creating a …


Dominoes

… game, as an online web application. We vaguely remember Dominoes from a while back and it involves …

  1. dominoes (we think of as tiles) … as the resource …
  2. randomosity … as many games do, regarding them being turned over to them all looking the same, and players randomly selecting their own tiles to play the game …
  3. a way to score … as many games do

This first day of work had us …

  • find a good online source at this useful link … thanks … to create a “parent resource” …

    … dominoes.png … via …

    1. control-command-shift-3 of that webpage
    2. open macOS PaintBrush desktop application
    3. File -> New from Clipboard
    4. form rectangle around the white on black section of tiles
    5. Edit -> Copy
    6. File -> New from Clipboard
    7. File -> Save As… dominoes.png
  • 28 x
    1. form rectangle around the white on black subsection of dominoes.png
    2. Edit -> Copy
    3. File -> New from Clipboard
    4. File -> Save As… dominoes_[leftHandDotCount]_[rightHandDotCount].png
  • 7 x
    1. form rectangle around the uniquely encountered leftHandDotCount left hand side of a dominoes_[leftHandDotCount]_[rightHandDotCount].png
    2. Edit -> Copy
    3. File -> New from Clipboard
    4. File -> Save As… dominoes_[leftHandDotCount].png

… off memories of how Dominoes might ask of us “resources” wise.

That left us, after using FileZilla uploading to a new RJM Programming /Games/Dominoes folder off that web server’s Apache Document Root folder, as a folder full of image files only.

In this early scenario here, there is an adage we try to maintain, but let’s ask why …


Why on an Apache and PHP web server is it a bad idea to not have an index.html nor index.htm nor index.php within a web server folder?

Not having an index file like index.html, index.htm, or index.php in an Apache folder is a bad idea because it exposes your entire directory structure and source files to the public via Apache’s automatic directory listing. This vulnerability, known as Directory Browsing or Information Disclosure, allows attackers to easily map your application, find sensitive backup files, and locate hidden scripts.

FileZilla is really great at remedying them, often times temporary dilemma, quickly. Within a web server folder a context menu option Create New File (we called index.html) in that folder (even zero length) is going to stop that issue weakness talked about above. Aaaaaaah! Now we can think more clearly on ways to design the online Dominoes version game play.


Previous relevant Animated Plane and Coconut Hunt Game Nuances Tutorial is shown below.

Animated Plane and Coconut Hunt Game Nuances Tutorial

Animated Plane and Coconut Hunt Game Nuances Tutorial

Today’s a day of nuanced progress, after yesterday’s Coconut Hunt Game Tutorial‘s “filling in sideways” work on our Animated Plane and Coconut Hunt Game web application. Today, we …

  • fixed some document.body.title annoyances whereby it would appear too often
  • worked on the default A option textarea via …
    1. some “panda 🐼 led recovery” modelling of a p emoji usage (with animation) and span emoji usage (without animation) … and …
    2. modelling of how iframe onload event can be used to develop dynamic Javascript (the default example changing the coconut 🥥 hunt into a bear 🐻 hunt?!) … as opposed to a document.createElement(‘script’) alternative approach
  • fixed some window.open too small size annoyances
  • allowed for screen co-ordinates cursor (on non-mobile), via onmousemove event logic, to assist intrepid users going above and beyond “overlay” positioning their own elements via position:absolute; left:?; top:?; in A option textareas
  • allowed for toggling of non-mobile cursor between as above and crosshair via right click
  • allowed for the last left:?; top:?; as above detected be remembered and involve itself as the default position:absolute; “overlay” positioning of the A option textarea default “panda 🐼 led recovery” emoji of above
  • allow for 8 seconds of time for a user to change default coconut 🥥 emoji to some other text via contenteditable=true ahead of the Hunt Game starting … thanks to this useful link regarding hiding a contenteditable=true focus border
  • allow for sharing of the Hunt Game
  • Hunt Game sound effects

Feel free to try these tweaks to our Animated Plane and Coconut Hunt Game, in a nuanced “latest draft” Animated Plane Coconut Hunt Game web application below!


Previous relevant Coconut Hunt Game Tutorial is shown below.

Coconut Hunt Game Tutorial

Coconut Hunt Game Tutorial

Are you a reader who has been amused or bemused by the word Game being in the blog posting titles lately, up to yesterday’s Animated Plane Game User Animations and Styling Tutorial, when No Game really, about any of it? Well, today, it’s …

Game On

Do you like coconuts? Can I ask you, have you ever looked into a coconut, and asked yourself …

I shell always love you.

? Well, have we got the game for you?! Start the ball rollingshell shaking via the first click/top on the coconut fallen from the tree. And from there, it’s a fast reactions game, to score well! Good luck, in the changed “latest draft” Animated Plane Coconut Hunt Game web application below!


Previous relevant Animated Plane Game User Animations and Styling Tutorial is shown below.

Animated Plane Game User Animations and Styling Tutorial

Animated Plane Game User Animations and Styling Tutorial

On top of yesterday’s Animated Plane Game User Content Sharing Tutorial‘s honing in on the five “nouns” of interest …

  • trees
  • plane
  • gymnast
  • clouds
  • ground

… today we wanted to offer two more user controllable parts to this Animated Plane Game web application, those being …

  • CSS styling … easy, as CSS can be dynamically added to a web application at the clientside, as the Javascript is executing … and, a bit more of a learning curve for beginners is …
  • user animations … we’re envisaging, in it’s “easiest to understand encapsulation for a newbie” uses …
    1. @keyframes
    2. transition

    … a whole big wooooorrrrlllldddd of animation study just by itself (and in order for modelling to, perhaps, help we used an example from this excellent link, thanks, as the default option A textarea usage model)

… but a hell of a lot easier for a user to establish than some arcane Javascript DOM animations involving setTimeout or setInterval timers?!

For these two new ideas, popup textarea windows appear to give the user plenty of space to play around in. As ever, email and SMS can follow up for that user to share with others what their animation ideas are, perhaps far removed from the original plane and gymnast scenario by the time they finish. And here it may be pertinent to point out that even using hashtag emailing (and even more so with SMSing) there must be message size limits that will stop you event-u-al-ly!

Try this in the changed “latest draft” Animated Plane Game web application below.

Did you know?

In yesterday’s “noun” work we talked about “content” defined by the user in terms of real references to media data URIs or URLs. Well, the other way a user can now affect “content” is via CSS. Below we make the plane and gymnast disappear via the C (for CSS styling) option (that can take you to a popup window textarea where you can Apply this) …


<style>
#myif { /* plane */
display:none; /* other choice could be visibility:hidden; */
}

#mytwoif { /* gymnast */
visibility:hidden; /* other choice could be display:none; */
}
</style>


Previous relevant Animated Plane Game User Content Sharing Tutorial is shown below.

Animated Plane Game User Content Sharing Tutorial

Animated Plane Game User Content Sharing Tutorial

Yesterday’s Animated Plane Game Primer Tutorial set up five “nouns” of interest …

  • trees
  • plane
  • gymnast
  • clouds
  • ground

… each of which has a relationship to a piece of media content. The border-image (ie. ground) content aspects we allow a user to define emoji text for, but the rest are associated with a data URI or URL.

Today’s work is to allow the user to specify these “content” data items themselves, as well as share this via email or SMS to another user, with those user “content” data items recreated for the recipient user clicking the email or SMS link containing those hashtagged user data components. Later we hope to expand the functionality more, from today’s …


function getsrc(fromoh) {
var forvpre='Currently this content points at ... ' + String.fromCharCode(10);
var forvsuf=String.fromCharCode(10) + 'Enter an alternative content URL (can be clipart style data URI you see often using Google Image (Copy Image Address via right click) Searches) ... or ... ' + String.fromCharCode(10) + String.fromCharCode(10) + '1[:URL] for trees, 2[:URL] for plane, 3[:URL] for gymnast, 4[:URL] for clouds, 5[:emoji(s)] for ground, E for email, S for SMS';
if (fromoh.indexOf(' src="//') != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(' src="')[1].split('"')[0] + forvsuf;
} else if (fromoh.indexOf(" src='//") != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(" src='")[1].split("'")[0] + forvsuf;
} else if (fromoh.indexOf(" src=//") != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(" src=")[1].split(" ")[0].split(">")[0] + forvsuf;
} else if (fromoh.indexOf(' src="') != -1) {
return forvpre + fromoh.split(' src="')[1].split('"')[0] + forvsuf;
} else if (fromoh.indexOf(" src='") != -1) {
return forvpre + fromoh.split(" src='")[1].split("'")[0] + forvsuf;
} else if (fromoh.indexOf(" src=") != -1) {
return forvpre + fromoh.split(" src=")[1].split(" ")[0].split(">")[0] + forvsuf;
}
return fromoh;
}

function yourprompt(ino, intlis) {
var ei=-1, si=-1;
isac=true;
var opsd=prompt(getsrc(ino.outerHTML), '');
if (opsd == null) { isac=false; return false; }
if (opsd.trim() != '') {
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;


case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
} else {
setTimeout(function(){ ino.click(); }, 100); return true;
}
isac=false;
return false;
}

function anyprompt(opsd) {
if (opsd.trim() != '') {
opsd=opsd;
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;

case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
}
}

function ourprompt(ino, intlis) {
var ei=-1, si=-1;
isac=true;
var opsd=null;
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
opsd=prompt(intlis + String.fromCharCode(10) + String.fromCharCode(10) + intlis, '');
} else {
opsd=prompt(getsrc(document.getElementById('myimg').outerHTML), '');
}
if (opsd == null) { isac=false; return false; }
if (opsd.trim() != '') {
opsd=opsd;
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;

case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
} else {
setTimeout(function(){ ino.click(); }, 100); return true;
}
isac=false;
return false;
}

… in the changed “eighth draft” Animated Plane Game web application.


Previous relevant Animated Plane Game Primer Tutorial is shown below.

Animated Plane Game Primer Tutorial

Animated Plane Game Primer Tutorial

The mix-blend-mode:multiply; discoveries (along with those naive previous usage without realizing it’s implications) we made creating Periodic Table Image Map Primer Tutorial recently has opened up new “vistas of possibility” (VOP, of course) for us, and has inspired us to give “just Javascript and CSS and HTML animated games” (aided in large part by clipart free content components) another go …

… with a “widget feel” now realizable, for us, knowing that white backgrounded HTML iframe content no longer has to hold us back piecing together animations (in an “OOP feeling” way) consisting of …

  • base webpage CSS and HTML and Javascript (DOM, also helping out the control of) …
  • HTML iframe components (and in our case the image content is it’s background image with background-size:contain; and background-repeat:no-repeat; along with a specific iframe width and height) for any one “noun” (or class of object) in your game storyboard … if you will … if you will … if you will … and …
  • HTML img components in a similar vein … but today’s trees did not need mix-blend-mode:multiply; because the originator made the background transparent (ie. another option with all this “animated pieces thinking”)

Animation(s) can be CSS @keyframe transitions (though not yet with animation above) or Javascript DOM logic via setTimeout (or setInterval) timers or animated GIF/webp content or, we daresay, many other approaches.

We’re going to tabularize below “how we got to the result above” below …

We started with a “first draft” … getting Freepik image plane image animated with a rudimentary green border-bottom representing the ground …
then to “second draft” … adding https://i.makeagif.com/media/8-11-2023/Xu_roP.gif animated GIF cloud background to go with edited Freepik image because mix-blend-mode:multiply will not mask out the non heterogenous bluish clouds in the image …
then to “third draft” … tweaking https://i.makeagif.com/media/8-11-2023/Xu_roP.gif animated GIF cloud background … …
then to “fourth draft” … establishing an SVG+XML (with SVG text emoji content) border-image for the bottom border representing the ground …
then to “fifth draft” … added acknowledgements for all the help …

Thanks to Image by brgfx on Freepik and https://i.makeagif.com/media/8-11-2023/Xu_roP.gif and https://procul.org/images/2025/Animated-Clouds-Gif/ and and https://au.pinterest.com/pin/587930926347995281/ and https://giphy.com/explore/trees-swaying-stickers

then to “sixth draft” … added https://au.pinterest.com/pin/587930926347995281/ animated GIF gymnast background and thereby proving that overlapping “iframe widgets” (helped out by mix-blend-mode:multiply presumably) was possible, and important …
then to “seventh draft” … added https://giphy.com/explore/trees-swaying-stickers giphy.com/explore/trees-swaying-stickers animated (and transparently backgrounded) webp swaying trees image along with tweaked Freepik image now animated GIF to animate the plane itself a little, in place, separate to the Javascript DOM based animation moving across the screen … for today’s final draft …

Stop Press

In tomorrow’s installment we allow for user defined content, and sharing, as per …

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.

Posted in eLearning, Event-Driven Programming, Games, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Dominoes Horizontal Block Game Tutorial

Dominoes Horizontal Block Game Tutorial

Dominoes Horizontal Block Game Tutorial

After yesterday’s Dominoes Game Sections Tutorial we have a …

Dominoes Horizontal Block Game

… initially coded for. Why the “Horizontal” here? Well, to allow “vertical roaming” we need to think a bit more, on it.

This ask of Google … css flip image‘s …

To flip an image using CSS, use the transform property with either the scaleX() or scaleY() function.

Quick Reference

Horizontal Flip (Mirror):
transform: scaleX(-1);

Vertical Flip (Upside Down):
transform: scaleY(-1);

Both (180-degree rotation):
transform: scale(-1, -1);

transform: scaleX(-1) idea was useful, thanks, as was css filter to blacken image out‘s …

To completely blacken an image out using a CSS filter, use filter: brightness(0);.

Quick Reference

css.blackout-image {
filter: brightness(0);
}

… this idea, thanks applied to our changed second draft Dominoes Block Game you can try below.


Previous relevant Dominoes Game Sections Tutorial is shown below.

Dominoes Game Sections Tutorial

Dominoes Game Sections Tutorial

Further to yesterday’s Dominoes Game Resources Tutorial‘s start to our Dominoes online game quest, and reading more about the rules of play regarding a Block Game version we’ve settled for the following sections on this game’s webpage designed for two players sharing the one screen (so far) …

  • header parts
  • playing area … where the tiles players play are placed
  • left and right player areas … show player names and score and current button of applicability …
  • left and right player tiles area … sometimes showing individual player tiles, sometimes showing underside of tile, with an honour system in play that the player whose turn it is not, turns away when asked …
  • stock area … contains the rest of the 28 dominoes not yet in play, showing underside of tile

Our strategy will be the first player to play is determined by whether left or right button is first selected, and from there in the game the order of play proceeds as per the rules of the Dominoes Block Game.

So far we think we’ll rewrite button content constantly according to what the status of the game at any given time. We can do that because the button elements are hosted by span hosting HTML elements.

And so, that is the plan regarding our first draft sections showing of proposed Dominoes Block Game, today.


Previous relevant Dominoes Game Resources Tutorial is shown below.

Dominoes Game Resources Tutorial

Dominoes Game Resources Tutorial

When creating an online web application game, like Animated Plane and Coconut Hunt Game Nuances Tutorial‘s Animated Plane and Coconut Hunt Game or games like playing card games, they involve “things” or …

nouns

… you can think of in programming (and many IDE) parlance as “resources”, and such games can lend themselves towards Object Oriented Programming (ie. OOP) code design, perhaps, and a set aside block of time preparing resources ahead of starting any coding. So it is with today’s start, for us, in creating a …


Dominoes

… game, as an online web application. We vaguely remember Dominoes from a while back and it involves …

  1. dominoes (we think of as tiles) … as the resource …
  2. randomosity … as many games do, regarding them being turned over to them all looking the same, and players randomly selecting their own tiles to play the game …
  3. a way to score … as many games do

This first day of work had us …

  • find a good online source at this useful link … thanks … to create a “parent resource” …

    … dominoes.png … via …

    1. control-command-shift-3 of that webpage
    2. open macOS PaintBrush desktop application
    3. File -> New from Clipboard
    4. form rectangle around the white on black section of tiles
    5. Edit -> Copy
    6. File -> New from Clipboard
    7. File -> Save As… dominoes.png
  • 28 x
    1. form rectangle around the white on black subsection of dominoes.png
    2. Edit -> Copy
    3. File -> New from Clipboard
    4. File -> Save As… dominoes_[leftHandDotCount]_[rightHandDotCount].png
  • 7 x
    1. form rectangle around the uniquely encountered leftHandDotCount left hand side of a dominoes_[leftHandDotCount]_[rightHandDotCount].png
    2. Edit -> Copy
    3. File -> New from Clipboard
    4. File -> Save As… dominoes_[leftHandDotCount].png

… off memories of how Dominoes might ask of us “resources” wise.

That left us, after using FileZilla uploading to a new RJM Programming /Games/Dominoes folder off that web server’s Apache Document Root folder, as a folder full of image files only.

In this early scenario here, there is an adage we try to maintain, but let’s ask why …


Why on an Apache and PHP web server is it a bad idea to not have an index.html nor index.htm nor index.php within a web server folder?

Not having an index file like index.html, index.htm, or index.php in an Apache folder is a bad idea because it exposes your entire directory structure and source files to the public via Apache’s automatic directory listing. This vulnerability, known as Directory Browsing or Information Disclosure, allows attackers to easily map your application, find sensitive backup files, and locate hidden scripts.

FileZilla is really great at remedying them, often times temporary dilemma, quickly. Within a web server folder a context menu option Create New File (we called index.html) in that folder (even zero length) is going to stop that issue weakness talked about above. Aaaaaaah! Now we can think more clearly on ways to design the online Dominoes version game play.


Previous relevant Animated Plane and Coconut Hunt Game Nuances Tutorial is shown below.

Animated Plane and Coconut Hunt Game Nuances Tutorial

Animated Plane and Coconut Hunt Game Nuances Tutorial

Today’s a day of nuanced progress, after yesterday’s Coconut Hunt Game Tutorial‘s “filling in sideways” work on our Animated Plane and Coconut Hunt Game web application. Today, we …

  • fixed some document.body.title annoyances whereby it would appear too often
  • worked on the default A option textarea via …
    1. some “panda 🐼 led recovery” modelling of a p emoji usage (with animation) and span emoji usage (without animation) … and …
    2. modelling of how iframe onload event can be used to develop dynamic Javascript (the default example changing the coconut 🥥 hunt into a bear 🐻 hunt?!) … as opposed to a document.createElement(‘script’) alternative approach
  • fixed some window.open too small size annoyances
  • allowed for screen co-ordinates cursor (on non-mobile), via onmousemove event logic, to assist intrepid users going above and beyond “overlay” positioning their own elements via position:absolute; left:?; top:?; in A option textareas
  • allowed for toggling of non-mobile cursor between as above and crosshair via right click
  • allowed for the last left:?; top:?; as above detected be remembered and involve itself as the default position:absolute; “overlay” positioning of the A option textarea default “panda 🐼 led recovery” emoji of above
  • allow for 8 seconds of time for a user to change default coconut 🥥 emoji to some other text via contenteditable=true ahead of the Hunt Game starting … thanks to this useful link regarding hiding a contenteditable=true focus border
  • allow for sharing of the Hunt Game
  • Hunt Game sound effects

Feel free to try these tweaks to our Animated Plane and Coconut Hunt Game, in a nuanced “latest draft” Animated Plane Coconut Hunt Game web application below!


Previous relevant Coconut Hunt Game Tutorial is shown below.

Coconut Hunt Game Tutorial

Coconut Hunt Game Tutorial

Are you a reader who has been amused or bemused by the word Game being in the blog posting titles lately, up to yesterday’s Animated Plane Game User Animations and Styling Tutorial, when No Game really, about any of it? Well, today, it’s …

Game On

Do you like coconuts? Can I ask you, have you ever looked into a coconut, and asked yourself …

I shell always love you.

? Well, have we got the game for you?! Start the ball rollingshell shaking via the first click/top on the coconut fallen from the tree. And from there, it’s a fast reactions game, to score well! Good luck, in the changed “latest draft” Animated Plane Coconut Hunt Game web application below!


Previous relevant Animated Plane Game User Animations and Styling Tutorial is shown below.

Animated Plane Game User Animations and Styling Tutorial

Animated Plane Game User Animations and Styling Tutorial

On top of yesterday’s Animated Plane Game User Content Sharing Tutorial‘s honing in on the five “nouns” of interest …

  • trees
  • plane
  • gymnast
  • clouds
  • ground

… today we wanted to offer two more user controllable parts to this Animated Plane Game web application, those being …

  • CSS styling … easy, as CSS can be dynamically added to a web application at the clientside, as the Javascript is executing … and, a bit more of a learning curve for beginners is …
  • user animations … we’re envisaging, in it’s “easiest to understand encapsulation for a newbie” uses …
    1. @keyframes
    2. transition

    … a whole big wooooorrrrlllldddd of animation study just by itself (and in order for modelling to, perhaps, help we used an example from this excellent link, thanks, as the default option A textarea usage model)

… but a hell of a lot easier for a user to establish than some arcane Javascript DOM animations involving setTimeout or setInterval timers?!

For these two new ideas, popup textarea windows appear to give the user plenty of space to play around in. As ever, email and SMS can follow up for that user to share with others what their animation ideas are, perhaps far removed from the original plane and gymnast scenario by the time they finish. And here it may be pertinent to point out that even using hashtag emailing (and even more so with SMSing) there must be message size limits that will stop you event-u-al-ly!

Try this in the changed “latest draft” Animated Plane Game web application below.

Did you know?

In yesterday’s “noun” work we talked about “content” defined by the user in terms of real references to media data URIs or URLs. Well, the other way a user can now affect “content” is via CSS. Below we make the plane and gymnast disappear via the C (for CSS styling) option (that can take you to a popup window textarea where you can Apply this) …


<style>
#myif { /* plane */
display:none; /* other choice could be visibility:hidden; */
}

#mytwoif { /* gymnast */
visibility:hidden; /* other choice could be display:none; */
}
</style>


Previous relevant Animated Plane Game User Content Sharing Tutorial is shown below.

Animated Plane Game User Content Sharing Tutorial

Animated Plane Game User Content Sharing Tutorial

Yesterday’s Animated Plane Game Primer Tutorial set up five “nouns” of interest …

  • trees
  • plane
  • gymnast
  • clouds
  • ground

… each of which has a relationship to a piece of media content. The border-image (ie. ground) content aspects we allow a user to define emoji text for, but the rest are associated with a data URI or URL.

Today’s work is to allow the user to specify these “content” data items themselves, as well as share this via email or SMS to another user, with those user “content” data items recreated for the recipient user clicking the email or SMS link containing those hashtagged user data components. Later we hope to expand the functionality more, from today’s …


function getsrc(fromoh) {
var forvpre='Currently this content points at ... ' + String.fromCharCode(10);
var forvsuf=String.fromCharCode(10) + 'Enter an alternative content URL (can be clipart style data URI you see often using Google Image (Copy Image Address via right click) Searches) ... or ... ' + String.fromCharCode(10) + String.fromCharCode(10) + '1[:URL] for trees, 2[:URL] for plane, 3[:URL] for gymnast, 4[:URL] for clouds, 5[:emoji(s)] for ground, E for email, S for SMS';
if (fromoh.indexOf(' src="//') != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(' src="')[1].split('"')[0] + forvsuf;
} else if (fromoh.indexOf(" src='//") != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(" src='")[1].split("'")[0] + forvsuf;
} else if (fromoh.indexOf(" src=//") != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(" src=")[1].split(" ")[0].split(">")[0] + forvsuf;
} else if (fromoh.indexOf(' src="') != -1) {
return forvpre + fromoh.split(' src="')[1].split('"')[0] + forvsuf;
} else if (fromoh.indexOf(" src='") != -1) {
return forvpre + fromoh.split(" src='")[1].split("'")[0] + forvsuf;
} else if (fromoh.indexOf(" src=") != -1) {
return forvpre + fromoh.split(" src=")[1].split(" ")[0].split(">")[0] + forvsuf;
}
return fromoh;
}

function yourprompt(ino, intlis) {
var ei=-1, si=-1;
isac=true;
var opsd=prompt(getsrc(ino.outerHTML), '');
if (opsd == null) { isac=false; return false; }
if (opsd.trim() != '') {
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;


case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
} else {
setTimeout(function(){ ino.click(); }, 100); return true;
}
isac=false;
return false;
}

function anyprompt(opsd) {
if (opsd.trim() != '') {
opsd=opsd;
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;

case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
}
}

function ourprompt(ino, intlis) {
var ei=-1, si=-1;
isac=true;
var opsd=null;
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
opsd=prompt(intlis + String.fromCharCode(10) + String.fromCharCode(10) + intlis, '');
} else {
opsd=prompt(getsrc(document.getElementById('myimg').outerHTML), '');
}
if (opsd == null) { isac=false; return false; }
if (opsd.trim() != '') {
opsd=opsd;
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;

case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
} else {
setTimeout(function(){ ino.click(); }, 100); return true;
}
isac=false;
return false;
}

… in the changed “eighth draft” Animated Plane Game web application.


Previous relevant Animated Plane Game Primer Tutorial is shown below.

Animated Plane Game Primer Tutorial

Animated Plane Game Primer Tutorial

The mix-blend-mode:multiply; discoveries (along with those naive previous usage without realizing it’s implications) we made creating Periodic Table Image Map Primer Tutorial recently has opened up new “vistas of possibility” (VOP, of course) for us, and has inspired us to give “just Javascript and CSS and HTML animated games” (aided in large part by clipart free content components) another go …

… with a “widget feel” now realizable, for us, knowing that white backgrounded HTML iframe content no longer has to hold us back piecing together animations (in an “OOP feeling” way) consisting of …

  • base webpage CSS and HTML and Javascript (DOM, also helping out the control of) …
  • HTML iframe components (and in our case the image content is it’s background image with background-size:contain; and background-repeat:no-repeat; along with a specific iframe width and height) for any one “noun” (or class of object) in your game storyboard … if you will … if you will … if you will … and …
  • HTML img components in a similar vein … but today’s trees did not need mix-blend-mode:multiply; because the originator made the background transparent (ie. another option with all this “animated pieces thinking”)

Animation(s) can be CSS @keyframe transitions (though not yet with animation above) or Javascript DOM logic via setTimeout (or setInterval) timers or animated GIF/webp content or, we daresay, many other approaches.

We’re going to tabularize below “how we got to the result above” below …

We started with a “first draft” … getting Freepik image plane image animated with a rudimentary green border-bottom representing the ground …
then to “second draft” … adding https://i.makeagif.com/media/8-11-2023/Xu_roP.gif animated GIF cloud background to go with edited Freepik image because mix-blend-mode:multiply will not mask out the non heterogenous bluish clouds in the image …
then to “third draft” … tweaking https://i.makeagif.com/media/8-11-2023/Xu_roP.gif animated GIF cloud background … …
then to “fourth draft” … establishing an SVG+XML (with SVG text emoji content) border-image for the bottom border representing the ground …
then to “fifth draft” … added acknowledgements for all the help …

Thanks to Image by brgfx on Freepik and https://i.makeagif.com/media/8-11-2023/Xu_roP.gif and https://procul.org/images/2025/Animated-Clouds-Gif/ and and https://au.pinterest.com/pin/587930926347995281/ and https://giphy.com/explore/trees-swaying-stickers

then to “sixth draft” … added https://au.pinterest.com/pin/587930926347995281/ animated GIF gymnast background and thereby proving that overlapping “iframe widgets” (helped out by mix-blend-mode:multiply presumably) was possible, and important …
then to “seventh draft” … added https://giphy.com/explore/trees-swaying-stickers giphy.com/explore/trees-swaying-stickers animated (and transparently backgrounded) webp swaying trees image along with tweaked Freepik image now animated GIF to animate the plane itself a little, in place, separate to the Javascript DOM based animation moving across the screen … for today’s final draft …

Stop Press

In tomorrow’s installment we allow for user defined content, and sharing, as per …

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.

Posted in eLearning, Event-Driven Programming, Games, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Dominoes Game Sections Tutorial

Dominoes Game Sections Tutorial

Dominoes Game Sections Tutorial

Further to yesterday’s Dominoes Game Resources Tutorial‘s start to our Dominoes online game quest, and reading more about the rules of play regarding a Block Game version we’ve settled for the following sections on this game’s webpage designed for two players sharing the one screen (so far) …

  • header parts
  • playing area … where the tiles players play are placed
  • left and right player areas … show player names and score and current button of applicability …
  • left and right player tiles area … sometimes showing individual player tiles, sometimes showing underside of tile, with an honour system in play that the player whose turn it is not, turns away when asked …
  • stock area … contains the rest of the 28 dominoes not yet in play, showing underside of tile

Our strategy will be the first player to play is determined by whether left or right button is first selected, and from there in the game the order of play proceeds as per the rules of the Dominoes Block Game.

So far we think we’ll rewrite button content constantly according to what the status of the game at any given time. We can do that because the button elements are hosted by span hosting HTML elements.

And so, that is the plan regarding our first draft sections showing of proposed Dominoes Block Game, today.


Previous relevant Dominoes Game Resources Tutorial is shown below.

Dominoes Game Resources Tutorial

Dominoes Game Resources Tutorial

When creating an online web application game, like Animated Plane and Coconut Hunt Game Nuances Tutorial‘s Animated Plane and Coconut Hunt Game or games like playing card games, they involve “things” or …

nouns

… you can think of in programming (and many IDE) parlance as “resources”, and such games can lend themselves towards Object Oriented Programming (ie. OOP) code design, perhaps, and a set aside block of time preparing resources ahead of starting any coding. So it is with today’s start, for us, in creating a …


Dominoes

… game, as an online web application. We vaguely remember Dominoes from a while back and it involves …

  1. dominoes (we think of as tiles) … as the resource …
  2. randomosity … as many games do, regarding them being turned over to them all looking the same, and players randomly selecting their own tiles to play the game …
  3. a way to score … as many games do

This first day of work had us …

  • find a good online source at this useful link … thanks … to create a “parent resource” …

    … dominoes.png … via …

    1. control-command-shift-3 of that webpage
    2. open macOS PaintBrush desktop application
    3. File -> New from Clipboard
    4. form rectangle around the white on black section of tiles
    5. Edit -> Copy
    6. File -> New from Clipboard
    7. File -> Save As… dominoes.png
  • 28 x
    1. form rectangle around the white on black subsection of dominoes.png
    2. Edit -> Copy
    3. File -> New from Clipboard
    4. File -> Save As… dominoes_[leftHandDotCount]_[rightHandDotCount].png
  • 7 x
    1. form rectangle around the uniquely encountered leftHandDotCount left hand side of a dominoes_[leftHandDotCount]_[rightHandDotCount].png
    2. Edit -> Copy
    3. File -> New from Clipboard
    4. File -> Save As… dominoes_[leftHandDotCount].png

… off memories of how Dominoes might ask of us “resources” wise.

That left us, after using FileZilla uploading to a new RJM Programming /Games/Dominoes folder off that web server’s Apache Document Root folder, as a folder full of image files only.

In this early scenario here, there is an adage we try to maintain, but let’s ask why …


Why on an Apache and PHP web server is it a bad idea to not have an index.html nor index.htm nor index.php within a web server folder?

Not having an index file like index.html, index.htm, or index.php in an Apache folder is a bad idea because it exposes your entire directory structure and source files to the public via Apache’s automatic directory listing. This vulnerability, known as Directory Browsing or Information Disclosure, allows attackers to easily map your application, find sensitive backup files, and locate hidden scripts.

FileZilla is really great at remedying them, often times temporary dilemma, quickly. Within a web server folder a context menu option Create New File (we called index.html) in that folder (even zero length) is going to stop that issue weakness talked about above. Aaaaaaah! Now we can think more clearly on ways to design the online Dominoes version game play.


Previous relevant Animated Plane and Coconut Hunt Game Nuances Tutorial is shown below.

Animated Plane and Coconut Hunt Game Nuances Tutorial

Animated Plane and Coconut Hunt Game Nuances Tutorial

Today’s a day of nuanced progress, after yesterday’s Coconut Hunt Game Tutorial‘s “filling in sideways” work on our Animated Plane and Coconut Hunt Game web application. Today, we …

  • fixed some document.body.title annoyances whereby it would appear too often
  • worked on the default A option textarea via …
    1. some “panda 🐼 led recovery” modelling of a p emoji usage (with animation) and span emoji usage (without animation) … and …
    2. modelling of how iframe onload event can be used to develop dynamic Javascript (the default example changing the coconut 🥥 hunt into a bear 🐻 hunt?!) … as opposed to a document.createElement(‘script’) alternative approach
  • fixed some window.open too small size annoyances
  • allowed for screen co-ordinates cursor (on non-mobile), via onmousemove event logic, to assist intrepid users going above and beyond “overlay” positioning their own elements via position:absolute; left:?; top:?; in A option textareas
  • allowed for toggling of non-mobile cursor between as above and crosshair via right click
  • allowed for the last left:?; top:?; as above detected be remembered and involve itself as the default position:absolute; “overlay” positioning of the A option textarea default “panda 🐼 led recovery” emoji of above
  • allow for 8 seconds of time for a user to change default coconut 🥥 emoji to some other text via contenteditable=true ahead of the Hunt Game starting … thanks to this useful link regarding hiding a contenteditable=true focus border
  • allow for sharing of the Hunt Game
  • Hunt Game sound effects

Feel free to try these tweaks to our Animated Plane and Coconut Hunt Game, in a nuanced “latest draft” Animated Plane Coconut Hunt Game web application below!


Previous relevant Coconut Hunt Game Tutorial is shown below.

Coconut Hunt Game Tutorial

Coconut Hunt Game Tutorial

Are you a reader who has been amused or bemused by the word Game being in the blog posting titles lately, up to yesterday’s Animated Plane Game User Animations and Styling Tutorial, when No Game really, about any of it? Well, today, it’s …

Game On

Do you like coconuts? Can I ask you, have you ever looked into a coconut, and asked yourself …

I shell always love you.

? Well, have we got the game for you?! Start the ball rollingshell shaking via the first click/top on the coconut fallen from the tree. And from there, it’s a fast reactions game, to score well! Good luck, in the changed “latest draft” Animated Plane Coconut Hunt Game web application below!


Previous relevant Animated Plane Game User Animations and Styling Tutorial is shown below.

Animated Plane Game User Animations and Styling Tutorial

Animated Plane Game User Animations and Styling Tutorial

On top of yesterday’s Animated Plane Game User Content Sharing Tutorial‘s honing in on the five “nouns” of interest …

  • trees
  • plane
  • gymnast
  • clouds
  • ground

… today we wanted to offer two more user controllable parts to this Animated Plane Game web application, those being …

  • CSS styling … easy, as CSS can be dynamically added to a web application at the clientside, as the Javascript is executing … and, a bit more of a learning curve for beginners is …
  • user animations … we’re envisaging, in it’s “easiest to understand encapsulation for a newbie” uses …
    1. @keyframes
    2. transition

    … a whole big wooooorrrrlllldddd of animation study just by itself (and in order for modelling to, perhaps, help we used an example from this excellent link, thanks, as the default option A textarea usage model)

… but a hell of a lot easier for a user to establish than some arcane Javascript DOM animations involving setTimeout or setInterval timers?!

For these two new ideas, popup textarea windows appear to give the user plenty of space to play around in. As ever, email and SMS can follow up for that user to share with others what their animation ideas are, perhaps far removed from the original plane and gymnast scenario by the time they finish. And here it may be pertinent to point out that even using hashtag emailing (and even more so with SMSing) there must be message size limits that will stop you event-u-al-ly!

Try this in the changed “latest draft” Animated Plane Game web application below.

Did you know?

In yesterday’s “noun” work we talked about “content” defined by the user in terms of real references to media data URIs or URLs. Well, the other way a user can now affect “content” is via CSS. Below we make the plane and gymnast disappear via the C (for CSS styling) option (that can take you to a popup window textarea where you can Apply this) …


<style>
#myif { /* plane */
display:none; /* other choice could be visibility:hidden; */
}

#mytwoif { /* gymnast */
visibility:hidden; /* other choice could be display:none; */
}
</style>


Previous relevant Animated Plane Game User Content Sharing Tutorial is shown below.

Animated Plane Game User Content Sharing Tutorial

Animated Plane Game User Content Sharing Tutorial

Yesterday’s Animated Plane Game Primer Tutorial set up five “nouns” of interest …

  • trees
  • plane
  • gymnast
  • clouds
  • ground

… each of which has a relationship to a piece of media content. The border-image (ie. ground) content aspects we allow a user to define emoji text for, but the rest are associated with a data URI or URL.

Today’s work is to allow the user to specify these “content” data items themselves, as well as share this via email or SMS to another user, with those user “content” data items recreated for the recipient user clicking the email or SMS link containing those hashtagged user data components. Later we hope to expand the functionality more, from today’s …


function getsrc(fromoh) {
var forvpre='Currently this content points at ... ' + String.fromCharCode(10);
var forvsuf=String.fromCharCode(10) + 'Enter an alternative content URL (can be clipart style data URI you see often using Google Image (Copy Image Address via right click) Searches) ... or ... ' + String.fromCharCode(10) + String.fromCharCode(10) + '1[:URL] for trees, 2[:URL] for plane, 3[:URL] for gymnast, 4[:URL] for clouds, 5[:emoji(s)] for ground, E for email, S for SMS';
if (fromoh.indexOf(' src="//') != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(' src="')[1].split('"')[0] + forvsuf;
} else if (fromoh.indexOf(" src='//") != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(" src='")[1].split("'")[0] + forvsuf;
} else if (fromoh.indexOf(" src=//") != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(" src=")[1].split(" ")[0].split(">")[0] + forvsuf;
} else if (fromoh.indexOf(' src="') != -1) {
return forvpre + fromoh.split(' src="')[1].split('"')[0] + forvsuf;
} else if (fromoh.indexOf(" src='") != -1) {
return forvpre + fromoh.split(" src='")[1].split("'")[0] + forvsuf;
} else if (fromoh.indexOf(" src=") != -1) {
return forvpre + fromoh.split(" src=")[1].split(" ")[0].split(">")[0] + forvsuf;
}
return fromoh;
}

function yourprompt(ino, intlis) {
var ei=-1, si=-1;
isac=true;
var opsd=prompt(getsrc(ino.outerHTML), '');
if (opsd == null) { isac=false; return false; }
if (opsd.trim() != '') {
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;


case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
} else {
setTimeout(function(){ ino.click(); }, 100); return true;
}
isac=false;
return false;
}

function anyprompt(opsd) {
if (opsd.trim() != '') {
opsd=opsd;
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;

case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
}
}

function ourprompt(ino, intlis) {
var ei=-1, si=-1;
isac=true;
var opsd=null;
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
opsd=prompt(intlis + String.fromCharCode(10) + String.fromCharCode(10) + intlis, '');
} else {
opsd=prompt(getsrc(document.getElementById('myimg').outerHTML), '');
}
if (opsd == null) { isac=false; return false; }
if (opsd.trim() != '') {
opsd=opsd;
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;

case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
} else {
setTimeout(function(){ ino.click(); }, 100); return true;
}
isac=false;
return false;
}

… in the changed “eighth draft” Animated Plane Game web application.


Previous relevant Animated Plane Game Primer Tutorial is shown below.

Animated Plane Game Primer Tutorial

Animated Plane Game Primer Tutorial

The mix-blend-mode:multiply; discoveries (along with those naive previous usage without realizing it’s implications) we made creating Periodic Table Image Map Primer Tutorial recently has opened up new “vistas of possibility” (VOP, of course) for us, and has inspired us to give “just Javascript and CSS and HTML animated games” (aided in large part by clipart free content components) another go …

… with a “widget feel” now realizable, for us, knowing that white backgrounded HTML iframe content no longer has to hold us back piecing together animations (in an “OOP feeling” way) consisting of …

  • base webpage CSS and HTML and Javascript (DOM, also helping out the control of) …
  • HTML iframe components (and in our case the image content is it’s background image with background-size:contain; and background-repeat:no-repeat; along with a specific iframe width and height) for any one “noun” (or class of object) in your game storyboard … if you will … if you will … if you will … and …
  • HTML img components in a similar vein … but today’s trees did not need mix-blend-mode:multiply; because the originator made the background transparent (ie. another option with all this “animated pieces thinking”)

Animation(s) can be CSS @keyframe transitions (though not yet with animation above) or Javascript DOM logic via setTimeout (or setInterval) timers or animated GIF/webp content or, we daresay, many other approaches.

We’re going to tabularize below “how we got to the result above” below …

We started with a “first draft” … getting Freepik image plane image animated with a rudimentary green border-bottom representing the ground …
then to “second draft” … adding https://i.makeagif.com/media/8-11-2023/Xu_roP.gif animated GIF cloud background to go with edited Freepik image because mix-blend-mode:multiply will not mask out the non heterogenous bluish clouds in the image …
then to “third draft” … tweaking https://i.makeagif.com/media/8-11-2023/Xu_roP.gif animated GIF cloud background … …
then to “fourth draft” … establishing an SVG+XML (with SVG text emoji content) border-image for the bottom border representing the ground …
then to “fifth draft” … added acknowledgements for all the help …

Thanks to Image by brgfx on Freepik and https://i.makeagif.com/media/8-11-2023/Xu_roP.gif and https://procul.org/images/2025/Animated-Clouds-Gif/ and and https://au.pinterest.com/pin/587930926347995281/ and https://giphy.com/explore/trees-swaying-stickers

then to “sixth draft” … added https://au.pinterest.com/pin/587930926347995281/ animated GIF gymnast background and thereby proving that overlapping “iframe widgets” (helped out by mix-blend-mode:multiply presumably) was possible, and important …
then to “seventh draft” … added https://giphy.com/explore/trees-swaying-stickers giphy.com/explore/trees-swaying-stickers animated (and transparently backgrounded) webp swaying trees image along with tweaked Freepik image now animated GIF to animate the plane itself a little, in place, separate to the Javascript DOM based animation moving across the screen … for today’s final draft …

Stop Press

In tomorrow’s installment we allow for user defined content, and sharing, as per …

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.

Posted in eLearning, Event-Driven Programming, Games, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Dominoes Game Resources Tutorial

Dominoes Game Resources Tutorial

Dominoes Game Resources Tutorial

When creating an online web application game, like Animated Plane and Coconut Hunt Game Nuances Tutorial‘s Animated Plane and Coconut Hunt Game or games like playing card games, they involve “things” or …

nouns

… you can think of in programming (and many IDE) parlance as “resources”, and such games can lend themselves towards Object Oriented Programming (ie. OOP) code design, perhaps, and a set aside block of time preparing resources ahead of starting any coding. So it is with today’s start, for us, in creating a …


Dominoes

… game, as an online web application. We vaguely remember Dominoes from a while back and it involves …

  1. dominoes (we think of as tiles) … as the resource …
  2. randomosity … as many games do, regarding them being turned over to them all looking the same, and players randomly selecting their own tiles to play the game …
  3. a way to score … as many games do

This first day of work had us …

  • find a good online source at this useful link … thanks … to create a “parent resource” …

    … dominoes.png … via …

    1. control-command-shift-3 of that webpage
    2. open macOS PaintBrush desktop application
    3. File -> New from Clipboard
    4. form rectangle around the white on black section of tiles
    5. Edit -> Copy
    6. File -> New from Clipboard
    7. File -> Save As… dominoes.png
  • 28 x
    1. form rectangle around the white on black subsection of dominoes.png
    2. Edit -> Copy
    3. File -> New from Clipboard
    4. File -> Save As… dominoes_[leftHandDotCount]_[rightHandDotCount].png
  • 7 x
    1. form rectangle around the uniquely encountered leftHandDotCount left hand side of a dominoes_[leftHandDotCount]_[rightHandDotCount].png
    2. Edit -> Copy
    3. File -> New from Clipboard
    4. File -> Save As… dominoes_[leftHandDotCount].png

… off memories of how Dominoes might ask of us “resources” wise.

That left us, after using FileZilla uploading to a new RJM Programming /Games/Dominoes folder off that web server’s Apache Document Root folder, as a folder full of image files only.

In this early scenario here, there is an adage we try to maintain, but let’s ask why …


Why on an Apache and PHP web server is it a bad idea to not have an index.html nor index.htm nor index.php within a web server folder?

Not having an index file like index.html, index.htm, or index.php in an Apache folder is a bad idea because it exposes your entire directory structure and source files to the public via Apache’s automatic directory listing. This vulnerability, known as Directory Browsing or Information Disclosure, allows attackers to easily map your application, find sensitive backup files, and locate hidden scripts.

FileZilla is really great at remedying them, often times temporary dilemma, quickly. Within a web server folder a context menu option Create New File (we called index.html) in that folder (even zero length) is going to stop that issue weakness talked about above. Aaaaaaah! Now we can think more clearly on ways to design the online Dominoes version game play.


Previous relevant Animated Plane and Coconut Hunt Game Nuances Tutorial is shown below.

Animated Plane and Coconut Hunt Game Nuances Tutorial

Animated Plane and Coconut Hunt Game Nuances Tutorial

Today’s a day of nuanced progress, after yesterday’s Coconut Hunt Game Tutorial‘s “filling in sideways” work on our Animated Plane and Coconut Hunt Game web application. Today, we …

  • fixed some document.body.title annoyances whereby it would appear too often
  • worked on the default A option textarea via …
    1. some “panda 🐼 led recovery” modelling of a p emoji usage (with animation) and span emoji usage (without animation) … and …
    2. modelling of how iframe onload event can be used to develop dynamic Javascript (the default example changing the coconut 🥥 hunt into a bear 🐻 hunt?!) … as opposed to a document.createElement(‘script’) alternative approach
  • fixed some window.open too small size annoyances
  • allowed for screen co-ordinates cursor (on non-mobile), via onmousemove event logic, to assist intrepid users going above and beyond “overlay” positioning their own elements via position:absolute; left:?; top:?; in A option textareas
  • allowed for toggling of non-mobile cursor between as above and crosshair via right click
  • allowed for the last left:?; top:?; as above detected be remembered and involve itself as the default position:absolute; “overlay” positioning of the A option textarea default “panda 🐼 led recovery” emoji of above
  • allow for 8 seconds of time for a user to change default coconut 🥥 emoji to some other text via contenteditable=true ahead of the Hunt Game starting … thanks to this useful link regarding hiding a contenteditable=true focus border
  • allow for sharing of the Hunt Game
  • Hunt Game sound effects

Feel free to try these tweaks to our Animated Plane and Coconut Hunt Game, in a nuanced “latest draft” Animated Plane Coconut Hunt Game web application below!


Previous relevant Coconut Hunt Game Tutorial is shown below.

Coconut Hunt Game Tutorial

Coconut Hunt Game Tutorial

Are you a reader who has been amused or bemused by the word Game being in the blog posting titles lately, up to yesterday’s Animated Plane Game User Animations and Styling Tutorial, when No Game really, about any of it? Well, today, it’s …

Game On

Do you like coconuts? Can I ask you, have you ever looked into a coconut, and asked yourself …

I shell always love you.

? Well, have we got the game for you?! Start the ball rollingshell shaking via the first click/top on the coconut fallen from the tree. And from there, it’s a fast reactions game, to score well! Good luck, in the changed “latest draft” Animated Plane Coconut Hunt Game web application below!


Previous relevant Animated Plane Game User Animations and Styling Tutorial is shown below.

Animated Plane Game User Animations and Styling Tutorial

Animated Plane Game User Animations and Styling Tutorial

On top of yesterday’s Animated Plane Game User Content Sharing Tutorial‘s honing in on the five “nouns” of interest …

  • trees
  • plane
  • gymnast
  • clouds
  • ground

… today we wanted to offer two more user controllable parts to this Animated Plane Game web application, those being …

  • CSS styling … easy, as CSS can be dynamically added to a web application at the clientside, as the Javascript is executing … and, a bit more of a learning curve for beginners is …
  • user animations … we’re envisaging, in it’s “easiest to understand encapsulation for a newbie” uses …
    1. @keyframes
    2. transition

    … a whole big wooooorrrrlllldddd of animation study just by itself (and in order for modelling to, perhaps, help we used an example from this excellent link, thanks, as the default option A textarea usage model)

… but a hell of a lot easier for a user to establish than some arcane Javascript DOM animations involving setTimeout or setInterval timers?!

For these two new ideas, popup textarea windows appear to give the user plenty of space to play around in. As ever, email and SMS can follow up for that user to share with others what their animation ideas are, perhaps far removed from the original plane and gymnast scenario by the time they finish. And here it may be pertinent to point out that even using hashtag emailing (and even more so with SMSing) there must be message size limits that will stop you event-u-al-ly!

Try this in the changed “latest draft” Animated Plane Game web application below.

Did you know?

In yesterday’s “noun” work we talked about “content” defined by the user in terms of real references to media data URIs or URLs. Well, the other way a user can now affect “content” is via CSS. Below we make the plane and gymnast disappear via the C (for CSS styling) option (that can take you to a popup window textarea where you can Apply this) …


<style>
#myif { /* plane */
display:none; /* other choice could be visibility:hidden; */
}

#mytwoif { /* gymnast */
visibility:hidden; /* other choice could be display:none; */
}
</style>


Previous relevant Animated Plane Game User Content Sharing Tutorial is shown below.

Animated Plane Game User Content Sharing Tutorial

Animated Plane Game User Content Sharing Tutorial

Yesterday’s Animated Plane Game Primer Tutorial set up five “nouns” of interest …

  • trees
  • plane
  • gymnast
  • clouds
  • ground

… each of which has a relationship to a piece of media content. The border-image (ie. ground) content aspects we allow a user to define emoji text for, but the rest are associated with a data URI or URL.

Today’s work is to allow the user to specify these “content” data items themselves, as well as share this via email or SMS to another user, with those user “content” data items recreated for the recipient user clicking the email or SMS link containing those hashtagged user data components. Later we hope to expand the functionality more, from today’s …


function getsrc(fromoh) {
var forvpre='Currently this content points at ... ' + String.fromCharCode(10);
var forvsuf=String.fromCharCode(10) + 'Enter an alternative content URL (can be clipart style data URI you see often using Google Image (Copy Image Address via right click) Searches) ... or ... ' + String.fromCharCode(10) + String.fromCharCode(10) + '1[:URL] for trees, 2[:URL] for plane, 3[:URL] for gymnast, 4[:URL] for clouds, 5[:emoji(s)] for ground, E for email, S for SMS';
if (fromoh.indexOf(' src="//') != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(' src="')[1].split('"')[0] + forvsuf;
} else if (fromoh.indexOf(" src='//") != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(" src='")[1].split("'")[0] + forvsuf;
} else if (fromoh.indexOf(" src=//") != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(" src=")[1].split(" ")[0].split(">")[0] + forvsuf;
} else if (fromoh.indexOf(' src="') != -1) {
return forvpre + fromoh.split(' src="')[1].split('"')[0] + forvsuf;
} else if (fromoh.indexOf(" src='") != -1) {
return forvpre + fromoh.split(" src='")[1].split("'")[0] + forvsuf;
} else if (fromoh.indexOf(" src=") != -1) {
return forvpre + fromoh.split(" src=")[1].split(" ")[0].split(">")[0] + forvsuf;
}
return fromoh;
}

function yourprompt(ino, intlis) {
var ei=-1, si=-1;
isac=true;
var opsd=prompt(getsrc(ino.outerHTML), '');
if (opsd == null) { isac=false; return false; }
if (opsd.trim() != '') {
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;


case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
} else {
setTimeout(function(){ ino.click(); }, 100); return true;
}
isac=false;
return false;
}

function anyprompt(opsd) {
if (opsd.trim() != '') {
opsd=opsd;
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;

case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
}
}

function ourprompt(ino, intlis) {
var ei=-1, si=-1;
isac=true;
var opsd=null;
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
opsd=prompt(intlis + String.fromCharCode(10) + String.fromCharCode(10) + intlis, '');
} else {
opsd=prompt(getsrc(document.getElementById('myimg').outerHTML), '');
}
if (opsd == null) { isac=false; return false; }
if (opsd.trim() != '') {
opsd=opsd;
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;

case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
} else {
setTimeout(function(){ ino.click(); }, 100); return true;
}
isac=false;
return false;
}

… in the changed “eighth draft” Animated Plane Game web application.


Previous relevant Animated Plane Game Primer Tutorial is shown below.

Animated Plane Game Primer Tutorial

Animated Plane Game Primer Tutorial

The mix-blend-mode:multiply; discoveries (along with those naive previous usage without realizing it’s implications) we made creating Periodic Table Image Map Primer Tutorial recently has opened up new “vistas of possibility” (VOP, of course) for us, and has inspired us to give “just Javascript and CSS and HTML animated games” (aided in large part by clipart free content components) another go …

… with a “widget feel” now realizable, for us, knowing that white backgrounded HTML iframe content no longer has to hold us back piecing together animations (in an “OOP feeling” way) consisting of …

  • base webpage CSS and HTML and Javascript (DOM, also helping out the control of) …
  • HTML iframe components (and in our case the image content is it’s background image with background-size:contain; and background-repeat:no-repeat; along with a specific iframe width and height) for any one “noun” (or class of object) in your game storyboard … if you will … if you will … if you will … and …
  • HTML img components in a similar vein … but today’s trees did not need mix-blend-mode:multiply; because the originator made the background transparent (ie. another option with all this “animated pieces thinking”)

Animation(s) can be CSS @keyframe transitions (though not yet with animation above) or Javascript DOM logic via setTimeout (or setInterval) timers or animated GIF/webp content or, we daresay, many other approaches.

We’re going to tabularize below “how we got to the result above” below …

We started with a “first draft” … getting Freepik image plane image animated with a rudimentary green border-bottom representing the ground …
then to “second draft” … adding https://i.makeagif.com/media/8-11-2023/Xu_roP.gif animated GIF cloud background to go with edited Freepik image because mix-blend-mode:multiply will not mask out the non heterogenous bluish clouds in the image …
then to “third draft” … tweaking https://i.makeagif.com/media/8-11-2023/Xu_roP.gif animated GIF cloud background … …
then to “fourth draft” … establishing an SVG+XML (with SVG text emoji content) border-image for the bottom border representing the ground …
then to “fifth draft” … added acknowledgements for all the help …

Thanks to Image by brgfx on Freepik and https://i.makeagif.com/media/8-11-2023/Xu_roP.gif and https://procul.org/images/2025/Animated-Clouds-Gif/ and and https://au.pinterest.com/pin/587930926347995281/ and https://giphy.com/explore/trees-swaying-stickers

then to “sixth draft” … added https://au.pinterest.com/pin/587930926347995281/ animated GIF gymnast background and thereby proving that overlapping “iframe widgets” (helped out by mix-blend-mode:multiply presumably) was possible, and important …
then to “seventh draft” … added https://giphy.com/explore/trees-swaying-stickers giphy.com/explore/trees-swaying-stickers animated (and transparently backgrounded) webp swaying trees image along with tweaked Freepik image now animated GIF to animate the plane itself a little, in place, separate to the Javascript DOM based animation moving across the screen … for today’s final draft …

Stop Press

In tomorrow’s installment we allow for user defined content, and sharing, as per …

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.

Posted in eLearning, Games, Operating System, Projects, Software, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , | Leave a comment

CSS Function Ideas Finally Finalized Tutorial

CSS Function Ideas Finalized Tutorial

CSS Function Ideas Finally Finalized Tutorial

Of course, with yesterday’s CSS Function Ideas Finalized Tutorial

We weren’t actually finalized!

But I might have been?

Aren’t you supposed to be faithful and loyal and forgiving?

But, just humans aside here, regarding the “C” (ie. “cascading”) in CSS, there are …

  • hierarchy … and …
  • order

… considerations with the CSS that can improve the functionality here. Take the CSS filter (and apparently “innerHTML” would like to come along for the ride) property …

… yes … to the beach would be ideal … thanks. And would you be able to give The Lu the afternoon off?!

That filter property can be space separated with it’s CSS so as to support many “filter clauses” and depending on the order you define, it can cause a different display effect. Similar is the CSS transform property, and so, today, we cater a bit for that idea by offering up a new “Compound” checkbox a user can use to see some of this “hierarchical order” CSS consideration, in action.

Feel free to try this out with a finally completed until further noted day 3 “Nuance Day” of css_function_ideas.html CSS Function ideas web application you can try below.


Previous relevant CSS Function Ideas Finalized Tutorial is shown below.

CSS Function Ideas Finalized Tutorial

CSS Function Ideas Finalized Tutorial

We’ve gone from “n to “z” today, completing yesterday’s CSS Function Ideas Tutorial‘s “a” to “m” start creating an inhouse look at CSS Functions usage converted into a web application you can try yourself, and inspired by the great W3school’s CSS Functions webpage, thanks.

And what was your biggest surprise?

We found the potential of CSS function ray() …

Defines the offset-path line segment that an animated element should follow

… pretty interesting, and totally new to us.

Try this out with the completed day 2 of css_function_ideas.html CSS Function ideas web application you can try below.


Previous relevant CSS Function Ideas Tutorial is shown below.

CSS Function Ideas Tutorial

CSS Function Ideas Tutorial

Can you just move a bit to the right?

Now a tad sideways? That’s almost it. If you’d just, now, stand on your head. Okay, that’s it, thank you kindly?!

We’re just reacclimatizing ourselves here, having had our eyes fully opened, having stumbled onto W3school’s CSS Functions webpage, thanks. We’ve only tipped our toes into the variety of CSS (Javascript script like) capabilities that are out there. And yes, we covered “invert” so you can stand up again now … ta, muchly.

We’re showing Keyboard Based Cursor Image CSS Filter Tutorial below because CSS Functions cover a lot of image (ie. img element) CSS styling smarts, and we have touched on this, as well as good ol’ “calc”.

In today’s two day project start we’ve allowed users the chance to try CSS Functions from “a” to “m”. In today’s work …

  1. we started the first draft a bit non-generically … and then …
  2. straightened up … ready to …
  3. fly … right …

    Oh … you’re there! You can move back to square one … ta, muchly, like?!

… with day 1 of 2 “a” to “m” css_function_ideas.html CSS Function ideas web application you can try below …


Previous relevant Keyboard Based Cursor Image CSS Filter Tutorial is shown below.

Keyboard Based Cursor Image CSS Filter Tutorial

Keyboard Based Cursor Image CSS Filter Tutorial

What next for the Lorem Picsum (or RJM Programming WordPress Blog Posting tutorial pictures) resource usage web application regarding the recent Keyboard Based Cursor Image Blog Source Link Tutorial?

We’re a bit sheepish about how easy it was to feel like we are in some Photoshop studio applying CSS such as …

<style>

html { filter: drop-shadow(16px 16px 20px blue); }

</style>

… to change how ever many background images you have involved with the background images of your webpage using the changed body_mouse_deepdive.html‘s “parent” single background image web application (or, for example, “parent” eight background RJM Programming Blog Tutorial Picture image web application).

The user access all hangs off a first Shift key press followed by a numeric key (on QWERTY keyboard the “0123456789” correspond to “)!@#$%^&*(” characters) point at the first ten entries in …


var kcmap=["filter: blur(5px);","filter: brightness(0.4);","filter: contrast(200%);","filter: drop-shadow(16px 16px 20px blue);","filter: grayscale(50%);","filter: hue-rotate(90deg);","filter: invert(75%);","filter: opacity(25%);","filter: saturate(30%);","filter: sepia(60%);","filter: none;];"]; // thanks to https://developer.mozilla.org/en-US/docs/Web/CSS/filter

… used in amongst the “onkeypress” event Javascript function …


if (evt.keyCode >= 48 && evt.keyCode <= 57) { newu+=('' + eval(-48 + evt.keyCode)); if (lastshiftcursor) { kpdone=false; document.head.innerHTML+=' <style> html { ' + kcmap[eval(-48 + evt.keyCode)] + ' } </style>'; lastbit=document.title.split('Cursor change ')[1]; document.title='' + kcmap[eval(-48 + evt.keyCode)] + ' ... Cursor change ' + lastbit; return true; }
}

Stop Press

Thinking on arrangements above we figured it would give the user more control so that if they repeatedly pressed the same numerical key that would increment or decrement numerical components within the CSS filter specification requiring a changed call


if (evt.keyCode >= 48 && evt.keyCode <= 57) { newu+=('' + eval(-48 + evt.keyCode)); if (lastshiftcursor) { kpdone=false; dcr=doublecheck(kcmap[eval(-48 + evt.keyCode)]); document.head.innerHTML+=' <style> html { ' + dcr + ' } </style>'; lastbit=document.title.split('Cursor change ')[1]; document.title='' + dcr + ' ... Cursor change ' + lastbit; return true;
}

… of the new Javascript …


function doublecheck(infid) {
var outfid=infid;
var within=infid.split('(')[1].split(')')[0];
var entries=within.split(',');
if (entries[0].replace(/^\ /g,'').indexOf(' ') != -1) { entries=within.replace(/\(\ /g,'(').split(' '); }
var withind='';
if (document.title.indexOf('(') != -1) { withind=document.title.split('(')[1].split(')')[0]; }
var entriesd=withind.split(',');
if (entriesd[0].replace(/^\ /g,'').indexOf(' ') != -1) { entriesd=withind.replace(/\(\ /g,'(').split(' '); }
var anum=0.0, bnum=0.0;
var isdeg=false;
if ((entriesd[0] + 'x').indexOf(' ') != -1) { isdeg=true; }


if (document.title.indexOf(infid.split('(')[0]) == 0) {
for (var ii=0; ii<entriesd.length; ii++) {
if (entriesd[ii].indexOf('%') != -1) {
anum=eval(entriesd[ii].trim().replace('%',''));
bnum=eval(entries[ii].trim().replace('%',''));
if (anum < 100 && !isdeg) {
outfid=outfid.replace('' + bnum + '%', '' + eval(1 + anum) + '%');
} else if (anum == 0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + '%', '' + eval(1 + anum) + '%');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + '%', '' + eval(-1 + anum) + '%');
}
} else if (entriesd[ii].indexOf('px') != -1) {
console.log('entries[' + ii + ']=' + entriesd[ii] + ' within outfid=' + outfid)
anum=eval(entriesd[ii].trim().replace('px',''));
bnum=eval(entries[ii].trim().replace('px',''));
if (anum < 100 && !isdeg) {
outfid=outfid.replace('' + bnum + 'px', '' + eval(1 + anum) + 'px');
} else if (anum == 0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + 'px', '' + eval(1 + anum) + 'px');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + 'px', '' + eval(-1 + anum) + 'px');
}
} else if (entriesd[ii].indexOf('deg') != -1) {
anum=eval(entriesd[ii].trim().replace('deg',''));
bnum=eval(entries[ii].trim().replace('deg',''));
if (anum < 90 && !isdeg) {
outfid=outfid.replace('' + bnum + 'deg', '' + eval(1 + anum) + 'deg');
} else if (anum == 0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + 'deg', '' + eval(1 + anum) + 'deg');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + 'deg', '' + eval(-1 + anum) + 'deg');
}
} else if (entriesd[ii].indexOf('.') != -1) {
anum=eval(entriesd[ii].trim());
bnum=eval(entries[ii].trim());
if (anum < 1.0 && !isdeg) {
outfid=outfid.replace('' + bnum + '', '' + eval(0.1 + anum) + '');
} else if (anum == 0.0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + '', '' + eval(0.1 + anum) + '');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + '', '' + eval(-0.1 + anum) + '');
}
}
}
if (isdeg) { outfid=outfid.replace(/\(\ /g,'(').replace('(', '( '); }
}
return outfid;
}


Previous relevant Keyboard Based Cursor Image Source Tutorial is shown below.

Keyboard Based Cursor Image Source Tutorial

Keyboard Based Cursor Image Source Tutorial

Another layer of functionality thinking on top of the work of yesterday’s Keyboard Based Cursor Multiple Background Images Tutorial

  • multiple background image functionality … could be today’s …
  • image source choice to add to the generous Lorem Picsum image resource … thanks … that of a resource of the tutorial images amongst those of this RJM Programming WordPress Blog you are reading

… channelling the ever nuanced start we made in this regard when we presented Image Pair Fitting into a Given Dimension Sources Tutorial, with its interfacing to an increasing role for the WordPress codex TwentyTen theme 404.php role dealing with the HTTP error 404 well known as “Webpage Not Found”.

To make this happen, in code, we had to start breaking up (parameterizing, if you prefer) the hardcoding …

//picsum.photos

… into (variable) …


thesource

… and …

?random=

… into (variable usage) …


themp + '?random='

reflected into code snippet example below …


var thesource=location.search.split('numbi=')[1] ? (decodeURIComponent(location.search.split('numbi=')[1].split('&')[0]).replace('+',' ').replace(' ',' ').replace('-',' ').substring(0,1) == ' ' ? '//www.rjmprogramming.com.au/ITblog' : '//picsu' + 'm.photos') : '//picsu' + 'm.photos';
var themp='';
if (thesource != '//picsu' + 'm.photos') {
themp='/';
}

if (numbi != '') {
if (eval('' + numbi) == 2) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top right; background-size: 50% 100%, 50% 100%; background-repeat: no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 3) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right; background-size: 33% 100%, 34% 100%, 33% 100%; background-repeat: no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 4) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top right, bottom left, bottom right; background-size: 50% 50%, 50% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 5) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, bottom left, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 6) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 33% 50%, 34% 50%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 7) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 27143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, center center, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 33%, 33% 50%, 34% 34%, 33% 50%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 8) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 27143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 87123646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, center left, center center, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 50%, 33% 34%, 34% 34%, 33% 33%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 9) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 27143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 67143446) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 87123646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, center left, center center, center right, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 33%, 33% 34%, 34% 34%, 33% 34%, 33% 33%, 34% 33%, 33% 33%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (thesource != '//picsu' + 'm.photos') {
document.head.innerHTML+='<style> ' + document.head.innerHTML.split('<style>')[1].split('</style>')[0].replace(/\/\/picsum\.photos/g, thesource).replace(/\?random\=/g, themp + '?random=').replace(/00\)/g, '00' + themp + '?random=' + Math.floor(Math.random() * 198765434) + ')') + ' </style>';
}
} else if (thesource != '//picsu' + 'm.photos') {
document.head.innerHTML+='<style> ' + document.head.innerHTML.split('<style>')[1].split('</style>')[0].replace(/\/\/picsum\.photos/g, thesource).replace(/\?random\=/g, themp + '?random=').replace(/00\)/g, '00' + themp + '?random=' + Math.floor(Math.random() * 198765434) + ')') + ' </style>';
}

… in our changed body_mouse_deepdive.html‘s “parent” single background image web application (or, for example, “parent” eight background RJM Programming Blog Tutorial Picture image web application) where a user can latch onto the new image source via a first key press is a + plus character

Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content … RJM Programming … May, 2022 … thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements. With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji. Optionally make emojis bigger after \ with + two time multipliers. Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can work. If first key is (+ is RJM image else) from 1 to 9 that will be number of background images displayed.


Previous relevant Keyboard Based Cursor Multiple Background Images Tutorial is shown below.

Keyboard Based Cursor Multiple Background Images Tutorial

Keyboard Based Cursor Multiple Background Images Tutorial

For the images, those background ones, used in the recent Canvas Graphics Editing in Zoomed Webpage Tutorial, we use the great Lorem Picsum resource. So far that has been the one background image covering the background of the webpage …


<style>

body {
display: inline-block;
font-size: 128px;
line-height: 1.2;
text-align: center;
background: url(//picsum.photos/1000/1000) center center no-repeat;
background-size: cover;
background-clip: text;
-webkit-background-clip: text;


color: rgba(255,0,0,0.6);

span { color: transparent; }
}

div {
background-color: transparent;
caret-color: transparent;
}

@media only screen and (max-width: 1000px) {
div {
background: url(//picsum.photos/1000/1000) center center no-repeat;
}
}

div:focus {
outline: none !important;
}

html {
height: 100%;
display: flex;
cursor: Url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\002753</text></svg>") 16 0, crosshair;
}

</style>

… nominally background-positioned “center center”. But there are 9 background-position of that similar ilk available …

  • top left
  • top center
  • top right
  • center left
  • center center
  • center right
  • bottom left
  • bottom center
  • bottom right

… which we’d like to, optionally, be involved with how a user uses our changed body_mouse_deepdive.html‘s “parent” single background image web application (or, for example, “parent” four background image web application).

So, how to make it be able to be controlled by those users? Well, those previous keyboard logics involving emojis always involved a leading “\” backslash, so that leaves open numbers from 1 to 9 entered as a first keyboard character entered meaning that that is how many background images is wanted by that user

Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content … RJM Programming … May, 2022 … thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements. With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji. Optionally make emojis bigger after \ with + two time multipliers. Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can remove pasted part as required. If first key is from 1 to 9 that will be number of background images displayed.

… supported by …


var numbi=location.search.split('numbi=')[1] ? reduce(decodeURIComponent(location.search.split('numbi=')[1].split('&')[0])) : '1';

if (numbi != '') {
if (eval('' + numbi) == 2) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top right; background-size: 50% 100%, 50% 100%; background-repeat: no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 3) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right; background-size: 33% 100%, 34% 100%, 33% 100%; background-repeat: no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 4) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top right, bottom left, bottom right; background-size: 50% 50%, 50% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 5) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, bottom left, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 6) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 33% 50%, 34% 50%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 7) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center center, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 33%, 33% 50%, 34% 34%, 33% 50%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 8) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=87123646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center left, center center, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 50%, 33% 34%, 34% 34%, 33% 33%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 9) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=67143446), url(//picsum.photos/1000/1000?random=87123646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center left, center center, center right, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 33%, 33% 34%, 34% 34%, 33% 34%, 33% 33%, 34% 33%, 33% 33%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
}
}


function reduce(invl) {
if (('' + invl).trim() == '') { return '1'; }
if (('' + invl).trim().replace(/0/g,'').replace(/1/g,'').replace(/0/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') != '') { return '1'; }
var retval=0, ij=0;
var cinvl='' + invl;
var xcinvl='';
for (ij=0; ij<cinvl.length; ij++) {
if (cinvl.substring(ij).substring(0,1) != '-') {
retval+=eval(cinvl.substring(ij).substring(0,1));
}
}
xcinvl='' + retval;
while (xcinvl.length > 1) {
retval=0;
for (ij=0; ij<xcinvl.length; ij++) {
if (xcinvl.substring(ij).substring(0,1) != '-') {
retval+=eval(xcinvl.substring(ij).substring(0,1));
}
}
xcinvl='' + retval;
}
if (retval == 0) { retval=1; }
return '' + retval;
}


Previous relevant Keyboard Based Cursor Canvas Content Copy Tutorial is shown below.

Keyboard Based Cursor Canvas Content Copy Tutorial

Keyboard Based Cursor Canvas Content Copy Tutorial

You may have noticed with yesterday’s Keyboard Based Cursor Share Content Copy Tutorial, crucial to the sharing code, was the use of the incredible HTML5 introduced canvas element, helped by that middleperson link to those public email and SMS sharing conduits, overseeing the great random Lorem Picsum background images and user created emoji and/or text initial annotations.

And this got us wondering whether there was a private (ie. inhouse) web application of the past that could further value add as another optional middleperson tool for (user) personalization (of the content) purposes. And yes, do you remember the canvas work involved in the featured web application of Emoji Borders and Backgrounds Canvas Annotation Tutorial?

It uses an interesting approach with the transference of data across from a canvas in one application to the canvas in that user_of_signature_signature.htm web application. Once our changed body_mouse_deepdive.html‘s “parent” web application has organized its canvas contents, it’s just a matter of …


var awo=null;
awo=window.open('./user_of_signature_signature.htm','_blank','top=100,left=100,width=800,height=800');

… for the “child” canvas annotator to effectively “suck up” the canvas data into its canvas via …


var cancont='';
var elemode=location.search.split('elemode=')[1] ? (location.search.split('elemode=')[1].split('&')[0]) : "canvas";

if (('' + window.opener).replace('null','') != '') {
var cans=window.opener.document.getElementsByTagName(elemode);
if (cans.length > 0) {
if (elemode == 'img') {
cancont=cans[0].src;
} else {
cancont=cans[0].toDataURL('image/png');
}
if (cancontw < 0 && canconth < 0) { cancontw=cans[0].width; canconth=cans[0].height; } } }

... possible because both "parent" and "child" exist on the same RJM Programming domain (web server).

Once there, another woooooorrrrrlllddd of image manipulations, via canvas, can await the user, perhaps ready for ongoing sharing possibilities with that "child".


Previous relevant Keyboard Based Cursor Share Content Copy Tutorial is shown below.

Keyboard Based Cursor Share Content Copy Tutorial

Keyboard Based Cursor Share Content Copy Tutorial

Yesterday's Keyboard Based Cursor Personalized Content Copy Tutorial has probably reached a point where some sharing mechanism is apt, for accountability and usefulness purposes, at the very least, regarding our recent web application allowing for foreground content on top of a random Lorem Picsum background image.

We've been helped out greatly by javascript - Can I take a screenshot from the clipboard? - Stack Overflow and html - How to render a blob on a canvas element? - Stack Overflow in the following new relevant Javascript code ...


function renderNoImage(canvas, blob) { // thanks to https://stackoverflow.com/questions/38004917/how-to-render-a-blob-on-a-canvas-element
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = (event) => {
URL.revokeObjectURL(event.target.src) // This is important. If you are not using the blob, you should release it if you don't want to reuse it. It's good for memory.
ctx.drawImage(event.target, 0, 0)
img.style.display='none';
img.style.zIndex='-123';
};
img.src = URL.createObjectURL(blob);
}


function renderImage(canvas, blob) { // thanks to https://stackoverflow.com/questions/38004917/how-to-render-a-blob-on-a-canvas-element
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = (event) => {
URL.revokeObjectURL(event.target.src) // This is important. If you are not using the blob, you should release it if you don't want to reuse it. It's good for memory.
ctx.drawImage(event.target, 0, 0)
};
img.src = URL.createObjectURL(blob);
}


addEventListener("paste", ev => { // thanks to https://stackoverflow.com/questions/55559432/can-i-take-a-screenshot-from-the-clipboard
for(const item of ev.clipboardData.items) { /// Clipboard may contain multiple elements of different type -- text, image, etc
if(item.type.startsWith("image/")) { /// We are only interested in clipboard data that is an image
if (emailee == '') {
emailee=prompt('Your clipboard has a useful image you could share the image with. Optionally, please enter an email address or SMS number to share with.');
if (emailee == null) { emailee=''; }
}
if (emailee.indexOf('@') != -1) {
document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="position:absolute;z-index:98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('aemail').href=document.getElementById('aemail').href.replace(':?', ':' + emailee + '?');
document.getElementById('aemail').click();
document.getElementById('mycanvas').innerHTML='';
} else if (emailee != '' && emailee.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') == '') {
document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="position:absolute;z-index:98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('asms').href=document.getElementById('asms').href.replace(':&', ':' + emailee + '&');
document.getElementById('asms').click();
document.getElementById('mycanvas').innerHTML='';
} else {
//document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="display:none;position:absolute;z-index:-98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderNoImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('mycanvas').innerHTML='';
}
}
}
});

... which is explained to the user in the following way ...

Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can remove pasted part as required.

... in the changed "proof of concept" body_mouse_deepdive.html live run.


Previous relevant Keyboard Based Cursor Personalized Content Copy Tutorial is shown below.

Keyboard Based Cursor Personalized Content Copy Tutorial

Keyboard Based Cursor Personalized Content Copy Tutorial

On top of yesterday's Keyboard Based Cursor Content Copy Tutorial we wanted to offer the user the chance for them to tailor their foreground content on top of the Lorem Picsum background image.

The user can enter this via the keyboard because there is an HTML div contenteditable=true pallette to work with ...


<div id=mydiv onfocus='setTimeout(alte, 1000);' ondblclick="this.innerHTML='';" onclick='stamp(event);' title='Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content ... RJM Programming ... May, 2022 ... thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements.' spellcheck='false' contenteditable=true style='width:100vw;height:100%;color:transparent;text-color:transparent;' onkeypress=kpcursorlook(event); onkeydown=cursorlook(event); onmousemove=xycursorlook(event); ontouchmove=xycursorlook(event);></div>

It's "title" attribute now talks about two new pieces of functionality, those being ...

  • You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji).
  • Double click existant foreground emoji element to clear all the foreground emoji elements.

The choice of keyboard input methodology also suits CSS "content" property definitions as one backslash followed by a hexidecimal value left padded with zeroes to a length of six. See us doing this below for an umbrella emoji (which could also be expressed in an HTML hexadecimal entity way &#x2602; ☂ the information for which you can find at Unicode Character 'UMBRELLA' (U+2602) we normally get to by entering "U+2602" at a web browser address bar, the knowledge for which we arrive at via entering "umbrella emojipedia" and moving down the top link's webpage to find the "U+2602") ...


<style> #myumbrella::after { content: '\002602'; } </style>

... that feeds into some new "onkeypress" keyboard event logic ...


function kpcursorlook(evt) {
var atofa=['a','b','c','d','e','f'];
var rgbit='';
if (evt.keyCode == 92) {
if (newu.length == 1) { gro=true; } else { gro=false; }
newu=("\\").substring(0,1);
} else if (evt.keyCode >= 48 && evt.keyCode <= 57) {
newu+=('' + eval(-48 + evt.keyCode));
} else if (evt.keyCode >= 65 && evt.keyCode <= 70) {
newu+=('' + atofa[eval(-65 + evt.keyCode)]);
} else if (evt.keyCode >= 97 && evt.keyCode <= 102) {
newu+=('' + atofa[eval(-97 + evt.keyCode)]);
}
if (newu.length == 7) {
if (lastcursor.indexOf(("\\\\").substring(0,2)) != -1) {
rgbit=lastcursor.split(("\\\\").substring(0,2))[1].substring(6);
lastcursor=lastcursor.split(("\\\\").substring(0,2))[0] + ("\\").substring(0,1) + newu + rgbit;
document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
} else if (lastcursor.indexOf(("\\").substring(0,1)) != -1) {
rgbit=lastcursor.split(("\\").substring(0,1))[1].substring(6);
lastcursor=lastcursor.split(("\\").substring(0,1))[0] + newu + rgbit;
if (gro) {
lastcursor=lastcursor.replace('>Shift/Alt/Ctrl', '>').replace('>Shift', '>').replace('>Alt', '>').replace('>Ctrl', '>').replace(" width='126'", " width='20'").replace(" width='66'", " width='20'").replace(" height='48'", " height='20'").replace('0 0 100 100', '0 0 20 20');
}
document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
}
}
// console.log(evt.keyCode);
}

... in the changed "proof of concept" body_mouse_deepdive.html live run.

Stop Press

Two more "title" attribute pieces of functionality are now ...

  • With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji.
  • Optionally make emojis bigger after \ with + two time multipliers.

The choice of keyboard input methodology also suits CSS "content" property definitions as one backslash followed by "first off" sets of HTML entities they should not left zero pad in their entry, followed by a last HTML entity hexidecimal value left padded with zeroes to a length of six to finish up with. See us doing this below for a woman rowing emoji (which could also be expressed in an HTML hexadecimal entity way &#x1f6a3;&#x0200d;&#x02640;&#x0fe0f; the information for which you can find at 🚣‍♀️ Woman Rowing Boat Emoji we normally get to by entering "woman rowing emoji" at the web browser address bar) ...


<style> #myrowing::after { content: '\01f6a3\00200d\002640\00fe0f'; } </style>

... in the changed "proof of concept" body_mouse_deepdive.html live run.


Previous relevant Keyboard Based Cursor Content Copy Tutorial is shown below.

Keyboard Based Cursor Content Copy Tutorial

Keyboard Based Cursor Content Copy Tutorial

The "onkeydown" keyboard event can involve in its logic three mouse event (event object) property usages that caught our interest recently ...

... and we wanted to have "keyboard" meets "mouse" events, along with the brilliance of Lorem Picsum regarding background image randomosity and quality, working with HTML ...


<div id=mydiv onfocus='setTimeout(alte, 1000);' onclick='stamp(this);' title='Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content ... RJM Programming ... May, 2022 ... thanks to https://picsum.photos/ Lorem Picsum' spellcheck='false' contenteditable=true style='width:100vw;height:100%;color:transparent;text-color:transparent;' data-onkeypress=xycursorlook(event); onkeydown=cursorlook(event); onmousemove=xycursorlook(event); ontouchmove=xycursorlook(event);></div>

... in a way we hadn't tried before that called on some inhouse cursor SVG creations (and so is, alas, just a non-mobile fully featured experience), in the sense that ...

  1. keyboard helps creating the "what" regarding content ...

    <script type='text/javascript'>
    var lastkeymodifier=''
    var lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
    var pos3=-1, pos4=-1;
    var subdiv=1;
    var lastpos3=-2, lastpos4=-1;
    var allowable=false;

    function cursorlook(evt) {
    if (evt.altKey) {
    if (lastkeymodifier != 'alt') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='66' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,0,255,0.3);fill:black;font-family:Verdana;font-size:17px;'><text y='80%'>Alt\\01f3d5</text></svg>\") 16 0, progress";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='alt';
    }
    } else if (evt.ctrlKey) {
    if (lastkeymodifier != 'ctrl') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='66' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:17px;'><text y='80%'>Ctrl\\01f333</text></svg>\") 16 0, pointer";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='ctrl';
    }
    } else if (evt.shiftKey) {
    if (lastkeymodifier != 'shift') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='66' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(255,0,0,0.3);fill:black;font-family:Verdana;font-size:17px;'><text y='80%'>Shift\\01f389</text></svg>\") 16 0, grab";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='shift';
    }
    } else {
    if (lastkeymodifier != '') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='';
    }
    }
    }
    </script>
  2. mouse "onmousemove" or "ontouchmove" helps with the "where" regarding content above ...

    <script type='text/javascript'>
    var pos3=-1, pos4=-1;
    var subdiv=1;
    var lastpos3=-2, lastpos4=-1;
    var allowable=false;

    function xycursorlook(e) {
    e = e || window.event;
    e.preventDefault();

    if (e.touches) {
    if (e.touches[0].pageX) {
    pos3 = e.touches[0].pageX;
    pos4 = e.touches[0].pageY;
    } else {
    pos3 = e.touches[0].clientX;
    pos4 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos3 = e.clientX;
    pos4 = e.clientY;
    } else {
    pos3 = e.pageX;
    pos4 = e.pageY;
    }
    }
    </script>
  3. preparations for "onclick" way a cursor can be plonked into (real lasting) content ...

    <script type='text/javascript'>
    var lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
    var pos3=-1, pos4=-1;
    var subdiv=1;
    var lastpos3=-2, lastpos4=-1;
    var allowable=false;

    function stamp(divo) {
    if (('' + pos3).indexOf('-') == -1) {
    if (allowable) {
    //if (allowed) {
    //allowed=false;
    //setTimeout(reseta, 2000);
    divo.innerHTML+='<div id=div' + subdiv + ' style="position:absolute;top:' + pos4 + 'px;left:' + pos3 + 'px;width:126px;height:48px;background-color:transparent;"></div><style> #div' + subdiv + ' { background:' + lastcursor.split(') ')[0] + ') no-repeat; } </style>';
    subdiv++;
    //console.log('lastpos4=' + lastpos4 + ' and pos4=' + pos4);
    //console.log('lastpos3=' + lastpos3 + ' and pos3=' + pos3);
    lastpos3=pos3;
    lastpos4=pos4;
    //}
    }
    }
    }
    </script>

... with the "proof of concept" body_mouse_deepdive.html live run.

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.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

CSS Function Ideas Finalized Tutorial

CSS Function Ideas Finalized Tutorial

CSS Function Ideas Finalized Tutorial

We’ve gone from “n to “z” today, completing yesterday’s CSS Function Ideas Tutorial‘s “a” to “m” start creating an inhouse look at CSS Functions usage converted into a web application you can try yourself, and inspired by the great W3school’s CSS Functions webpage, thanks.

And what was your biggest surprise?

We found the potential of CSS function ray() …

Defines the offset-path line segment that an animated element should follow

… pretty interesting, and totally new to us.

Try this out with the completed day 2 of css_function_ideas.html CSS Function ideas web application you can try below.


Previous relevant CSS Function Ideas Tutorial is shown below.

CSS Function Ideas Tutorial

CSS Function Ideas Tutorial

Can you just move a bit to the right?

Now a tad sideways? That’s almost it. If you’d just, now, stand on your head. Okay, that’s it, thank you kindly?!

We’re just reacclimatizing ourselves here, having had our eyes fully opened, having stumbled onto W3school’s CSS Functions webpage, thanks. We’ve only tipped our toes into the variety of CSS (Javascript script like) capabilities that are out there. And yes, we covered “invert” so you can stand up again now … ta, muchly.

We’re showing Keyboard Based Cursor Image CSS Filter Tutorial below because CSS Functions cover a lot of image (ie. img element) CSS styling smarts, and we have touched on this, as well as good ol’ “calc”.

In today’s two day project start we’ve allowed users the chance to try CSS Functions from “a” to “m”. In today’s work …

  1. we started the first draft a bit non-generically … and then …
  2. straightened up … ready to …
  3. fly … right …

    Oh … you’re there! You can move back to square one … ta, muchly, like?!

… with day 1 of 2 “a” to “m” css_function_ideas.html CSS Function ideas web application you can try below …


Previous relevant Keyboard Based Cursor Image CSS Filter Tutorial is shown below.

Keyboard Based Cursor Image CSS Filter Tutorial

Keyboard Based Cursor Image CSS Filter Tutorial

What next for the Lorem Picsum (or RJM Programming WordPress Blog Posting tutorial pictures) resource usage web application regarding the recent Keyboard Based Cursor Image Blog Source Link Tutorial?

We’re a bit sheepish about how easy it was to feel like we are in some Photoshop studio applying CSS such as …

<style>

html { filter: drop-shadow(16px 16px 20px blue); }

</style>

… to change how ever many background images you have involved with the background images of your webpage using the changed body_mouse_deepdive.html‘s “parent” single background image web application (or, for example, “parent” eight background RJM Programming Blog Tutorial Picture image web application).

The user access all hangs off a first Shift key press followed by a numeric key (on QWERTY keyboard the “0123456789” correspond to “)!@#$%^&*(” characters) point at the first ten entries in …


var kcmap=["filter: blur(5px);","filter: brightness(0.4);","filter: contrast(200%);","filter: drop-shadow(16px 16px 20px blue);","filter: grayscale(50%);","filter: hue-rotate(90deg);","filter: invert(75%);","filter: opacity(25%);","filter: saturate(30%);","filter: sepia(60%);","filter: none;];"]; // thanks to https://developer.mozilla.org/en-US/docs/Web/CSS/filter

… used in amongst the “onkeypress” event Javascript function …


if (evt.keyCode >= 48 && evt.keyCode <= 57) { newu+=('' + eval(-48 + evt.keyCode)); if (lastshiftcursor) { kpdone=false; document.head.innerHTML+=' <style> html { ' + kcmap[eval(-48 + evt.keyCode)] + ' } </style>'; lastbit=document.title.split('Cursor change ')[1]; document.title='' + kcmap[eval(-48 + evt.keyCode)] + ' ... Cursor change ' + lastbit; return true; }
}

Stop Press

Thinking on arrangements above we figured it would give the user more control so that if they repeatedly pressed the same numerical key that would increment or decrement numerical components within the CSS filter specification requiring a changed call


if (evt.keyCode >= 48 && evt.keyCode <= 57) { newu+=('' + eval(-48 + evt.keyCode)); if (lastshiftcursor) { kpdone=false; dcr=doublecheck(kcmap[eval(-48 + evt.keyCode)]); document.head.innerHTML+=' <style> html { ' + dcr + ' } </style>'; lastbit=document.title.split('Cursor change ')[1]; document.title='' + dcr + ' ... Cursor change ' + lastbit; return true;
}

… of the new Javascript …


function doublecheck(infid) {
var outfid=infid;
var within=infid.split('(')[1].split(')')[0];
var entries=within.split(',');
if (entries[0].replace(/^\ /g,'').indexOf(' ') != -1) { entries=within.replace(/\(\ /g,'(').split(' '); }
var withind='';
if (document.title.indexOf('(') != -1) { withind=document.title.split('(')[1].split(')')[0]; }
var entriesd=withind.split(',');
if (entriesd[0].replace(/^\ /g,'').indexOf(' ') != -1) { entriesd=withind.replace(/\(\ /g,'(').split(' '); }
var anum=0.0, bnum=0.0;
var isdeg=false;
if ((entriesd[0] + 'x').indexOf(' ') != -1) { isdeg=true; }


if (document.title.indexOf(infid.split('(')[0]) == 0) {
for (var ii=0; ii<entriesd.length; ii++) {
if (entriesd[ii].indexOf('%') != -1) {
anum=eval(entriesd[ii].trim().replace('%',''));
bnum=eval(entries[ii].trim().replace('%',''));
if (anum < 100 && !isdeg) {
outfid=outfid.replace('' + bnum + '%', '' + eval(1 + anum) + '%');
} else if (anum == 0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + '%', '' + eval(1 + anum) + '%');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + '%', '' + eval(-1 + anum) + '%');
}
} else if (entriesd[ii].indexOf('px') != -1) {
console.log('entries[' + ii + ']=' + entriesd[ii] + ' within outfid=' + outfid)
anum=eval(entriesd[ii].trim().replace('px',''));
bnum=eval(entries[ii].trim().replace('px',''));
if (anum < 100 && !isdeg) {
outfid=outfid.replace('' + bnum + 'px', '' + eval(1 + anum) + 'px');
} else if (anum == 0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + 'px', '' + eval(1 + anum) + 'px');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + 'px', '' + eval(-1 + anum) + 'px');
}
} else if (entriesd[ii].indexOf('deg') != -1) {
anum=eval(entriesd[ii].trim().replace('deg',''));
bnum=eval(entries[ii].trim().replace('deg',''));
if (anum < 90 && !isdeg) {
outfid=outfid.replace('' + bnum + 'deg', '' + eval(1 + anum) + 'deg');
} else if (anum == 0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + 'deg', '' + eval(1 + anum) + 'deg');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + 'deg', '' + eval(-1 + anum) + 'deg');
}
} else if (entriesd[ii].indexOf('.') != -1) {
anum=eval(entriesd[ii].trim());
bnum=eval(entries[ii].trim());
if (anum < 1.0 && !isdeg) {
outfid=outfid.replace('' + bnum + '', '' + eval(0.1 + anum) + '');
} else if (anum == 0.0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + '', '' + eval(0.1 + anum) + '');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + '', '' + eval(-0.1 + anum) + '');
}
}
}
if (isdeg) { outfid=outfid.replace(/\(\ /g,'(').replace('(', '( '); }
}
return outfid;
}


Previous relevant Keyboard Based Cursor Image Source Tutorial is shown below.

Keyboard Based Cursor Image Source Tutorial

Keyboard Based Cursor Image Source Tutorial

Another layer of functionality thinking on top of the work of yesterday’s Keyboard Based Cursor Multiple Background Images Tutorial

  • multiple background image functionality … could be today’s …
  • image source choice to add to the generous Lorem Picsum image resource … thanks … that of a resource of the tutorial images amongst those of this RJM Programming WordPress Blog you are reading

… channelling the ever nuanced start we made in this regard when we presented Image Pair Fitting into a Given Dimension Sources Tutorial, with its interfacing to an increasing role for the WordPress codex TwentyTen theme 404.php role dealing with the HTTP error 404 well known as “Webpage Not Found”.

To make this happen, in code, we had to start breaking up (parameterizing, if you prefer) the hardcoding …

//picsum.photos

… into (variable) …


thesource

… and …

?random=

… into (variable usage) …


themp + '?random='

reflected into code snippet example below …


var thesource=location.search.split('numbi=')[1] ? (decodeURIComponent(location.search.split('numbi=')[1].split('&')[0]).replace('+',' ').replace(' ',' ').replace('-',' ').substring(0,1) == ' ' ? '//www.rjmprogramming.com.au/ITblog' : '//picsu' + 'm.photos') : '//picsu' + 'm.photos';
var themp='';
if (thesource != '//picsu' + 'm.photos') {
themp='/';
}

if (numbi != '') {
if (eval('' + numbi) == 2) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top right; background-size: 50% 100%, 50% 100%; background-repeat: no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 3) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right; background-size: 33% 100%, 34% 100%, 33% 100%; background-repeat: no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 4) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top right, bottom left, bottom right; background-size: 50% 50%, 50% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 5) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, bottom left, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 6) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 33% 50%, 34% 50%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 7) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 27143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, center center, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 33%, 33% 50%, 34% 34%, 33% 50%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 8) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 27143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 87123646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, center left, center center, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 50%, 33% 34%, 34% 34%, 33% 33%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 9) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 27143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 67143446) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 87123646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, center left, center center, center right, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 33%, 33% 34%, 34% 34%, 33% 34%, 33% 33%, 34% 33%, 33% 33%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (thesource != '//picsu' + 'm.photos') {
document.head.innerHTML+='<style> ' + document.head.innerHTML.split('<style>')[1].split('</style>')[0].replace(/\/\/picsum\.photos/g, thesource).replace(/\?random\=/g, themp + '?random=').replace(/00\)/g, '00' + themp + '?random=' + Math.floor(Math.random() * 198765434) + ')') + ' </style>';
}
} else if (thesource != '//picsu' + 'm.photos') {
document.head.innerHTML+='<style> ' + document.head.innerHTML.split('<style>')[1].split('</style>')[0].replace(/\/\/picsum\.photos/g, thesource).replace(/\?random\=/g, themp + '?random=').replace(/00\)/g, '00' + themp + '?random=' + Math.floor(Math.random() * 198765434) + ')') + ' </style>';
}

… in our changed body_mouse_deepdive.html‘s “parent” single background image web application (or, for example, “parent” eight background RJM Programming Blog Tutorial Picture image web application) where a user can latch onto the new image source via a first key press is a + plus character

Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content … RJM Programming … May, 2022 … thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements. With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji. Optionally make emojis bigger after \ with + two time multipliers. Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can work. If first key is (+ is RJM image else) from 1 to 9 that will be number of background images displayed.


Previous relevant Keyboard Based Cursor Multiple Background Images Tutorial is shown below.

Keyboard Based Cursor Multiple Background Images Tutorial

Keyboard Based Cursor Multiple Background Images Tutorial

For the images, those background ones, used in the recent Canvas Graphics Editing in Zoomed Webpage Tutorial, we use the great Lorem Picsum resource. So far that has been the one background image covering the background of the webpage …


<style>

body {
display: inline-block;
font-size: 128px;
line-height: 1.2;
text-align: center;
background: url(//picsum.photos/1000/1000) center center no-repeat;
background-size: cover;
background-clip: text;
-webkit-background-clip: text;


color: rgba(255,0,0,0.6);

span { color: transparent; }
}

div {
background-color: transparent;
caret-color: transparent;
}

@media only screen and (max-width: 1000px) {
div {
background: url(//picsum.photos/1000/1000) center center no-repeat;
}
}

div:focus {
outline: none !important;
}

html {
height: 100%;
display: flex;
cursor: Url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\002753</text></svg>") 16 0, crosshair;
}

</style>

… nominally background-positioned “center center”. But there are 9 background-position of that similar ilk available …

  • top left
  • top center
  • top right
  • center left
  • center center
  • center right
  • bottom left
  • bottom center
  • bottom right

… which we’d like to, optionally, be involved with how a user uses our changed body_mouse_deepdive.html‘s “parent” single background image web application (or, for example, “parent” four background image web application).

So, how to make it be able to be controlled by those users? Well, those previous keyboard logics involving emojis always involved a leading “\” backslash, so that leaves open numbers from 1 to 9 entered as a first keyboard character entered meaning that that is how many background images is wanted by that user

Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content … RJM Programming … May, 2022 … thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements. With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji. Optionally make emojis bigger after \ with + two time multipliers. Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can remove pasted part as required. If first key is from 1 to 9 that will be number of background images displayed.

… supported by …


var numbi=location.search.split('numbi=')[1] ? reduce(decodeURIComponent(location.search.split('numbi=')[1].split('&')[0])) : '1';

if (numbi != '') {
if (eval('' + numbi) == 2) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top right; background-size: 50% 100%, 50% 100%; background-repeat: no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 3) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right; background-size: 33% 100%, 34% 100%, 33% 100%; background-repeat: no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 4) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top right, bottom left, bottom right; background-size: 50% 50%, 50% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 5) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, bottom left, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 6) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 33% 50%, 34% 50%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 7) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center center, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 33%, 33% 50%, 34% 34%, 33% 50%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 8) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=87123646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center left, center center, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 50%, 33% 34%, 34% 34%, 33% 33%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 9) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=67143446), url(//picsum.photos/1000/1000?random=87123646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center left, center center, center right, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 33%, 33% 34%, 34% 34%, 33% 34%, 33% 33%, 34% 33%, 33% 33%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
}
}


function reduce(invl) {
if (('' + invl).trim() == '') { return '1'; }
if (('' + invl).trim().replace(/0/g,'').replace(/1/g,'').replace(/0/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') != '') { return '1'; }
var retval=0, ij=0;
var cinvl='' + invl;
var xcinvl='';
for (ij=0; ij<cinvl.length; ij++) {
if (cinvl.substring(ij).substring(0,1) != '-') {
retval+=eval(cinvl.substring(ij).substring(0,1));
}
}
xcinvl='' + retval;
while (xcinvl.length > 1) {
retval=0;
for (ij=0; ij<xcinvl.length; ij++) {
if (xcinvl.substring(ij).substring(0,1) != '-') {
retval+=eval(xcinvl.substring(ij).substring(0,1));
}
}
xcinvl='' + retval;
}
if (retval == 0) { retval=1; }
return '' + retval;
}


Previous relevant Keyboard Based Cursor Canvas Content Copy Tutorial is shown below.

Keyboard Based Cursor Canvas Content Copy Tutorial

Keyboard Based Cursor Canvas Content Copy Tutorial

You may have noticed with yesterday’s Keyboard Based Cursor Share Content Copy Tutorial, crucial to the sharing code, was the use of the incredible HTML5 introduced canvas element, helped by that middleperson link to those public email and SMS sharing conduits, overseeing the great random Lorem Picsum background images and user created emoji and/or text initial annotations.

And this got us wondering whether there was a private (ie. inhouse) web application of the past that could further value add as another optional middleperson tool for (user) personalization (of the content) purposes. And yes, do you remember the canvas work involved in the featured web application of Emoji Borders and Backgrounds Canvas Annotation Tutorial?

It uses an interesting approach with the transference of data across from a canvas in one application to the canvas in that user_of_signature_signature.htm web application. Once our changed body_mouse_deepdive.html‘s “parent” web application has organized its canvas contents, it’s just a matter of …


var awo=null;
awo=window.open('./user_of_signature_signature.htm','_blank','top=100,left=100,width=800,height=800');

… for the “child” canvas annotator to effectively “suck up” the canvas data into its canvas via …


var cancont='';
var elemode=location.search.split('elemode=')[1] ? (location.search.split('elemode=')[1].split('&')[0]) : "canvas";

if (('' + window.opener).replace('null','') != '') {
var cans=window.opener.document.getElementsByTagName(elemode);
if (cans.length > 0) {
if (elemode == 'img') {
cancont=cans[0].src;
} else {
cancont=cans[0].toDataURL('image/png');
}
if (cancontw < 0 && canconth < 0) { cancontw=cans[0].width; canconth=cans[0].height; } } }

... possible because both "parent" and "child" exist on the same RJM Programming domain (web server).

Once there, another woooooorrrrrlllddd of image manipulations, via canvas, can await the user, perhaps ready for ongoing sharing possibilities with that "child".


Previous relevant Keyboard Based Cursor Share Content Copy Tutorial is shown below.

Keyboard Based Cursor Share Content Copy Tutorial

Keyboard Based Cursor Share Content Copy Tutorial

Yesterday's Keyboard Based Cursor Personalized Content Copy Tutorial has probably reached a point where some sharing mechanism is apt, for accountability and usefulness purposes, at the very least, regarding our recent web application allowing for foreground content on top of a random Lorem Picsum background image.

We've been helped out greatly by javascript - Can I take a screenshot from the clipboard? - Stack Overflow and html - How to render a blob on a canvas element? - Stack Overflow in the following new relevant Javascript code ...


function renderNoImage(canvas, blob) { // thanks to https://stackoverflow.com/questions/38004917/how-to-render-a-blob-on-a-canvas-element
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = (event) => {
URL.revokeObjectURL(event.target.src) // This is important. If you are not using the blob, you should release it if you don't want to reuse it. It's good for memory.
ctx.drawImage(event.target, 0, 0)
img.style.display='none';
img.style.zIndex='-123';
};
img.src = URL.createObjectURL(blob);
}


function renderImage(canvas, blob) { // thanks to https://stackoverflow.com/questions/38004917/how-to-render-a-blob-on-a-canvas-element
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = (event) => {
URL.revokeObjectURL(event.target.src) // This is important. If you are not using the blob, you should release it if you don't want to reuse it. It's good for memory.
ctx.drawImage(event.target, 0, 0)
};
img.src = URL.createObjectURL(blob);
}


addEventListener("paste", ev => { // thanks to https://stackoverflow.com/questions/55559432/can-i-take-a-screenshot-from-the-clipboard
for(const item of ev.clipboardData.items) { /// Clipboard may contain multiple elements of different type -- text, image, etc
if(item.type.startsWith("image/")) { /// We are only interested in clipboard data that is an image
if (emailee == '') {
emailee=prompt('Your clipboard has a useful image you could share the image with. Optionally, please enter an email address or SMS number to share with.');
if (emailee == null) { emailee=''; }
}
if (emailee.indexOf('@') != -1) {
document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="position:absolute;z-index:98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('aemail').href=document.getElementById('aemail').href.replace(':?', ':' + emailee + '?');
document.getElementById('aemail').click();
document.getElementById('mycanvas').innerHTML='';
} else if (emailee != '' && emailee.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') == '') {
document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="position:absolute;z-index:98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('asms').href=document.getElementById('asms').href.replace(':&', ':' + emailee + '&');
document.getElementById('asms').click();
document.getElementById('mycanvas').innerHTML='';
} else {
//document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="display:none;position:absolute;z-index:-98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderNoImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('mycanvas').innerHTML='';
}
}
}
});

... which is explained to the user in the following way ...

Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can remove pasted part as required.

... in the changed "proof of concept" body_mouse_deepdive.html live run.


Previous relevant Keyboard Based Cursor Personalized Content Copy Tutorial is shown below.

Keyboard Based Cursor Personalized Content Copy Tutorial

Keyboard Based Cursor Personalized Content Copy Tutorial

On top of yesterday's Keyboard Based Cursor Content Copy Tutorial we wanted to offer the user the chance for them to tailor their foreground content on top of the Lorem Picsum background image.

The user can enter this via the keyboard because there is an HTML div contenteditable=true pallette to work with ...


<div id=mydiv onfocus='setTimeout(alte, 1000);' ondblclick="this.innerHTML='';" onclick='stamp(event);' title='Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content ... RJM Programming ... May, 2022 ... thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements.' spellcheck='false' contenteditable=true style='width:100vw;height:100%;color:transparent;text-color:transparent;' onkeypress=kpcursorlook(event); onkeydown=cursorlook(event); onmousemove=xycursorlook(event); ontouchmove=xycursorlook(event);></div>

It's "title" attribute now talks about two new pieces of functionality, those being ...

  • You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji).
  • Double click existant foreground emoji element to clear all the foreground emoji elements.

The choice of keyboard input methodology also suits CSS "content" property definitions as one backslash followed by a hexidecimal value left padded with zeroes to a length of six. See us doing this below for an umbrella emoji (which could also be expressed in an HTML hexadecimal entity way &#x2602; ☂ the information for which you can find at Unicode Character 'UMBRELLA' (U+2602) we normally get to by entering "U+2602" at a web browser address bar, the knowledge for which we arrive at via entering "umbrella emojipedia" and moving down the top link's webpage to find the "U+2602") ...


<style> #myumbrella::after { content: '\002602'; } </style>

... that feeds into some new "onkeypress" keyboard event logic ...


function kpcursorlook(evt) {
var atofa=['a','b','c','d','e','f'];
var rgbit='';
if (evt.keyCode == 92) {
if (newu.length == 1) { gro=true; } else { gro=false; }
newu=("\\").substring(0,1);
} else if (evt.keyCode >= 48 && evt.keyCode <= 57) {
newu+=('' + eval(-48 + evt.keyCode));
} else if (evt.keyCode >= 65 && evt.keyCode <= 70) {
newu+=('' + atofa[eval(-65 + evt.keyCode)]);
} else if (evt.keyCode >= 97 && evt.keyCode <= 102) {
newu+=('' + atofa[eval(-97 + evt.keyCode)]);
}
if (newu.length == 7) {
if (lastcursor.indexOf(("\\\\").substring(0,2)) != -1) {
rgbit=lastcursor.split(("\\\\").substring(0,2))[1].substring(6);
lastcursor=lastcursor.split(("\\\\").substring(0,2))[0] + ("\\").substring(0,1) + newu + rgbit;
document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
} else if (lastcursor.indexOf(("\\").substring(0,1)) != -1) {
rgbit=lastcursor.split(("\\").substring(0,1))[1].substring(6);
lastcursor=lastcursor.split(("\\").substring(0,1))[0] + newu + rgbit;
if (gro) {
lastcursor=lastcursor.replace('>Shift/Alt/Ctrl', '>').replace('>Shift', '>').replace('>Alt', '>').replace('>Ctrl', '>').replace(" width='126'", " width='20'").replace(" width='66'", " width='20'").replace(" height='48'", " height='20'").replace('0 0 100 100', '0 0 20 20');
}
document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
}
}
// console.log(evt.keyCode);
}

... in the changed "proof of concept" body_mouse_deepdive.html live run.

Stop Press

Two more "title" attribute pieces of functionality are now ...

  • With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji.
  • Optionally make emojis bigger after \ with + two time multipliers.

The choice of keyboard input methodology also suits CSS "content" property definitions as one backslash followed by "first off" sets of HTML entities they should not left zero pad in their entry, followed by a last HTML entity hexidecimal value left padded with zeroes to a length of six to finish up with. See us doing this below for a woman rowing emoji (which could also be expressed in an HTML hexadecimal entity way &#x1f6a3;&#x0200d;&#x02640;&#x0fe0f; the information for which you can find at 🚣‍♀️ Woman Rowing Boat Emoji we normally get to by entering "woman rowing emoji" at the web browser address bar) ...


<style> #myrowing::after { content: '\01f6a3\00200d\002640\00fe0f'; } </style>

... in the changed "proof of concept" body_mouse_deepdive.html live run.


Previous relevant Keyboard Based Cursor Content Copy Tutorial is shown below.

Keyboard Based Cursor Content Copy Tutorial

Keyboard Based Cursor Content Copy Tutorial

The "onkeydown" keyboard event can involve in its logic three mouse event (event object) property usages that caught our interest recently ...

... and we wanted to have "keyboard" meets "mouse" events, along with the brilliance of Lorem Picsum regarding background image randomosity and quality, working with HTML ...


<div id=mydiv onfocus='setTimeout(alte, 1000);' onclick='stamp(this);' title='Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content ... RJM Programming ... May, 2022 ... thanks to https://picsum.photos/ Lorem Picsum' spellcheck='false' contenteditable=true style='width:100vw;height:100%;color:transparent;text-color:transparent;' data-onkeypress=xycursorlook(event); onkeydown=cursorlook(event); onmousemove=xycursorlook(event); ontouchmove=xycursorlook(event);></div>

... in a way we hadn't tried before that called on some inhouse cursor SVG creations (and so is, alas, just a non-mobile fully featured experience), in the sense that ...

  1. keyboard helps creating the "what" regarding content ...

    <script type='text/javascript'>
    var lastkeymodifier=''
    var lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
    var pos3=-1, pos4=-1;
    var subdiv=1;
    var lastpos3=-2, lastpos4=-1;
    var allowable=false;

    function cursorlook(evt) {
    if (evt.altKey) {
    if (lastkeymodifier != 'alt') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='66' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,0,255,0.3);fill:black;font-family:Verdana;font-size:17px;'><text y='80%'>Alt\\01f3d5</text></svg>\") 16 0, progress";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='alt';
    }
    } else if (evt.ctrlKey) {
    if (lastkeymodifier != 'ctrl') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='66' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:17px;'><text y='80%'>Ctrl\\01f333</text></svg>\") 16 0, pointer";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='ctrl';
    }
    } else if (evt.shiftKey) {
    if (lastkeymodifier != 'shift') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='66' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(255,0,0,0.3);fill:black;font-family:Verdana;font-size:17px;'><text y='80%'>Shift\\01f389</text></svg>\") 16 0, grab";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='shift';
    }
    } else {
    if (lastkeymodifier != '') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='';
    }
    }
    }
    </script>
  2. mouse "onmousemove" or "ontouchmove" helps with the "where" regarding content above ...

    <script type='text/javascript'>
    var pos3=-1, pos4=-1;
    var subdiv=1;
    var lastpos3=-2, lastpos4=-1;
    var allowable=false;

    function xycursorlook(e) {
    e = e || window.event;
    e.preventDefault();

    if (e.touches) {
    if (e.touches[0].pageX) {
    pos3 = e.touches[0].pageX;
    pos4 = e.touches[0].pageY;
    } else {
    pos3 = e.touches[0].clientX;
    pos4 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos3 = e.clientX;
    pos4 = e.clientY;
    } else {
    pos3 = e.pageX;
    pos4 = e.pageY;
    }
    }
    </script>
  3. preparations for "onclick" way a cursor can be plonked into (real lasting) content ...

    <script type='text/javascript'>
    var lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
    var pos3=-1, pos4=-1;
    var subdiv=1;
    var lastpos3=-2, lastpos4=-1;
    var allowable=false;

    function stamp(divo) {
    if (('' + pos3).indexOf('-') == -1) {
    if (allowable) {
    //if (allowed) {
    //allowed=false;
    //setTimeout(reseta, 2000);
    divo.innerHTML+='<div id=div' + subdiv + ' style="position:absolute;top:' + pos4 + 'px;left:' + pos3 + 'px;width:126px;height:48px;background-color:transparent;"></div><style> #div' + subdiv + ' { background:' + lastcursor.split(') ')[0] + ') no-repeat; } </style>';
    subdiv++;
    //console.log('lastpos4=' + lastpos4 + ' and pos4=' + pos4);
    //console.log('lastpos3=' + lastpos3 + ' and pos3=' + pos3);
    lastpos3=pos3;
    lastpos4=pos4;
    //}
    }
    }
    }
    </script>

... with the "proof of concept" body_mouse_deepdive.html live run.

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.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , | Leave a comment

CSS Function Ideas Tutorial

CSS Function Ideas Tutorial

CSS Function Ideas Tutorial

Can you just move a bit to the right?

Now a tad sideways? That’s almost it. If you’d just, now, stand on your head. Okay, that’s it, thank you kindly?!

We’re just reacclimatizing ourselves here, having had our eyes fully opened, having stumbled onto W3school’s CSS Functions webpage, thanks. We’ve only tipped our toes into the variety of CSS (Javascript script like) capabilities that are out there. And yes, we covered “invert” so you can stand up again now … ta, muchly.

We’re showing Keyboard Based Cursor Image CSS Filter Tutorial below because CSS Functions cover a lot of image (ie. img element) CSS styling smarts, and we have touched on this, as well as good ol’ “calc”.

In today’s two day project start we’ve allowed users the chance to try CSS Functions from “a” to “m”. In today’s work …

  1. we started the first draft a bit non-generically … and then …
  2. straightened up … ready to …
  3. fly … right …

    Oh … you’re there! You can move back to square one … ta, muchly, like?!

… with day 1 of 2 “a” to “m” css_function_ideas.html CSS Function ideas web application you can try below …


Previous relevant Keyboard Based Cursor Image CSS Filter Tutorial is shown below.

Keyboard Based Cursor Image CSS Filter Tutorial

Keyboard Based Cursor Image CSS Filter Tutorial

What next for the Lorem Picsum (or RJM Programming WordPress Blog Posting tutorial pictures) resource usage web application regarding the recent Keyboard Based Cursor Image Blog Source Link Tutorial?

We’re a bit sheepish about how easy it was to feel like we are in some Photoshop studio applying CSS such as …

<style>

html { filter: drop-shadow(16px 16px 20px blue); }

</style>

… to change how ever many background images you have involved with the background images of your webpage using the changed body_mouse_deepdive.html‘s “parent” single background image web application (or, for example, “parent” eight background RJM Programming Blog Tutorial Picture image web application).

The user access all hangs off a first Shift key press followed by a numeric key (on QWERTY keyboard the “0123456789” correspond to “)!@#$%^&*(” characters) point at the first ten entries in …


var kcmap=["filter: blur(5px);","filter: brightness(0.4);","filter: contrast(200%);","filter: drop-shadow(16px 16px 20px blue);","filter: grayscale(50%);","filter: hue-rotate(90deg);","filter: invert(75%);","filter: opacity(25%);","filter: saturate(30%);","filter: sepia(60%);","filter: none;];"]; // thanks to https://developer.mozilla.org/en-US/docs/Web/CSS/filter

… used in amongst the “onkeypress” event Javascript function …


if (evt.keyCode >= 48 && evt.keyCode <= 57) { newu+=('' + eval(-48 + evt.keyCode)); if (lastshiftcursor) { kpdone=false; document.head.innerHTML+=' <style> html { ' + kcmap[eval(-48 + evt.keyCode)] + ' } </style>'; lastbit=document.title.split('Cursor change ')[1]; document.title='' + kcmap[eval(-48 + evt.keyCode)] + ' ... Cursor change ' + lastbit; return true; }
}

Stop Press

Thinking on arrangements above we figured it would give the user more control so that if they repeatedly pressed the same numerical key that would increment or decrement numerical components within the CSS filter specification requiring a changed call


if (evt.keyCode >= 48 && evt.keyCode <= 57) { newu+=('' + eval(-48 + evt.keyCode)); if (lastshiftcursor) { kpdone=false; dcr=doublecheck(kcmap[eval(-48 + evt.keyCode)]); document.head.innerHTML+=' <style> html { ' + dcr + ' } </style>'; lastbit=document.title.split('Cursor change ')[1]; document.title='' + dcr + ' ... Cursor change ' + lastbit; return true;
}

… of the new Javascript …


function doublecheck(infid) {
var outfid=infid;
var within=infid.split('(')[1].split(')')[0];
var entries=within.split(',');
if (entries[0].replace(/^\ /g,'').indexOf(' ') != -1) { entries=within.replace(/\(\ /g,'(').split(' '); }
var withind='';
if (document.title.indexOf('(') != -1) { withind=document.title.split('(')[1].split(')')[0]; }
var entriesd=withind.split(',');
if (entriesd[0].replace(/^\ /g,'').indexOf(' ') != -1) { entriesd=withind.replace(/\(\ /g,'(').split(' '); }
var anum=0.0, bnum=0.0;
var isdeg=false;
if ((entriesd[0] + 'x').indexOf(' ') != -1) { isdeg=true; }


if (document.title.indexOf(infid.split('(')[0]) == 0) {
for (var ii=0; ii<entriesd.length; ii++) {
if (entriesd[ii].indexOf('%') != -1) {
anum=eval(entriesd[ii].trim().replace('%',''));
bnum=eval(entries[ii].trim().replace('%',''));
if (anum < 100 && !isdeg) {
outfid=outfid.replace('' + bnum + '%', '' + eval(1 + anum) + '%');
} else if (anum == 0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + '%', '' + eval(1 + anum) + '%');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + '%', '' + eval(-1 + anum) + '%');
}
} else if (entriesd[ii].indexOf('px') != -1) {
console.log('entries[' + ii + ']=' + entriesd[ii] + ' within outfid=' + outfid)
anum=eval(entriesd[ii].trim().replace('px',''));
bnum=eval(entries[ii].trim().replace('px',''));
if (anum < 100 && !isdeg) {
outfid=outfid.replace('' + bnum + 'px', '' + eval(1 + anum) + 'px');
} else if (anum == 0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + 'px', '' + eval(1 + anum) + 'px');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + 'px', '' + eval(-1 + anum) + 'px');
}
} else if (entriesd[ii].indexOf('deg') != -1) {
anum=eval(entriesd[ii].trim().replace('deg',''));
bnum=eval(entries[ii].trim().replace('deg',''));
if (anum < 90 && !isdeg) {
outfid=outfid.replace('' + bnum + 'deg', '' + eval(1 + anum) + 'deg');
} else if (anum == 0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + 'deg', '' + eval(1 + anum) + 'deg');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + 'deg', '' + eval(-1 + anum) + 'deg');
}
} else if (entriesd[ii].indexOf('.') != -1) {
anum=eval(entriesd[ii].trim());
bnum=eval(entries[ii].trim());
if (anum < 1.0 && !isdeg) {
outfid=outfid.replace('' + bnum + '', '' + eval(0.1 + anum) + '');
} else if (anum == 0.0) {
isdeg=false;
outfid=outfid.replace(/\(\ /g,'(');
outfid=outfid.replace('' + bnum + '', '' + eval(0.1 + anum) + '');
} else {
isdeg=true;
outfid=outfid.replace('' + bnum + '', '' + eval(-0.1 + anum) + '');
}
}
}
if (isdeg) { outfid=outfid.replace(/\(\ /g,'(').replace('(', '( '); }
}
return outfid;
}


Previous relevant Keyboard Based Cursor Image Source Tutorial is shown below.

Keyboard Based Cursor Image Source Tutorial

Keyboard Based Cursor Image Source Tutorial

Another layer of functionality thinking on top of the work of yesterday’s Keyboard Based Cursor Multiple Background Images Tutorial

  • multiple background image functionality … could be today’s …
  • image source choice to add to the generous Lorem Picsum image resource … thanks … that of a resource of the tutorial images amongst those of this RJM Programming WordPress Blog you are reading

… channelling the ever nuanced start we made in this regard when we presented Image Pair Fitting into a Given Dimension Sources Tutorial, with its interfacing to an increasing role for the WordPress codex TwentyTen theme 404.php role dealing with the HTTP error 404 well known as “Webpage Not Found”.

To make this happen, in code, we had to start breaking up (parameterizing, if you prefer) the hardcoding …

//picsum.photos

… into (variable) …


thesource

… and …

?random=

… into (variable usage) …


themp + '?random='

reflected into code snippet example below …


var thesource=location.search.split('numbi=')[1] ? (decodeURIComponent(location.search.split('numbi=')[1].split('&')[0]).replace('+',' ').replace(' ',' ').replace('-',' ').substring(0,1) == ' ' ? '//www.rjmprogramming.com.au/ITblog' : '//picsu' + 'm.photos') : '//picsu' + 'm.photos';
var themp='';
if (thesource != '//picsu' + 'm.photos') {
themp='/';
}

if (numbi != '') {
if (eval('' + numbi) == 2) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top right; background-size: 50% 100%, 50% 100%; background-repeat: no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 3) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right; background-size: 33% 100%, 34% 100%, 33% 100%; background-repeat: no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 4) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top right, bottom left, bottom right; background-size: 50% 50%, 50% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 5) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, bottom left, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 6) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 33% 50%, 34% 50%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 7) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 27143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, center center, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 33%, 33% 50%, 34% 34%, 33% 50%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 8) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 27143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 87123646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, center left, center center, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 50%, 33% 34%, 34% 34%, 33% 33%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 9) {
document.head.innerHTML+='<style> #mydiv, body { background: url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76547646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 27143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 67143446) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 87123646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 10143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70143646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 50147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 70147646) + '), url(' + thesource + '/1000/1000' + themp + '?random=0' + Math.floor(Math.random() * 76147646) + '); background-position: top left, top center, top right, center left, center center, center right, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 33%, 33% 34%, 34% 34%, 33% 34%, 33% 33%, 34% 33%, 33% 33%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (thesource != '//picsu' + 'm.photos') {
document.head.innerHTML+='<style> ' + document.head.innerHTML.split('<style>')[1].split('</style>')[0].replace(/\/\/picsum\.photos/g, thesource).replace(/\?random\=/g, themp + '?random=').replace(/00\)/g, '00' + themp + '?random=' + Math.floor(Math.random() * 198765434) + ')') + ' </style>';
}
} else if (thesource != '//picsu' + 'm.photos') {
document.head.innerHTML+='<style> ' + document.head.innerHTML.split('<style>')[1].split('</style>')[0].replace(/\/\/picsum\.photos/g, thesource).replace(/\?random\=/g, themp + '?random=').replace(/00\)/g, '00' + themp + '?random=' + Math.floor(Math.random() * 198765434) + ')') + ' </style>';
}

… in our changed body_mouse_deepdive.html‘s “parent” single background image web application (or, for example, “parent” eight background RJM Programming Blog Tutorial Picture image web application) where a user can latch onto the new image source via a first key press is a + plus character

Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content … RJM Programming … May, 2022 … thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements. With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji. Optionally make emojis bigger after \ with + two time multipliers. Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can work. If first key is (+ is RJM image else) from 1 to 9 that will be number of background images displayed.


Previous relevant Keyboard Based Cursor Multiple Background Images Tutorial is shown below.

Keyboard Based Cursor Multiple Background Images Tutorial

Keyboard Based Cursor Multiple Background Images Tutorial

For the images, those background ones, used in the recent Canvas Graphics Editing in Zoomed Webpage Tutorial, we use the great Lorem Picsum resource. So far that has been the one background image covering the background of the webpage …


<style>

body {
display: inline-block;
font-size: 128px;
line-height: 1.2;
text-align: center;
background: url(//picsum.photos/1000/1000) center center no-repeat;
background-size: cover;
background-clip: text;
-webkit-background-clip: text;


color: rgba(255,0,0,0.6);

span { color: transparent; }
}

div {
background-color: transparent;
caret-color: transparent;
}

@media only screen and (max-width: 1000px) {
div {
background: url(//picsum.photos/1000/1000) center center no-repeat;
}
}

div:focus {
outline: none !important;
}

html {
height: 100%;
display: flex;
cursor: Url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\002753</text></svg>") 16 0, crosshair;
}

</style>

… nominally background-positioned “center center”. But there are 9 background-position of that similar ilk available …

  • top left
  • top center
  • top right
  • center left
  • center center
  • center right
  • bottom left
  • bottom center
  • bottom right

… which we’d like to, optionally, be involved with how a user uses our changed body_mouse_deepdive.html‘s “parent” single background image web application (or, for example, “parent” four background image web application).

So, how to make it be able to be controlled by those users? Well, those previous keyboard logics involving emojis always involved a leading “\” backslash, so that leaves open numbers from 1 to 9 entered as a first keyboard character entered meaning that that is how many background images is wanted by that user

Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content … RJM Programming … May, 2022 … thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements. With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji. Optionally make emojis bigger after \ with + two time multipliers. Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can remove pasted part as required. If first key is from 1 to 9 that will be number of background images displayed.

… supported by …


var numbi=location.search.split('numbi=')[1] ? reduce(decodeURIComponent(location.search.split('numbi=')[1].split('&')[0])) : '1';

if (numbi != '') {
if (eval('' + numbi) == 2) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top right; background-size: 50% 100%, 50% 100%; background-repeat: no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 3) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right; background-size: 33% 100%, 34% 100%, 33% 100%; background-repeat: no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 4) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top right, bottom left, bottom right; background-size: 50% 50%, 50% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 5) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, bottom left, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 6) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 33% 50%, 34% 50%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 7) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center center, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 33%, 33% 50%, 34% 34%, 33% 50%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 8) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=87123646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center left, center center, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 50%, 33% 34%, 34% 34%, 33% 33%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 9) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=67143446), url(//picsum.photos/1000/1000?random=87123646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center left, center center, center right, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 33%, 33% 34%, 34% 34%, 33% 34%, 33% 33%, 34% 33%, 33% 33%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
}
}


function reduce(invl) {
if (('' + invl).trim() == '') { return '1'; }
if (('' + invl).trim().replace(/0/g,'').replace(/1/g,'').replace(/0/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') != '') { return '1'; }
var retval=0, ij=0;
var cinvl='' + invl;
var xcinvl='';
for (ij=0; ij<cinvl.length; ij++) {
if (cinvl.substring(ij).substring(0,1) != '-') {
retval+=eval(cinvl.substring(ij).substring(0,1));
}
}
xcinvl='' + retval;
while (xcinvl.length > 1) {
retval=0;
for (ij=0; ij<xcinvl.length; ij++) {
if (xcinvl.substring(ij).substring(0,1) != '-') {
retval+=eval(xcinvl.substring(ij).substring(0,1));
}
}
xcinvl='' + retval;
}
if (retval == 0) { retval=1; }
return '' + retval;
}


Previous relevant Keyboard Based Cursor Canvas Content Copy Tutorial is shown below.

Keyboard Based Cursor Canvas Content Copy Tutorial

Keyboard Based Cursor Canvas Content Copy Tutorial

You may have noticed with yesterday’s Keyboard Based Cursor Share Content Copy Tutorial, crucial to the sharing code, was the use of the incredible HTML5 introduced canvas element, helped by that middleperson link to those public email and SMS sharing conduits, overseeing the great random Lorem Picsum background images and user created emoji and/or text initial annotations.

And this got us wondering whether there was a private (ie. inhouse) web application of the past that could further value add as another optional middleperson tool for (user) personalization (of the content) purposes. And yes, do you remember the canvas work involved in the featured web application of Emoji Borders and Backgrounds Canvas Annotation Tutorial?

It uses an interesting approach with the transference of data across from a canvas in one application to the canvas in that user_of_signature_signature.htm web application. Once our changed body_mouse_deepdive.html‘s “parent” web application has organized its canvas contents, it’s just a matter of …


var awo=null;
awo=window.open('./user_of_signature_signature.htm','_blank','top=100,left=100,width=800,height=800');

… for the “child” canvas annotator to effectively “suck up” the canvas data into its canvas via …


var cancont='';
var elemode=location.search.split('elemode=')[1] ? (location.search.split('elemode=')[1].split('&')[0]) : "canvas";

if (('' + window.opener).replace('null','') != '') {
var cans=window.opener.document.getElementsByTagName(elemode);
if (cans.length > 0) {
if (elemode == 'img') {
cancont=cans[0].src;
} else {
cancont=cans[0].toDataURL('image/png');
}
if (cancontw < 0 && canconth < 0) { cancontw=cans[0].width; canconth=cans[0].height; } } }

... possible because both "parent" and "child" exist on the same RJM Programming domain (web server).

Once there, another woooooorrrrrlllddd of image manipulations, via canvas, can await the user, perhaps ready for ongoing sharing possibilities with that "child".


Previous relevant Keyboard Based Cursor Share Content Copy Tutorial is shown below.

Keyboard Based Cursor Share Content Copy Tutorial

Keyboard Based Cursor Share Content Copy Tutorial

Yesterday's Keyboard Based Cursor Personalized Content Copy Tutorial has probably reached a point where some sharing mechanism is apt, for accountability and usefulness purposes, at the very least, regarding our recent web application allowing for foreground content on top of a random Lorem Picsum background image.

We've been helped out greatly by javascript - Can I take a screenshot from the clipboard? - Stack Overflow and html - How to render a blob on a canvas element? - Stack Overflow in the following new relevant Javascript code ...


function renderNoImage(canvas, blob) { // thanks to https://stackoverflow.com/questions/38004917/how-to-render-a-blob-on-a-canvas-element
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = (event) => {
URL.revokeObjectURL(event.target.src) // This is important. If you are not using the blob, you should release it if you don't want to reuse it. It's good for memory.
ctx.drawImage(event.target, 0, 0)
img.style.display='none';
img.style.zIndex='-123';
};
img.src = URL.createObjectURL(blob);
}


function renderImage(canvas, blob) { // thanks to https://stackoverflow.com/questions/38004917/how-to-render-a-blob-on-a-canvas-element
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = (event) => {
URL.revokeObjectURL(event.target.src) // This is important. If you are not using the blob, you should release it if you don't want to reuse it. It's good for memory.
ctx.drawImage(event.target, 0, 0)
};
img.src = URL.createObjectURL(blob);
}


addEventListener("paste", ev => { // thanks to https://stackoverflow.com/questions/55559432/can-i-take-a-screenshot-from-the-clipboard
for(const item of ev.clipboardData.items) { /// Clipboard may contain multiple elements of different type -- text, image, etc
if(item.type.startsWith("image/")) { /// We are only interested in clipboard data that is an image
if (emailee == '') {
emailee=prompt('Your clipboard has a useful image you could share the image with. Optionally, please enter an email address or SMS number to share with.');
if (emailee == null) { emailee=''; }
}
if (emailee.indexOf('@') != -1) {
document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="position:absolute;z-index:98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('aemail').href=document.getElementById('aemail').href.replace(':?', ':' + emailee + '?');
document.getElementById('aemail').click();
document.getElementById('mycanvas').innerHTML='';
} else if (emailee != '' && emailee.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') == '') {
document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="position:absolute;z-index:98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('asms').href=document.getElementById('asms').href.replace(':&', ':' + emailee + '&');
document.getElementById('asms').click();
document.getElementById('mycanvas').innerHTML='';
} else {
//document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="display:none;position:absolute;z-index:-98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderNoImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('mycanvas').innerHTML='';
}
}
}
});

... which is explained to the user in the following way ...

Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can remove pasted part as required.

... in the changed "proof of concept" body_mouse_deepdive.html live run.


Previous relevant Keyboard Based Cursor Personalized Content Copy Tutorial is shown below.

Keyboard Based Cursor Personalized Content Copy Tutorial

Keyboard Based Cursor Personalized Content Copy Tutorial

On top of yesterday's Keyboard Based Cursor Content Copy Tutorial we wanted to offer the user the chance for them to tailor their foreground content on top of the Lorem Picsum background image.

The user can enter this via the keyboard because there is an HTML div contenteditable=true pallette to work with ...


<div id=mydiv onfocus='setTimeout(alte, 1000);' ondblclick="this.innerHTML='';" onclick='stamp(event);' title='Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content ... RJM Programming ... May, 2022 ... thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements.' spellcheck='false' contenteditable=true style='width:100vw;height:100%;color:transparent;text-color:transparent;' onkeypress=kpcursorlook(event); onkeydown=cursorlook(event); onmousemove=xycursorlook(event); ontouchmove=xycursorlook(event);></div>

It's "title" attribute now talks about two new pieces of functionality, those being ...

  • You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji).
  • Double click existant foreground emoji element to clear all the foreground emoji elements.

The choice of keyboard input methodology also suits CSS "content" property definitions as one backslash followed by a hexidecimal value left padded with zeroes to a length of six. See us doing this below for an umbrella emoji (which could also be expressed in an HTML hexadecimal entity way &#x2602; ☂ the information for which you can find at Unicode Character 'UMBRELLA' (U+2602) we normally get to by entering "U+2602" at a web browser address bar, the knowledge for which we arrive at via entering "umbrella emojipedia" and moving down the top link's webpage to find the "U+2602") ...


<style> #myumbrella::after { content: '\002602'; } </style>

... that feeds into some new "onkeypress" keyboard event logic ...


function kpcursorlook(evt) {
var atofa=['a','b','c','d','e','f'];
var rgbit='';
if (evt.keyCode == 92) {
if (newu.length == 1) { gro=true; } else { gro=false; }
newu=("\\").substring(0,1);
} else if (evt.keyCode >= 48 && evt.keyCode <= 57) {
newu+=('' + eval(-48 + evt.keyCode));
} else if (evt.keyCode >= 65 && evt.keyCode <= 70) {
newu+=('' + atofa[eval(-65 + evt.keyCode)]);
} else if (evt.keyCode >= 97 && evt.keyCode <= 102) {
newu+=('' + atofa[eval(-97 + evt.keyCode)]);
}
if (newu.length == 7) {
if (lastcursor.indexOf(("\\\\").substring(0,2)) != -1) {
rgbit=lastcursor.split(("\\\\").substring(0,2))[1].substring(6);
lastcursor=lastcursor.split(("\\\\").substring(0,2))[0] + ("\\").substring(0,1) + newu + rgbit;
document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
} else if (lastcursor.indexOf(("\\").substring(0,1)) != -1) {
rgbit=lastcursor.split(("\\").substring(0,1))[1].substring(6);
lastcursor=lastcursor.split(("\\").substring(0,1))[0] + newu + rgbit;
if (gro) {
lastcursor=lastcursor.replace('>Shift/Alt/Ctrl', '>').replace('>Shift', '>').replace('>Alt', '>').replace('>Ctrl', '>').replace(" width='126'", " width='20'").replace(" width='66'", " width='20'").replace(" height='48'", " height='20'").replace('0 0 100 100', '0 0 20 20');
}
document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
}
}
// console.log(evt.keyCode);
}

... in the changed "proof of concept" body_mouse_deepdive.html live run.

Stop Press

Two more "title" attribute pieces of functionality are now ...

  • With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji.
  • Optionally make emojis bigger after \ with + two time multipliers.

The choice of keyboard input methodology also suits CSS "content" property definitions as one backslash followed by "first off" sets of HTML entities they should not left zero pad in their entry, followed by a last HTML entity hexidecimal value left padded with zeroes to a length of six to finish up with. See us doing this below for a woman rowing emoji (which could also be expressed in an HTML hexadecimal entity way &#x1f6a3;&#x0200d;&#x02640;&#x0fe0f; the information for which you can find at 🚣‍♀️ Woman Rowing Boat Emoji we normally get to by entering "woman rowing emoji" at the web browser address bar) ...


<style> #myrowing::after { content: '\01f6a3\00200d\002640\00fe0f'; } </style>

... in the changed "proof of concept" body_mouse_deepdive.html live run.


Previous relevant Keyboard Based Cursor Content Copy Tutorial is shown below.

Keyboard Based Cursor Content Copy Tutorial

Keyboard Based Cursor Content Copy Tutorial

The "onkeydown" keyboard event can involve in its logic three mouse event (event object) property usages that caught our interest recently ...

... and we wanted to have "keyboard" meets "mouse" events, along with the brilliance of Lorem Picsum regarding background image randomosity and quality, working with HTML ...


<div id=mydiv onfocus='setTimeout(alte, 1000);' onclick='stamp(this);' title='Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content ... RJM Programming ... May, 2022 ... thanks to https://picsum.photos/ Lorem Picsum' spellcheck='false' contenteditable=true style='width:100vw;height:100%;color:transparent;text-color:transparent;' data-onkeypress=xycursorlook(event); onkeydown=cursorlook(event); onmousemove=xycursorlook(event); ontouchmove=xycursorlook(event);></div>

... in a way we hadn't tried before that called on some inhouse cursor SVG creations (and so is, alas, just a non-mobile fully featured experience), in the sense that ...

  1. keyboard helps creating the "what" regarding content ...

    <script type='text/javascript'>
    var lastkeymodifier=''
    var lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
    var pos3=-1, pos4=-1;
    var subdiv=1;
    var lastpos3=-2, lastpos4=-1;
    var allowable=false;

    function cursorlook(evt) {
    if (evt.altKey) {
    if (lastkeymodifier != 'alt') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='66' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,0,255,0.3);fill:black;font-family:Verdana;font-size:17px;'><text y='80%'>Alt\\01f3d5</text></svg>\") 16 0, progress";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='alt';
    }
    } else if (evt.ctrlKey) {
    if (lastkeymodifier != 'ctrl') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='66' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:17px;'><text y='80%'>Ctrl\\01f333</text></svg>\") 16 0, pointer";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='ctrl';
    }
    } else if (evt.shiftKey) {
    if (lastkeymodifier != 'shift') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='66' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(255,0,0,0.3);fill:black;font-family:Verdana;font-size:17px;'><text y='80%'>Shift\\01f389</text></svg>\") 16 0, grab";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='shift';
    }
    } else {
    if (lastkeymodifier != '') {
    lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
    document.head.innerHTML+='<style> html { cursor: ' + lastcursor + '; } </style>';
    lastkeymodifier='';
    }
    }
    }
    </script>
  2. mouse "onmousemove" or "ontouchmove" helps with the "where" regarding content above ...

    <script type='text/javascript'>
    var pos3=-1, pos4=-1;
    var subdiv=1;
    var lastpos3=-2, lastpos4=-1;
    var allowable=false;

    function xycursorlook(e) {
    e = e || window.event;
    e.preventDefault();

    if (e.touches) {
    if (e.touches[0].pageX) {
    pos3 = e.touches[0].pageX;
    pos4 = e.touches[0].pageY;
    } else {
    pos3 = e.touches[0].clientX;
    pos4 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos3 = e.clientX;
    pos4 = e.clientY;
    } else {
    pos3 = e.pageX;
    pos4 = e.pageY;
    }
    }
    </script>
  3. preparations for "onclick" way a cursor can be plonked into (real lasting) content ...

    <script type='text/javascript'>
    var lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
    var pos3=-1, pos4=-1;
    var subdiv=1;
    var lastpos3=-2, lastpos4=-1;
    var allowable=false;

    function stamp(divo) {
    if (('' + pos3).indexOf('-') == -1) {
    if (allowable) {
    //if (allowed) {
    //allowed=false;
    //setTimeout(reseta, 2000);
    divo.innerHTML+='<div id=div' + subdiv + ' style="position:absolute;top:' + pos4 + 'px;left:' + pos3 + 'px;width:126px;height:48px;background-color:transparent;"></div><style> #div' + subdiv + ' { background:' + lastcursor.split(') ')[0] + ') no-repeat; } </style>';
    subdiv++;
    //console.log('lastpos4=' + lastpos4 + ' and pos4=' + pos4);
    //console.log('lastpos3=' + lastpos3 + ' and pos3=' + pos3);
    lastpos3=pos3;
    lastpos4=pos4;
    //}
    }
    }
    }
    </script>

... with the "proof of concept" body_mouse_deepdive.html live run.

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.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , | Leave a comment

Text to Emoji Onkeydown Tutorial

Text to Emoji Onkeydown Tutorial

Text to Emoji Onkeydown Tutorial

We’re revisiting the Text to Emoji web application work we talked about at Text to Emoji Preview Tutorial because …

  1. we wanted to add some HTML textarea element onkeydown keyboard event logic to be able to, via some element title attributes, show a preview view of the “Text to Emoji” conversion ideas … and …
  2. improved the sharing logic accordingly, being able that way, to include these preview views in the email and/or SMS body

… using this new Javascript function …


var keyhelp='', lastword='', lastawords=' ', lastwords='', lastewords='', wastitle='', lastdelim='', lastfword='', prevlaste='';

function okd(evt) {
if (event.key === "Backspace") {
//console.log("Backspace key pressed.");
if (evt.target.title.substring(0,1) == ' ') {
if (evt.target.title.slice(-1) >= '0' && evt.target.title.slice(-1) <= 'z') {
evt.target.title=evt.target.title.substring(0,eval(-1 + eval('' + evt.target.title.length)));
document.body.title=evt.target.title;
}
}
if (lastword.trim() != '') {
if (lastword.slice(-1) >= ' ' && lastword.slice(-1) <= '~') {
if (lastewords.trim() != '') {
if (('' + lastewords + '#@#@').indexOf(lastword + + '#@#@') != -1) {
lastewords=lastewords.substring(0,eval(-1 + eval('' + lastewords.length)));
}
}
if (lastawords.trim() != '') {
if (('' + lastawords + '#@#@').indexOf(lastword + + '#@#@') != -1) {
lastawords=lastawords.substring(0,eval(-1 + eval('' + lastawords.length)));
}
}
if (lastwords.trim() != '') {
if (('' + lastwords + '#@#@').indexOf(lastword + + '#@#@') != -1) {
lastwords=lastwords.substring(0,eval(-1 + eval('' + lastwords.length)));
}
}
if (lastword.trim() != '') {
lastword=lastword.substring(0,eval(-1 + eval('' + lastword.length)));
}
}
lastdelim='';
}
return true;
} else if (event.key === "Delete") {
//console.log("Delete key pressed.");
if (evt.target.title.substring(0,1) == ' ') {
if (evt.target.title.slice(-1) >= '0' && evt.target.title.slice(-1) <= 'z') {
evt.target.title=evt.target.title.substring(0,eval(-1 + eval('' + evt.target.title.length)));
document.body.title=evt.target.title;
}
}
if (lastword.trim() != '') {
if (lastword.slice(-1) >= ' ' && lastword.slice(-1) <= '~') {
if (lastewords.trim() != '') {
if (('' + lastewords + '#@#@').indexOf(lastword + + '#@#@') != -1) {
lastewords=lastewords.substring(0,eval(-1 + eval('' + lastewords.length)));
}
}
if (lastawords.trim() != '') {
if (('' + lastawords + '#@#@').indexOf(lastword + + '#@#@') != -1) {
lastawords=lastawords.substring(0,eval(-1 + eval('' + lastawords.length)));
}
}
if (lastwords.trim() != '') {
if (('' + lastwords + '#@#@').indexOf(lastword + + '#@#@') != -1) {
lastwords=lastwords.substring(0,eval(-1 + eval('' + lastwords.length)));
}
}
if (lastword.trim() != '') {
lastword=lastword.substring(0,eval(-1 + eval('' + lastword.length)));
}
}
lastdelim='';
}
return true;
}
//if (evt.altKey) {
// return false;
//} else if (evt.ctrlKey) {
// return false;
//} else if (evt.shiftKey) {
// return false;
//}
var jdone=false;
var ichar = evt.which || evt.keyCode;
if (ichar == 32) {
prevlaste='';
if (lastewords == ' ') {
lastewords='';
} else {
lastawords+=lastword + ' ';
lastwords+=lastword + ' ';
if (evt.target.title.substring(0,1) == ' ') {
if (lastdelim == '') {
evt.target.title+=lastdelim + ' ' + lastword.replace(/\&\#1320\;/g,'');
//document.title='a';
document.body.title=evt.target.title;
} else if (lastword.slice(-1) != lastdelim && lastdelim != '') {
evt.target.title+=lastdelim + ' ' + lastword.replace(/\&\#1320\;/g,'');
document.body.title=evt.target.title;
//document.title='b';
}
}
}
lastword='';
lastdelim='';
lastfword='';
} else {
if (eval('' + ('' + evt.key).length) == 1) {
switch (('' + evt.key)) {
case 'Shift':
break;

case 'Alt':
break;

case 'Ctrl':
break;

case 'Meta':
break;

default:
//lastword+=('' + evt.key).replace('Shift','').replace('Alt','').replace('Ctrl','');
if (('' + evt.key) == '.' || ('' + evt.key) == '!' || ('' + evt.key) == '?' || ('' + evt.key) == ':' || ('' + evt.key) == ';' || ('' + evt.key) == '|' || ('' + evt.key) == '&' || ('' + evt.key) == ',' || ('' + evt.key) == '/') {
prevlaste='';
if (lastawords != ' ' && keyhelp.toLowerCase().indexOf('|' + lastword.toLowerCase() + '~') != -1 && lastword.trim() != '') {
lastewords=lastwords + lastdelim + keyhelp.toLowerCase().split('|' + lastword.toLowerCase() + '~')[0].split('~')[eval(-1 + keyhelp.toLowerCase().split('|' + lastword.toLowerCase() + '~')[0].split('~').length)] + evt.key;
//alert(lastawords + '0:' + lastword + ' ... ' + lastewords);
lastwords+=lastword + evt.key;
lastawords+=lastword + evt.key;
lastdelim='' + evt.key;
jdone=true;
lastdelim='';
//alert('HeRe=' + evt.key);
} else if (lastawords != ' ' && keyhelp.toLowerCase().indexOf('|' + lastawords.trim().toLowerCase() + '~') != -1 && lastawords.trim() != '') {
lastewords=lastwords + lastdelim + keyhelp.toLowerCase().split('|' + lastawords.trim().toLowerCase() + '~')[0].split('~')[eval(-1 + keyhelp.toLowerCase().split('|' + lastawords.trim().toLowerCase() + '~')[0].split('~').length)] + evt.key;
//alert(lastawords + '1:' + lastword + ' ... ' + lastewords);
lastwords+=lastword + evt.key;
lastawords+=lastword + evt.key;
lastdelim='' + evt.key;
jdone=true;
lastdelim='';
//alert('HeRE=' + evt.key);
} else if (evt.target.title.substring(0,1) == ' ') {
if ((evt.target.title + '#$@#').indexOf((lastword + '#$@#')) != -1) {
evt.target.title+=' ' + evt.key;
lastwords+=evt.key;
lastawords+=evt.key;
lastewords+=evt.key;
} else if (lastfword != '') {
evt.target.title+=(' ' + lastword.replace(/\&\#1320\;/g,'')).replace(' ' + lastfword, '') + evt.key;
lastewords=lastwords + evt.key;

lastwords+=evt.key;
lastawords+=evt.key;
lastdelim=''; // ?

//document.title='c';
lastword='';
//alert(evt.target.title + ' RE ' + lastword + ' and lastdelim=' + lastdelim + ' and lastawords=' + lastawords);
} else {
evt.target.title+=' ' + lastword.replace(/\&\#1320\;/g,'') + evt.key;
lastewords=lastwords + lastword.replace(/\&\#1320\;/g,'') + evt.key;

lastwords+=lastword.replace(/\&\#1320\;/g,'') + evt.key;
lastawords+=lastword.replace(/\&\#1320\;/g,'') + evt.key;
lastdelim=''; // ?
lastword='';

//document.title='d';
//alert('Here=' + evt.key);
}
document.body.title=evt.target.title;
lastdelim='' + evt.key;
//document.title='e';
lastfword='';

//jdone=true; // ?

}
//alert('Here');
}
if (lastword == '' && evt.key == lastdelim) {
lastword=lastword;
} else {
lastword+=('' + evt.key);
}
//alert(lastword + ' ... ' + evt.key);
break;
}
}
if (!jdone && keyhelp.toLowerCase().indexOf('|' + lastword.toLowerCase() + '~') != -1 && lastword.trim() != '') {
if (lastfword != lastword) {
lastfword=lastword;
prevlaste=lastwords + lastword;
lastewords=lastwords + lastdelim + keyhelp.toLowerCase().split('|' + lastword.toLowerCase() + '~')[0].split('~')[eval(-1 + keyhelp.toLowerCase().split('|' + lastword.toLowerCase() + '~')[0].split('~').length)];
//alert('2:' + lastword + ' ... ' + lastewords + ' and lastdelim=' + lastdelim);
lastwords+=lastword;
lastawords+=lastword;
lastdelim='';
} else if (('' + evt.key) == '.' || ('' + evt.key) == '!' || ('' + evt.key) == '?' || ('' + evt.key) == ':' || ('' + evt.key) == ';' || ('' + evt.key) == '|' || ('' + evt.key) == '&' || ('' + evt.key) == ',' || ('' + evt.key) == '/') {
lastfword='';
lastwords+=evt.key;
lastawords+=evt.key;
lastewords+=evt.key;
lastdelim='';
} else {
return true; //alert(lastword + 'huh?' + lastfword);
}
} else if (!jdone && keyhelp.toLowerCase().indexOf('|' + lastawords.trim().toLowerCase() + '~') != -1 && lastawords.trim() != '') {
if (lastfword != lastword) {
lastfword=lastword;
prevlaste=lastwords + lastword;
lastewords=lastwords + lastdelim + keyhelp.toLowerCase().split('|' + lastawords.trim().toLowerCase() + '~')[0].split('~')[eval(-1 + keyhelp.toLowerCase().split('|' + lastawords.trim().toLowerCase() + '~')[0].split('~').length)];
//alert('3:' + lastword + ' ... ' + lastewords + ' and lastdelim=' + lastdelim);
lastwords+=lastword;
lastawords+=lastword;
lastdelim='';
}
} else if (!jdone && prevlaste != '') {
lastewords=prevlaste + evt.key;
lastwords=lastewords;
lastawords+=evt.key;
lastword+=evt.key;
evt.target.title=' ' + lastewords.replace(/\&\#1320\;/g,'');
document.body.title=evt.target.title;
prevlaste='';
lastdelim='';
return true;
}
}
if (lastewords.trim() != '') {
if (wastitle == '') {
wastitle=evt.target.title;
}
//evt.target.title=lastdelim + ' ' + lastewords.replace(/\&\#1320\;/g,'');
//evt.target.title=' ' + lastdelim + lastewords.replace(/\&\#1320\;/g,'');
evt.target.title=' ' + lastewords.replace(/\&\#1320\;/g,'');
document.body.title=evt.target.title;
//document.title='f';
lastwords=lastewords;
lastewords=' ';
lastawords=' ';
lastdelim='';
}
return true;
}

… to do this in the HTML and Javascript changed fillin_gaps_with_emojis.html “Text to Emoji” web application helped out by the changed fillin_gaps_with_emojis.php PHP.


Previous relevant Text to Emoji Preview Tutorial is shown below.

Text to Emoji Preview Tutorial

Text to Emoji Preview Tutorial

Yesterday’s HTML Editor HTML Preview Tutorial set us to thinking that its “Preview” of “future display” could also work well with our Text to Emoji Short Code Translation Textarea Flip Flop Tutorial‘s “Text to Emoji” web application.

Within …

  • yesterday’s work HTML iframe destination was populated via some HTML via that iframe’s “srcdoc” attribute … whereas with …
  • today’s work switches the “target” attribute of an HTML form (POSTing data to some PHP) to our “overlay preview” HTML iframe before putting that form’s “target” attribute back to the normal flow of work … achieved as simply as adding HTML snippets

    <form id="iform" onsubmit="this.target=document.getElementById('itarget').value; setTimeout(latback, 3000); return true;" target='iftext' method='POST' action='./fillin_gaps_with_emojis.php'><input type=hidden name=itarget id=itarget value=iftext></input>
    <|-- rest of form follows would include submit button used by "document.getElementById('mysubm').click();" code below to submit form -->
    </form>

    … with associated Javascript (after) …

    function latback() {
    document.getElementById('itarget').value='iftext';
    }

    … and with associated Javascript (before Preview)

    function popdiv(ot) {
    wasih=document.getElementById('intext').value;
    if (unpopsecs != 0 && document.getElementById('khtmlcontent')) {
    if (1 == 1) {
    document.getElementById('itarget').value='khtmlcontent';
    document.getElementById('khtmlcontent').style.zIndex='99';
    document.getElementById('khtmlcontent').style.display='block';
    document.body.style.cursor='progress';
    document.body.style.cursor='progress';
    document.getElementById('mydiv').style.cursor='progress';
    document.getElementById('khtmlcontent').style.cursor='progress';
    document.getElementById('mysubm').click();
    //document.getElementById('myaltb').click();
    setTimeout(halfpopdiv, Math.floor(eval(unpopsecs / 10)));
    setTimeout(unpopdiv, unpopsecs);
    } else
    {
    document.getElementById('khtmlcontent').srcdoc=ot.value;
    document.getElementById('khtmlcontent').style.zIndex='99';
    document.body.style.cursor='progress';
    document.getElementById('mydiv').style.cursor='progress';
    document.getElementById('khtmlcontent').style.cursor='progress';
    setTimeout(halfpopdiv, Math.floor(eval(unpopsecs / 10)));
    setTimeout(unpopdiv, unpopsecs);
    }
    }
    }

Both techniques work to further emphasise just how useful and flexible are HTML iframe elements regarding HTML navigation choices.

Team that HTML iframe navigation talent with the CSS “overlay” talents of …

… effectively controlling the “overlay” CSS (inferred, via rgba) friend …

  • opacity … teamed with other “overlay” CSS property friends …
  • z-index … and …
  • position:absolute; top:[matchedTopOfUnderlay]px; left:[matchedLeftOfUnderlay]px; (as well as width:[matchedWidthOfUnderlay]px; height:[matchedHeightOfUnderlay]px; today)

… and you have quite a powerful combination to work with to “jazz up” the “display smarts” of your web applications, a bit reminiscent of “rubber banding” previews of graphic element creations.

Feel free to (re-)try the HTML and Javascript changed fillin_gaps_with_emojis.html “Text to Emoji” web application.


Previous relevant Text to Emoji Short Code Translation Textarea Flip Flop Tutorial is shown below.

Text to Emoji Short Code Translation Textarea Flip Flop Tutorial

Text to Emoji Short Code Translation Textarea Flip Flop Tutorial

The basis for yesterday’s Text to Emoji Short Code Translation Textarea Rotation Tutorial rotation functionality revolves around the CSS transform property

transform: none|transform-functions|initial|inherit;

… specifically the use of the “rotate([numDegrees]deg)” “transform-function” and helped out considerably by a big friend of recent times … style=position:fixed

And today we delve into two more of those “transform-functions” to facilitate flip (mirror image in X) and flop (mirror image in Y), adding to yesterday’s …

  • rotation of text … “transform-function” “rotate([numDegrees]deg)” … with today’s and/or based …
  • flip of text … “transform-function” “scaleX(-1)” … and/or …
  • flop of text … “transform-function” “scaleY(-1)”

… all funnelled through that same Javascript prompt user access point of yesterday where the “prompt” of the prompt now goes …

Rotate text by your entry degrees. Negative entry (including -0) additionally flips. Appending a space additionally flops.

As you can imagine if you gyrate yourself thinking about “transformations” (eg. the Twister game) order can be important, and we found a simplistic idea like …


style=" transform: scale(-1,-1); "

… (ie. flipping and flopping) applied to one “div” element could not be made to work, for us. So here’s the lesson here. If you have nested elements, where this style=” transform: scale(-1,-1); “ fails (and yes, we also failed with style=” transform: scaleX(-1) scaleY(-1); “) we found …

  • apply to parent element style=” transform: scaleX(-1); “
  • apply to child element style=” transform: scaleY(-1); “

… and suddenly we were getting somewhere.

Again, the changed PHP helper fillin_gaps_with_emojis.php to the live run link off the HTML and Javascript changed fillin_gaps_with_emojis.html code.


Previous relevant Text to Emoji Short Code Translation Textarea Rotation Tutorial is shown below.

Text to Emoji Short Code Translation Textarea Rotation Tutorial

Text to Emoji Short Code Translation Textarea Rotation Tutorial

When you look around you at advertisements and signage you may see lots of ways to represent text, and here we include emojis in that thinking. And that is another reason we think emojis are useful. For we graphically challenged, to learn about emojis opens up a whole new area of (self) expression.

As such, onto yesterday’s Text to Emoji Short Code Translation Textarea Sharing Tutorial work we wanted to offer a text rotation additional (and optional) piece of functionality that you can access via a “Text” hardcoding becomes “a” link to prompt window piece of functionality that gets you to some new PHP code …

<?php

$rot="";
if (isset($_POST['rotate']) || isset($_GET['rotate'])) {
if (isset($_POST['rotate'])) {
$rot=('' . str_replace('+',' ',urldecode($_POST['rotate'])) . '');
} else {
$rot=('' . str_replace('+',' ',urldecode($_GET['rotate'])) . '');
}
}

if (isset($_POST['intext']) || isset($_GET['intext'])) {
if (isset($_POST['intext'])) {
$intext=' ' . str_replace('+',' ',urldecode($_POST['intext'])) . ' ';
} else {
$intext=' ' . str_replace('+',' ',urldecode($_GET['intext'])) . ' ';
}
$phpsc='HTTP://www.rjmprogramming.com.au/PHP/short_codes.php';
if (strpos($_SERVER['SERVER_NAME'], "localhost") !== false) {
$phpsc=str_replace(':80/', '/', 'http://localhost:' . $_SERVER['SERVER_PORT'] . '/short_codes.php');
//echo $phpsc;
//exit;
}
$outtxt=file_get_contents($phpsc . '?intext=' . urlencode($intext));
if ($outtxt != "") { //file_exists($phpsc)) { //'../PHP/short_codes/php')) {
if ($intext != '') {
$outtext=$intext;
if (intval($rot) < 90) {
$xp="60";
$yp="20";
} else if (intval($rot) < 180) {
$xp="80";
$yp="60";
} else if (intval($rot) < 270) {
$xp="60";
$yp="80";
} else {
$xp="40";
$yp="50";
}

if ($outtxt == "") { $outtxt=file_get_contents($phpsc . '?intext=' . urlencode($intext)); }
if (strpos($outtxt, '</body>') !== false) {
$bod='<body' . explode('>', explode('<body', $outtxt)[1])[0] . '>';
$outtext=str_replace('<p>', '', str_replace('</p>', '', explode($bod, explode('</body>', $outtxt)[0])[1]));
if ($outtext != $intext) {
if ($rot != "" && $rot != "0") {
//if (strlen($rot) === 3) { $xp=80"; }
$oneis=explode('.', ('' . sin(deg2rad($rot)) * 100.0))[0];
$twois=explode('.', ('' . cos(deg2rad($rot)) * 100.0))[0];
$threeis=explode('.', ('' . (0.0 - sin(deg2rad($rot))) * 100.0))[0];
$fouris=explode('.', ('' . (0.0 - cos(deg2rad($rot))) * 100.0))[0];
//echo "<html><head><title>Emoji-ize Text - RJM Programming - June, 2021</title><meta charset='UTF-8'></head><body style='width:100%;'><p>" . str_replace("\n","<br>",str_replace("$@!"," ",trim($outtext))) . "</p></body></html>";
echo "<html><head><title>Emoji-ize Text - RJM Programming - June, 2021</title><meta charset='UTF-8'><script type='text/javascript'>

function getTopLeft(width, height, theta ) { // thanks to https://board.flashkit.com/board/showthread.php?775357-Find-four-points-of-rotated-rectangle
// half width and height directed appropriately (for top left)
var hw = -width / 2;
var hh = -height / 2;
var xcos = Math.cos( theta );
var xsin = Math.sin( theta );
//alert('hw=' + hw + ' height=' + height + ' theta=' + theta + ' ' + ('' + eval(-1 * eval(hw * xsin + hh * xcos ))).split('.')[0] + '.' + ('' + eval(1 * eval(hw * xcos - hh * xsin))).split('.')[0]);
//return ('' + eval(-1 * eval(hw * xcos - hh * xsin))).split('.')[0] + '.' + ('' + eval(-1 * eval(hw * xsin + hh * xcos ))).split('.')[0];
//return ('' + eval(-1 * eval(hw * xsin + hh * xcos ))).split('.')[0] + '.' + ('' + eval(1 * eval(hw * xcos - hh * xsin))).split('.')[0];
return ('' + eval(hw * xcos - hh * xsin)).split('.')[0] + '.' + ('' + eval(hw * xsin + hh * xcos )).split('.')[0];
}


if (window.parent) { if (parent.document.getElementById('divinvis')) { var tts='' + parent.document.getElementById('divinvis').getBoundingClientRect().width, tst='' + parent.document.getElementById('divinvis').getBoundingClientRect().height, ttis=getTopLeft(parent.document.getElementById('divinvis').getBoundingClientRect().width,parent.document.getElementById('divinvis').getBoundingClientRect().height," . deg2rad($rot) . "); parent.document.getElementById('divinvis').style.position='fixed'; parent.document.getElementById('divinvis').style.top='" . $yp . "%'; parent.document.getElementById('divinvis').style.left='" . $xp . "%'; if (1 == 4) { parent.document.getElementById('divinvis').style.transformOrigin='center center'; } var xxx='translate(' + eval(('' + ttis).split('.')[0]) + ',' + eval(('' + ttis).split('.')[1]) + ') '; if (1 == 1) { xxx=''; } parent.document.getElementById('divinvis').style.transform=xxx + ' rotate(" . $rot . "deg) ' + ''; parent.document.getElementById('divinvis').style.opacity='0.5'; } } </script></head><body style='width:100%;'><p>" . str_replace("\n","<br>",str_replace("$@!"," ",trim($outtext))) . "</p></body></html>";
} else {

echo "<html><head><title>Emoji-ize Text - RJM Programming - June, 2021</title><meta charset='UTF-8'></head><body style='width:100%;'><p>" . str_replace("\n","<br>",str_replace("$@!"," ",trim($outtext))) . "</p></body></html>";
}
exit;
}
}
}
}

?>

The changed PHP helper fillin_gaps_with_emojis.php to the live run link off the HTML and Javascript changed fillin_gaps_with_emojis.html code.


Previous relevant Text to Emoji Short Code Translation Textarea Sharing Tutorial is shown below.

Text to Emoji Short Code Translation Textarea Sharing Tutorial

Text to Emoji Short Code Translation Textarea Sharing Tutorial

The work of yesterday’s Short Code Personalized Emoji in Sector Game Tutorial had more implications than just for the game web application of the “discovery time” …

If you are a programmer dealing with emojis all the time, and therefore visiting websites like …

… on a regular basis you will probably have seen mention of Emoji “Short codes” of the form “:[short_code]:” (eg. :e-mail: or :grinning_face:) used by Github and Slack (and, we think, Facebook) which we want to get into today, as an idea for our players in our Emoji in Sector game be able to personalize their player names

The concept of emoji short codes gives us a foot in the door to English Phrase “emoji translation” albeit tiny phrases … still?! Do you remember the work of the reasonably recent Text to Emoji Translation Textarea Sharing Tutorial? Well, rather than …

  • “word by word” emoji translation principles (as used previously) … we can now offer …
  • emoji short code translation of recognised English Phrases (with one underscored emoji short code representing an emoji for those words of an English Phrase) … eg. “man running” or “disappointed face” … all the way back to single word short code translation “fall throughs” left (like above) …
    <?php

    if (file_exists('../PHP/short_codes/php')) {
    if ($intext != '') {
    $outtext=$intext;
    $outtxt=file_get_contents('../PHP/short_codes/php?intext=' . urlencode($intext));
    if (strpos($outtxt, '</body>') !== false) {
    $bod='<body' . explode('>', explode('<body', $outtxt)[1])[0] . '>';
    $outtext=str_replace('<p>', '', str_replace('</p>', '', explode($bod, explode('</body>', $outtxt)[0])[1]));
    if ($outtext != $intext) {
    echo "<html><head><title>Emoji-ize Text - RJM Programming - June, 2021</title><meta charset='UTF-8'></head><body style='width:100%;'><p>" . str_replace("\n","<br>",str_replace("$@!"," ",trim($outtext))) . "</p></body></html>";
    exit;
    }
    }
    }
    }

    ?>

… as a better paradigm (a tad more AI feeling) for the workings of the changed PHP helper fillin_gaps_with_emojis.php to the live run link we welcome you to (re-)try.


Previous relevant Text to Emoji Translation Textarea Sharing Tutorial is shown below.

Text to Emoji Translation Textarea Sharing Tutorial

Text to Emoji Translation Textarea Sharing Tutorial

The recent Text to Emoji Translation Textarea PHP Sort Tutorial got to “selfish point status”. Huh?! Well, that is the status with a web application that “creates” or “converts” or can be thought of as “useful” or being a “tool” but makes no “internal use” functionality to help with sharing your creativity with anybody else. Of course, any sharing is optional, but it’s good to include it in the logic, where possible, and with this particular web application it is “hugely possible” using four modes of sharing conduit into play …

  • email emoji-izing text via an inline HTML email form sent via PHP mail
  • email emoji-izing text via a downloadable HTML attachment sent via PHP mail
  • email emoji-izing text via a URL link in a client email via “a” “mailto:” link (that you can amend further at the client email application end)
  • SMS emoji-izing text via a URL link in a client email via “a” “sms:” link

… and the newly added “Email or SMS” input type=submit button added can be used in email emoji-izing text via an inline HTML email form sent via PHP mail so as, if required, to continue on with the chain of communication.

Interesting things we needed to do, and surprised us (some of which just constantly surprise me, but perhaps not you), were …

  • email emoji-izing text via an inline HTML email form sent via PHP mail …
    1. we needed to allow GET (only way inline HTML email forms work) logic (work the more widely distributed “name” attributes for input type=submit elements) …

      var intext=location.search.split('intext=')[1] ? decodeURIComponent(location.search.split('intext=')[1].split('&')[0]).replace(/\+/g,' ') : '';
      var emailsms=location.search.split('emailsms=')[1] ? decodeURIComponent(location.search.split('emailsms=')[1].split('&')[0]).replace(/\+/g,' ') : '';
      var myaltb=location.search.split('myaltb=')[1] ? decodeURIComponent(location.search.split('myaltb=')[1].split('&')[0]).replace(/\+/g,' ') : '';
  • email emoji-izing text via a downloadable HTML attachment sent via PHP mail …
    1. need for …
      <meta charset="UTF-8">
  • email emoji-izing text via a URL link in a client email via “a” “mailto:” link (that you can amend further at the client email application end) …
    1. no need for double encodeURIComponent usage (whereas SMS below does need) as per …

      function dummyencodeURIComponent(invl) {
      return invl;
      }

      ais.href='mailto:' + etois + '?subject=' + encodeURIComponent('My Emoji-izing Text') + '&body=' + encodeURIComponent('HTTPS://www.rjmprogramming.com.au/HTMLCSS/fillin_gaps_with_emojis.html?intext=' + dummyencodeURIComponent(encodeURIComponent(document.getElementById('intext').value)));
  • SMS emoji-izing text via a URL link in a client email via “a” “sms:” link …
    1. need for double encodeURIComponent usage as per …

      ais.href='sms:' + etois + '&body=' + encodeURIComponent('HTTPS://www.rjmprogramming.com.au/HTMLCSS/fillin_gaps_with_emojis.html?intext=' + encodeURIComponent(encodeURIComponent(document.getElementById('intext').value)));

And so the changed PHP helper fillin_gaps_with_emojis.php is ready for you to (re-)try at this live run link, where you can share your creativity.


Previous relevant Text to Emoji Translation Textarea PHP Sort Tutorial is shown below.

Text to Emoji Translation Textarea PHP Sort Tutorial

Text to Emoji Translation Textarea PHP Sort Tutorial

You can definitely benefit, as a programmer, with a sceptical outlook. The way we developed the recent Text to Emoji Translation Textarea Tutorial‘s web application was a case in point. It felt too simplistic by half, and so it panned out to be. But here again, revisits help. Trying things out, and honestly trying to break it. This “trying to break it” started out with us trying “face” and “smile” and combinations to no avail. No emoji description is that simple. But then we tried …


smile, Grinning Face with Sweat

… and that’s where we discovered the source of our unease. Before the fix it “Emoji-ized” this to …


smile, 😀 with Sweat

… whereas it would have been better to have “Emoji-ized” that to …


smile, 😅

So, where to fix this? It’s the PHP helper responsible. Could it be as simple as presenting the ~[Emoji]|[Text] array pairings in an order whereby the longer [Text] lengths appear first? So far, with our testing, it appears … “Yup”.

And so we involve PHP’s sort function, in context, in the changed PHP code below …


$ diff fillin_gaps_with_emojis.php-GETME fillin_gaps_with_emojis.php_GETME
31,44d30
< $emarrpre=explode($ea, $objphp);
< $objphp=$ea;
< $emarr=[];
< $emarrlens=[];
< for ($ib=0; $ib<sizeof($emarrpre); $ib++) {
< array_push($emarrlens, ('' . (99 - strlen($emarrpre[$ib]))) . $emarrpre[$ib]);
< }
< sort($emarrlens);
< for ($ib=0; $ib<sizeof($emarrlens); $ib++) {
< $objphp.=substr($emarrlens[$ib], 2) . '~'; //array_push($emarr, substr($emarrlens[$ib], 2));
< }
< $emarr=explode($endspan, $objphp);
< } else {
< $emarr=explode($endspan, $objphp);
45a32
> $emarr=explode($endspan, $objphp);

Have you noticed other types of “sort” functions in PHP? Why not use those? Well, when possible, we like to work with the “no frills” versions of language choices, rather than the obverse idea of “making the code less verbose”. We like to fit in with “what has always been there” we’d guess you’d say. And so that is where that codeline


array_push($emarrlens, ('' . (99 - strlen($emarrpre[$ib]))) . $emarrpre[$ib]);

… is turning a “numeric sorting concept” (the length of [Text]) into a set length character result (us hoping no [Text] is longer than 89).

No change to the parent HTML/Javascript code here for the changed PHP helper fillin_gaps_with_emojis.php ready for you to (re-)try at this live run link.


Previous relevant Text to Emoji Translation Textarea Tutorial is shown below.

Text to Emoji Translation Textarea Tutorial

Text to Emoji Translation Textarea Tutorial

Within the design of the web application behind yesterday’s Text to Emoji Translation Primer Tutorial it would have grated with many web purists that …

  • the data being textual (emojis are text) …
  • we entered “data” into a “textarea” element … no complaints … very suitable … but …
  • we translated into an “iframe” element … huh?!

Yes, this is not the best approach, we concur. And yet, it is not all bad. Let’s tabularize what we mean here (including macOS two finger gesture or Windows right click menu functionality possibilities), below …

Element type Description Pro Con
Textarea Repository of Text data ✔✔
Iframe Repository of Text data
Textarea Resizable
Iframe Resizable
Textarea Paragraph direction control
Iframe Paragraph direction control
Textarea Printing of Text data
Iframe Printing of Text data
Textarea Copy/paste of Text data
Iframe Copy/paste of Text data
Textarea New tab
Iframe New tab
Textarea New window
Iframe New window
Textarea Spelling and grammar check
Iframe Spelling and grammar check
Textarea Text to speech (macOS)
Iframe Text to speech (macOS)
Textarea Uppercase/lowercase (macOS)
Iframe Uppercase/lowercase (macOS)
Textarea Text services (macOS eg. iTunes Text to Speech recordings)
Iframe Text services (macOS eg. iTunes Text to Speech recordings)
Textarea Search engine lookup (macOS)
Iframe Search engine lookup (macOS)
Textarea Element source code
Iframe Element source code
Textarea Emoji specific title on non-mobile hover
Iframe Emoji specific title on non-mobile hover

And so, we allow for the old “Iframe” element approach to still be accessed, but turn the default workflow into a design whereby “Emoji-ize” textual results end up in a “Textarea” element for a changed parent HTML/Javascript fillin_gaps_with_emojis.html ready for you to (re-)try at this live run link.


Previous relevant Text to Emoji Translation Primer Tutorial is shown below.

Text to Emoji Translation Primer Tutorial

Text to Emoji Translation Primer Tutorial

We’re starting a new coding project, today, calling on the genius of Emojipedia for an …


Emoji-ize Text

… mangling of English … as well as an interesting substitutional feeling web tool.

Admittedly we started the day wondering about that “bluetooth icon” Spotify tutorial of recent times, wondering about how we could have improved the presentation via …

  • delayed iPhone photo technique … yes, but what if there was …
  • an emoji for that Bluetooth icon look a lot of us know by now

… and looking into that second idea was surprised that the Bluetooth icon, let alone emojis for concepts like WiFi or “Power On” (ie. concepts, by and large, we guess) will either never become emojis or will be slow to get to becoming an emoji. More, emojis suit our real object nouns in our languages, and so we wanted to write a substitutional web application to see whether my theorizing carries any weight.

The user enters into a textarea element their text of interest, then they click/touch a button, and this HTML/Javascript fillin_gaps_with_emojis.html parent asks of the called PHP fillin_gaps_with_emojis.php

Simple idea you might be interested in trying, in a new window, or below …

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.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , | Leave a comment