Chess Game Practice Castling Tutorial

Chess Game Practice Castling Tutorial

Chess Game Practice Castling Tutorial

Maybe in mathematics, in school, you discussed limits (and/or perhaps even “proof by contradiction” and/or “paradoxes”). You know, those fancy ways of saying if “such and such” you never finish the race, such as in “Achilles and the Tortoise”

Achilles and the tortoise

Achilles and the tortoise
In a race, the quickest runner can never over­take the slowest, since the pursuer must first reach the point whence the pursued started, so that the slower must always hold a lead.

— as recounted by Aristotle, Physics VI:9, 239b15
In the paradox of Achilles and the tortoise, Achilles is in a footrace with the tortoise. Achilles allows the tortoise a head start of 100 meters, for example. Suppose that each racer starts running at some constant speed, one faster than the other. After some finite time, Achilles will have run 100 meters, bringing him to the tortoise’s starting point. During this time, the tortoise has run a much shorter distance, say 2 meters. It will then take Achilles some further time to run that distance, by which time the tortoise will have advanced farther; and then more time still to reach this third point, while the tortoise moves ahead. Thus, whenever Achilles arrives somewhere the tortoise has been, he still has some distance to go before he can even reach the tortoise. As Aristotle noted, this argument is similar to the Dichotomy.[14] It lacks, however, the apparent conclusion of motionlessness.

Beware the project that runs the same way, by worrying too much about the one percenters. On the other side of the ledger though, is that you learn far less when not trying to tackle any of those one percenters. With these thoughts swirling around we undertook the first of the “doozies” (amidst a lot of swearing and “what have we gotten ourselves into here” thoughts) referenced in yesterday’s Chess Game Practice Basic Moves Tutorial


Castling (between a Rook and a King with a lot of provisos)

We learnt things about the interface between “drag events” and events like “onmouseover”, the latter of which we needed to resort to, alas. If you didn’t, life would be much easier, and try to design the initial premise, perhaps, better, so that those two wooooorrrrlllldddsss never have to meet (and just image the in-law get togethers!).

We learnt, again, that DOM methodology can come undone when there is no time gap between element arrangements that rely on a previous Javascript DOM arranged task. Take a look at our setInterval Javascript function setup to help here …


var domcmds=[];


function dodoms() {
var stopit=false;
# Irrelevant to blurb above ...
if (document.getElementById('span4') && fouroh == '') { fouroh=document.getElementById('span4').outerHTML; }
if (document.getElementById('span5') && wsixoh == '') { wsixoh=document.getElementById('span5').outerHTML; }
if (document.getElementById('span6') && sixoh == '') { sixoh=document.getElementById('span6').outerHTML; }
if (document.getElementById('span0') && spanzero == '') { spanzero=document.getElementById('span0').outerHTML; }
if (document.getElementById('span1') && spanfive == '') { spanfive=document.getElementById('span1').outerHTML; }
if (document.getElementById('td22') && tdtte == '') { tdtte=document.getElementById('td22').outerHTML.split('>')[0] + '></td>'; }
if (document.getElementById('td211') && wtdtte == '') { wtdtte=document.getElementById('td211').outerHTML.split('>')[0] + '></td>'; }
if (document.getElementById('td193') && wwtdtte == '') { wwtdtte=document.getElementById('td193').outerHTML.split('>')[0] + '></td>'; }
if (document.getElementById('td11') && wwwtdtte == '') { wwwtdtte=document.getElementById('td11').outerHTML.split('>')[0] + '></td>'; }

# Relevant below ...
for (var ikj=0; ikj<domcmds.length; ikj++) {
if (!stopit && domcmds[ikj] != '') {
stopit=true;
//if (prompt(domcmds[ikj], domcmds[ikj])) {
eval(domcmds[ikj]);
//}
domcmds[ikj]='';
}
}
//domcmds=[];
}

… called into play via “one only” call …


setInterval(dodoms, 1000);

… and given DOM (but doesn’t have to be) jobs to do via Javascript commands, such as a few examples from our “Castling” code …


domcmds.push("document.getElementById('td202').innerHTML='" + wsixoh + "'; ");
domcmds.push("document.getElementById('td203').innerHTML='" + spanfive + "'; ");
domcmds.push("document.getElementById('tr8').innerHTML='" + wwtdtte + "' + document.getElementById('tr8').innerHTML; itisthiscmove='b'; adddrop('" + lohoh.split(' id="')[1].split('"')[0] + "'); ");

… the Javascript DOM actions of which would have a one second gap between each domcmds[] array member “call to action”.

Again, why not try the changed experimental_drag_and_drop.htm HTML and Javascript and CSS assisted “fourth draft” chess_game.php Chess Practice Game for you to better practice your Chess …


Previous relevant Chess Game Practice Basic Moves Tutorial is shown below.

Chess Game Practice Basic Moves Tutorial

Chess Game Practice Basic Moves Tutorial

Adding onto yesterday’s Chess Game Practice Layout Tutorial‘s basis for a more formal Chess game, today we feel like we’re in the calm …


Coding for the basic pawn and knight and bishop and rook and queen and king chess piece moving rules

… before the storm, into the future, coding for …

  • castling
  • knowing when your King is in check or somebody has put your King in check
  • knowing when an illegal move has happened regarding leaving your own King in check
  • knowing when it’s Checkmate (or perhaps even Stalemate)

… in the category of “doozy”.

So, why not try the changed experimental_drag_and_drop.htm HTML and Javascript and CSS assisted “third draft” chess_game.php Chess Practice Game for you to better practice your Chess …


Previous relevant Chess Game Practice Layout Tutorial is shown below.

Chess Game Practice Layout Tutorial

Chess Game Practice Layout Tutorial

Onto yesterday’s Chess Game Practice Tutorial‘s Chess Game Practice web application, today, we’ve developed further, in a “layout” sense, to allow for …

  • practice via Drag and Drop from the top emojis into your select Chess Board game positions … (no news there) … and, today …
  • initiate the Chess Board for a traditional game of Chess between black and white players … and …
  • weird layout of Chess Board where pieces are placed randomly and nonsensically

… but no piece move logic yet! That is for tomorrow, but this “layout” logic helped us get to a better piece identification set of protocols to work with. So, try the changed experimental_drag_and_drop.htm HTML and Javascript and CSS assisted “second draft” chess_game.php Chess Practice Game for you to … practice (after choosing a layout) …


Previous relevant Chess Game Practice Tutorial is shown below.

Chess Game Practice Tutorial

Chess Game Practice Tutorial

Further to the recent Sentence Shuffle Game Tutorial‘s concepts regarding …

  • Drag and Drop
  • emojis
  • pseudo sentences (ie. the chess pieces)

… we present our start to our Chess web application, we’re calling “Chess Game Practice” for now because it will take some time. In today’s first draft …

  • we assemble the chess pieces in a line (like an emoji sentence) up the top …
  • draggable … onto …
  • a black and white squared chess board … our “Drop Zone”

… and the chess pieces can be dragged around the board as well, but no checks on legal or illegal moves yet, nor the default starting positions to a game. Anyway, a changed experimental_drag_and_drop.htm HTML and Javascript and CSS underpins a calling “first draft” chess_game.php Chess Practice Game for you to … practice …

Did you know?

A little esoteric, we know, but research (thanks to this useful link) got us to (finally) discover the Clayton’s emoji. In other words, an emoji taking no (or little to no) screen display space but differentiates one emoji representation from another when you want to just differentiate via “innerHTML” content, for HTML elements. It’s (the “nobreak”) …



You missed it?! Try …


&#8288;

Why, regarding chess, are we interested? It means regarding the two black rooks, for example, adding a &#8288; to its display contents makes little difference, but we can hone in on an exact black rook, “innerHTML” wise, in the code.


Previous relevant Sentence Shuffle Game Tutorial is shown below.

Sentence Shuffle Game Tutorial

Sentence Shuffle Game Tutorial

More genericization onto yesterday’s Numbers Guessing Game Tutorial‘s …

  • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
  • allow the number of cells across in a column not be 3

… has us considering making the dragee be made up of more than one part, today, continuing on with our Drag and Drop functionalities of recent times.

The first game type of application of this, we sort of stumbled upon, trying it, is to create a …


Sentence Shuffle game

(good for ESL perhaps) where a sentence’s words are shuffled and the user “gets satisfaction” (euphemism for “we’re not keeping score”) from piecing a sentence back together again. Arguments for this involve …

Get ? or & argument label Use
sourcenum Count of words in sentence or less than or equal to 0 for web application to count them
shuffle Any mention causes sentence word shuffling to occur … game on!
yourblurb Optionally define your own sentence

… for our changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

Did you know?

We wanted to improve functionality, by changing our usual “-” hardcoding to a link “+” idea whereby the user can enter in their own “yourblurb” sentence, as above. It being collected in a Javascript prompt popup window, the user can enter emojis (via control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control=space for iOS, top left + for Android keyboard) as part of the sentence mix, the only rule being a space character separates words in a sentence with our further changed experimental_drag_and_drop.htm HTML and Javascript and CSS sentence shuffle game web application.

And then we thought we should also allow for a Pictogram Puzzle scenario (where every picture is worth a thousand words, they say) with our furtherer changed experimental_drag_and_drop.htm HTML and Javascript and CSS sentence image shuffle game web application (thanks to https://www.puzzles-on-line-niche.com)


Previous relevant Numbers Guessing Game Tutorial is shown below.

Numbers Guessing Game Tutorial

Numbers Guessing Game Tutorial

We’ve been working on aspects to the genericity of the table that is …

The Drop Zone

… do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

  • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
  • allow the number of cells across in a column not be 3

… in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

Stop Press

On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


var lastbco=null;

const target = document.querySelector("#target");
target.addEventListener("dragover", (ev) => {
if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
ev.preventDefault();
if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
//document.getElementById(sourceid).style.opacity='0.6';
lastbco=ev.target;
ev.target.style.backgroundColor='pink';
if (document.getElementById('mybut')) {
if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
} else {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
}
}
}

//document.getElementById(sourceid).style.cursor='progress';
//ev.target.style.cursor='progress';
//ev.target.dataTransfer.dropEffect = 'progress';

});


Previous relevant Planet Moon Game Tutorial is shown below.

Planet Moon Game Tutorial

Planet Moon Game Tutorial

Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

<?php

$templategame=file_get_contents('./experimental_drag_and_drop.htm');

?>

… and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

  • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
  • simply …
    <?php

    echo $templategame;

    ?>
    … outputs a webpage …
  • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

… in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

Stop Press

We fully concur with any adage that goes …

You learn most from your mistakes

… just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


Hanging issues mostly team up with code within a loop

The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

<?php

$goodlist=',Mercury,Venus,';
$badlist=',Mercury,Venus,';


while (strlen($goodlist) == strlen($badlist)) {
$goodlist=',Mercury,Venus,';

$badlist=',Mercury,Venus,';

$correctans=rand(0,8);
$sofar=';';
for ($i=0; $i<9; $i++) {
$j=rand(0, (-1 + sizeof($wikidesignations)));
if ($crandlist == '') {
$crandlist='' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
} else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
$j=rand(0, (-1 + sizeof($wikidesignations)));
}
$crandlist.=',' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
} else {
if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
$crandlist.=',' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
}
}
}

?>


Previous relevant Enneagram Type Game Tutorial is shown below.

Australian Street Type Game Tutorial

Enneagram Type Game Tutorial

A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

Enneagram Types

… of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

It being a topic …

  1. beyond our ken
  2. outside our usual subject matter

… you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


nine types of

… search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


nine types of enneagram

… to flesh out a family of “game interest”, we hope?!

Our first draft PHP game is also playable below …


Previous relevant Australian Street Type Game Tutorial is shown below.

Australian Street Type Game Tutorial

Australian Street Type Game Tutorial

The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

you are not alone

Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

Our first draft PHP game is also playable below …


Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

Experimental Drag and Drop Game Tutorial

Experimental Drag and Drop Game Tutorial

It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

Drop Zone

Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

Yes

… is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

Experimental Drag and Drop Primer Tutorial

Experimental Drag and Drop Primer Tutorial

We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

… but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

… to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

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, Games, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Chess Game Practice Basic Moves Tutorial

Chess Game Practice Basic Moves Tutorial

Chess Game Practice Basic Moves Tutorial

Adding onto yesterday’s Chess Game Practice Layout Tutorial‘s basis for a more formal Chess game, today we feel like we’re in the calm …


Coding for the basic pawn and knight and bishop and rook and queen and king chess piece moving rules

… before the storm, into the future, coding for …

  • castling
  • knowing when your King is in check or somebody has put your King in check
  • knowing when an illegal move has happened regarding leaving your own King in check
  • knowing when it’s Checkmate (or perhaps even Stalemate)

… in the category of “doozy”.

So, why not try the changed experimental_drag_and_drop.htm HTML and Javascript and CSS assisted “third draft” chess_game.php Chess Practice Game for you to better practice your Chess …


Previous relevant Chess Game Practice Layout Tutorial is shown below.

Chess Game Practice Layout Tutorial

Chess Game Practice Layout Tutorial

Onto yesterday’s Chess Game Practice Tutorial‘s Chess Game Practice web application, today, we’ve developed further, in a “layout” sense, to allow for …

  • practice via Drag and Drop from the top emojis into your select Chess Board game positions … (no news there) … and, today …
  • initiate the Chess Board for a traditional game of Chess between black and white players … and …
  • weird layout of Chess Board where pieces are placed randomly and nonsensically

… but no piece move logic yet! That is for tomorrow, but this “layout” logic helped us get to a better piece identification set of protocols to work with. So, try the changed experimental_drag_and_drop.htm HTML and Javascript and CSS assisted “second draft” chess_game.php Chess Practice Game for you to … practice (after choosing a layout) …


Previous relevant Chess Game Practice Tutorial is shown below.

Chess Game Practice Tutorial

Chess Game Practice Tutorial

Further to the recent Sentence Shuffle Game Tutorial‘s concepts regarding …

  • Drag and Drop
  • emojis
  • pseudo sentences (ie. the chess pieces)

… we present our start to our Chess web application, we’re calling “Chess Game Practice” for now because it will take some time. In today’s first draft …

  • we assemble the chess pieces in a line (like an emoji sentence) up the top …
  • draggable … onto …
  • a black and white squared chess board … our “Drop Zone”

… and the chess pieces can be dragged around the board as well, but no checks on legal or illegal moves yet, nor the default starting positions to a game. Anyway, a changed experimental_drag_and_drop.htm HTML and Javascript and CSS underpins a calling “first draft” chess_game.php Chess Practice Game for you to … practice …

Did you know?

A little esoteric, we know, but research (thanks to this useful link) got us to (finally) discover the Clayton’s emoji. In other words, an emoji taking no (or little to no) screen display space but differentiates one emoji representation from another when you want to just differentiate via “innerHTML” content, for HTML elements. It’s (the “nobreak”) …



You missed it?! Try …


&#8288;

Why, regarding chess, are we interested? It means regarding the two black rooks, for example, adding a &#8288; to its display contents makes little difference, but we can hone in on an exact black rook, “innerHTML” wise, in the code.


Previous relevant Sentence Shuffle Game Tutorial is shown below.

Sentence Shuffle Game Tutorial

Sentence Shuffle Game Tutorial

More genericization onto yesterday’s Numbers Guessing Game Tutorial‘s …

  • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
  • allow the number of cells across in a column not be 3

… has us considering making the dragee be made up of more than one part, today, continuing on with our Drag and Drop functionalities of recent times.

The first game type of application of this, we sort of stumbled upon, trying it, is to create a …


Sentence Shuffle game

(good for ESL perhaps) where a sentence’s words are shuffled and the user “gets satisfaction” (euphemism for “we’re not keeping score”) from piecing a sentence back together again. Arguments for this involve …

Get ? or & argument label Use
sourcenum Count of words in sentence or less than or equal to 0 for web application to count them
shuffle Any mention causes sentence word shuffling to occur … game on!
yourblurb Optionally define your own sentence

… for our changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

Did you know?

We wanted to improve functionality, by changing our usual “-” hardcoding to a link “+” idea whereby the user can enter in their own “yourblurb” sentence, as above. It being collected in a Javascript prompt popup window, the user can enter emojis (via control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control=space for iOS, top left + for Android keyboard) as part of the sentence mix, the only rule being a space character separates words in a sentence with our further changed experimental_drag_and_drop.htm HTML and Javascript and CSS sentence shuffle game web application.

And then we thought we should also allow for a Pictogram Puzzle scenario (where every picture is worth a thousand words, they say) with our furtherer changed experimental_drag_and_drop.htm HTML and Javascript and CSS sentence image shuffle game web application (thanks to https://www.puzzles-on-line-niche.com)


Previous relevant Numbers Guessing Game Tutorial is shown below.

Numbers Guessing Game Tutorial

Numbers Guessing Game Tutorial

We’ve been working on aspects to the genericity of the table that is …

The Drop Zone

… do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

  • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
  • allow the number of cells across in a column not be 3

… in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

Stop Press

On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


var lastbco=null;

const target = document.querySelector("#target");
target.addEventListener("dragover", (ev) => {
if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
ev.preventDefault();
if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
//document.getElementById(sourceid).style.opacity='0.6';
lastbco=ev.target;
ev.target.style.backgroundColor='pink';
if (document.getElementById('mybut')) {
if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
} else {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
}
}
}

//document.getElementById(sourceid).style.cursor='progress';
//ev.target.style.cursor='progress';
//ev.target.dataTransfer.dropEffect = 'progress';

});


Previous relevant Planet Moon Game Tutorial is shown below.

Planet Moon Game Tutorial

Planet Moon Game Tutorial

Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

<?php

$templategame=file_get_contents('./experimental_drag_and_drop.htm');

?>

… and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

  • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
  • simply …
    <?php

    echo $templategame;

    ?>
    … outputs a webpage …
  • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

… in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

Stop Press

We fully concur with any adage that goes …

You learn most from your mistakes

… just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


Hanging issues mostly team up with code within a loop

The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

<?php

$goodlist=',Mercury,Venus,';
$badlist=',Mercury,Venus,';


while (strlen($goodlist) == strlen($badlist)) {
$goodlist=',Mercury,Venus,';

$badlist=',Mercury,Venus,';

$correctans=rand(0,8);
$sofar=';';
for ($i=0; $i<9; $i++) {
$j=rand(0, (-1 + sizeof($wikidesignations)));
if ($crandlist == '') {
$crandlist='' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
} else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
$j=rand(0, (-1 + sizeof($wikidesignations)));
}
$crandlist.=',' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
} else {
if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
$crandlist.=',' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
}
}
}

?>


Previous relevant Enneagram Type Game Tutorial is shown below.

Australian Street Type Game Tutorial

Enneagram Type Game Tutorial

A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

Enneagram Types

… of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

It being a topic …

  1. beyond our ken
  2. outside our usual subject matter

… you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


nine types of

… search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


nine types of enneagram

… to flesh out a family of “game interest”, we hope?!

Our first draft PHP game is also playable below …


Previous relevant Australian Street Type Game Tutorial is shown below.

Australian Street Type Game Tutorial

Australian Street Type Game Tutorial

The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

you are not alone

Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

Our first draft PHP game is also playable below …


Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

Experimental Drag and Drop Game Tutorial

Experimental Drag and Drop Game Tutorial

It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

Drop Zone

Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

Yes

… is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

Experimental Drag and Drop Primer Tutorial

Experimental Drag and Drop Primer Tutorial

We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

… but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

… to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

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, Games, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Chess Game Practice Layout Tutorial

Chess Game Practice Layout Tutorial

Chess Game Practice Layout Tutorial

Onto yesterday’s Chess Game Practice Tutorial‘s Chess Game Practice web application, today, we’ve developed further, in a “layout” sense, to allow for …

  • practice via Drag and Drop from the top emojis into your select Chess Board game positions … (no news there) … and, today …
  • initiate the Chess Board for a traditional game of Chess between black and white players … and …
  • weird layout of Chess Board where pieces are placed randomly and nonsensically

… but no piece move logic yet! That is for tomorrow, but this “layout” logic helped us get to a better piece identification set of protocols to work with. So, try the changed experimental_drag_and_drop.htm HTML and Javascript and CSS assisted “second draft” chess_game.php Chess Practice Game for you to … practice (after choosing a layout) …


Previous relevant Chess Game Practice Tutorial is shown below.

Chess Game Practice Tutorial

Chess Game Practice Tutorial

Further to the recent Sentence Shuffle Game Tutorial‘s concepts regarding …

  • Drag and Drop
  • emojis
  • pseudo sentences (ie. the chess pieces)

… we present our start to our Chess web application, we’re calling “Chess Game Practice” for now because it will take some time. In today’s first draft …

  • we assemble the chess pieces in a line (like an emoji sentence) up the top …
  • draggable … onto …
  • a black and white squared chess board … our “Drop Zone”

… and the chess pieces can be dragged around the board as well, but no checks on legal or illegal moves yet, nor the default starting positions to a game. Anyway, a changed experimental_drag_and_drop.htm HTML and Javascript and CSS underpins a calling “first draft” chess_game.php Chess Practice Game for you to … practice …

Did you know?

A little esoteric, we know, but research (thanks to this useful link) got us to (finally) discover the Clayton’s emoji. In other words, an emoji taking no (or little to no) screen display space but differentiates one emoji representation from another when you want to just differentiate via “innerHTML” content, for HTML elements. It’s (the “nobreak”) …



You missed it?! Try …


&#8288;

Why, regarding chess, are we interested? It means regarding the two black rooks, for example, adding a &#8288; to its display contents makes little difference, but we can hone in on an exact black rook, “innerHTML” wise, in the code.


Previous relevant Sentence Shuffle Game Tutorial is shown below.

Sentence Shuffle Game Tutorial

Sentence Shuffle Game Tutorial

More genericization onto yesterday’s Numbers Guessing Game Tutorial‘s …

  • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
  • allow the number of cells across in a column not be 3

… has us considering making the dragee be made up of more than one part, today, continuing on with our Drag and Drop functionalities of recent times.

The first game type of application of this, we sort of stumbled upon, trying it, is to create a …


Sentence Shuffle game

(good for ESL perhaps) where a sentence’s words are shuffled and the user “gets satisfaction” (euphemism for “we’re not keeping score”) from piecing a sentence back together again. Arguments for this involve …

Get ? or & argument label Use
sourcenum Count of words in sentence or less than or equal to 0 for web application to count them
shuffle Any mention causes sentence word shuffling to occur … game on!
yourblurb Optionally define your own sentence

… for our changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

Did you know?

We wanted to improve functionality, by changing our usual “-” hardcoding to a link “+” idea whereby the user can enter in their own “yourblurb” sentence, as above. It being collected in a Javascript prompt popup window, the user can enter emojis (via control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control=space for iOS, top left + for Android keyboard) as part of the sentence mix, the only rule being a space character separates words in a sentence with our further changed experimental_drag_and_drop.htm HTML and Javascript and CSS sentence shuffle game web application.

And then we thought we should also allow for a Pictogram Puzzle scenario (where every picture is worth a thousand words, they say) with our furtherer changed experimental_drag_and_drop.htm HTML and Javascript and CSS sentence image shuffle game web application (thanks to https://www.puzzles-on-line-niche.com)


Previous relevant Numbers Guessing Game Tutorial is shown below.

Numbers Guessing Game Tutorial

Numbers Guessing Game Tutorial

We’ve been working on aspects to the genericity of the table that is …

The Drop Zone

… do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

  • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
  • allow the number of cells across in a column not be 3

… in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

Stop Press

On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


var lastbco=null;

const target = document.querySelector("#target");
target.addEventListener("dragover", (ev) => {
if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
ev.preventDefault();
if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
//document.getElementById(sourceid).style.opacity='0.6';
lastbco=ev.target;
ev.target.style.backgroundColor='pink';
if (document.getElementById('mybut')) {
if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
} else {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
}
}
}

//document.getElementById(sourceid).style.cursor='progress';
//ev.target.style.cursor='progress';
//ev.target.dataTransfer.dropEffect = 'progress';

});


Previous relevant Planet Moon Game Tutorial is shown below.

Planet Moon Game Tutorial

Planet Moon Game Tutorial

Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

<?php

$templategame=file_get_contents('./experimental_drag_and_drop.htm');

?>

… and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

  • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
  • simply …
    <?php

    echo $templategame;

    ?>
    … outputs a webpage …
  • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

… in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

Stop Press

We fully concur with any adage that goes …

You learn most from your mistakes

… just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


Hanging issues mostly team up with code within a loop

The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

<?php

$goodlist=',Mercury,Venus,';
$badlist=',Mercury,Venus,';


while (strlen($goodlist) == strlen($badlist)) {
$goodlist=',Mercury,Venus,';

$badlist=',Mercury,Venus,';

$correctans=rand(0,8);
$sofar=';';
for ($i=0; $i<9; $i++) {
$j=rand(0, (-1 + sizeof($wikidesignations)));
if ($crandlist == '') {
$crandlist='' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
} else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
$j=rand(0, (-1 + sizeof($wikidesignations)));
}
$crandlist.=',' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
} else {
if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
$crandlist.=',' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
}
}
}

?>


Previous relevant Enneagram Type Game Tutorial is shown below.

Australian Street Type Game Tutorial

Enneagram Type Game Tutorial

A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

Enneagram Types

… of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

It being a topic …

  1. beyond our ken
  2. outside our usual subject matter

… you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


nine types of

… search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


nine types of enneagram

… to flesh out a family of “game interest”, we hope?!

Our first draft PHP game is also playable below …


Previous relevant Australian Street Type Game Tutorial is shown below.

Australian Street Type Game Tutorial

Australian Street Type Game Tutorial

The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

you are not alone

Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

Our first draft PHP game is also playable below …


Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

Experimental Drag and Drop Game Tutorial

Experimental Drag and Drop Game Tutorial

It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

Drop Zone

Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

Yes

… is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

Experimental Drag and Drop Primer Tutorial

Experimental Drag and Drop Primer Tutorial

We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

… but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

… to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

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

Chess Game Practice Tutorial

Chess Game Practice Tutorial

Chess Game Practice Tutorial

Further to the recent Sentence Shuffle Game Tutorial‘s concepts regarding …

  • Drag and Drop
  • emojis
  • pseudo sentences (ie. the chess pieces)

… we present our start to our Chess web application, we’re calling “Chess Game Practice” for now because it will take some time. In today’s first draft …

  • we assemble the chess pieces in a line (like an emoji sentence) up the top …
  • draggable … onto …
  • a black and white squared chess board … our “Drop Zone”

… and the chess pieces can be dragged around the board as well, but no checks on legal or illegal moves yet, nor the default starting positions to a game. Anyway, a changed experimental_drag_and_drop.htm HTML and Javascript and CSS underpins a calling “first draft” chess_game.php Chess Practice Game for you to … practice …

Did you know?

A little esoteric, we know, but research (thanks to this useful link) got us to (finally) discover the Clayton’s emoji. In other words, an emoji taking no (or little to no) screen display space but differentiates one emoji representation from another when you want to just differentiate via “innerHTML” content, for HTML elements. It’s (the “nobreak”) …



You missed it?! Try …


&#8288;

Why, regarding chess, are we interested? It means regarding the two black rooks, for example, adding a &#8288; to its display contents makes little difference, but we can hone in on an exact black rook, “innerHTML” wise, in the code.


Previous relevant Sentence Shuffle Game Tutorial is shown below.

Sentence Shuffle Game Tutorial

Sentence Shuffle Game Tutorial

More genericization onto yesterday’s Numbers Guessing Game Tutorial‘s …

  • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
  • allow the number of cells across in a column not be 3

… has us considering making the dragee be made up of more than one part, today, continuing on with our Drag and Drop functionalities of recent times.

The first game type of application of this, we sort of stumbled upon, trying it, is to create a …


Sentence Shuffle game

(good for ESL perhaps) where a sentence’s words are shuffled and the user “gets satisfaction” (euphemism for “we’re not keeping score”) from piecing a sentence back together again. Arguments for this involve …

Get ? or & argument label Use
sourcenum Count of words in sentence or less than or equal to 0 for web application to count them
shuffle Any mention causes sentence word shuffling to occur … game on!
yourblurb Optionally define your own sentence

… for our changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

Did you know?

We wanted to improve functionality, by changing our usual “-” hardcoding to a link “+” idea whereby the user can enter in their own “yourblurb” sentence, as above. It being collected in a Javascript prompt popup window, the user can enter emojis (via control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control=space for iOS, top left + for Android keyboard) as part of the sentence mix, the only rule being a space character separates words in a sentence with our further changed experimental_drag_and_drop.htm HTML and Javascript and CSS sentence shuffle game web application.

And then we thought we should also allow for a Pictogram Puzzle scenario (where every picture is worth a thousand words, they say) with our furtherer changed experimental_drag_and_drop.htm HTML and Javascript and CSS sentence image shuffle game web application (thanks to https://www.puzzles-on-line-niche.com)


Previous relevant Numbers Guessing Game Tutorial is shown below.

Numbers Guessing Game Tutorial

Numbers Guessing Game Tutorial

We’ve been working on aspects to the genericity of the table that is …

The Drop Zone

… do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

  • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
  • allow the number of cells across in a column not be 3

… in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

Stop Press

On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


var lastbco=null;

const target = document.querySelector("#target");
target.addEventListener("dragover", (ev) => {
if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
ev.preventDefault();
if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
//document.getElementById(sourceid).style.opacity='0.6';
lastbco=ev.target;
ev.target.style.backgroundColor='pink';
if (document.getElementById('mybut')) {
if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
} else {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
}
}
}

//document.getElementById(sourceid).style.cursor='progress';
//ev.target.style.cursor='progress';
//ev.target.dataTransfer.dropEffect = 'progress';

});


Previous relevant Planet Moon Game Tutorial is shown below.

Planet Moon Game Tutorial

Planet Moon Game Tutorial

Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

<?php

$templategame=file_get_contents('./experimental_drag_and_drop.htm');

?>

… and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

  • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
  • simply …
    <?php

    echo $templategame;

    ?>
    … outputs a webpage …
  • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

… in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

Stop Press

We fully concur with any adage that goes …

You learn most from your mistakes

… just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


Hanging issues mostly team up with code within a loop

The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

<?php

$goodlist=',Mercury,Venus,';
$badlist=',Mercury,Venus,';


while (strlen($goodlist) == strlen($badlist)) {
$goodlist=',Mercury,Venus,';

$badlist=',Mercury,Venus,';

$correctans=rand(0,8);
$sofar=';';
for ($i=0; $i<9; $i++) {
$j=rand(0, (-1 + sizeof($wikidesignations)));
if ($crandlist == '') {
$crandlist='' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
} else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
$j=rand(0, (-1 + sizeof($wikidesignations)));
}
$crandlist.=',' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
} else {
if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
$crandlist.=',' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
}
}
}

?>


Previous relevant Enneagram Type Game Tutorial is shown below.

Australian Street Type Game Tutorial

Enneagram Type Game Tutorial

A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

Enneagram Types

… of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

It being a topic …

  1. beyond our ken
  2. outside our usual subject matter

… you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


nine types of

… search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


nine types of enneagram

… to flesh out a family of “game interest”, we hope?!

Our first draft PHP game is also playable below …


Previous relevant Australian Street Type Game Tutorial is shown below.

Australian Street Type Game Tutorial

Australian Street Type Game Tutorial

The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

you are not alone

Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

Our first draft PHP game is also playable below …


Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

Experimental Drag and Drop Game Tutorial

Experimental Drag and Drop Game Tutorial

It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

Drop Zone

Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

Yes

… is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

Experimental Drag and Drop Primer Tutorial

Experimental Drag and Drop Primer Tutorial

We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

… but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

… to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

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

Canvas via Image Web Share API Photo Postcard Tutorial

Canvas via Image Web Share API Photo Postcard Tutorial

Canvas via Image Web Share API Photo Postcard Tutorial

We discovered, further to yesterday’s Canvas via Image Web Share API Personalization Tutorial, out and about, with an iPhone, that …

Image Input Mode Image Sizing Modus Operandi
URL Actual (canvas resized to image)
Contain (canvas)
Cover (canvas)
Browsing Actual (canvas resized to image)
Contain (canvas)
Cover (canvas)

… of Images to Canvas No Clicking Form Signature Tutorial times was worth refocussing on, regarding the combination of …

  • Browsing … Contain (canvas) … option above … and …
  • Take Photo … mobile device option … which, if followed through on, is more than likely to leave …
  • On the right hand side of the canvas there will be white space suitable to scribble a message to complete your …
  • Postcard … which you can optionally …
  • Share

… and if you are using the https: protocol with the Safari and Google Chrome web browser(s), we can help out more with that last step, being able to make a sharing button show the word “Postcard” …


function checkonyellow() {
var ibuta=[], jbuta=0;
if (safariblurb != '') {
if (document.getElementById('shareurl')) {
if (document.getElementById('shareurl').outerHTML.indexOf('yellow') != -1) {
ibuta=document.getElementsByTagName('input');
for (jbuta=0; jbuta<ibuta.length; jbuta++) {
if (('' + ibuta[jbuta].value) == 'Share URL Link') {
ibuta[jbuta].value='Postcard';
ibuta[jbuta].style.backgroundColor='cyan';
}
}
} else {
setTimeout(checkonyellow, 3000);
}
} else if (parent.document.getElementById('shareurl')) {
if (parent.document.getElementById('shareurl').outerHTML.indexOf('yellow') != -1) {
ibuta=parent.document.getElementsByTagName('input');
for (jbuta=0; jbuta<ibuta.length; jbuta++) {
if (('' + ibuta[jbuta].value) == 'Share URL Link') {
ibuta[jbuta].value='Postcard';
ibuta[jbuta].style.backgroundColor='cyan';
}
}
} else {
setTimeout(checkonyellow, 3000);
}
} else if (top.document.getElementById('shareurl')) {
if (top.document.getElementById('shareurl').outerHTML.indexOf('yellow') != -1) {
ibuta=top.document.getElementsByTagName('input');
for (jbuta=0; jbuta<ibuta.length; jbuta++) {
if (('' + ibuta[jbuta].value) == 'Share URL Link') {
ibuta[jbuta].value='Postcard';
ibuta[jbuta].style.backgroundColor='cyan';
}
}
} else {
setTimeout(checkonyellow, 3000);
}
}
}
}

… to make the procedure …

Postcard via smart device Camera advice …

1. Touch browsing Choose File button that has just appeared.
2. Choose to Take Photo.
3. Consider any zooming in or selfie modes of use in Photo mode.
4. Take photo with Camera app white button, choosing Use Photo or Retake, as required.
5. Scribble any optional messaging in white area to right, or use other discreet touch functionalities.
6. Optionally email off to recipient (as textbox below goes yellow, click email sender button to its left for easier usage).

… more obvious, via the changed external Javascript signature_signature.js code used by our signature use in canvas supervisory web application.


Previous relevant Canvas via Image Web Share API Personalization Tutorial is shown below.

Canvas via Image Web Share API Tutorial

Canvas via Image Web Share API Personalization Tutorial

Yesterday’s Canvas via Imge Web Share API Tutorial‘s Web Share API (so far, on Safari and Google Chrome web browser(s)) image (via canvas) sharing functionality did not have enough privacy for the user, as far as we were concerned. We’re not going in for some two factor authentication level of privacy here, and so we’ve opted for the use of the word “Personalization” in today’s blog posting title.

What we’ve done here is incorporate into the image name (a form of) the IP address of the sender of the image, which the receiver is using (for that extra privacy) as they click the email link, that now involves (a form of) this IP address in its formation.

No surprises here, that we’d have to involve our changed PHP helper signature_signature.php “specialist signature PHP helper” more, getting this solution together.

And no surprises here, that we’d try to involve the web server’s disk areas outside the scope of its (Apache) Document Root hierarchy. That step, alone, is important to force a curious user, to work their way through an inhouse PHP webpage URL of some sort, in order to extract that …

  • image data in the form of a web server file … to a …
  • public domain webpage image in an HTML img tag where its src attribute is populated via that web server file’s equivalent base64 data URI …
    <?php

    echo "<html><body><img title='" . $thename . '' . "' src='data:image/webp;base64," . base64_encode(file_get_contents(DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . $thename . '')) . "'></img>" . $therest . "</body></html>";

    ?>

Am sure you are not surprised that today’s external Javascript web_share_api_test.js Web Share API specialist needed to change


function tctowebp() {
var ourcanvc='';
var canvs=[];
if (window.top) {
canvs=top.document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0 && window.parent) {
canvs=parent.document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0) {
canvs=document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0 && window.parent) {
canvs=parent.document.getElementsByTagName('canvas');
if (eval('' + canvs.length) == 0 && window.top) {
canvs=top.document.getElementsByTagName('canvas');
}
}
if (eval('' + canvs.length) > 0) {
ourcanvc=canvs[0].toDataURL('image/webp');
if (lastcanvc != ' ') {
if (lastcanvc != ourcanvc) {
lastcanvc=ourcanvc;
canvc=ourcanvc;
czhr = new XMLHttpRequest();
czform = new FormData();
czform.append('webpit', canvc);
if (newidea.indexOf('canvas.webp') == -1) { // eg. MAMP ... http://localhost:8888/signature_signature.php?mycanvasimage=0000__1
czform.append('websecurepit', '' + myipadwsi);
}

czhr.onreadystatechange=cstateChanged;
czhr.open('post', './signature_signature.php', true);
czhr.send(czform);
} else {
if (document.getElementById('shareurl')) {
document.getElementById('shareurl').style.backgroundColor='#f9f9f9';
}
}
}
lastcanvc=ourcanvc;
}
return ourcanvc;
}

… as well, regarding its incorporation of Web Share API logic into our inhouse User of Signature canvas based web application, best tried, these days, in the Safari and Google Chrome web browser(s) using https: (secure) protocol?!


Previous relevant Canvas via Imge Web Share API Tutorial is shown below.

Canvas via Image Web Share API Tutorial

Canvas via Imge Web Share API Tutorial

We’re on the lookout for ways to improve the sharing and collaboration functionality of yesterday’s Images to Canvas No Clicking Form Signature Tutorial‘s “User of Signature” canvas using web application. We’re calling on ..

  • Safari and Google Chrome web browser(s) … for the moment, supporting the …
  • Web Share API … in order to …
  • Fill out email (or other communication idea) attachment links or documents … that …
  • Prepare the message before you, the user, flesh out the message as you send it off to the recipient

… a more guaranteed way, these days, because there are more and more ways restrictions may stop you doing similar functionality with a mail server arrangement on your public domain website, where we use the Exim mail server, at the RJM Programming domain.

As far as data goes for this, we also call on our changed PHP helper signature_signature.php to create a webp image file for sharing …

<?php

if (isset($_POST['webpit'])) {
file_put_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'canvas.webp', base64_decode(explode(";base64,", str_replace(' ','+',urldecode($_POST['webpit'])))[1]));
exit;
}

?>

… as applicable. The modus operandi for this back at today’s changed web_share_api_test.js external Javascript Web Share API specialist, uses Ajax methodologies …


var canvc=' ', lastcanvc=' ', czhr=null, czform=null;

function cstateChanged() {
if (czhr.readyState == 4) {
if (czhr.status == 200) {
if (1 == 2) { alert('Did it'); }
if (document.getElementById('shareurl')) {
document.getElementById('shareurl').style.backgroundColor='yellow';
}
}
}
}

function tctowebp() {
var ourcanvc='';
var canvs=[];
if (window.top) {
canvs=top.document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0 && window.parent) {
canvs=parent.document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0) {
canvs=document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0 && window.parent) {
canvs=parent.document.getElementsByTagName('canvas');
if (eval('' + canvs.length) == 0 && window.top) {
canvs=top.document.getElementsByTagName('canvas');
}
}
if (eval('' + canvs.length) > 0) {
ourcanvc=canvs[0].toDataURL('image/webp');
if (lastcanvc != ' ') {
if (lastcanvc != ourcanvc) {
lastcanvc=ourcanvc;
canvc=ourcanvc;
czhr = new XMLHttpRequest();
czform = new FormData();
czform.append('webpit', canvc);
czhr.onreadystatechange=cstateChanged;
czhr.open('post', './signature_signature.php', true);
czhr.send(czform);
} else {
if (document.getElementById('shareurl')) {
document.getElementById('shareurl').style.backgroundColor='#f9f9f9';
}
}
}
lastcanvc=ourcanvc;
}
return ourcanvc;
}

… and set in motion via a couple of different parental calls such as …


<script type='text/javascript' src='/web_share_api_test.js?canvasshare=as_necessary9876' defer></script>

… in …

… for cuter Safari and Google Chrome web browser sharing and collaboration work.


Previous relevant Images to Canvas No Clicking Form Signature Tutorial is shown below.

Images to Canvas No Clicking Form Signature Tutorial

Images to Canvas No Clicking Form Signature Tutorial

Surprisingly, it’s been more than a year since we changed anything to do with our …

  • canvas based …
  • images and annotation … accepting …
  • scribble (ie. can handle signatures) … perhaps …
  • form filling helping web application

… (when we presented Canvas Graphics Editing in Zoomed Webpage Tutorial) and we found that in order to add six more such Annotation option helpers into the mix …

Image Input Mode Image Sizing Modus Operandi
URL Actual (canvas resized to image)
Contain (canvas)
Cover (canvas)
Browsing Actual (canvas resized to image)
Contain (canvas)
Cover (canvas)

… we only needed to change the external Javascript signature_signature.js code used by our signature use in canvas supervisory web application so that when you can not ask so much of the user regarding image scaling, and avoid any canvas clicking that way, offering these six new annotation functionality options.


Previous relevant Canvas Graphics Editing in Zoomed Webpage Tutorial is shown below.

Canvas Graphics Editing in Zoomed Webpage Tutorial

Canvas Graphics Editing in Zoomed Webpage Tutorial

Software integration can be useful for a number of reasons …

  • code reuse
  • modularisation of functionality … and in our case …
  • if you like coding via “intervention points” you will enjoy coding for software integration improvements

As you might imagine it is easier in terms of the fact you can change “both ends” of the software integration, if it is “inhouse”, and luckily, today, our software integration is “inhouse”.

When we presented the recent Keyboard Based Cursor Canvas Content Copy Tutorial it focussed our attention on an improvement we could make to that user_of_signature_signature.htm canvas image editing web application. We wanted to offer the software integration with this web application to be able to successfully handle a webpage that has been zoomed to zoom factor different to 1.0 (or 100%).

We noticed before today’s very simple changes to external Javascript signature_signature.js code, graphic positioning on the canvas was wrong when the webpage had a zoom factor that is not 1.

Applying the canvas co-ordinate references through “the lens of” Javascript function zmb below …


var zzfac=location.search.split('zoom=')[1] ? decodeURIComponent(location.search.split('zoom=')[1].split('&')[0]) : "";
if (('' + location.hash).indexOf('zoom=') != -1) { zzfac=decodeURIComponent(('' + location.hash).split('zoom=')[1].split(';')[0]); }

function zmb(inco) {
if (zzfac != '') {
if (zzfac.indexOf('%') != -1) {
return eval(eval(eval('' + inco) / eval('' + zzfac.replace('%', ''))) * 100.0);
} else {
return eval(eval('' + inco) / eval('' + zzfac));
}
}
return inco;
}

used in the following example code below …


topelem.addEventListener('mousedown', function(event) {
if (topin) {
topin.value='- -' + isScribble + ',' + lastx + ',' + lasty + ',' + x + ',' + y;
}
if (isScribble == 1) {
threebackpmore=twobackpmore; twobackpmore=lastpmore; lastpmore=pmore; pmore=' pxam1 ';
isScribble=2;
if (event.pageX || event.pageY) {
ppx=zmb(event.pageX) - elemLeft;
ppy=zmb(event.pageY) - elemTop;
} else {
ppx=zmb(event.clientX) - elemLeft;
ppy=zmb(event.clientY) - elemTop;
}
if (pdgebi(topdcmcheck('dcm'))) {
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('text') == 0) {
//parent.document.title='here3 ' + tx + ',' + ty;
if (1 == 2 && tlx < 0 && tly < 0) {
tlx=ppx;
tly=ppy;
}
if (tx >= 0 && ty >= 0) {
prevtx=tx;
prevty=ty;
trotis=eval(((Math.atan2((ppy - prevty), (ppx - prevtx)) * 180.0 / Math.PI) + 360) % 360);
if (pdgebi('trotation')) {
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('textseq') == 0) {
jsrectbits[0]=prevtx;
jsrectbits[1]=prevty;
jsrectbits[2]=ppx;
jsrectbits[3]=ppy;
if (Math.abs(prevty - ppy) > Math.abs(prevtx - ppx)) {
trotis=eval(((Math.atan2((prevtx - ppx), (ppy - prevty)) * 180.0 / Math.PI) + 360) % 360);
}
}
parent.document.getElementById('trotation').value=Math.floor(trotis);
ppx=prevtx;
ppy=prevty;
prevtx=-1;
prevty=-1;
exceptwhen=endtrue(''); //true;
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('textseq') == -1) parent.document.getElementById(topdcmcheck('dcm')).value = 'Text';
}
//alert(trotis);
}
tx=ppx;
ty=ppy;
} else {
tx=ppx;
ty=ppy;
prevtx=-1;
prevty=-1;
}
} else {
tx=ppx;
ty=ppy;
prevtx=-1;
prevty=-1;
}
lastx=0; // new to scribble
lasty=0;
x=0;
y=0;
}
});

… we now have reasonable graphic positioning for the canvas when its webpage window has a non 1.0 zoom factor applied.


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 Ajax, eLearning, Event-Driven Programming, iOS, Photography, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Canvas via Image Web Share API Personalization Tutorial

Canvas via Image Web Share API Tutorial

Canvas via Image Web Share API Personalization Tutorial

Yesterday’s Canvas via Imge Web Share API Tutorial‘s Web Share API (so far, on Safari and Google Chrome web browser(s)) image (via canvas) sharing functionality did not have enough privacy for the user, as far as we were concerned. We’re not going in for some two factor authentication level of privacy here, and so we’ve opted for the use of the word “Personalization” in today’s blog posting title.

What we’ve done here is incorporate into the image name (a form of) the IP address of the sender of the image, which the receiver is using (for that extra privacy) as they click the email link, that now involves (a form of) this IP address in its formation.

No surprises here, that we’d have to involve our changed PHP helper signature_signature.php “specialist signature PHP helper” more, getting this solution together.

And no surprises here, that we’d try to involve the web server’s disk areas outside the scope of its (Apache) Document Root hierarchy. That step, alone, is important to force a curious user, to work their way through an inhouse PHP webpage URL of some sort, in order to extract that …

  • image data in the form of a web server file … to a …
  • public domain webpage image in an HTML img tag where its src attribute is populated via that web server file’s equivalent base64 data URI …
    <?php

    echo "<html><body><img title='" . $thename . '' . "' src='data:image/webp;base64," . base64_encode(file_get_contents(DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . $thename . '')) . "'></img>" . $therest . "</body></html>";

    ?>

Am sure you are not surprised that today’s external Javascript web_share_api_test.js Web Share API specialist needed to change


function tctowebp() {
var ourcanvc='';
var canvs=[];
if (window.top) {
canvs=top.document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0 && window.parent) {
canvs=parent.document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0) {
canvs=document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0 && window.parent) {
canvs=parent.document.getElementsByTagName('canvas');
if (eval('' + canvs.length) == 0 && window.top) {
canvs=top.document.getElementsByTagName('canvas');
}
}
if (eval('' + canvs.length) > 0) {
ourcanvc=canvs[0].toDataURL('image/webp');
if (lastcanvc != ' ') {
if (lastcanvc != ourcanvc) {
lastcanvc=ourcanvc;
canvc=ourcanvc;
czhr = new XMLHttpRequest();
czform = new FormData();
czform.append('webpit', canvc);
if (newidea.indexOf('canvas.webp') == -1) { // eg. MAMP ... http://localhost:8888/signature_signature.php?mycanvasimage=0000__1
czform.append('websecurepit', '' + myipadwsi);
}

czhr.onreadystatechange=cstateChanged;
czhr.open('post', './signature_signature.php', true);
czhr.send(czform);
} else {
if (document.getElementById('shareurl')) {
document.getElementById('shareurl').style.backgroundColor='#f9f9f9';
}
}
}
lastcanvc=ourcanvc;
}
return ourcanvc;
}

… as well, regarding its incorporation of Web Share API logic into our inhouse User of Signature canvas based web application, best tried, these days, in the Safari and Google Chrome web browser(s) using https: (secure) protocol?!


Previous relevant Canvas via Imge Web Share API Tutorial is shown below.

Canvas via Image Web Share API Tutorial

Canvas via Imge Web Share API Tutorial

We’re on the lookout for ways to improve the sharing and collaboration functionality of yesterday’s Images to Canvas No Clicking Form Signature Tutorial‘s “User of Signature” canvas using web application. We’re calling on ..

  • Safari and Google Chrome web browser(s) … for the moment, supporting the …
  • Web Share API … in order to …
  • Fill out email (or other communication idea) attachment links or documents … that …
  • Prepare the message before you, the user, flesh out the message as you send it off to the recipient

… a more guaranteed way, these days, because there are more and more ways restrictions may stop you doing similar functionality with a mail server arrangement on your public domain website, where we use the Exim mail server, at the RJM Programming domain.

As far as data goes for this, we also call on our changed PHP helper signature_signature.php to create a webp image file for sharing …

<?php

if (isset($_POST['webpit'])) {
file_put_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'canvas.webp', base64_decode(explode(";base64,", str_replace(' ','+',urldecode($_POST['webpit'])))[1]));
exit;
}

?>

… as applicable. The modus operandi for this back at today’s changed web_share_api_test.js external Javascript Web Share API specialist, uses Ajax methodologies …


var canvc=' ', lastcanvc=' ', czhr=null, czform=null;

function cstateChanged() {
if (czhr.readyState == 4) {
if (czhr.status == 200) {
if (1 == 2) { alert('Did it'); }
if (document.getElementById('shareurl')) {
document.getElementById('shareurl').style.backgroundColor='yellow';
}
}
}
}

function tctowebp() {
var ourcanvc='';
var canvs=[];
if (window.top) {
canvs=top.document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0 && window.parent) {
canvs=parent.document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0) {
canvs=document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0 && window.parent) {
canvs=parent.document.getElementsByTagName('canvas');
if (eval('' + canvs.length) == 0 && window.top) {
canvs=top.document.getElementsByTagName('canvas');
}
}
if (eval('' + canvs.length) > 0) {
ourcanvc=canvs[0].toDataURL('image/webp');
if (lastcanvc != ' ') {
if (lastcanvc != ourcanvc) {
lastcanvc=ourcanvc;
canvc=ourcanvc;
czhr = new XMLHttpRequest();
czform = new FormData();
czform.append('webpit', canvc);
czhr.onreadystatechange=cstateChanged;
czhr.open('post', './signature_signature.php', true);
czhr.send(czform);
} else {
if (document.getElementById('shareurl')) {
document.getElementById('shareurl').style.backgroundColor='#f9f9f9';
}
}
}
lastcanvc=ourcanvc;
}
return ourcanvc;
}

… and set in motion via a couple of different parental calls such as …


<script type='text/javascript' src='/web_share_api_test.js?canvasshare=as_necessary9876' defer></script>

… in …

… for cuter Safari and Google Chrome web browser sharing and collaboration work.


Previous relevant Images to Canvas No Clicking Form Signature Tutorial is shown below.

Images to Canvas No Clicking Form Signature Tutorial

Images to Canvas No Clicking Form Signature Tutorial

Surprisingly, it’s been more than a year since we changed anything to do with our …

  • canvas based …
  • images and annotation … accepting …
  • scribble (ie. can handle signatures) … perhaps …
  • form filling helping web application

… (when we presented Canvas Graphics Editing in Zoomed Webpage Tutorial) and we found that in order to add six more such Annotation option helpers into the mix …

Image Input Mode Image Sizing Modus Operandi
URL Actual (canvas resized to image)
Contain (canvas)
Cover (canvas)
Browsing Actual (canvas resized to image)
Contain (canvas)
Cover (canvas)

… we only needed to change the external Javascript signature_signature.js code used by our signature use in canvas supervisory web application so that when you can not ask so much of the user regarding image scaling, and avoid any canvas clicking that way, offering these six new annotation functionality options.


Previous relevant Canvas Graphics Editing in Zoomed Webpage Tutorial is shown below.

Canvas Graphics Editing in Zoomed Webpage Tutorial

Canvas Graphics Editing in Zoomed Webpage Tutorial

Software integration can be useful for a number of reasons …

  • code reuse
  • modularisation of functionality … and in our case …
  • if you like coding via “intervention points” you will enjoy coding for software integration improvements

As you might imagine it is easier in terms of the fact you can change “both ends” of the software integration, if it is “inhouse”, and luckily, today, our software integration is “inhouse”.

When we presented the recent Keyboard Based Cursor Canvas Content Copy Tutorial it focussed our attention on an improvement we could make to that user_of_signature_signature.htm canvas image editing web application. We wanted to offer the software integration with this web application to be able to successfully handle a webpage that has been zoomed to zoom factor different to 1.0 (or 100%).

We noticed before today’s very simple changes to external Javascript signature_signature.js code, graphic positioning on the canvas was wrong when the webpage had a zoom factor that is not 1.

Applying the canvas co-ordinate references through “the lens of” Javascript function zmb below …


var zzfac=location.search.split('zoom=')[1] ? decodeURIComponent(location.search.split('zoom=')[1].split('&')[0]) : "";
if (('' + location.hash).indexOf('zoom=') != -1) { zzfac=decodeURIComponent(('' + location.hash).split('zoom=')[1].split(';')[0]); }

function zmb(inco) {
if (zzfac != '') {
if (zzfac.indexOf('%') != -1) {
return eval(eval(eval('' + inco) / eval('' + zzfac.replace('%', ''))) * 100.0);
} else {
return eval(eval('' + inco) / eval('' + zzfac));
}
}
return inco;
}

used in the following example code below …


topelem.addEventListener('mousedown', function(event) {
if (topin) {
topin.value='- -' + isScribble + ',' + lastx + ',' + lasty + ',' + x + ',' + y;
}
if (isScribble == 1) {
threebackpmore=twobackpmore; twobackpmore=lastpmore; lastpmore=pmore; pmore=' pxam1 ';
isScribble=2;
if (event.pageX || event.pageY) {
ppx=zmb(event.pageX) - elemLeft;
ppy=zmb(event.pageY) - elemTop;
} else {
ppx=zmb(event.clientX) - elemLeft;
ppy=zmb(event.clientY) - elemTop;
}
if (pdgebi(topdcmcheck('dcm'))) {
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('text') == 0) {
//parent.document.title='here3 ' + tx + ',' + ty;
if (1 == 2 && tlx < 0 && tly < 0) {
tlx=ppx;
tly=ppy;
}
if (tx >= 0 && ty >= 0) {
prevtx=tx;
prevty=ty;
trotis=eval(((Math.atan2((ppy - prevty), (ppx - prevtx)) * 180.0 / Math.PI) + 360) % 360);
if (pdgebi('trotation')) {
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('textseq') == 0) {
jsrectbits[0]=prevtx;
jsrectbits[1]=prevty;
jsrectbits[2]=ppx;
jsrectbits[3]=ppy;
if (Math.abs(prevty - ppy) > Math.abs(prevtx - ppx)) {
trotis=eval(((Math.atan2((prevtx - ppx), (ppy - prevty)) * 180.0 / Math.PI) + 360) % 360);
}
}
parent.document.getElementById('trotation').value=Math.floor(trotis);
ppx=prevtx;
ppy=prevty;
prevtx=-1;
prevty=-1;
exceptwhen=endtrue(''); //true;
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('textseq') == -1) parent.document.getElementById(topdcmcheck('dcm')).value = 'Text';
}
//alert(trotis);
}
tx=ppx;
ty=ppy;
} else {
tx=ppx;
ty=ppy;
prevtx=-1;
prevty=-1;
}
} else {
tx=ppx;
ty=ppy;
prevtx=-1;
prevty=-1;
}
lastx=0; // new to scribble
lasty=0;
x=0;
y=0;
}
});

… we now have reasonable graphic positioning for the canvas when its webpage window has a non 1.0 zoom factor applied.


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.

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

Canvas via Image Web Share API Tutorial

Canvas via Image Web Share API Tutorial

Canvas via Imge Web Share API Tutorial

We’re on the lookout for ways to improve the sharing and collaboration functionality of yesterday’s Images to Canvas No Clicking Form Signature Tutorial‘s “User of Signature” canvas using web application. We’re calling on ..

  • Safari and Google Chrome web browser(s) … for the moment, supporting the …
  • Web Share API … in order to …
  • Fill out email (or other communication idea) attachment links or documents … that …
  • Prepare the message before you, the user, flesh out the message as you send it off to the recipient

… a more guaranteed way, these days, because there are more and more ways restrictions may stop you doing similar functionality with a mail server arrangement on your public domain website, where we use the Exim mail server, at the RJM Programming domain.

As far as data goes for this, we also call on our changed PHP helper signature_signature.php to create a webp image file for sharing …

<?php

if (isset($_POST['webpit'])) {
file_put_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'canvas.webp', base64_decode(explode(";base64,", str_replace(' ','+',urldecode($_POST['webpit'])))[1]));
exit;
}

?>

… as applicable. The modus operandi for this back at today’s changed web_share_api_test.js external Javascript Web Share API specialist, uses Ajax methodologies …


var canvc=' ', lastcanvc=' ', czhr=null, czform=null;

function cstateChanged() {
if (czhr.readyState == 4) {
if (czhr.status == 200) {
if (1 == 2) { alert('Did it'); }
if (document.getElementById('shareurl')) {
document.getElementById('shareurl').style.backgroundColor='yellow';
}
}
}
}

function tctowebp() {
var ourcanvc='';
var canvs=[];
if (window.top) {
canvs=top.document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0 && window.parent) {
canvs=parent.document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0) {
canvs=document.getElementsByTagName('canvas');
}
if (eval('' + canvs.length) == 0 && window.parent) {
canvs=parent.document.getElementsByTagName('canvas');
if (eval('' + canvs.length) == 0 && window.top) {
canvs=top.document.getElementsByTagName('canvas');
}
}
if (eval('' + canvs.length) > 0) {
ourcanvc=canvs[0].toDataURL('image/webp');
if (lastcanvc != ' ') {
if (lastcanvc != ourcanvc) {
lastcanvc=ourcanvc;
canvc=ourcanvc;
czhr = new XMLHttpRequest();
czform = new FormData();
czform.append('webpit', canvc);
czhr.onreadystatechange=cstateChanged;
czhr.open('post', './signature_signature.php', true);
czhr.send(czform);
} else {
if (document.getElementById('shareurl')) {
document.getElementById('shareurl').style.backgroundColor='#f9f9f9';
}
}
}
lastcanvc=ourcanvc;
}
return ourcanvc;
}

… and set in motion via a couple of different parental calls such as …


<script type='text/javascript' src='/web_share_api_test.js?canvasshare=as_necessary9876' defer></script>

… in …

… for cuter Safari and Google Chrome web browser sharing and collaboration work.


Previous relevant Images to Canvas No Clicking Form Signature Tutorial is shown below.

Images to Canvas No Clicking Form Signature Tutorial

Images to Canvas No Clicking Form Signature Tutorial

Surprisingly, it’s been more than a year since we changed anything to do with our …

  • canvas based …
  • images and annotation … accepting …
  • scribble (ie. can handle signatures) … perhaps …
  • form filling helping web application

… (when we presented Canvas Graphics Editing in Zoomed Webpage Tutorial) and we found that in order to add six more such Annotation option helpers into the mix …

Image Input Mode Image Sizing Modus Operandi
URL Actual (canvas resized to image)
Contain (canvas)
Cover (canvas)
Browsing Actual (canvas resized to image)
Contain (canvas)
Cover (canvas)

… we only needed to change the external Javascript signature_signature.js code used by our signature use in canvas supervisory web application so that when you can not ask so much of the user regarding image scaling, and avoid any canvas clicking that way, offering these six new annotation functionality options.


Previous relevant Canvas Graphics Editing in Zoomed Webpage Tutorial is shown below.

Canvas Graphics Editing in Zoomed Webpage Tutorial

Canvas Graphics Editing in Zoomed Webpage Tutorial

Software integration can be useful for a number of reasons …

  • code reuse
  • modularisation of functionality … and in our case …
  • if you like coding via “intervention points” you will enjoy coding for software integration improvements

As you might imagine it is easier in terms of the fact you can change “both ends” of the software integration, if it is “inhouse”, and luckily, today, our software integration is “inhouse”.

When we presented the recent Keyboard Based Cursor Canvas Content Copy Tutorial it focussed our attention on an improvement we could make to that user_of_signature_signature.htm canvas image editing web application. We wanted to offer the software integration with this web application to be able to successfully handle a webpage that has been zoomed to zoom factor different to 1.0 (or 100%).

We noticed before today’s very simple changes to external Javascript signature_signature.js code, graphic positioning on the canvas was wrong when the webpage had a zoom factor that is not 1.

Applying the canvas co-ordinate references through “the lens of” Javascript function zmb below …


var zzfac=location.search.split('zoom=')[1] ? decodeURIComponent(location.search.split('zoom=')[1].split('&')[0]) : "";
if (('' + location.hash).indexOf('zoom=') != -1) { zzfac=decodeURIComponent(('' + location.hash).split('zoom=')[1].split(';')[0]); }

function zmb(inco) {
if (zzfac != '') {
if (zzfac.indexOf('%') != -1) {
return eval(eval(eval('' + inco) / eval('' + zzfac.replace('%', ''))) * 100.0);
} else {
return eval(eval('' + inco) / eval('' + zzfac));
}
}
return inco;
}

used in the following example code below …


topelem.addEventListener('mousedown', function(event) {
if (topin) {
topin.value='- -' + isScribble + ',' + lastx + ',' + lasty + ',' + x + ',' + y;
}
if (isScribble == 1) {
threebackpmore=twobackpmore; twobackpmore=lastpmore; lastpmore=pmore; pmore=' pxam1 ';
isScribble=2;
if (event.pageX || event.pageY) {
ppx=zmb(event.pageX) - elemLeft;
ppy=zmb(event.pageY) - elemTop;
} else {
ppx=zmb(event.clientX) - elemLeft;
ppy=zmb(event.clientY) - elemTop;
}
if (pdgebi(topdcmcheck('dcm'))) {
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('text') == 0) {
//parent.document.title='here3 ' + tx + ',' + ty;
if (1 == 2 && tlx < 0 && tly < 0) {
tlx=ppx;
tly=ppy;
}
if (tx >= 0 && ty >= 0) {
prevtx=tx;
prevty=ty;
trotis=eval(((Math.atan2((ppy - prevty), (ppx - prevtx)) * 180.0 / Math.PI) + 360) % 360);
if (pdgebi('trotation')) {
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('textseq') == 0) {
jsrectbits[0]=prevtx;
jsrectbits[1]=prevty;
jsrectbits[2]=ppx;
jsrectbits[3]=ppy;
if (Math.abs(prevty - ppy) > Math.abs(prevtx - ppx)) {
trotis=eval(((Math.atan2((prevtx - ppx), (ppy - prevty)) * 180.0 / Math.PI) + 360) % 360);
}
}
parent.document.getElementById('trotation').value=Math.floor(trotis);
ppx=prevtx;
ppy=prevty;
prevtx=-1;
prevty=-1;
exceptwhen=endtrue(''); //true;
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('textseq') == -1) parent.document.getElementById(topdcmcheck('dcm')).value = 'Text';
}
//alert(trotis);
}
tx=ppx;
ty=ppy;
} else {
tx=ppx;
ty=ppy;
prevtx=-1;
prevty=-1;
}
} else {
tx=ppx;
ty=ppy;
prevtx=-1;
prevty=-1;
}
lastx=0; // new to scribble
lasty=0;
x=0;
y=0;
}
});

… we now have reasonable graphic positioning for the canvas when its webpage window has a non 1.0 zoom factor applied.


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.

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

Images to Canvas No Clicking Form Signature Tutorial

Images to Canvas No Clicking Form Signature Tutorial

Images to Canvas No Clicking Form Signature Tutorial

Surprisingly, it’s been more than a year since we changed anything to do with our …

  • canvas based …
  • images and annotation … accepting …
  • scribble (ie. can handle signatures) … perhaps …
  • form filling helping web application

… (when we presented Canvas Graphics Editing in Zoomed Webpage Tutorial) and we found that in order to add six more such Annotation option helpers into the mix …

Image Input Mode Image Sizing Modus Operandi
URL Actual (canvas resized to image)
Contain (canvas)
Cover (canvas)
Browsing Actual (canvas resized to image)
Contain (canvas)
Cover (canvas)

… we only needed to change the external Javascript signature_signature.js code used by our signature use in canvas supervisory web application so that when you can not ask so much of the user regarding image scaling, and avoid any canvas clicking that way, offering these six new annotation functionality options.


Previous relevant Canvas Graphics Editing in Zoomed Webpage Tutorial is shown below.

Canvas Graphics Editing in Zoomed Webpage Tutorial

Canvas Graphics Editing in Zoomed Webpage Tutorial

Software integration can be useful for a number of reasons …

  • code reuse
  • modularisation of functionality … and in our case …
  • if you like coding via “intervention points” you will enjoy coding for software integration improvements

As you might imagine it is easier in terms of the fact you can change “both ends” of the software integration, if it is “inhouse”, and luckily, today, our software integration is “inhouse”.

When we presented the recent Keyboard Based Cursor Canvas Content Copy Tutorial it focussed our attention on an improvement we could make to that user_of_signature_signature.htm canvas image editing web application. We wanted to offer the software integration with this web application to be able to successfully handle a webpage that has been zoomed to zoom factor different to 1.0 (or 100%).

We noticed before today’s very simple changes to external Javascript signature_signature.js code, graphic positioning on the canvas was wrong when the webpage had a zoom factor that is not 1.

Applying the canvas co-ordinate references through “the lens of” Javascript function zmb below …


var zzfac=location.search.split('zoom=')[1] ? decodeURIComponent(location.search.split('zoom=')[1].split('&')[0]) : "";
if (('' + location.hash).indexOf('zoom=') != -1) { zzfac=decodeURIComponent(('' + location.hash).split('zoom=')[1].split(';')[0]); }

function zmb(inco) {
if (zzfac != '') {
if (zzfac.indexOf('%') != -1) {
return eval(eval(eval('' + inco) / eval('' + zzfac.replace('%', ''))) * 100.0);
} else {
return eval(eval('' + inco) / eval('' + zzfac));
}
}
return inco;
}

used in the following example code below …


topelem.addEventListener('mousedown', function(event) {
if (topin) {
topin.value='- -' + isScribble + ',' + lastx + ',' + lasty + ',' + x + ',' + y;
}
if (isScribble == 1) {
threebackpmore=twobackpmore; twobackpmore=lastpmore; lastpmore=pmore; pmore=' pxam1 ';
isScribble=2;
if (event.pageX || event.pageY) {
ppx=zmb(event.pageX) - elemLeft;
ppy=zmb(event.pageY) - elemTop;
} else {
ppx=zmb(event.clientX) - elemLeft;
ppy=zmb(event.clientY) - elemTop;
}
if (pdgebi(topdcmcheck('dcm'))) {
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('text') == 0) {
//parent.document.title='here3 ' + tx + ',' + ty;
if (1 == 2 && tlx < 0 && tly < 0) {
tlx=ppx;
tly=ppy;
}
if (tx >= 0 && ty >= 0) {
prevtx=tx;
prevty=ty;
trotis=eval(((Math.atan2((ppy - prevty), (ppx - prevtx)) * 180.0 / Math.PI) + 360) % 360);
if (pdgebi('trotation')) {
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('textseq') == 0) {
jsrectbits[0]=prevtx;
jsrectbits[1]=prevty;
jsrectbits[2]=ppx;
jsrectbits[3]=ppy;
if (Math.abs(prevty - ppy) > Math.abs(prevtx - ppx)) {
trotis=eval(((Math.atan2((prevtx - ppx), (ppy - prevty)) * 180.0 / Math.PI) + 360) % 360);
}
}
parent.document.getElementById('trotation').value=Math.floor(trotis);
ppx=prevtx;
ppy=prevty;
prevtx=-1;
prevty=-1;
exceptwhen=endtrue(''); //true;
if (parent.document.getElementById(topdcmcheck('dcm')).value.indexOf('textseq') == -1) parent.document.getElementById(topdcmcheck('dcm')).value = 'Text';
}
//alert(trotis);
}
tx=ppx;
ty=ppy;
} else {
tx=ppx;
ty=ppy;
prevtx=-1;
prevty=-1;
}
} else {
tx=ppx;
ty=ppy;
prevtx=-1;
prevty=-1;
}
lastx=0; // new to scribble
lasty=0;
x=0;
y=0;
}
});

… we now have reasonable graphic positioning for the canvas when its webpage window has a non 1.0 zoom factor applied.


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.

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