Walking Trip …

Walking Trip

Walking Trip

Offenbach's Suite ... Warts 'n All

Offenbach's Suite ... Warts 'n All

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

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

Animated GIF Via Sequenced Images Delimiter Tutorial

Animated GIF Via Sequenced Images Delimiter Tutorial

Animated GIF Via Sequenced Images Delimiter Tutorial

Around here we believe in the idea that aspirational users should be rewarded with enhanced functionality, today that being a comma (“,”) set of delimiter functionality on top of the minus sign (“-“) “range functionality” of yesterday’s Animated GIF Via Sequenced Images Tutorial. With advanced, perhaps non-obvious usage, we generally leave it up to those aspirational (adventurous) users to see what’s possible, but at least with non-mobile users, mention the advanced usage when hovering via the HTML title property that is displayed by default with HTML elements. Why be obtuse like this? Well, we also believe in web applications with no snobbiness regarding user ability. Of course, we fail big time on occasions, making things difficult for everyone, but that aspirational side to the more “marketable” web applications is important, we think.

We also believe in delimitation, for the aspirational user to work with, rather than cluttering web applications with multiple sets of buttons or dropdowns, for these different levels of sophistication of usage. So yesterday we had ..

  • minus “-” “range” delimiter usage … like “and” … and today we do …
  • comma “,” delimiter usage … like “or”

… and as you may know as a programmer, “or” can encompass “and” anyway (in the sense that you need to check for “and” usage within any supported “or” usage), so the job is much bigger, if you incorporate “or” thoughts after the initial design … ohhhhhh well … we live and learn.

The other aspect though, about “or” thoughts, is that they are normally only (additionally) good for people in a hurry, wanting to formulate their thoughts all at once, because, as you may surmise, if you have used our animated GIF creator live run yourself, an existant “or” option of use is already there in the sense that the URL textboxes are already formed as a linked list, when the user can enter URLs one at a time to their heart’s content already. However, there will be users who prefer to answer everything within the one textbox, and those people are helped out today with today’s additional comma (“,”) “or” logics.

Again, see what we mean with the changed tutorial_to_animated_gif.php‘s animated GIF creator live run in action below …

To get to the same point as yesterday’s “range” IMG_1385-1394.JPG usage we show you …

IMG_1385,1386.JPG,1387,1388,1389,1390,1391,1392,1393,1394
IMG_1385-1394.JPG
IMG_1385.JPG … through to, incrementing the count by one (ie. 8 images here in middle) … IMG_1394.JPG


Previous relevant Animated GIF Via Sequenced Images Tutorial is shown below.

Animated GIF Via Sequenced Images Tutorial

Animated GIF Via Sequenced Images Tutorial

The “making of” animated GIF (explanatory image) for yesterday’s World Clickarounds Google Map Chart Onclick Logic Tutorial involved more than ten (but today we’ll be using ten) images that had to be entered in our inhouse web application, here, to create animated GIFs, as fully defined absolute URLs. The frustrating thing about that is that the image URLs formed a pattern with their naming as per …

IMG_1385.JPG … through to, incrementing the count by one (ie. 8 images here in middle) … IMG_1394.JPG

… but why not allow our web application be more savvy and user friendly and less error prone by letting the user define all these ten URLs in the one new interactive entry

IMG_1385-1394.JPG
IMG_1385.JPG … through to, incrementing the count by one (ie. 8 images here in middle) … IMG_1394.JPG

… the understanding with the code logic being we first check that IMG_1385-1394.JPG is not an existant URL when interpreting that “-” (minus) delimitation as flagging one of these “range entries”? That one entry will cause the other nine URLs to be filled in, and that first one replaced with IMG_1385.JPG as its entry.

Maybe you are perplexed that we have a PHP web application here, and we can’t be helped out by good ol’ glob. Well, glob is just for local web files, not absolute URLs (though an absolute URL of the same domain as the web application sits can be turned into a local file definition). So only think glob (in the morning, afternoon tea, dusk and supper time … but we digress) when this local file situation can be “worked” into a wildcard (eg. * (any number of) and ? (one character) and ones like [0-9] (for range of (integer) characters)).

To make our web application “do its stuff” here, we use two techniques …

  • at the parent level of its PHP run of HTML we use “client pre-emptive iframe” (like “suck it and see” loading of an image into an iframe, and look for success versus problems) methodologies to determine if a URL definition with a “-” is an image file (ie. in iframe, it will succeed) or a range definition (ie. in iframe, it will fail) … then, just for that “fail” scenario …
  • we call (the same PHP (added to) codeset) in an iframe via the Javascript call …

    function more(what) { // we know image range URL (with "-"), ID of calling input textbox, prefix of URL before numbers, suffix of URL after numbers, count of images so far making up animated GIF definition, number to indicate offset to apply to number to get to the next one, end number (as applicable), start number
    return document.URL.split('#')[0].split('?')[0] + '?urlminus=' + encodeURIComponent(what) + '&lastioid=' + encodeURIComponent(lastioid) + '&upprefix=' + encodeURIComponent(upprefix) + '&upsuffix=' + encodeURIComponent(upsuffix) + '&icnt=' + encodeURIComponent(icnt) + '&incis=' + encodeURIComponent(incis) + '&upto=' + encodeURIComponent(upto) + '&thisto=' + encodeURIComponent(thisto);
    }

    … to have today’s new (self contained) PHP code below fill out the other individual URLs within the range as well as amending the first to be that first (has to be existant) URL at the start of the URL image (integer numerical) range, helped out enormously by good ol’ file_get_contents

    if (isset($_GET['urlminus']) && isset($_GET['icnt']) && isset($_GET['lastioid']) && isset($_GET['incis']) && isset($_GET['upprefix']) && isset($_GET['upsuffix']) && isset($_GET['upto']) && isset($_GET['thisto'])) {
    $urlminus=str_replace("+"," ",urldecode($_GET['urlminus']));
    $upprefix=str_replace("+"," ",urldecode($_GET['upprefix']));
    $upsuffix=str_replace("+"," ",urldecode($_GET['upsuffix']));
    $lastioid=str_replace("+"," ",urldecode($_GET['lastioid']));
    $incis=str_replace("+"," ",urldecode($_GET['incis']));
    $icnt=str_replace("+"," ",urldecode($_GET['icnt']));
    $upto=str_replace("+"," ",urldecode($_GET['upto']));
    $thisto=str_replace("+"," ",urldecode($_GET['thisto']));
    $scris="";
    $cis=file_get_contents(str_replace('https:','http:',$urlminus));
    if ($cis != "") {
    $scris.="\n<scr" . "ipt type='text/javascript'>\n";
    $scris.="\n var icnt=eval(-1 + " . $icnt . "), lastio='" . $lastioid . "', fo=null, newi=null; \n function dothis() { \n";
    $scris.="\n if (icnt == 1) { \n";
    $scris.="\n parent.document.getElementById('slideshow').value='" . $urlminus . "'; \n } else if (lastio != '') { parent.document.getElementById(lastio).value='" . $urlminus . "'; \n } \n";
    if ("$icnt" == "2" || "$lastioid" != "") { $urlminus=""; }
    while ($cis != "") {
    $sc=strlen($cis);
    $scris.="\n if ('" . $sc . "' != '1') { \n";
    $scris.="\n fo=parent.document.getElementById('fdiv' + icnt); \n";
    $scris.="\n icnt++; \n";
    $scris.="\n newi=parent.document.getElementById('slideshow' + icnt); \n";
    $scris.="\n if (newi) { if (newi.innerHTML.length == 0) { newi=null; } } \n";

    $scris.="\n if (fo != null && newi == null) { \n";
    $scris.="\n if (fo.id == 'slideshow') { fo.value='" . $urlminus . "'; } else { fo.innerHTML+=\"Tutorial Slideshow Image \" + icnt + \" <input title='Please note a minus between numericals can define a URL range of image URLs' onblur='maybemore(this.value, this.id, this);' style='width:70%;' type='text' id='slideshow\" + icnt + \"' name='slideshow\" + icnt + \"' value='" . $urlminus . "'></input><br><br><div id='fdiv\" + icnt + \"'></div>\"; } \n";
    $scris.="\n } \n";
    $scris.="\n } \n";
    if ("$thisto" == "$upto" || ((-1 + $thisto) < $upto && "$incis" == "-1") || ((1 + $thisto) > $upto && "$incis" != "-1")) {
    $cis="";
    } else {
    if ("$incis" == "-1") {
    $thisto--;
    $urlminus=$upprefix . $thisto . $upsuffix;
    $cis=file_get_contents(str_replace('https:','http:',$urlminus));
    if ("$upto" != "" && $cis == "") { $cis=" "; }
    } else {
    $thisto++;
    $urlminus=$upprefix . $thisto . $upsuffix;
    $cis=file_get_contents(str_replace('https:','http:',$urlminus));
    if ("$upto" != "" && $cis == "") { $cis=" "; }
    }
    }
    }
    $scris.="\n } \n </scr" . "ipt>\n";
    }
    if ($scris != "") {
    echo "<!doctype html><html><head>" . $scris . "</head><body onload=dothis();> </body></html>";
    }
    exit;
    }

See what we mean with the changed tutorial_to_animated_gif.php‘s animated GIF creator live run in action below …


Previous relevant World Clickarounds Google Map Chart Onclick Logic Tutorial is shown below.

World Clickarounds Google Map Chart Onclick Logic Tutorial

World Clickarounds Google Map Chart Onclick Logic Tutorial

Revisiting our World Clickaround web applications today, last talked about with Canvas Annotation Email Attachment User Acceptance Tutorial, we were gobsmacked that we hadn’t defaulted their use of the Google Chart Map Charts integrated in, to allow for inhouse “onclick” (via a Google Chart select event) logic.

Without this integration you miss being able to click near a place and …

  • use “Z” option to find nearest TimeZone (and then onto option “W” Weather) and option “T” for TimeZone information
  • use “S” for Sun Angle … and others of that ilk … and …
  • use “G” for (navigating to) various Google Map views
  • use “Y” for YouTube video lookup (though one of the nearest Airports (that have a known name) may do better here
  • use “A” for Nearest Airports (though you probably got this up already)

… anyway … didn’t want these possibilities to be hidden any longer.

The fix was very simple applied to many HTML web applications (as below), that being to add &onclick=y into the map.php based URLs in the code linking to our Google Chart Map Chart interfacing.


Previous relevant Canvas Annotation Email Attachment User Acceptance Tutorial is shown below.

Canvas Annotation Email Attachment User Acceptance Tutorial

Canvas Annotation Email Attachment User Acceptance Tutorial

An important part of a web (or desktop or mobile) application is user acceptance. User acceptance is, as the words would imply, the giving of your (developing) web application to real users, to test out usability … or UX (user experience). We do this today for our “Canvas Annotation Email Attachment” web application, and use it to “Annotate” a make believe trip, some of the “talking points” of which are “overlayed” on our “Welcome to Nation” map introduced a couple of days ago when we presented Canvas Annotation Email Attachment Transparency Tutorial and this resulted in an email sent with the attachment as you see in today’s tutorial picture.

User acceptance often throws up surprising findings, some easy to handle, and others that are likely to be extremely hard to implement, or impossible, or unworkable at this time. We addressed some of the easier ones to improve the web application, as listed below …

  1. as far as “overlay” thoughts go overlaying a transparent image on top of a clean map goes, we found, before user acceptance, that we would have had to type in the URL to the web application, again, at the address bar, rather than having a way to do it in the web application, so we turned the “Your” in “Your Annotations++” to be a dropdown, that if you change its value, you start the web application again, and can immediately arrange to overlay what you may have emailed off (to yourself, possibly) and downloaded locally onto your hard disk
  2. (after the email today … alas) … as far as the red or yellow click/touch blobs appearing (a little annoyingly) during Annotation operations, we allow you, now, to click on any part of the green bit of the Annotation menu, to turn off these blobs … alas … and you may want to do your own research, perhaps starting at this very useful link we “bit the bullet” and made non-generic HTML changes, as well as generic external Javascript changes, to allow for this … adding a new global variable blobc containing the colour of the “blob” … no, not that “blob”, this ..
  3. allow an original URL image to be supplied on the address bar URL as with this URL for today’s “fantasy trip” from “Alice Springs to Broome”

… and so what functionality features featured in our user acceptance test …

Again, for today’s work, the external Javascript world.js needed to change (regarding the user acceptance testing) like this today, regarding this new “Canvas Annotation Email” image fitting ideas, and our (common) PHP you could call intair.php is unchanged for any/all of (changed slightly) …

Hope you will try some or all of these web applications, and their “Canvas Annotation” and “Email Attachment” functionality, maybe even in a real world situation, emailing the results out to somebody, perhaps?


Previous relevant Canvas Annotation Email Attachment Image Fit Tutorial is shown below.

Canvas Annotation Email Attachment Image Fit Tutorial

Canvas Annotation Email Attachment Image Fit Tutorial

There is still more to do with regard to image manipulations functionality regarding our “Canvas Annotation Email Attachment” and “Clickaround” web applications. We want to be able to offer image scaling via user defined click or touch event outcomes on our HTML canvas.

What we do today in the form of a new HTML select element dropdown containing image placement options …

  1. place or overlay images not according to user click or touch events on the HTML canvas element, but use other “Annotation++” menu settings
  2. fit the image into the rectangle formed by the user’s last two click or touch canvas co-ordinates
  3. fit the image into the rectangle width, only, formed by the user’s last two click or touch canvas co-ordinates
  4. fit the image into the rectangle height, only, formed by the user’s last two click or touch canvas co-ordinates

The workings of this new functionality includes the HTML canvas methods …

So, for today’s work, only the external Javascript world.js needed to change like this today, regarding this new “Canvas Annotation Email” image fitting ideas, and our (common) PHP you could call intair.php is unchanged for any/all of …

Hope you will try some or all of these web applications, and their “Canvas Annotation” and “Email Attachment” functionality.


Previous relevant Canvas Annotation Email Attachment Transparency Tutorial is shown below.

Canvas Annotation Email Attachment Transparency Tutorial

Canvas Annotation Email Attachment Transparency Tutorial

We’ve thought of some more useful functionality regarding our “Canvas Annotation Email Attachment” and “Clickaround” web applications. To explore possibilities here going forward, and with regard to ideas regarding genericization possibilities, which aren’t a straightforward “yes” decision for today’s ideas.

What we do today is …

  1. we add to the “Where Is?” functionality of “Clickaround” web applications that we first talked about with Canvas Clickaround Where Is Primer Tutorial by allowing not only a Place Name (of an Airport) to be the only option that results in active usefulness with the web application, but also allow that same HTML input type=text element to specify a latitude;longitude[;placeName] for the case of the majority of places on Earth that don’t have an airport
  2. we add an extra functionality type similar to the “Undo” button of Canvas Annotation Email Attachment Undo Tutorial as shown way below that simply undoes the HTML canvas original image (the map), replacing it with a transparent background HTML canvas element that is then loaded with all the rest of the new Annotations you, the user, had added, since … hope you can see how useful this idea could be for a whole new set of “overlay” thoughts, which we’ll endeavour to refine in your mind as time goes on
  3. we add a whole new “Clickaround” and “Canvas Annotation Email Attachment” web application we are calling “Welcome To Nation” because we use the wonderful map developed by TreatyRepublic.net, thanks, in the tutorial sequence culminating in Australian Indigenous Language HTML Map jQuery YQL Tutorial

Now that second new functionality we are trialling with that new third new HTML and Javascript source code welcometonation.html with its live run link.

Often with genericization possibilities, the detail of how things could work, or perhaps not, in a “generic way”, are best “played out” in terms of a new “player” into the scene. So that is how we proceed today. This trialling also affects that first piece of functionality, with “Welcome to Nation” usage, having the window.open() “compiler” of selected “Where Is?” dropdown selections opening back in the “welcometonation.html” rather than the default (for all other “Clickaround” web applications, as it stands right now) “world.html” … a job to do here, for later, is to check that the user’s “latitude;longitude[;placeName]” entry falls within that “subset” map of the world … no such checks here today.

Anyway, going through this motion … yes … we found there is thinking to do making “genericization” of that second functionality idea work, and this is for tomorrow, and on. As is explaining how “overlay” possibilities expand here with that second idea above.

But the real wonder is in the intricacy of the culture, “the oldest surviving culture in the world”, of the Koori people, the first people of Australia, and so with that third option’s new Welcome to Nation web application is a new first option of the “web application” “Clickaround” dropdown at the right that points at the HTML map element Indigenous Australian Language Map web application Indigenous Australian Language Regions, where you point at a region and can open search engine and other information relevant to that indigenous language and peoples of interest.

So, for today’s work, the external Javascript world.js needed to change like this today, regarding this new “Canvas Annotation Email” background transparency idea, and our (common) PHP you could call intair.php changed quite a bit, as it controls “Where Is?” functionality ideas to any/all of …

Hope you try some or all of these out.


Previous relevant Canvas Annotation Email Attachment Scale and Clip Tutorial is shown below.

Canvas Annotation Email Attachment Scale and Clip Tutorial

Canvas Annotation Email Attachment Scale and Clip Tutorial

We’ve been busy continuing on with our Annotations functionality quest, specifically regarding Image content for Annotations, and the ability to be able to Scale and Clip (or crop) those images within the HTML canvas element that hosts them. This is also part of the functionality we need in our “toolbox” for our eventual destination with all this Annotation (with optional Email Attachment) functionality.

Some considerations with Scale, Clip and Rotation (the latter of which we first set our sights on with Canvas Annotation Email Attachment Rotation Tutorial as shown below) thoughts are …

  • what should the origin point of rotation be? … we follow the lead of this excellent link … thanks … and choose the centre of the canvas element … but also as of today’s work we offer the last click/touch position to be an option for positioning
  • should the canvas dimensions change? … this is debatable … and we continue, for now, to say “no” to this … but we are still open to changing this
  • do you rotate all canvas content or just an added image’s content? … we allow for both modes of use … we’ve added the ability for Annotation computer font text to rotate, as of today, as well
  • what should the origin point of clipping be? … we allow a percentage or pixel user defined method of defining

Today’s scaling and clipping calls on the full canvas.drawImage() specification. Up to now we’ve only ventured to the first of the three incarnations of ctx.drawImage calls below …

void ctx.drawImage(image, dx, dy);
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

… as you can read more about at that great link … but we make use of all three with today’s work, especially the third call with the clipping parameters “sx, sy, sWidth, sHeight” supplementing scaling parameters “dWidth, dHeight”.

So yet again, no HTML files needed to change today, and our (common) external Javascript you could call world.js changed quite a bit, adding Scaling and Clipping functionality to the recently added Rotation functionality affecting any/all of …

We’ll be back to explain more soon.


Previous relevant Canvas Annotation Email Attachment Rotation Tutorial is shown below.

Canvas Annotation Email Attachment Rotation Tutorial

Canvas Annotation Email Attachment Rotation Tutorial

It’s time to return to Annotations, specifically Image content for Annotations, and the ability to be able to Rotate those images, or the whole HTML canvas element that hosts them. It’s part of the functionality we need in our “toolbox” for our eventual destination with all this Annotation functionality.

Some considerations with Rotation thoughts are …

  • what should the origin point of rotation be? … we follow the lead of this excellent link … thanks … and choose the centre of the canvas element
  • should the canvas dimensions change? … this is debatable … and we have, for now, said “no” to this … but we are open to changing this, along with “cropping” and “scaling” and “specified offsets for rotated images” for follow up tutorials
  • do you rotate all canvas content or just an added image’s content? … we allow for both modes of use

Along the way, today, we thought we should add, at least for non-mobile platforms with an “onmouseover” event (available), the means to show “canvas” co-ordinates to assist these users with “Offset X and Y” decisions, perhaps.

Once again, no HTML files needed to change today, and our (common) external Javascript you could call world.js changed quite a bit, adding Rotation functionality affecting any/all of …


Canvas Annotation Email Attachment Undo Tutorial is shown below.

Canvas Annotation Email Attachment Undo Tutorial

Canvas Annotation Email Attachment Undo Tutorial

A web application allowing user defined Annotations is better when there is an “Undo” and “Redo” functionality option. This is because with any user intervention, there can be erroneous work, which sometimes can be a real pain to recover from scratch.

With “Undo” and “Redo” functionality, however, you do not want the user to think it is as much a part of the “mainstream” of the web application’s functionality, so we supply a “-” (minus) button for “Undo” and a “+” (plus) button for “Redo”, and make them smaller than other Annotation functionality buttons.

So how do we achieve this functionality? We actually do it by actually …

  1. always clearing the contents of the HTML canvas element
  2. always place the original image via canvas.drawImage() method
  3. calling on a stored Javascript array containing HTML canvas drawing statements, flagging the ones that represent a single user defined action, that one “single user defined action” being what an “Undo” or “Redo” action works regarding

There is a great resource for information about the Javascript “Array” object called ECMAScript® Language Specification (we got to via this link, which is also excellent as an “Array” object member functionality synopsis (and which we urge you to consult), thanks).

You may wonder about how canvas.drawImage() parameter 1 (an image object) is handled. We assume you will only be interested in “Undo”s and “Redo”s of the last image (object) involved, which is stored in a global variable (and rereferenced by “Undo” and/or “Redo”) when the Annotations are created (and built up) by the user.

So yet again, our world.html (with its live run) did not need to change for this new “Undo”/”Redo” functionality but our external Javascript you could call world.js changed quite a bit, setting up these Javascript arrays storing HTML canvas commands, for later use in “Undo” and “Redo” scenarios instigated by users clicking the relevant respective (small) “-” and “+” buttons.

As for …

We “might” have genericized the world.html changes into other HTMLs of its ilk … well, we decided against that for now … but will later … and partly the reason is that there is more to do, and we just want to concentrate on world.html

… we can now apply changes to the other HTML web applications …

Also changing is the email attachment PHP helper you could call world.php changed in this way.

Hope this HTML canvas web application set gives you some ideas for work of your own. To read some of the background to this, try Canvas Email Attachment Scribble Tutorial as shown below.


Previous relevant Canvas Email Attachment Scribble Tutorial is shown below.

Canvas Email Attachment Scribble Tutorial

Canvas Email Attachment Scribble Tutorial

Personally think that Annotations are better when there is a “Scribble” functionality option. Perhaps you want to “sign off” on your Annotations. Without a “Scribble” option, it’s a bit impersonal relying on computer fonts as the means by which you “sign” the work.

And down the track it’s helping with our “final aim”, which will be revealed as time goes on.

To “Scribble” the main mouse event that interests us is the “onmousemove” event which happens when the mouse … moves … in which case if you are in “Scribble” mode, draw a line between the last two data points. So from that you would glean, and we’ll fill in, as well, that …

  • the user needs to tell the computer it wants to start into “Scribble” mode (like a green light on the traffic light) … after a 2 second delay to allow the user to position themselves with their mouse … so we introduce a button for that, that the user can click … but how does the user do what was considered in the early days of all graphical application work … “pen up” … ie. mouse up … so …
  • if onmouseup (or touchend) gets triggered we want it not to draw lines but be ready to resume (like a yellow light on the traffic light) … and when in this mode …
  • if onmousedown gets triggered while “the traffic light is yellow” (ie. in the mode above) we want it to start to draw lines again with any mouse moves … and to call the whole thing off …
  • if the keyboard is used stop any “Scribble” operations (or click the crossed out button supplied) (like a red light on the traffic light)

Reinventing penmanpersonship is a bit of a stretch, but nevertheless, adds a degree of authenticity to your content, for this is what you are doing, should you go on and email your work as an email attachment … you become an uploader of content … yet again, no doubt. This is a lot more common on the net for all of us, as each day passes. Maybe also, as each night passes. Even as Collingwood streams down the left wing, and passes, no doubt.

Yet again, our world.html did not need to change for this new “Scribble” functionality but our external Javascript you could call world.js changed quite a bit, setting up these mouse (or touch) event logics, as its Javascript “setTimeout” delayed onload function …



function touchHandler(event) // thanks to //stackoverflow.com/questions/1517924/javascript-mapping-touch-events-to-mouse-events
{
var touches = event.changedTouches,
first = touches[0],
type = "";
//if (event.targetTouches.length == 1) {

switch(event.type)
{
//case "touchstart": type="mousedown"; break;
case "touchmove": type="mousemove"; break;
case "touchend": type="mouseup"; break;
default: return;
}

//initMouseEvent(type, canBubble, cancelable, view, clickCount,
// screenX, screenY, clientX, clientY, ctrlKey,
// altKey, shiftKey, metaKey, button, relatedTarget);

var simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(type, true, true, window, 1,
first.screenX, first.screenY,
first.clientX, first.clientY, false,
false, false, false, 0/*left*/, null);

first.target.dispatchEvent(simulatedEvent);

event.preventDefault();
event.stopPropagation();

switch(type)
{
//case "mousedown": if (isScribble == 1) { isScribble=2; } break;
case "mousemove": if (isScribble == 2) {
if (x == 0 && y == 0 && lastx == 0 && lasty == 0) {
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
lastx=x;
lasty=y;
} else {
lastx=x;
lasty=y;
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
}
if (x != lastx || y != lasty) {
document.getElementById('divannotation').style.display='block';
document.getElementById('myisubject').style.display = 'inline';
document.getElementById('myiemail').style.display = 'inline';
context.strokeStyle=document.getElementById('mycolour').value;
context.beginPath();
context.moveTo(x,y);
context.lineTo(lastx,lasty);
context.stroke();
}
}
break;
case "mouseup": if (isScribble == 2) { isScribble=1; } break;
default: return;
}
}

function tryit() {
var tds=document.getElementsByTagName('td'), hstuff='';
if (tds.length > 0) {
hstuff+="<div style='position: absolute; top:600px; left:860px; display:none; background-color: lightgreen; ' id='divan" + "notation'><h4>Your Annotations++</h4>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/line.png' onclick=' doline(); ' alt='Line' title='Line'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/rectangle.png' onclick=' dorectangle(); ' alt='Rectangle' title='Rectangle'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/rectangleborder.png' onclick=' dorectangleborder(); ' alt='Rectangle Border' title='Rectangle Border'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/circle.png' onclick=' docircle(); ' alt='Circle' title='Circle'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/clear.png' onclick=' clearall(); ' alt='Clear' title='Clear'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/sline.png' onclick=\" alert('Ready to Scribble in two seconds. Any key stroke stops scribbling.'); setTimeout(intwo,2000); \" alt='Scribble' title=''></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/zline.png' onclick=' isScribble=0; ' alt='End of scribble' title='End of scribble'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/image.png' onclick=\" document.getElementById('file').click(); document.getElementById('file').style.display='block'; document.getElementById('dpf').style.display='block'; \" alt='Image' title='Image'></img><input style='display:none;' id='file' type='file' name='file'><div id=dpf style='display:none;'>  <span class='readBytesButtons'><button style='display:none;' data-endbyte='4' data-startbyte='0'>1-5</button><button style='display:none;' data-endbyte='14' data-startbyte='5'>6-15</button><button style='display:none;' data-endbyte='7' data-startbyte='6'>7-8</button><br>... vs Image URL: <input type='url' value='+' onblur='readUBlob(this.value,0,0);' style='width:60%;'></input><br>... Offset X: <input style='width:25%;' id='xoff' type='number' value='0'></input> Offset Y: <input style='width:25%;' id='yoff' type='number' value='0'></input><br><button onclick='readBlob(0,0);'>Place into Canvas</button><button onclick='readOBlob(0,0);'>Overlay into Canvas</button></div><div id='byte_range' style='display:none;'></div><div id='byte_content' style='display:none;'></div><input id='fil' value='' type='hidden'></input><img id='spareimg' src='' style='display:none;'></img>";
hstuff+="<br>Annotation (optional): <input onblur='placeannotation(this);' id='iannotation' type='text' value=''></input><br><span>Anno B&W (optional): <input onblur='placeannotation(this);' id='jannotation' type='text' value=''></input><br>Style: <input type='text' id='myfont' value='18px Verdana'></input> <input type='text' id='mycolour' value='black'></input></span><br>";
hstuff+="<form style='display:none;' id='myform' method='post' enctype='application/x-www-urlencoded' action='//www.rjmprogramming.com.au/HTMLCSS/world.php' target='myiframetwo'><input type='hidden' name='mysubject' id='mysubject' value='My World Map'></input><input type='hidden' name='myfname' id='myfname' value=''></input><input type='submit' id='bsubmit' value='Submit' style='display:none;'></input><input type='hidden' name='ismobile' id='ismobile' value=''></input><input type='hidden' name='mode' id='mode' value='1'></input><input type='hidden' name='to' id='to' value=''></input><input type='hidden' name='mydurl' id='mydurl' value=''></input></form>";
hstuff+="<iframe style='display:none;' id='myiframetwo' src='//www.rjmprogramming.com.au/HTMLCSS/world.php'></iframe>";
hstuff+="<input style='display:none;' onblur='fixmyemail(this.value + String.fromCharCode(32),1);' type='text' id='myisubject' value='My World Map '></input> <input style='background-color: yellow;' type='button' value='Email (optional)' onclick=' capture(document.getElementById(" + '"' + "mydurl" + '"' + "),document.getElementById(" + '"' + "bsubmit" + '"' + "),document.getElementById(" + '"' + "myemail" + '"' + ")); '></input> <a style='display:none;' target='_blank' id='myemail' href='mailto:fill.in.email@address?subject=My%20World%20Map&body='></a><input style='display:none;' onblur='fixmyemail(this.value,0);' type='text' id='myiemail' value='' title='Fill this in for emailed attachment'></input>";
hstuff+="</div>";
if (tds[eval(-1 + tds.length)].innerHTML.indexOf('diva' + 'nnotaxtion') == -1) tds[eval(-1 + tds.length)].innerHTML+=hstuff;
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
var hh = today.getHours();
var minm = today.getMinutes(); //January is 0!
var ss = today.getSeconds();
document.getElementById('myfname').value = "world_" + yyyy + "_" + mm + "_" + hh + "_" + minm + "_" + ss + ".png";
document.getElementById('myform').action = document.getElementById('myform').action.replace('?mode=1', '');
document.getElementById('mode').value = '';
document.getElementById('ismobile').value = 'y';
document.getElementById('myisubject').style.display = 'inline';
document.getElementById('myiemail').style.display = 'inline';
document.getElementById('myform').action = document.getElementById('myform').action.replace('?mode=1', '');
document.getElementById('myform').action = document.getElementById('myform').action.replace('mode=1', 'mode=');
//document.getElementById('myemail').href = '#' + document.getElementById('myemail').href;
}

document.body.addEventListener('keyup', function(event) {
if (isScribble == 2 || isScribble == 1) {
isScribble=0;
}
});

if (isTouch || isiPad) {
//elem.addEventListener("touchstart", touchHandler, true);
elem.addEventListener("touchmove", touchHandler, true);
elem.addEventListener("touchend", touchHandler, true);
elem.addEventListener("touchcancel", touchHandler, true);

//elem.addEventListener('touchstart', function(event) {
// if (isScribble == 1) {
// isScribble=2;
// }
//});

} else {

elem.addEventListener('mouseup', function(event) {
if (isScribble == 2) {
isScribble=1;
}
});

elem.addEventListener('touchend', function(event) {
if (isScribble == 2) {
isScribble=1;
}
});

elem.addEventListener('touchstart', function(event) {
if (isScribble == 1) {
isScribble=2;
}
});

elem.addEventListener('mousedown', function(event) {
if (isScribble == 1) {
isScribble=2;
}
});

elem.addEventListener('mousemove', function(event) {
if (isScribble == 2) {

if (x == 0 && y == 0 && lastx == 0 && lasty == 0) {
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
lastx=x;
lasty=y;
} else {
lastx=x;
lasty=y;
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
}

if (x != lastx || y != lasty) {
document.getElementById('divannotation').style.display='block';
document.getElementById('myisubject').style.display = 'inline';
document.getElementById('myiemail').style.display = 'inline';
context.strokeStyle=document.getElementById('mycolour').value;
context.beginPath();
context.moveTo(x,y);
context.lineTo(lastx,lasty);
context.stroke();
}
}

});

}


setTimeout(tryit, 2000);

… as you can see from this link. Regarding some mobile platform issues we’d like to thank this really useful link … so, thanks. And if actions speak louder than words no doubt you’ll be wanting the live run link.

As for …

We “might” have genericized the world.html changes into other HTMLs of its ilk … well, we decided against that for now … but will later … and partly the reason is that there is more to do, and we just want to concentrate on world.html

… from last time’s Canvas Email Attachment New Image Tutorial as shown below, that still remains the case … there is more to do. Hope to see you back again for that then.


Previous relevant Canvas Email Attachment New Image Tutorial is shown below.

Canvas Email Attachment New Image Tutorial

Canvas Email Attachment New Image Tutorial

When we last left off with Canvas Image Email Attachment External Javascript Tutorial project we posed two ongoing “trailers”/”spoiler alerts” …

  • We “might” have genericized the world.html changes into other HTMLs of its ilk … well, we decided against that for now … but will later … and partly the reason is that there is more to do, and we just want to concentrate on world.html with …
  • Did you guess what functionality we might want to do next? We want to allow the user to “overlay” or “clobber” the existing canvas’s map image with an image of their choosing in one of two entry methods …
    1. via a Browse button selection of an image on their computer … or …
    2. via the specification of a URL pointing at an image (on the web, probably)

We’ve grappled with the relatively newly arrived brilliance of HTML5 with ideas off Browse buttons and their manipulation of file data, the methods of which don’t even need PHP or ASP.Net (or any other server side language) to proceed … cute, huh?! We referenced this great link when we presented PHP/HTML/Javascript Media & Document File Browse Tutorial, and you may want to reference that regarding the useful Javascript HTML5 FileReader methods. Another really useful link for today’s work is … what we just linked … we presume … thanks. We find FileReader.readAsDataURL() method to be just what we want today to take the data of a file as a data URL and be able to use the canvas.drawImage() to place that image data onto the canvas by “overlaying” it or “clobbering” it.

Our world.html did not need to change for this new image friendly functionality but our external Javascript you could call world.js changed quite a bit as you can see from this link.

To envisage all this, you really should try a live run of our interactive World Map (with Annotation and Email Attachment functionality) web application. We hope some Browse button thoughts start springing forth from the bit below the hair (or if you’re standing on your head right now … the bit above the hair).


Previous relevant Canvas Image Email Attachment External Javascript Tutorial is shown below.

Canvas Image Email Attachment External Javascript Tutorial

Canvas Image Email Attachment External Javascript Tutorial

Rome wasn’t built in a day … just read “SPQR A History of Ancient Rome” by Mary Beard, to confirm that. And software takes time, and often revisits and rethinks, in between, running it past people, perhaps. So it is with the build up of our “cause”, which we’ll eventually reveal, that started with Canvas Image Email Attachment Primer Tutorial as shown below, and moves on today, in two directions …

  • Organization wise … we move some of the “Annotation++” functionality specifics to external Javascript … via …

    <script type='text/javascript' src='world.js' defer></script>

    … to be more modular, and to apply it to other web applications like world.html that aren’t world.html (which we will also do event-U-al-ly … maybe even today?! … you’ll see at the end of this blog posting if we have)
  • Functionality wise … we allow for more than “Annotations” now … hence the “Annotation++” notation above … we’ve been delving into our HTML canvas codes for logic to draw lines and rectangles (including a “huge white rectangle” to “clear” the canvas) and circles today

When you redesign arrangements this way, you should retest all the functionality combinations to make sure you haven’t broken anything … because that would be kinda’ stUpid. The adage should be that you leave things better than when you start, to do a good job … doh!

So there’s still an important bit of “base” functionality missing, and we’ll get to that next time, though maybe you’ve guessed what it would be yourself?!

So take a look at our HTML and Javascript and CSS world.html which changed as per this link which now calls on new external Javascript you could call world.js if you like. Unchanged is the concept (and the content) regarding the HTML using PHP server side code you could call world.php within an HTML iframe element. Again, please don’t think you’ll be able to achieve this functionality just with client-side Javascript. It involves server data. So here is a live run link in order for you to try this new functionality, which kicks into action from the second canvas click/touch, and on.

Hint: Don’t be shy to try some “rgba([red0-255],[blue0-255],[green0-255],[opacity0.0-1.0])” colour field possibilities in combination with the filled in rectangle option to improve your “overlay” functionality possibilities, as with today’s main tutorial picture.


Previous relevant Canvas Image Email Attachment Primer Tutorial is shown below.

Canvas Image Email Attachment Primer Tutorial

Canvas Image Email Attachment Primer Tutorial

Maybe you remember the series of blog postings that we last visited with HTML5 Canvas Map Clickaround Onresize Tutorial some time ago? We’ve been, over the last couple of days, working out how to …

  • take an HTML canvas element’s [canvasContext].drawImage() image
  • be able to overlay some interactively entered textual annotations over the top of user entered rectangle corners
  • take a snapshot of this canvas with its annotations via [canvasContext].toDataURL() (woh!)
  • use an HTML form element with method=POST target=myiframetwo to post the data to our (new) PHP (featuring the use of php://input for the first time, for us anyway) … which …
  • emails that snapshot to someone

We allow for …

  1. non-mobile platforms to use their email clients, perhaps, via a body link to an image file stored on the rjmprogramming.com.au domain web server … or, because such functionality is awkward for mobile platforms, we …

  2. allow for the canvas contents be turned into image data that can be used as the data for an email attachment, thus allowing the web server to not have to store the data (there) now

Here’s some of the PHP code to create that email with its attachment, for your perusal (where $idata has that data URL data of the canvas’s contents, that is image/png data (in base64)) …


//$headers = 'From: ' . 'rmetcalfe@rjmprogramming.com.au' . $eol;
$headers = 'Reply-To: ' . 'rmetcalfe@rjmprogramming.com.au' . $eol;
// 'X-Mailer: PHP/' . phpversion();
$contents = "";
if ($idata != "") $contents = $idata;
if (strpos('~' . $mybody, '~http') !== false || $contents != "") {
if ($contents == "") $contents = @file_get_contents($mybody);
if ($contents != '') {
//
date_default_timezone_set('Australia/Perth');
//
//$mysubject .= ' ... ' . $mybody;
$fs = explode("/", $mybody);
$filename = $fs[-1 + sizeof($fs)];
$content = chunk_split(base64_encode($contents));
//
// a random hash will be necessary to send mixed content
$separator = md5(time());
//
$headers .= "MIME-Version: 1.0" . $eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol . $eol;
$headers .= "Content-Transfer-Encoding: 7bit" . $eol;
$headers .= "This is a MIME encoded message." . $eol . $eol;
//
// message
$headers .= "--" . $separator . $eol;
$headers .= "Content-Type: text/plain; charset=\"iso-8859-1\"" . $eol;
$headers .= "Content-Transfer-Encoding: 8bit" . $eol . $eol;
//
$headers .= "Please see attached image below:" . $eol . $eol;
//
// attachment
$headers .= "--" . $separator . $eol;
$headers .= "Content-Type: application/octet-stream; name=\"" . $filename . "\"" . $eol;
$headers .= "Content-Transfer-Encoding: base64" . $eol;
$headers .= "Content-Disposition: attachment;filename=\"" . $filename . "\"" . $eol;
$headers .= $content . $eol . $eol;
$headers .= "--" . $separator . "--";
//
ourpremail($tem, $mysubject, "", $headers); // emails to $tem
}
}

And so, with our proof of concept ideas, the world becomes (hopefully, lots of) our (collective) oyster(s), given a little imagination, here. Really, take a look at our HTML and Javascript and CSS world.html which changed as per this link. It has new PHP server side code you could call world.php within an HTML iframe element. Please don’t think you’ll be able to achieve this functionality just with client-side Javascript. It involves server data. So here is a live run link in order for you to try this new functionality, which kicks into action from the second canvas click/touch, and on.


Previous relevant HTML5 Canvas Map Clickaround Onresize Tutorial is shown below.

HTML5 Canvas Map Clickaround Overlay Tutorial

HTML5 Canvas Map Clickaround Overlay Tutorial

Yesterday we came back after quite some time in the (PHP) server world to some client (Javascript and HTML) work, and today, after yesterday’s HTML5 Canvas Map Clickaround Overlay Tutorial as shown below, we tackle a client Javascript event, the “onresize” event (best intervened with in terms of looking at the Javascript DOM “window” object rather than the “document” object), that is often “left until last” in a programmer’s mind … and often not thought about at all. That’s often me … but not today.

Perhaps the reason it is (often) neglected is that the design (you’ve come up with) leaves lots of room, and the styling “position:absolute;” concept is not used at all with your web application. Yesterday, though, “position:absolute;” is pivotal to the working of the web application, as is the positioning of the HTML canvas element at (0,0) … why? … the slightly glib answer here is that to complicate life is to complicate your web application, and if you can cater for the simple case, why not work with that simple case, with its simplified coding logic?

Okay, so what’s the scenario with yesterday’s HTML5 Canvas Map Clickaround Overlay Tutorial where the Javascript “onresize” event gets triggered. On a laptop or desktop computer, it is when you “drag” (a window corner) and, we anticipate, shrink your window (by then “dropping” (a window corner)) to end up with a window smaller than the set established size, width or height, we cater for with the HTML canvas element’s width or height.

Now we currently rely on the right hand side being the user controlling side, but if a user shrinks the window, and we refuse to get into any “zooming” logic … my strong advice is not to go there … you have two choices to my mind …

  1. “copy” the right hand HTML (into an existant blank HTML div element’s innerHTML) and “overlay” at (0,0) (with less opacity than the rest)
  2. “copy” the right hand HTML and use Javascript (where myWidth is calculated width of the HTML canvas element … remember this functionality from yesterday?) … and use window.open(“”,”Title”,”top=0px,left=” + eval(20 + myWidth) + “px,width=350px,height=600px”) (along with a global variable wadd) … for a popup window, as per …

    wadd = window.open("","Your Place and Airports Map Goes Here ...","top=0px,left=" + eval(20 + myWidth) + "px,width=350px,height=600px");
    and then use wadd.document.write([someHTML]) … as per …

    var newhtml="<!doctype html><html><head>" + document.head.innerHTML + "</head><body>" + document.getElementById('dhuh').innerHTML.replace(/opacity:0.0;/g, "opacity:1.0;").replace('"Cloudy"', '').replace('id="myqiframe', 'id="myiframe').replace('id="mypqiframe', 'id="mypiframe').replace('id="myqa', 'id="mya');
    wadd.document.write(newhtml);

You’ve probably guessed by the added detail in the second of above, the first idea was awkward, but if you want to pursue it yourself, via leads, look for the (left in) if (additional != ”) { } logic parts in the HTML/Javascript coding of cloudy_world.html (or try the live run).

We later use a Javascript setTimeout() call to wait a while while the hidden right hand side’s HTML iframe element is filled out with the Airport Data Near Your World Map Clicked Position, and through that knowledge over to the “wadd” window (where it is viewable, presumably … unless you’ve repositioned again (which is okay to test if you want)).

So, today, everything should be as per yesterday with no “resizing” (and of course the programmer adage to “not make things backward in functionality” would tell you that to hold onto this “tooth and nail” should be thought of as extremely important … probably of higher priority than any new functionality … think probably users get pretty annoyed by things that used to work, not working later, because of your own newly introduced bug).

It behoves me, my liege, to leave you with the HTML/Javascript code differences, to make this happen, from yesterday, here, and we hope it helps you in some small way. We also want to thank the “powers that be” for the excellent advice at this link, for this topic … thanks, as always.


Previous relevant HTML5 Canvas Map Clickaround Overlay Tutorial is shown below.

HTML5 Canvas Map Clickaround Overlay Tutorial

HTML5 Canvas Map Clickaround Overlay Tutorial

After some time in the (PHP) server world, it’s time to dive back into some client (Javascript and HTML) work, in this client/server world of web applications.

Today we revisit the “overlay” theme of blog postings, as the web application world is full of possibilities for overlay ideas.

This time we overlay an HTML div element completely on top of an HTML canvas element, with some opacity (or some transparency), during the body “onload” event. We do not adjust the DOM “z-index” style property for either element. So what happens in this scenario when you click on this “multiple” HTML element combination? Well, it pans out you click on the HTML div element, so we have another task to do at the body “onload” event, to see things right, regarding the working of this web application, which starts where we left off with HTML5 Canvas Map Clickaround Follow Up Tutorial as shown below.

From this basis, this is how we got to today … there was HTML cloudy_world.html that changed like here.

You’ll see in the code above some great code presented at useful link (thanks) which is great for defining an HTML element’s size via …


function SetBox(what) {
var div = document.getElementById(what);
if (div.getBoundingClientRect) { // Internet Explorer, Firefox 3+, Google Chrome, Opera 9.5+, Safari 4+
// do stuff
}
}

… and we hope you can see that the implications for “overlay” ideas you have are huge … and that is fine … but you may wonder how the HTML div element is made to drape right over all the canvas element … well, it uses styling as per …

  • position: absolute;
  • top and left and width and height parameters are all defined
  • borderTop defined as having a size the same as height above as per our HTML div id=’boxdiv’ element …

    document.getElementById('boxdiv').style.position = 'absolute';
    document.getElementById('boxdiv').style.top = y + "px";
    document.getElementById('boxdiv').style.left = x + "px";
    document.getElementById('boxdiv').style.width = w + "px";
    document.getElementById('boxdiv').style.height = h + "px";
    document.getElementById('boxdiv').style.borderTop = h + 'px solid rgba(255,255,255,0.5)';

… and you’ll also see with the code how the HTML div id=’boxdiv’ element’s “onclick” details are transferred to the (effectively underlying) HTML canvas element, where all the previous business logic of the web application resided, and continues to function (once you make variables “x” and “y” global and control how they are derived at the HTML div id=’boxdiv’ element’s “onclick” event logic).

So please try the live run to see all this in action.


Previous relevant HTML5 Canvas Map Clickaround Follow Up Tutorial is shown below.

HTML5 Canvas Map Clickaround Follow Up Tutorial

HTML5 Canvas Map Clickaround Follow Up Tutorial

HTML5 brought in the incredibly useful “canvas” element, for the first time. Its existence opens up a whole new world of possibilities for web applications that are graphical by nature, as we saw yesterday with HTML5 Canvas Map Clickaround Primer Tutorial as shown below. Today, we extend that functionality as of yesterday, by adding the use of a public data feed to enhance the information we present with the Google Map “iframe” we use, and for this we need to thank, profusely, The Global Airport Database project by Arash Partow … thanks very much. Now this database (really a file), as you can imagine, has data that changes over time, so is probably best used as a data feed. Nevertheless, the exercise of using it as a snapshot is useful, and we go ahead and show the nearest 4 airports on the database, in that Google Map “iframe” as of April, 2015.

This involved the use of PHP (intair.php) to read the file and parse it, which wasn’t hard as it contains well formed “:” delimited data, and there is just the check needed for security hidden data given a latitude and longitude of zero … unless I’m mistaken, and where the water goes down the sink the other way as you cross the equator due south of London has several hundred microscopic airports run by ants … what a movie script?!

With the canvas element’s drawImage() method, we use to position the image map of interest, you can draw more than your own geometrical constructs, you can have an image, and that image could be a map, as for today’s “World Clickaround” web application (with access to maps of Brazil and Ireland and United States of America too), where you click on the map (and thanks to mapsofworld.com for downloadable free maps here) to show a Google Map of interest via Google Chart Map Chart. Maybe you can use the map of the World to …

  • plan a trip
  • look up where relatives live
  • count the fire hydrants in Monaco

This web application calls on tiny bits of mapping knowledge, namely the “orientation” of your “map”, as you are effectively digitizing to show where you want your Google Map to zoom in on.

Please have a go of our live run or download the HTML programming source code you could call world.htm (brazil.htm, ireland.htm, united_states.htm), or do both?!

From yesterday, this is how we got to today … there was new PHP you could call intair.php … and then there was changed HTML, the changes for which look like … world.htm, brazil.htm, ireland.htm, united_states.htm


Previous relevant HTML5 Canvas Map Clickaround Primer Tutorial is shown below.

HTML5 Canvas Map Clickaround Primer Tutorial

HTML5 Canvas Map Clickaround Primer Tutorial

HTML5 brought in the incredibly useful “canvas” element, for the first time. Its existence opens up a whole new world of possibilities for web applications that are graphical by nature.

With the canvas element’s drawImage() method you can draw more than your own geometrical constructs, you can have an image, and that image could be a map, as for today’s “Ireland Clickaround” web application (with access to maps of Brazil and United States of America and the World too), where you click on the map (and thanks to mapsofworld.com for downloadable free maps here) to show a Google Map of interest via Google Chart Map Chart. Maybe you can use the map of Ireland to …

  • plan a trip
  • look up where relatives live
  • imagine you’re in O’Connell Street

This web application calls on tiny bits of mapping knowledge, namely the “orientation” of your “map”, as you are effectively digitizing to show where you want your Google Map to zoom in on.

This is one of those occasions that your (simple) software is a lot more effective using the Mercator map projection (that exaggerates the polar areas (like you might have had at school) because the simple latitude and longitude distances everywhere are the same (but relative areas definitely are not (ie. much bigger than reality near the poles))). Unfortunately, our United States of America projection is not Mercator, but you’ll still get a “ball park” Google Maps feel.

So we can have it that if the user doesn’t zoom, they need no orientation checks, but otherwise we need to determine a scale, by the user clicking on Dublin, on the map, and from that, we can work out the scaling that needs to be applied, as the top left co-ordinate is arranged to be (0,0) via the style=”position: absolute; top:0; left:0; “ part of …


<canvas id="canvaselement" width=600 height=600 style="position: absolute; top:0; left:0; " />

Please have a go of our live run or download the HTML programming source code you could call ireland.html (brazil.html, united_states.html, world.html), or do both?!

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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

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

Animated GIF Via Sequenced Images Tutorial

Animated GIF Via Sequenced Images Tutorial

Animated GIF Via Sequenced Images Tutorial

The “making of” animated GIF (explanatory image) for yesterday’s World Clickarounds Google Map Chart Onclick Logic Tutorial involved more than ten (but today we’ll be using ten) images that had to be entered in our inhouse web application, here, to create animated GIFs, as fully defined absolute URLs. The frustrating thing about that is that the image URLs formed a pattern with their naming as per …

IMG_1385.JPG … through to, incrementing the count by one (ie. 8 images here in middle) … IMG_1394.JPG

… but why not allow our web application be more savvy and user friendly and less error prone by letting the user define all these ten URLs in the one new interactive entry

IMG_1385-1394.JPG
IMG_1385.JPG … through to, incrementing the count by one (ie. 8 images here in middle) … IMG_1394.JPG

… the understanding with the code logic being we first check that IMG_1385-1394.JPG is not an existant URL when interpreting that “-” (minus) delimitation as flagging one of these “range entries”? That one entry will cause the other nine URLs to be filled in, and that first one replaced with IMG_1385.JPG as its entry.

Maybe you are perplexed that we have a PHP web application here, and we can’t be helped out by good ol’ glob. Well, glob is just for local web files, not absolute URLs (though an absolute URL of the same domain as the web application sits can be turned into a local file definition). So only think glob (in the morning, afternoon tea, dusk and supper time … but we digress) when this local file situation can be “worked” into a wildcard (eg. * (any number of) and ? (one character) and ones like [0-9] (for range of (integer) characters)).

To make our web application “do its stuff” here, we use two techniques …

  • at the parent level of its PHP run of HTML we use “client pre-emptive iframe” (like “suck it and see” loading of an image into an iframe, and look for success versus problems) methodologies to determine if a URL definition with a “-” is an image file (ie. in iframe, it will succeed) or a range definition (ie. in iframe, it will fail) … then, just for that “fail” scenario …
  • we call (the same PHP (added to) codeset) in an iframe via the Javascript call …

    function more(what) { // we know image range URL (with "-"), ID of calling input textbox, prefix of URL before numbers, suffix of URL after numbers, count of images so far making up animated GIF definition, number to indicate offset to apply to number to get to the next one, end number (as applicable), start number
    return document.URL.split('#')[0].split('?')[0] + '?urlminus=' + encodeURIComponent(what) + '&lastioid=' + encodeURIComponent(lastioid) + '&upprefix=' + encodeURIComponent(upprefix) + '&upsuffix=' + encodeURIComponent(upsuffix) + '&icnt=' + encodeURIComponent(icnt) + '&incis=' + encodeURIComponent(incis) + '&upto=' + encodeURIComponent(upto) + '&thisto=' + encodeURIComponent(thisto);
    }

    … to have today’s new (self contained) PHP code below fill out the other individual URLs within the range as well as amending the first to be that first (has to be existant) URL at the start of the URL image (integer numerical) range, helped out enormously by good ol’ file_get_contents

    if (isset($_GET['urlminus']) && isset($_GET['icnt']) && isset($_GET['lastioid']) && isset($_GET['incis']) && isset($_GET['upprefix']) && isset($_GET['upsuffix']) && isset($_GET['upto']) && isset($_GET['thisto'])) {
    $urlminus=str_replace("+"," ",urldecode($_GET['urlminus']));
    $upprefix=str_replace("+"," ",urldecode($_GET['upprefix']));
    $upsuffix=str_replace("+"," ",urldecode($_GET['upsuffix']));
    $lastioid=str_replace("+"," ",urldecode($_GET['lastioid']));
    $incis=str_replace("+"," ",urldecode($_GET['incis']));
    $icnt=str_replace("+"," ",urldecode($_GET['icnt']));
    $upto=str_replace("+"," ",urldecode($_GET['upto']));
    $thisto=str_replace("+"," ",urldecode($_GET['thisto']));
    $scris="";
    $cis=file_get_contents(str_replace('https:','http:',$urlminus));
    if ($cis != "") {
    $scris.="\n<scr" . "ipt type='text/javascript'>\n";
    $scris.="\n var icnt=eval(-1 + " . $icnt . "), lastio='" . $lastioid . "', fo=null, newi=null; \n function dothis() { \n";
    $scris.="\n if (icnt == 1) { \n";
    $scris.="\n parent.document.getElementById('slideshow').value='" . $urlminus . "'; \n } else if (lastio != '') { parent.document.getElementById(lastio).value='" . $urlminus . "'; \n } \n";
    if ("$icnt" == "2" || "$lastioid" != "") { $urlminus=""; }
    while ($cis != "") {
    $sc=strlen($cis);
    $scris.="\n if ('" . $sc . "' != '1') { \n";
    $scris.="\n fo=parent.document.getElementById('fdiv' + icnt); \n";
    $scris.="\n icnt++; \n";
    $scris.="\n newi=parent.document.getElementById('slideshow' + icnt); \n";
    $scris.="\n if (newi) { if (newi.innerHTML.length == 0) { newi=null; } } \n";

    $scris.="\n if (fo != null && newi == null) { \n";
    $scris.="\n if (fo.id == 'slideshow') { fo.value='" . $urlminus . "'; } else { fo.innerHTML+=\"Tutorial Slideshow Image \" + icnt + \" <input title='Please note a minus between numericals can define a URL range of image URLs' onblur='maybemore(this.value, this.id, this);' style='width:70%;' type='text' id='slideshow\" + icnt + \"' name='slideshow\" + icnt + \"' value='" . $urlminus . "'></input><br><br><div id='fdiv\" + icnt + \"'></div>\"; } \n";
    $scris.="\n } \n";
    $scris.="\n } \n";
    if ("$thisto" == "$upto" || ((-1 + $thisto) < $upto && "$incis" == "-1") || ((1 + $thisto) > $upto && "$incis" != "-1")) {
    $cis="";
    } else {
    if ("$incis" == "-1") {
    $thisto--;
    $urlminus=$upprefix . $thisto . $upsuffix;
    $cis=file_get_contents(str_replace('https:','http:',$urlminus));
    if ("$upto" != "" && $cis == "") { $cis=" "; }
    } else {
    $thisto++;
    $urlminus=$upprefix . $thisto . $upsuffix;
    $cis=file_get_contents(str_replace('https:','http:',$urlminus));
    if ("$upto" != "" && $cis == "") { $cis=" "; }
    }
    }
    }
    $scris.="\n } \n </scr" . "ipt>\n";
    }
    if ($scris != "") {
    echo "<!doctype html><html><head>" . $scris . "</head><body onload=dothis();> </body></html>";
    }
    exit;
    }

See what we mean with the changed tutorial_to_animated_gif.php‘s animated GIF creator live run in action below …


Previous relevant World Clickarounds Google Map Chart Onclick Logic Tutorial is shown below.

World Clickarounds Google Map Chart Onclick Logic Tutorial

World Clickarounds Google Map Chart Onclick Logic Tutorial

Revisiting our World Clickaround web applications today, last talked about with Canvas Annotation Email Attachment User Acceptance Tutorial, we were gobsmacked that we hadn’t defaulted their use of the Google Chart Map Charts integrated in, to allow for inhouse “onclick” (via a Google Chart select event) logic.

Without this integration you miss being able to click near a place and …

  • use “Z” option to find nearest TimeZone (and then onto option “W” Weather) and option “T” for TimeZone information
  • use “S” for Sun Angle … and others of that ilk … and …
  • use “G” for (navigating to) various Google Map views
  • use “Y” for YouTube video lookup (though one of the nearest Airports (that have a known name) may do better here
  • use “A” for Nearest Airports (though you probably got this up already)

… anyway … didn’t want these possibilities to be hidden any longer.

The fix was very simple applied to many HTML web applications (as below), that being to add &onclick=y into the map.php based URLs in the code linking to our Google Chart Map Chart interfacing.


Previous relevant Canvas Annotation Email Attachment User Acceptance Tutorial is shown below.

Canvas Annotation Email Attachment User Acceptance Tutorial

Canvas Annotation Email Attachment User Acceptance Tutorial

An important part of a web (or desktop or mobile) application is user acceptance. User acceptance is, as the words would imply, the giving of your (developing) web application to real users, to test out usability … or UX (user experience). We do this today for our “Canvas Annotation Email Attachment” web application, and use it to “Annotate” a make believe trip, some of the “talking points” of which are “overlayed” on our “Welcome to Nation” map introduced a couple of days ago when we presented Canvas Annotation Email Attachment Transparency Tutorial and this resulted in an email sent with the attachment as you see in today’s tutorial picture.

User acceptance often throws up surprising findings, some easy to handle, and others that are likely to be extremely hard to implement, or impossible, or unworkable at this time. We addressed some of the easier ones to improve the web application, as listed below …

  1. as far as “overlay” thoughts go overlaying a transparent image on top of a clean map goes, we found, before user acceptance, that we would have had to type in the URL to the web application, again, at the address bar, rather than having a way to do it in the web application, so we turned the “Your” in “Your Annotations++” to be a dropdown, that if you change its value, you start the web application again, and can immediately arrange to overlay what you may have emailed off (to yourself, possibly) and downloaded locally onto your hard disk
  2. (after the email today … alas) … as far as the red or yellow click/touch blobs appearing (a little annoyingly) during Annotation operations, we allow you, now, to click on any part of the green bit of the Annotation menu, to turn off these blobs … alas … and you may want to do your own research, perhaps starting at this very useful link we “bit the bullet” and made non-generic HTML changes, as well as generic external Javascript changes, to allow for this … adding a new global variable blobc containing the colour of the “blob” … no, not that “blob”, this ..
  3. allow an original URL image to be supplied on the address bar URL as with this URL for today’s “fantasy trip” from “Alice Springs to Broome”

… and so what functionality features featured in our user acceptance test …

Again, for today’s work, the external Javascript world.js needed to change (regarding the user acceptance testing) like this today, regarding this new “Canvas Annotation Email” image fitting ideas, and our (common) PHP you could call intair.php is unchanged for any/all of (changed slightly) …

Hope you will try some or all of these web applications, and their “Canvas Annotation” and “Email Attachment” functionality, maybe even in a real world situation, emailing the results out to somebody, perhaps?


Previous relevant Canvas Annotation Email Attachment Image Fit Tutorial is shown below.

Canvas Annotation Email Attachment Image Fit Tutorial

Canvas Annotation Email Attachment Image Fit Tutorial

There is still more to do with regard to image manipulations functionality regarding our “Canvas Annotation Email Attachment” and “Clickaround” web applications. We want to be able to offer image scaling via user defined click or touch event outcomes on our HTML canvas.

What we do today in the form of a new HTML select element dropdown containing image placement options …

  1. place or overlay images not according to user click or touch events on the HTML canvas element, but use other “Annotation++” menu settings
  2. fit the image into the rectangle formed by the user’s last two click or touch canvas co-ordinates
  3. fit the image into the rectangle width, only, formed by the user’s last two click or touch canvas co-ordinates
  4. fit the image into the rectangle height, only, formed by the user’s last two click or touch canvas co-ordinates

The workings of this new functionality includes the HTML canvas methods …

So, for today’s work, only the external Javascript world.js needed to change like this today, regarding this new “Canvas Annotation Email” image fitting ideas, and our (common) PHP you could call intair.php is unchanged for any/all of …

Hope you will try some or all of these web applications, and their “Canvas Annotation” and “Email Attachment” functionality.


Previous relevant Canvas Annotation Email Attachment Transparency Tutorial is shown below.

Canvas Annotation Email Attachment Transparency Tutorial

Canvas Annotation Email Attachment Transparency Tutorial

We’ve thought of some more useful functionality regarding our “Canvas Annotation Email Attachment” and “Clickaround” web applications. To explore possibilities here going forward, and with regard to ideas regarding genericization possibilities, which aren’t a straightforward “yes” decision for today’s ideas.

What we do today is …

  1. we add to the “Where Is?” functionality of “Clickaround” web applications that we first talked about with Canvas Clickaround Where Is Primer Tutorial by allowing not only a Place Name (of an Airport) to be the only option that results in active usefulness with the web application, but also allow that same HTML input type=text element to specify a latitude;longitude[;placeName] for the case of the majority of places on Earth that don’t have an airport
  2. we add an extra functionality type similar to the “Undo” button of Canvas Annotation Email Attachment Undo Tutorial as shown way below that simply undoes the HTML canvas original image (the map), replacing it with a transparent background HTML canvas element that is then loaded with all the rest of the new Annotations you, the user, had added, since … hope you can see how useful this idea could be for a whole new set of “overlay” thoughts, which we’ll endeavour to refine in your mind as time goes on
  3. we add a whole new “Clickaround” and “Canvas Annotation Email Attachment” web application we are calling “Welcome To Nation” because we use the wonderful map developed by TreatyRepublic.net, thanks, in the tutorial sequence culminating in Australian Indigenous Language HTML Map jQuery YQL Tutorial

Now that second new functionality we are trialling with that new third new HTML and Javascript source code welcometonation.html with its live run link.

Often with genericization possibilities, the detail of how things could work, or perhaps not, in a “generic way”, are best “played out” in terms of a new “player” into the scene. So that is how we proceed today. This trialling also affects that first piece of functionality, with “Welcome to Nation” usage, having the window.open() “compiler” of selected “Where Is?” dropdown selections opening back in the “welcometonation.html” rather than the default (for all other “Clickaround” web applications, as it stands right now) “world.html” … a job to do here, for later, is to check that the user’s “latitude;longitude[;placeName]” entry falls within that “subset” map of the world … no such checks here today.

Anyway, going through this motion … yes … we found there is thinking to do making “genericization” of that second functionality idea work, and this is for tomorrow, and on. As is explaining how “overlay” possibilities expand here with that second idea above.

But the real wonder is in the intricacy of the culture, “the oldest surviving culture in the world”, of the Koori people, the first people of Australia, and so with that third option’s new Welcome to Nation web application is a new first option of the “web application” “Clickaround” dropdown at the right that points at the HTML map element Indigenous Australian Language Map web application Indigenous Australian Language Regions, where you point at a region and can open search engine and other information relevant to that indigenous language and peoples of interest.

So, for today’s work, the external Javascript world.js needed to change like this today, regarding this new “Canvas Annotation Email” background transparency idea, and our (common) PHP you could call intair.php changed quite a bit, as it controls “Where Is?” functionality ideas to any/all of …

Hope you try some or all of these out.


Previous relevant Canvas Annotation Email Attachment Scale and Clip Tutorial is shown below.

Canvas Annotation Email Attachment Scale and Clip Tutorial

Canvas Annotation Email Attachment Scale and Clip Tutorial

We’ve been busy continuing on with our Annotations functionality quest, specifically regarding Image content for Annotations, and the ability to be able to Scale and Clip (or crop) those images within the HTML canvas element that hosts them. This is also part of the functionality we need in our “toolbox” for our eventual destination with all this Annotation (with optional Email Attachment) functionality.

Some considerations with Scale, Clip and Rotation (the latter of which we first set our sights on with Canvas Annotation Email Attachment Rotation Tutorial as shown below) thoughts are …

  • what should the origin point of rotation be? … we follow the lead of this excellent link … thanks … and choose the centre of the canvas element … but also as of today’s work we offer the last click/touch position to be an option for positioning
  • should the canvas dimensions change? … this is debatable … and we continue, for now, to say “no” to this … but we are still open to changing this
  • do you rotate all canvas content or just an added image’s content? … we allow for both modes of use … we’ve added the ability for Annotation computer font text to rotate, as of today, as well
  • what should the origin point of clipping be? … we allow a percentage or pixel user defined method of defining

Today’s scaling and clipping calls on the full canvas.drawImage() specification. Up to now we’ve only ventured to the first of the three incarnations of ctx.drawImage calls below …

void ctx.drawImage(image, dx, dy);
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

… as you can read more about at that great link … but we make use of all three with today’s work, especially the third call with the clipping parameters “sx, sy, sWidth, sHeight” supplementing scaling parameters “dWidth, dHeight”.

So yet again, no HTML files needed to change today, and our (common) external Javascript you could call world.js changed quite a bit, adding Scaling and Clipping functionality to the recently added Rotation functionality affecting any/all of …

We’ll be back to explain more soon.


Previous relevant Canvas Annotation Email Attachment Rotation Tutorial is shown below.

Canvas Annotation Email Attachment Rotation Tutorial

Canvas Annotation Email Attachment Rotation Tutorial

It’s time to return to Annotations, specifically Image content for Annotations, and the ability to be able to Rotate those images, or the whole HTML canvas element that hosts them. It’s part of the functionality we need in our “toolbox” for our eventual destination with all this Annotation functionality.

Some considerations with Rotation thoughts are …

  • what should the origin point of rotation be? … we follow the lead of this excellent link … thanks … and choose the centre of the canvas element
  • should the canvas dimensions change? … this is debatable … and we have, for now, said “no” to this … but we are open to changing this, along with “cropping” and “scaling” and “specified offsets for rotated images” for follow up tutorials
  • do you rotate all canvas content or just an added image’s content? … we allow for both modes of use

Along the way, today, we thought we should add, at least for non-mobile platforms with an “onmouseover” event (available), the means to show “canvas” co-ordinates to assist these users with “Offset X and Y” decisions, perhaps.

Once again, no HTML files needed to change today, and our (common) external Javascript you could call world.js changed quite a bit, adding Rotation functionality affecting any/all of …


Canvas Annotation Email Attachment Undo Tutorial is shown below.

Canvas Annotation Email Attachment Undo Tutorial

Canvas Annotation Email Attachment Undo Tutorial

A web application allowing user defined Annotations is better when there is an “Undo” and “Redo” functionality option. This is because with any user intervention, there can be erroneous work, which sometimes can be a real pain to recover from scratch.

With “Undo” and “Redo” functionality, however, you do not want the user to think it is as much a part of the “mainstream” of the web application’s functionality, so we supply a “-” (minus) button for “Undo” and a “+” (plus) button for “Redo”, and make them smaller than other Annotation functionality buttons.

So how do we achieve this functionality? We actually do it by actually …

  1. always clearing the contents of the HTML canvas element
  2. always place the original image via canvas.drawImage() method
  3. calling on a stored Javascript array containing HTML canvas drawing statements, flagging the ones that represent a single user defined action, that one “single user defined action” being what an “Undo” or “Redo” action works regarding

There is a great resource for information about the Javascript “Array” object called ECMAScript® Language Specification (we got to via this link, which is also excellent as an “Array” object member functionality synopsis (and which we urge you to consult), thanks).

You may wonder about how canvas.drawImage() parameter 1 (an image object) is handled. We assume you will only be interested in “Undo”s and “Redo”s of the last image (object) involved, which is stored in a global variable (and rereferenced by “Undo” and/or “Redo”) when the Annotations are created (and built up) by the user.

So yet again, our world.html (with its live run) did not need to change for this new “Undo”/”Redo” functionality but our external Javascript you could call world.js changed quite a bit, setting up these Javascript arrays storing HTML canvas commands, for later use in “Undo” and “Redo” scenarios instigated by users clicking the relevant respective (small) “-” and “+” buttons.

As for …

We “might” have genericized the world.html changes into other HTMLs of its ilk … well, we decided against that for now … but will later … and partly the reason is that there is more to do, and we just want to concentrate on world.html

… we can now apply changes to the other HTML web applications …

Also changing is the email attachment PHP helper you could call world.php changed in this way.

Hope this HTML canvas web application set gives you some ideas for work of your own. To read some of the background to this, try Canvas Email Attachment Scribble Tutorial as shown below.


Previous relevant Canvas Email Attachment Scribble Tutorial is shown below.

Canvas Email Attachment Scribble Tutorial

Canvas Email Attachment Scribble Tutorial

Personally think that Annotations are better when there is a “Scribble” functionality option. Perhaps you want to “sign off” on your Annotations. Without a “Scribble” option, it’s a bit impersonal relying on computer fonts as the means by which you “sign” the work.

And down the track it’s helping with our “final aim”, which will be revealed as time goes on.

To “Scribble” the main mouse event that interests us is the “onmousemove” event which happens when the mouse … moves … in which case if you are in “Scribble” mode, draw a line between the last two data points. So from that you would glean, and we’ll fill in, as well, that …

  • the user needs to tell the computer it wants to start into “Scribble” mode (like a green light on the traffic light) … after a 2 second delay to allow the user to position themselves with their mouse … so we introduce a button for that, that the user can click … but how does the user do what was considered in the early days of all graphical application work … “pen up” … ie. mouse up … so …
  • if onmouseup (or touchend) gets triggered we want it not to draw lines but be ready to resume (like a yellow light on the traffic light) … and when in this mode …
  • if onmousedown gets triggered while “the traffic light is yellow” (ie. in the mode above) we want it to start to draw lines again with any mouse moves … and to call the whole thing off …
  • if the keyboard is used stop any “Scribble” operations (or click the crossed out button supplied) (like a red light on the traffic light)

Reinventing penmanpersonship is a bit of a stretch, but nevertheless, adds a degree of authenticity to your content, for this is what you are doing, should you go on and email your work as an email attachment … you become an uploader of content … yet again, no doubt. This is a lot more common on the net for all of us, as each day passes. Maybe also, as each night passes. Even as Collingwood streams down the left wing, and passes, no doubt.

Yet again, our world.html did not need to change for this new “Scribble” functionality but our external Javascript you could call world.js changed quite a bit, setting up these mouse (or touch) event logics, as its Javascript “setTimeout” delayed onload function …



function touchHandler(event) // thanks to //stackoverflow.com/questions/1517924/javascript-mapping-touch-events-to-mouse-events
{
var touches = event.changedTouches,
first = touches[0],
type = "";
//if (event.targetTouches.length == 1) {

switch(event.type)
{
//case "touchstart": type="mousedown"; break;
case "touchmove": type="mousemove"; break;
case "touchend": type="mouseup"; break;
default: return;
}

//initMouseEvent(type, canBubble, cancelable, view, clickCount,
// screenX, screenY, clientX, clientY, ctrlKey,
// altKey, shiftKey, metaKey, button, relatedTarget);

var simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(type, true, true, window, 1,
first.screenX, first.screenY,
first.clientX, first.clientY, false,
false, false, false, 0/*left*/, null);

first.target.dispatchEvent(simulatedEvent);

event.preventDefault();
event.stopPropagation();

switch(type)
{
//case "mousedown": if (isScribble == 1) { isScribble=2; } break;
case "mousemove": if (isScribble == 2) {
if (x == 0 && y == 0 && lastx == 0 && lasty == 0) {
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
lastx=x;
lasty=y;
} else {
lastx=x;
lasty=y;
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
}
if (x != lastx || y != lasty) {
document.getElementById('divannotation').style.display='block';
document.getElementById('myisubject').style.display = 'inline';
document.getElementById('myiemail').style.display = 'inline';
context.strokeStyle=document.getElementById('mycolour').value;
context.beginPath();
context.moveTo(x,y);
context.lineTo(lastx,lasty);
context.stroke();
}
}
break;
case "mouseup": if (isScribble == 2) { isScribble=1; } break;
default: return;
}
}

function tryit() {
var tds=document.getElementsByTagName('td'), hstuff='';
if (tds.length > 0) {
hstuff+="<div style='position: absolute; top:600px; left:860px; display:none; background-color: lightgreen; ' id='divan" + "notation'><h4>Your Annotations++</h4>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/line.png' onclick=' doline(); ' alt='Line' title='Line'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/rectangle.png' onclick=' dorectangle(); ' alt='Rectangle' title='Rectangle'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/rectangleborder.png' onclick=' dorectangleborder(); ' alt='Rectangle Border' title='Rectangle Border'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/circle.png' onclick=' docircle(); ' alt='Circle' title='Circle'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/clear.png' onclick=' clearall(); ' alt='Clear' title='Clear'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/sline.png' onclick=\" alert('Ready to Scribble in two seconds. Any key stroke stops scribbling.'); setTimeout(intwo,2000); \" alt='Scribble' title=''></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/zline.png' onclick=' isScribble=0; ' alt='End of scribble' title='End of scribble'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/image.png' onclick=\" document.getElementById('file').click(); document.getElementById('file').style.display='block'; document.getElementById('dpf').style.display='block'; \" alt='Image' title='Image'></img><input style='display:none;' id='file' type='file' name='file'><div id=dpf style='display:none;'>  <span class='readBytesButtons'><button style='display:none;' data-endbyte='4' data-startbyte='0'>1-5</button><button style='display:none;' data-endbyte='14' data-startbyte='5'>6-15</button><button style='display:none;' data-endbyte='7' data-startbyte='6'>7-8</button><br>... vs Image URL: <input type='url' value='+' onblur='readUBlob(this.value,0,0);' style='width:60%;'></input><br>... Offset X: <input style='width:25%;' id='xoff' type='number' value='0'></input> Offset Y: <input style='width:25%;' id='yoff' type='number' value='0'></input><br><button onclick='readBlob(0,0);'>Place into Canvas</button><button onclick='readOBlob(0,0);'>Overlay into Canvas</button></div><div id='byte_range' style='display:none;'></div><div id='byte_content' style='display:none;'></div><input id='fil' value='' type='hidden'></input><img id='spareimg' src='' style='display:none;'></img>";
hstuff+="<br>Annotation (optional): <input onblur='placeannotation(this);' id='iannotation' type='text' value=''></input><br><span>Anno B&W (optional): <input onblur='placeannotation(this);' id='jannotation' type='text' value=''></input><br>Style: <input type='text' id='myfont' value='18px Verdana'></input> <input type='text' id='mycolour' value='black'></input></span><br>";
hstuff+="<form style='display:none;' id='myform' method='post' enctype='application/x-www-urlencoded' action='//www.rjmprogramming.com.au/HTMLCSS/world.php' target='myiframetwo'><input type='hidden' name='mysubject' id='mysubject' value='My World Map'></input><input type='hidden' name='myfname' id='myfname' value=''></input><input type='submit' id='bsubmit' value='Submit' style='display:none;'></input><input type='hidden' name='ismobile' id='ismobile' value=''></input><input type='hidden' name='mode' id='mode' value='1'></input><input type='hidden' name='to' id='to' value=''></input><input type='hidden' name='mydurl' id='mydurl' value=''></input></form>";
hstuff+="<iframe style='display:none;' id='myiframetwo' src='//www.rjmprogramming.com.au/HTMLCSS/world.php'></iframe>";
hstuff+="<input style='display:none;' onblur='fixmyemail(this.value + String.fromCharCode(32),1);' type='text' id='myisubject' value='My World Map '></input> <input style='background-color: yellow;' type='button' value='Email (optional)' onclick=' capture(document.getElementById(" + '"' + "mydurl" + '"' + "),document.getElementById(" + '"' + "bsubmit" + '"' + "),document.getElementById(" + '"' + "myemail" + '"' + ")); '></input> <a style='display:none;' target='_blank' id='myemail' href='mailto:fill.in.email@address?subject=My%20World%20Map&body='></a><input style='display:none;' onblur='fixmyemail(this.value,0);' type='text' id='myiemail' value='' title='Fill this in for emailed attachment'></input>";
hstuff+="</div>";
if (tds[eval(-1 + tds.length)].innerHTML.indexOf('diva' + 'nnotaxtion') == -1) tds[eval(-1 + tds.length)].innerHTML+=hstuff;
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
var hh = today.getHours();
var minm = today.getMinutes(); //January is 0!
var ss = today.getSeconds();
document.getElementById('myfname').value = "world_" + yyyy + "_" + mm + "_" + hh + "_" + minm + "_" + ss + ".png";
document.getElementById('myform').action = document.getElementById('myform').action.replace('?mode=1', '');
document.getElementById('mode').value = '';
document.getElementById('ismobile').value = 'y';
document.getElementById('myisubject').style.display = 'inline';
document.getElementById('myiemail').style.display = 'inline';
document.getElementById('myform').action = document.getElementById('myform').action.replace('?mode=1', '');
document.getElementById('myform').action = document.getElementById('myform').action.replace('mode=1', 'mode=');
//document.getElementById('myemail').href = '#' + document.getElementById('myemail').href;
}

document.body.addEventListener('keyup', function(event) {
if (isScribble == 2 || isScribble == 1) {
isScribble=0;
}
});

if (isTouch || isiPad) {
//elem.addEventListener("touchstart", touchHandler, true);
elem.addEventListener("touchmove", touchHandler, true);
elem.addEventListener("touchend", touchHandler, true);
elem.addEventListener("touchcancel", touchHandler, true);

//elem.addEventListener('touchstart', function(event) {
// if (isScribble == 1) {
// isScribble=2;
// }
//});

} else {

elem.addEventListener('mouseup', function(event) {
if (isScribble == 2) {
isScribble=1;
}
});

elem.addEventListener('touchend', function(event) {
if (isScribble == 2) {
isScribble=1;
}
});

elem.addEventListener('touchstart', function(event) {
if (isScribble == 1) {
isScribble=2;
}
});

elem.addEventListener('mousedown', function(event) {
if (isScribble == 1) {
isScribble=2;
}
});

elem.addEventListener('mousemove', function(event) {
if (isScribble == 2) {

if (x == 0 && y == 0 && lastx == 0 && lasty == 0) {
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
lastx=x;
lasty=y;
} else {
lastx=x;
lasty=y;
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
}

if (x != lastx || y != lasty) {
document.getElementById('divannotation').style.display='block';
document.getElementById('myisubject').style.display = 'inline';
document.getElementById('myiemail').style.display = 'inline';
context.strokeStyle=document.getElementById('mycolour').value;
context.beginPath();
context.moveTo(x,y);
context.lineTo(lastx,lasty);
context.stroke();
}
}

});

}


setTimeout(tryit, 2000);

… as you can see from this link. Regarding some mobile platform issues we’d like to thank this really useful link … so, thanks. And if actions speak louder than words no doubt you’ll be wanting the live run link.

As for …

We “might” have genericized the world.html changes into other HTMLs of its ilk … well, we decided against that for now … but will later … and partly the reason is that there is more to do, and we just want to concentrate on world.html

… from last time’s Canvas Email Attachment New Image Tutorial as shown below, that still remains the case … there is more to do. Hope to see you back again for that then.


Previous relevant Canvas Email Attachment New Image Tutorial is shown below.

Canvas Email Attachment New Image Tutorial

Canvas Email Attachment New Image Tutorial

When we last left off with Canvas Image Email Attachment External Javascript Tutorial project we posed two ongoing “trailers”/”spoiler alerts” …

  • We “might” have genericized the world.html changes into other HTMLs of its ilk … well, we decided against that for now … but will later … and partly the reason is that there is more to do, and we just want to concentrate on world.html with …
  • Did you guess what functionality we might want to do next? We want to allow the user to “overlay” or “clobber” the existing canvas’s map image with an image of their choosing in one of two entry methods …
    1. via a Browse button selection of an image on their computer … or …
    2. via the specification of a URL pointing at an image (on the web, probably)

We’ve grappled with the relatively newly arrived brilliance of HTML5 with ideas off Browse buttons and their manipulation of file data, the methods of which don’t even need PHP or ASP.Net (or any other server side language) to proceed … cute, huh?! We referenced this great link when we presented PHP/HTML/Javascript Media & Document File Browse Tutorial, and you may want to reference that regarding the useful Javascript HTML5 FileReader methods. Another really useful link for today’s work is … what we just linked … we presume … thanks. We find FileReader.readAsDataURL() method to be just what we want today to take the data of a file as a data URL and be able to use the canvas.drawImage() to place that image data onto the canvas by “overlaying” it or “clobbering” it.

Our world.html did not need to change for this new image friendly functionality but our external Javascript you could call world.js changed quite a bit as you can see from this link.

To envisage all this, you really should try a live run of our interactive World Map (with Annotation and Email Attachment functionality) web application. We hope some Browse button thoughts start springing forth from the bit below the hair (or if you’re standing on your head right now … the bit above the hair).


Previous relevant Canvas Image Email Attachment External Javascript Tutorial is shown below.

Canvas Image Email Attachment External Javascript Tutorial

Canvas Image Email Attachment External Javascript Tutorial

Rome wasn’t built in a day … just read “SPQR A History of Ancient Rome” by Mary Beard, to confirm that. And software takes time, and often revisits and rethinks, in between, running it past people, perhaps. So it is with the build up of our “cause”, which we’ll eventually reveal, that started with Canvas Image Email Attachment Primer Tutorial as shown below, and moves on today, in two directions …

  • Organization wise … we move some of the “Annotation++” functionality specifics to external Javascript … via …

    <script type='text/javascript' src='world.js' defer></script>

    … to be more modular, and to apply it to other web applications like world.html that aren’t world.html (which we will also do event-U-al-ly … maybe even today?! … you’ll see at the end of this blog posting if we have)
  • Functionality wise … we allow for more than “Annotations” now … hence the “Annotation++” notation above … we’ve been delving into our HTML canvas codes for logic to draw lines and rectangles (including a “huge white rectangle” to “clear” the canvas) and circles today

When you redesign arrangements this way, you should retest all the functionality combinations to make sure you haven’t broken anything … because that would be kinda’ stUpid. The adage should be that you leave things better than when you start, to do a good job … doh!

So there’s still an important bit of “base” functionality missing, and we’ll get to that next time, though maybe you’ve guessed what it would be yourself?!

So take a look at our HTML and Javascript and CSS world.html which changed as per this link which now calls on new external Javascript you could call world.js if you like. Unchanged is the concept (and the content) regarding the HTML using PHP server side code you could call world.php within an HTML iframe element. Again, please don’t think you’ll be able to achieve this functionality just with client-side Javascript. It involves server data. So here is a live run link in order for you to try this new functionality, which kicks into action from the second canvas click/touch, and on.

Hint: Don’t be shy to try some “rgba([red0-255],[blue0-255],[green0-255],[opacity0.0-1.0])” colour field possibilities in combination with the filled in rectangle option to improve your “overlay” functionality possibilities, as with today’s main tutorial picture.


Previous relevant Canvas Image Email Attachment Primer Tutorial is shown below.

Canvas Image Email Attachment Primer Tutorial

Canvas Image Email Attachment Primer Tutorial

Maybe you remember the series of blog postings that we last visited with HTML5 Canvas Map Clickaround Onresize Tutorial some time ago? We’ve been, over the last couple of days, working out how to …

  • take an HTML canvas element’s [canvasContext].drawImage() image
  • be able to overlay some interactively entered textual annotations over the top of user entered rectangle corners
  • take a snapshot of this canvas with its annotations via [canvasContext].toDataURL() (woh!)
  • use an HTML form element with method=POST target=myiframetwo to post the data to our (new) PHP (featuring the use of php://input for the first time, for us anyway) … which …
  • emails that snapshot to someone

We allow for …

  1. non-mobile platforms to use their email clients, perhaps, via a body link to an image file stored on the rjmprogramming.com.au domain web server … or, because such functionality is awkward for mobile platforms, we …

  2. allow for the canvas contents be turned into image data that can be used as the data for an email attachment, thus allowing the web server to not have to store the data (there) now

Here’s some of the PHP code to create that email with its attachment, for your perusal (where $idata has that data URL data of the canvas’s contents, that is image/png data (in base64)) …


//$headers = 'From: ' . 'rmetcalfe@rjmprogramming.com.au' . $eol;
$headers = 'Reply-To: ' . 'rmetcalfe@rjmprogramming.com.au' . $eol;
// 'X-Mailer: PHP/' . phpversion();
$contents = "";
if ($idata != "") $contents = $idata;
if (strpos('~' . $mybody, '~http') !== false || $contents != "") {
if ($contents == "") $contents = @file_get_contents($mybody);
if ($contents != '') {
//
date_default_timezone_set('Australia/Perth');
//
//$mysubject .= ' ... ' . $mybody;
$fs = explode("/", $mybody);
$filename = $fs[-1 + sizeof($fs)];
$content = chunk_split(base64_encode($contents));
//
// a random hash will be necessary to send mixed content
$separator = md5(time());
//
$headers .= "MIME-Version: 1.0" . $eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol . $eol;
$headers .= "Content-Transfer-Encoding: 7bit" . $eol;
$headers .= "This is a MIME encoded message." . $eol . $eol;
//
// message
$headers .= "--" . $separator . $eol;
$headers .= "Content-Type: text/plain; charset=\"iso-8859-1\"" . $eol;
$headers .= "Content-Transfer-Encoding: 8bit" . $eol . $eol;
//
$headers .= "Please see attached image below:" . $eol . $eol;
//
// attachment
$headers .= "--" . $separator . $eol;
$headers .= "Content-Type: application/octet-stream; name=\"" . $filename . "\"" . $eol;
$headers .= "Content-Transfer-Encoding: base64" . $eol;
$headers .= "Content-Disposition: attachment;filename=\"" . $filename . "\"" . $eol;
$headers .= $content . $eol . $eol;
$headers .= "--" . $separator . "--";
//
ourpremail($tem, $mysubject, "", $headers); // emails to $tem
}
}

And so, with our proof of concept ideas, the world becomes (hopefully, lots of) our (collective) oyster(s), given a little imagination, here. Really, take a look at our HTML and Javascript and CSS world.html which changed as per this link. It has new PHP server side code you could call world.php within an HTML iframe element. Please don’t think you’ll be able to achieve this functionality just with client-side Javascript. It involves server data. So here is a live run link in order for you to try this new functionality, which kicks into action from the second canvas click/touch, and on.


Previous relevant HTML5 Canvas Map Clickaround Onresize Tutorial is shown below.

HTML5 Canvas Map Clickaround Overlay Tutorial

HTML5 Canvas Map Clickaround Overlay Tutorial

Yesterday we came back after quite some time in the (PHP) server world to some client (Javascript and HTML) work, and today, after yesterday’s HTML5 Canvas Map Clickaround Overlay Tutorial as shown below, we tackle a client Javascript event, the “onresize” event (best intervened with in terms of looking at the Javascript DOM “window” object rather than the “document” object), that is often “left until last” in a programmer’s mind … and often not thought about at all. That’s often me … but not today.

Perhaps the reason it is (often) neglected is that the design (you’ve come up with) leaves lots of room, and the styling “position:absolute;” concept is not used at all with your web application. Yesterday, though, “position:absolute;” is pivotal to the working of the web application, as is the positioning of the HTML canvas element at (0,0) … why? … the slightly glib answer here is that to complicate life is to complicate your web application, and if you can cater for the simple case, why not work with that simple case, with its simplified coding logic?

Okay, so what’s the scenario with yesterday’s HTML5 Canvas Map Clickaround Overlay Tutorial where the Javascript “onresize” event gets triggered. On a laptop or desktop computer, it is when you “drag” (a window corner) and, we anticipate, shrink your window (by then “dropping” (a window corner)) to end up with a window smaller than the set established size, width or height, we cater for with the HTML canvas element’s width or height.

Now we currently rely on the right hand side being the user controlling side, but if a user shrinks the window, and we refuse to get into any “zooming” logic … my strong advice is not to go there … you have two choices to my mind …

  1. “copy” the right hand HTML (into an existant blank HTML div element’s innerHTML) and “overlay” at (0,0) (with less opacity than the rest)
  2. “copy” the right hand HTML and use Javascript (where myWidth is calculated width of the HTML canvas element … remember this functionality from yesterday?) … and use window.open(“”,”Title”,”top=0px,left=” + eval(20 + myWidth) + “px,width=350px,height=600px”) (along with a global variable wadd) … for a popup window, as per …

    wadd = window.open("","Your Place and Airports Map Goes Here ...","top=0px,left=" + eval(20 + myWidth) + "px,width=350px,height=600px");
    and then use wadd.document.write([someHTML]) … as per …

    var newhtml="<!doctype html><html><head>" + document.head.innerHTML + "</head><body>" + document.getElementById('dhuh').innerHTML.replace(/opacity:0.0;/g, "opacity:1.0;").replace('"Cloudy"', '').replace('id="myqiframe', 'id="myiframe').replace('id="mypqiframe', 'id="mypiframe').replace('id="myqa', 'id="mya');
    wadd.document.write(newhtml);

You’ve probably guessed by the added detail in the second of above, the first idea was awkward, but if you want to pursue it yourself, via leads, look for the (left in) if (additional != ”) { } logic parts in the HTML/Javascript coding of cloudy_world.html (or try the live run).

We later use a Javascript setTimeout() call to wait a while while the hidden right hand side’s HTML iframe element is filled out with the Airport Data Near Your World Map Clicked Position, and through that knowledge over to the “wadd” window (where it is viewable, presumably … unless you’ve repositioned again (which is okay to test if you want)).

So, today, everything should be as per yesterday with no “resizing” (and of course the programmer adage to “not make things backward in functionality” would tell you that to hold onto this “tooth and nail” should be thought of as extremely important … probably of higher priority than any new functionality … think probably users get pretty annoyed by things that used to work, not working later, because of your own newly introduced bug).

It behoves me, my liege, to leave you with the HTML/Javascript code differences, to make this happen, from yesterday, here, and we hope it helps you in some small way. We also want to thank the “powers that be” for the excellent advice at this link, for this topic … thanks, as always.


Previous relevant HTML5 Canvas Map Clickaround Overlay Tutorial is shown below.

HTML5 Canvas Map Clickaround Overlay Tutorial

HTML5 Canvas Map Clickaround Overlay Tutorial

After some time in the (PHP) server world, it’s time to dive back into some client (Javascript and HTML) work, in this client/server world of web applications.

Today we revisit the “overlay” theme of blog postings, as the web application world is full of possibilities for overlay ideas.

This time we overlay an HTML div element completely on top of an HTML canvas element, with some opacity (or some transparency), during the body “onload” event. We do not adjust the DOM “z-index” style property for either element. So what happens in this scenario when you click on this “multiple” HTML element combination? Well, it pans out you click on the HTML div element, so we have another task to do at the body “onload” event, to see things right, regarding the working of this web application, which starts where we left off with HTML5 Canvas Map Clickaround Follow Up Tutorial as shown below.

From this basis, this is how we got to today … there was HTML cloudy_world.html that changed like here.

You’ll see in the code above some great code presented at useful link (thanks) which is great for defining an HTML element’s size via …


function SetBox(what) {
var div = document.getElementById(what);
if (div.getBoundingClientRect) { // Internet Explorer, Firefox 3+, Google Chrome, Opera 9.5+, Safari 4+
// do stuff
}
}

… and we hope you can see that the implications for “overlay” ideas you have are huge … and that is fine … but you may wonder how the HTML div element is made to drape right over all the canvas element … well, it uses styling as per …

  • position: absolute;
  • top and left and width and height parameters are all defined
  • borderTop defined as having a size the same as height above as per our HTML div id=’boxdiv’ element …

    document.getElementById('boxdiv').style.position = 'absolute';
    document.getElementById('boxdiv').style.top = y + "px";
    document.getElementById('boxdiv').style.left = x + "px";
    document.getElementById('boxdiv').style.width = w + "px";
    document.getElementById('boxdiv').style.height = h + "px";
    document.getElementById('boxdiv').style.borderTop = h + 'px solid rgba(255,255,255,0.5)';

… and you’ll also see with the code how the HTML div id=’boxdiv’ element’s “onclick” details are transferred to the (effectively underlying) HTML canvas element, where all the previous business logic of the web application resided, and continues to function (once you make variables “x” and “y” global and control how they are derived at the HTML div id=’boxdiv’ element’s “onclick” event logic).

So please try the live run to see all this in action.


Previous relevant HTML5 Canvas Map Clickaround Follow Up Tutorial is shown below.

HTML5 Canvas Map Clickaround Follow Up Tutorial

HTML5 Canvas Map Clickaround Follow Up Tutorial

HTML5 brought in the incredibly useful “canvas” element, for the first time. Its existence opens up a whole new world of possibilities for web applications that are graphical by nature, as we saw yesterday with HTML5 Canvas Map Clickaround Primer Tutorial as shown below. Today, we extend that functionality as of yesterday, by adding the use of a public data feed to enhance the information we present with the Google Map “iframe” we use, and for this we need to thank, profusely, The Global Airport Database project by Arash Partow … thanks very much. Now this database (really a file), as you can imagine, has data that changes over time, so is probably best used as a data feed. Nevertheless, the exercise of using it as a snapshot is useful, and we go ahead and show the nearest 4 airports on the database, in that Google Map “iframe” as of April, 2015.

This involved the use of PHP (intair.php) to read the file and parse it, which wasn’t hard as it contains well formed “:” delimited data, and there is just the check needed for security hidden data given a latitude and longitude of zero … unless I’m mistaken, and where the water goes down the sink the other way as you cross the equator due south of London has several hundred microscopic airports run by ants … what a movie script?!

With the canvas element’s drawImage() method, we use to position the image map of interest, you can draw more than your own geometrical constructs, you can have an image, and that image could be a map, as for today’s “World Clickaround” web application (with access to maps of Brazil and Ireland and United States of America too), where you click on the map (and thanks to mapsofworld.com for downloadable free maps here) to show a Google Map of interest via Google Chart Map Chart. Maybe you can use the map of the World to …

  • plan a trip
  • look up where relatives live
  • count the fire hydrants in Monaco

This web application calls on tiny bits of mapping knowledge, namely the “orientation” of your “map”, as you are effectively digitizing to show where you want your Google Map to zoom in on.

Please have a go of our live run or download the HTML programming source code you could call world.htm (brazil.htm, ireland.htm, united_states.htm), or do both?!

From yesterday, this is how we got to today … there was new PHP you could call intair.php … and then there was changed HTML, the changes for which look like … world.htm, brazil.htm, ireland.htm, united_states.htm


Previous relevant HTML5 Canvas Map Clickaround Primer Tutorial is shown below.

HTML5 Canvas Map Clickaround Primer Tutorial

HTML5 Canvas Map Clickaround Primer Tutorial

HTML5 brought in the incredibly useful “canvas” element, for the first time. Its existence opens up a whole new world of possibilities for web applications that are graphical by nature.

With the canvas element’s drawImage() method you can draw more than your own geometrical constructs, you can have an image, and that image could be a map, as for today’s “Ireland Clickaround” web application (with access to maps of Brazil and United States of America and the World too), where you click on the map (and thanks to mapsofworld.com for downloadable free maps here) to show a Google Map of interest via Google Chart Map Chart. Maybe you can use the map of Ireland to …

  • plan a trip
  • look up where relatives live
  • imagine you’re in O’Connell Street

This web application calls on tiny bits of mapping knowledge, namely the “orientation” of your “map”, as you are effectively digitizing to show where you want your Google Map to zoom in on.

This is one of those occasions that your (simple) software is a lot more effective using the Mercator map projection (that exaggerates the polar areas (like you might have had at school) because the simple latitude and longitude distances everywhere are the same (but relative areas definitely are not (ie. much bigger than reality near the poles))). Unfortunately, our United States of America projection is not Mercator, but you’ll still get a “ball park” Google Maps feel.

So we can have it that if the user doesn’t zoom, they need no orientation checks, but otherwise we need to determine a scale, by the user clicking on Dublin, on the map, and from that, we can work out the scaling that needs to be applied, as the top left co-ordinate is arranged to be (0,0) via the style=”position: absolute; top:0; left:0; “ part of …


<canvas id="canvaselement" width=600 height=600 style="position: absolute; top:0; left:0; " />

Please have a go of our live run or download the HTML programming source code you could call ireland.html (brazil.html, united_states.html, world.html), or do both?!

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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

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

World Clickarounds Google Map Chart Onclick Logic Tutorial

World Clickarounds Google Map Chart Onclick Logic Tutorial

World Clickarounds Google Map Chart Onclick Logic Tutorial

Revisiting our World Clickaround web applications today, last talked about with Canvas Annotation Email Attachment User Acceptance Tutorial, we were gobsmacked that we hadn’t defaulted their use of the Google Chart Map Charts integrated in, to allow for inhouse “onclick” (via a Google Chart select event) logic.

Without this integration you miss being able to click near a place and …

  • use “Z” option to find nearest TimeZone (and then onto option “W” Weather) and option “T” for TimeZone information
  • use “S” for Sun Angle … and others of that ilk … and …
  • use “G” for (navigating to) various Google Map views
  • use “Y” for YouTube video lookup (though one of the nearest Airports (that have a known name) may do better here
  • use “A” for Nearest Airports (though you probably got this up already)

… anyway … didn’t want these possibilities to be hidden any longer.

The fix was very simple applied to many HTML web applications (as below), that being to add &onclick=y into the map.php based URLs in the code linking to our Google Chart Map Chart interfacing.


Previous relevant Canvas Annotation Email Attachment User Acceptance Tutorial is shown below.

Canvas Annotation Email Attachment User Acceptance Tutorial

Canvas Annotation Email Attachment User Acceptance Tutorial

An important part of a web (or desktop or mobile) application is user acceptance. User acceptance is, as the words would imply, the giving of your (developing) web application to real users, to test out usability … or UX (user experience). We do this today for our “Canvas Annotation Email Attachment” web application, and use it to “Annotate” a make believe trip, some of the “talking points” of which are “overlayed” on our “Welcome to Nation” map introduced a couple of days ago when we presented Canvas Annotation Email Attachment Transparency Tutorial and this resulted in an email sent with the attachment as you see in today’s tutorial picture.

User acceptance often throws up surprising findings, some easy to handle, and others that are likely to be extremely hard to implement, or impossible, or unworkable at this time. We addressed some of the easier ones to improve the web application, as listed below …

  1. as far as “overlay” thoughts go overlaying a transparent image on top of a clean map goes, we found, before user acceptance, that we would have had to type in the URL to the web application, again, at the address bar, rather than having a way to do it in the web application, so we turned the “Your” in “Your Annotations++” to be a dropdown, that if you change its value, you start the web application again, and can immediately arrange to overlay what you may have emailed off (to yourself, possibly) and downloaded locally onto your hard disk
  2. (after the email today … alas) … as far as the red or yellow click/touch blobs appearing (a little annoyingly) during Annotation operations, we allow you, now, to click on any part of the green bit of the Annotation menu, to turn off these blobs … alas … and you may want to do your own research, perhaps starting at this very useful link we “bit the bullet” and made non-generic HTML changes, as well as generic external Javascript changes, to allow for this … adding a new global variable blobc containing the colour of the “blob” … no, not that “blob”, this ..
  3. allow an original URL image to be supplied on the address bar URL as with this URL for today’s “fantasy trip” from “Alice Springs to Broome”

… and so what functionality features featured in our user acceptance test …

Again, for today’s work, the external Javascript world.js needed to change (regarding the user acceptance testing) like this today, regarding this new “Canvas Annotation Email” image fitting ideas, and our (common) PHP you could call intair.php is unchanged for any/all of (changed slightly) …

Hope you will try some or all of these web applications, and their “Canvas Annotation” and “Email Attachment” functionality, maybe even in a real world situation, emailing the results out to somebody, perhaps?


Previous relevant Canvas Annotation Email Attachment Image Fit Tutorial is shown below.

Canvas Annotation Email Attachment Image Fit Tutorial

Canvas Annotation Email Attachment Image Fit Tutorial

There is still more to do with regard to image manipulations functionality regarding our “Canvas Annotation Email Attachment” and “Clickaround” web applications. We want to be able to offer image scaling via user defined click or touch event outcomes on our HTML canvas.

What we do today in the form of a new HTML select element dropdown containing image placement options …

  1. place or overlay images not according to user click or touch events on the HTML canvas element, but use other “Annotation++” menu settings
  2. fit the image into the rectangle formed by the user’s last two click or touch canvas co-ordinates
  3. fit the image into the rectangle width, only, formed by the user’s last two click or touch canvas co-ordinates
  4. fit the image into the rectangle height, only, formed by the user’s last two click or touch canvas co-ordinates

The workings of this new functionality includes the HTML canvas methods …

So, for today’s work, only the external Javascript world.js needed to change like this today, regarding this new “Canvas Annotation Email” image fitting ideas, and our (common) PHP you could call intair.php is unchanged for any/all of …

Hope you will try some or all of these web applications, and their “Canvas Annotation” and “Email Attachment” functionality.


Previous relevant Canvas Annotation Email Attachment Transparency Tutorial is shown below.

Canvas Annotation Email Attachment Transparency Tutorial

Canvas Annotation Email Attachment Transparency Tutorial

We’ve thought of some more useful functionality regarding our “Canvas Annotation Email Attachment” and “Clickaround” web applications. To explore possibilities here going forward, and with regard to ideas regarding genericization possibilities, which aren’t a straightforward “yes” decision for today’s ideas.

What we do today is …

  1. we add to the “Where Is?” functionality of “Clickaround” web applications that we first talked about with Canvas Clickaround Where Is Primer Tutorial by allowing not only a Place Name (of an Airport) to be the only option that results in active usefulness with the web application, but also allow that same HTML input type=text element to specify a latitude;longitude[;placeName] for the case of the majority of places on Earth that don’t have an airport
  2. we add an extra functionality type similar to the “Undo” button of Canvas Annotation Email Attachment Undo Tutorial as shown way below that simply undoes the HTML canvas original image (the map), replacing it with a transparent background HTML canvas element that is then loaded with all the rest of the new Annotations you, the user, had added, since … hope you can see how useful this idea could be for a whole new set of “overlay” thoughts, which we’ll endeavour to refine in your mind as time goes on
  3. we add a whole new “Clickaround” and “Canvas Annotation Email Attachment” web application we are calling “Welcome To Nation” because we use the wonderful map developed by TreatyRepublic.net, thanks, in the tutorial sequence culminating in Australian Indigenous Language HTML Map jQuery YQL Tutorial

Now that second new functionality we are trialling with that new third new HTML and Javascript source code welcometonation.html with its live run link.

Often with genericization possibilities, the detail of how things could work, or perhaps not, in a “generic way”, are best “played out” in terms of a new “player” into the scene. So that is how we proceed today. This trialling also affects that first piece of functionality, with “Welcome to Nation” usage, having the window.open() “compiler” of selected “Where Is?” dropdown selections opening back in the “welcometonation.html” rather than the default (for all other “Clickaround” web applications, as it stands right now) “world.html” … a job to do here, for later, is to check that the user’s “latitude;longitude[;placeName]” entry falls within that “subset” map of the world … no such checks here today.

Anyway, going through this motion … yes … we found there is thinking to do making “genericization” of that second functionality idea work, and this is for tomorrow, and on. As is explaining how “overlay” possibilities expand here with that second idea above.

But the real wonder is in the intricacy of the culture, “the oldest surviving culture in the world”, of the Koori people, the first people of Australia, and so with that third option’s new Welcome to Nation web application is a new first option of the “web application” “Clickaround” dropdown at the right that points at the HTML map element Indigenous Australian Language Map web application Indigenous Australian Language Regions, where you point at a region and can open search engine and other information relevant to that indigenous language and peoples of interest.

So, for today’s work, the external Javascript world.js needed to change like this today, regarding this new “Canvas Annotation Email” background transparency idea, and our (common) PHP you could call intair.php changed quite a bit, as it controls “Where Is?” functionality ideas to any/all of …

Hope you try some or all of these out.


Previous relevant Canvas Annotation Email Attachment Scale and Clip Tutorial is shown below.

Canvas Annotation Email Attachment Scale and Clip Tutorial

Canvas Annotation Email Attachment Scale and Clip Tutorial

We’ve been busy continuing on with our Annotations functionality quest, specifically regarding Image content for Annotations, and the ability to be able to Scale and Clip (or crop) those images within the HTML canvas element that hosts them. This is also part of the functionality we need in our “toolbox” for our eventual destination with all this Annotation (with optional Email Attachment) functionality.

Some considerations with Scale, Clip and Rotation (the latter of which we first set our sights on with Canvas Annotation Email Attachment Rotation Tutorial as shown below) thoughts are …

  • what should the origin point of rotation be? … we follow the lead of this excellent link … thanks … and choose the centre of the canvas element … but also as of today’s work we offer the last click/touch position to be an option for positioning
  • should the canvas dimensions change? … this is debatable … and we continue, for now, to say “no” to this … but we are still open to changing this
  • do you rotate all canvas content or just an added image’s content? … we allow for both modes of use … we’ve added the ability for Annotation computer font text to rotate, as of today, as well
  • what should the origin point of clipping be? … we allow a percentage or pixel user defined method of defining

Today’s scaling and clipping calls on the full canvas.drawImage() specification. Up to now we’ve only ventured to the first of the three incarnations of ctx.drawImage calls below …

void ctx.drawImage(image, dx, dy);
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

… as you can read more about at that great link … but we make use of all three with today’s work, especially the third call with the clipping parameters “sx, sy, sWidth, sHeight” supplementing scaling parameters “dWidth, dHeight”.

So yet again, no HTML files needed to change today, and our (common) external Javascript you could call world.js changed quite a bit, adding Scaling and Clipping functionality to the recently added Rotation functionality affecting any/all of …

We’ll be back to explain more soon.


Previous relevant Canvas Annotation Email Attachment Rotation Tutorial is shown below.

Canvas Annotation Email Attachment Rotation Tutorial

Canvas Annotation Email Attachment Rotation Tutorial

It’s time to return to Annotations, specifically Image content for Annotations, and the ability to be able to Rotate those images, or the whole HTML canvas element that hosts them. It’s part of the functionality we need in our “toolbox” for our eventual destination with all this Annotation functionality.

Some considerations with Rotation thoughts are …

  • what should the origin point of rotation be? … we follow the lead of this excellent link … thanks … and choose the centre of the canvas element
  • should the canvas dimensions change? … this is debatable … and we have, for now, said “no” to this … but we are open to changing this, along with “cropping” and “scaling” and “specified offsets for rotated images” for follow up tutorials
  • do you rotate all canvas content or just an added image’s content? … we allow for both modes of use

Along the way, today, we thought we should add, at least for non-mobile platforms with an “onmouseover” event (available), the means to show “canvas” co-ordinates to assist these users with “Offset X and Y” decisions, perhaps.

Once again, no HTML files needed to change today, and our (common) external Javascript you could call world.js changed quite a bit, adding Rotation functionality affecting any/all of …


Canvas Annotation Email Attachment Undo Tutorial is shown below.

Canvas Annotation Email Attachment Undo Tutorial

Canvas Annotation Email Attachment Undo Tutorial

A web application allowing user defined Annotations is better when there is an “Undo” and “Redo” functionality option. This is because with any user intervention, there can be erroneous work, which sometimes can be a real pain to recover from scratch.

With “Undo” and “Redo” functionality, however, you do not want the user to think it is as much a part of the “mainstream” of the web application’s functionality, so we supply a “-” (minus) button for “Undo” and a “+” (plus) button for “Redo”, and make them smaller than other Annotation functionality buttons.

So how do we achieve this functionality? We actually do it by actually …

  1. always clearing the contents of the HTML canvas element
  2. always place the original image via canvas.drawImage() method
  3. calling on a stored Javascript array containing HTML canvas drawing statements, flagging the ones that represent a single user defined action, that one “single user defined action” being what an “Undo” or “Redo” action works regarding

There is a great resource for information about the Javascript “Array” object called ECMAScript® Language Specification (we got to via this link, which is also excellent as an “Array” object member functionality synopsis (and which we urge you to consult), thanks).

You may wonder about how canvas.drawImage() parameter 1 (an image object) is handled. We assume you will only be interested in “Undo”s and “Redo”s of the last image (object) involved, which is stored in a global variable (and rereferenced by “Undo” and/or “Redo”) when the Annotations are created (and built up) by the user.

So yet again, our world.html (with its live run) did not need to change for this new “Undo”/”Redo” functionality but our external Javascript you could call world.js changed quite a bit, setting up these Javascript arrays storing HTML canvas commands, for later use in “Undo” and “Redo” scenarios instigated by users clicking the relevant respective (small) “-” and “+” buttons.

As for …

We “might” have genericized the world.html changes into other HTMLs of its ilk … well, we decided against that for now … but will later … and partly the reason is that there is more to do, and we just want to concentrate on world.html

… we can now apply changes to the other HTML web applications …

Also changing is the email attachment PHP helper you could call world.php changed in this way.

Hope this HTML canvas web application set gives you some ideas for work of your own. To read some of the background to this, try Canvas Email Attachment Scribble Tutorial as shown below.


Previous relevant Canvas Email Attachment Scribble Tutorial is shown below.

Canvas Email Attachment Scribble Tutorial

Canvas Email Attachment Scribble Tutorial

Personally think that Annotations are better when there is a “Scribble” functionality option. Perhaps you want to “sign off” on your Annotations. Without a “Scribble” option, it’s a bit impersonal relying on computer fonts as the means by which you “sign” the work.

And down the track it’s helping with our “final aim”, which will be revealed as time goes on.

To “Scribble” the main mouse event that interests us is the “onmousemove” event which happens when the mouse … moves … in which case if you are in “Scribble” mode, draw a line between the last two data points. So from that you would glean, and we’ll fill in, as well, that …

  • the user needs to tell the computer it wants to start into “Scribble” mode (like a green light on the traffic light) … after a 2 second delay to allow the user to position themselves with their mouse … so we introduce a button for that, that the user can click … but how does the user do what was considered in the early days of all graphical application work … “pen up” … ie. mouse up … so …
  • if onmouseup (or touchend) gets triggered we want it not to draw lines but be ready to resume (like a yellow light on the traffic light) … and when in this mode …
  • if onmousedown gets triggered while “the traffic light is yellow” (ie. in the mode above) we want it to start to draw lines again with any mouse moves … and to call the whole thing off …
  • if the keyboard is used stop any “Scribble” operations (or click the crossed out button supplied) (like a red light on the traffic light)

Reinventing penmanpersonship is a bit of a stretch, but nevertheless, adds a degree of authenticity to your content, for this is what you are doing, should you go on and email your work as an email attachment … you become an uploader of content … yet again, no doubt. This is a lot more common on the net for all of us, as each day passes. Maybe also, as each night passes. Even as Collingwood streams down the left wing, and passes, no doubt.

Yet again, our world.html did not need to change for this new “Scribble” functionality but our external Javascript you could call world.js changed quite a bit, setting up these mouse (or touch) event logics, as its Javascript “setTimeout” delayed onload function …



function touchHandler(event) // thanks to //stackoverflow.com/questions/1517924/javascript-mapping-touch-events-to-mouse-events
{
var touches = event.changedTouches,
first = touches[0],
type = "";
//if (event.targetTouches.length == 1) {

switch(event.type)
{
//case "touchstart": type="mousedown"; break;
case "touchmove": type="mousemove"; break;
case "touchend": type="mouseup"; break;
default: return;
}

//initMouseEvent(type, canBubble, cancelable, view, clickCount,
// screenX, screenY, clientX, clientY, ctrlKey,
// altKey, shiftKey, metaKey, button, relatedTarget);

var simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(type, true, true, window, 1,
first.screenX, first.screenY,
first.clientX, first.clientY, false,
false, false, false, 0/*left*/, null);

first.target.dispatchEvent(simulatedEvent);

event.preventDefault();
event.stopPropagation();

switch(type)
{
//case "mousedown": if (isScribble == 1) { isScribble=2; } break;
case "mousemove": if (isScribble == 2) {
if (x == 0 && y == 0 && lastx == 0 && lasty == 0) {
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
lastx=x;
lasty=y;
} else {
lastx=x;
lasty=y;
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
}
if (x != lastx || y != lasty) {
document.getElementById('divannotation').style.display='block';
document.getElementById('myisubject').style.display = 'inline';
document.getElementById('myiemail').style.display = 'inline';
context.strokeStyle=document.getElementById('mycolour').value;
context.beginPath();
context.moveTo(x,y);
context.lineTo(lastx,lasty);
context.stroke();
}
}
break;
case "mouseup": if (isScribble == 2) { isScribble=1; } break;
default: return;
}
}

function tryit() {
var tds=document.getElementsByTagName('td'), hstuff='';
if (tds.length > 0) {
hstuff+="<div style='position: absolute; top:600px; left:860px; display:none; background-color: lightgreen; ' id='divan" + "notation'><h4>Your Annotations++</h4>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/line.png' onclick=' doline(); ' alt='Line' title='Line'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/rectangle.png' onclick=' dorectangle(); ' alt='Rectangle' title='Rectangle'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/rectangleborder.png' onclick=' dorectangleborder(); ' alt='Rectangle Border' title='Rectangle Border'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/circle.png' onclick=' docircle(); ' alt='Circle' title='Circle'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/clear.png' onclick=' clearall(); ' alt='Clear' title='Clear'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/sline.png' onclick=\" alert('Ready to Scribble in two seconds. Any key stroke stops scribbling.'); setTimeout(intwo,2000); \" alt='Scribble' title=''></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/zline.png' onclick=' isScribble=0; ' alt='End of scribble' title='End of scribble'></img>";
hstuff+=" <img src='//www.rjmprogramming.com.au/MarkItUp/image.png' onclick=\" document.getElementById('file').click(); document.getElementById('file').style.display='block'; document.getElementById('dpf').style.display='block'; \" alt='Image' title='Image'></img><input style='display:none;' id='file' type='file' name='file'><div id=dpf style='display:none;'>  <span class='readBytesButtons'><button style='display:none;' data-endbyte='4' data-startbyte='0'>1-5</button><button style='display:none;' data-endbyte='14' data-startbyte='5'>6-15</button><button style='display:none;' data-endbyte='7' data-startbyte='6'>7-8</button><br>... vs Image URL: <input type='url' value='+' onblur='readUBlob(this.value,0,0);' style='width:60%;'></input><br>... Offset X: <input style='width:25%;' id='xoff' type='number' value='0'></input> Offset Y: <input style='width:25%;' id='yoff' type='number' value='0'></input><br><button onclick='readBlob(0,0);'>Place into Canvas</button><button onclick='readOBlob(0,0);'>Overlay into Canvas</button></div><div id='byte_range' style='display:none;'></div><div id='byte_content' style='display:none;'></div><input id='fil' value='' type='hidden'></input><img id='spareimg' src='' style='display:none;'></img>";
hstuff+="<br>Annotation (optional): <input onblur='placeannotation(this);' id='iannotation' type='text' value=''></input><br><span>Anno B&W (optional): <input onblur='placeannotation(this);' id='jannotation' type='text' value=''></input><br>Style: <input type='text' id='myfont' value='18px Verdana'></input> <input type='text' id='mycolour' value='black'></input></span><br>";
hstuff+="<form style='display:none;' id='myform' method='post' enctype='application/x-www-urlencoded' action='//www.rjmprogramming.com.au/HTMLCSS/world.php' target='myiframetwo'><input type='hidden' name='mysubject' id='mysubject' value='My World Map'></input><input type='hidden' name='myfname' id='myfname' value=''></input><input type='submit' id='bsubmit' value='Submit' style='display:none;'></input><input type='hidden' name='ismobile' id='ismobile' value=''></input><input type='hidden' name='mode' id='mode' value='1'></input><input type='hidden' name='to' id='to' value=''></input><input type='hidden' name='mydurl' id='mydurl' value=''></input></form>";
hstuff+="<iframe style='display:none;' id='myiframetwo' src='//www.rjmprogramming.com.au/HTMLCSS/world.php'></iframe>";
hstuff+="<input style='display:none;' onblur='fixmyemail(this.value + String.fromCharCode(32),1);' type='text' id='myisubject' value='My World Map '></input> <input style='background-color: yellow;' type='button' value='Email (optional)' onclick=' capture(document.getElementById(" + '"' + "mydurl" + '"' + "),document.getElementById(" + '"' + "bsubmit" + '"' + "),document.getElementById(" + '"' + "myemail" + '"' + ")); '></input> <a style='display:none;' target='_blank' id='myemail' href='mailto:fill.in.email@address?subject=My%20World%20Map&body='></a><input style='display:none;' onblur='fixmyemail(this.value,0);' type='text' id='myiemail' value='' title='Fill this in for emailed attachment'></input>";
hstuff+="</div>";
if (tds[eval(-1 + tds.length)].innerHTML.indexOf('diva' + 'nnotaxtion') == -1) tds[eval(-1 + tds.length)].innerHTML+=hstuff;
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
var hh = today.getHours();
var minm = today.getMinutes(); //January is 0!
var ss = today.getSeconds();
document.getElementById('myfname').value = "world_" + yyyy + "_" + mm + "_" + hh + "_" + minm + "_" + ss + ".png";
document.getElementById('myform').action = document.getElementById('myform').action.replace('?mode=1', '');
document.getElementById('mode').value = '';
document.getElementById('ismobile').value = 'y';
document.getElementById('myisubject').style.display = 'inline';
document.getElementById('myiemail').style.display = 'inline';
document.getElementById('myform').action = document.getElementById('myform').action.replace('?mode=1', '');
document.getElementById('myform').action = document.getElementById('myform').action.replace('mode=1', 'mode=');
//document.getElementById('myemail').href = '#' + document.getElementById('myemail').href;
}

document.body.addEventListener('keyup', function(event) {
if (isScribble == 2 || isScribble == 1) {
isScribble=0;
}
});

if (isTouch || isiPad) {
//elem.addEventListener("touchstart", touchHandler, true);
elem.addEventListener("touchmove", touchHandler, true);
elem.addEventListener("touchend", touchHandler, true);
elem.addEventListener("touchcancel", touchHandler, true);

//elem.addEventListener('touchstart', function(event) {
// if (isScribble == 1) {
// isScribble=2;
// }
//});

} else {

elem.addEventListener('mouseup', function(event) {
if (isScribble == 2) {
isScribble=1;
}
});

elem.addEventListener('touchend', function(event) {
if (isScribble == 2) {
isScribble=1;
}
});

elem.addEventListener('touchstart', function(event) {
if (isScribble == 1) {
isScribble=2;
}
});

elem.addEventListener('mousedown', function(event) {
if (isScribble == 1) {
isScribble=2;
}
});

elem.addEventListener('mousemove', function(event) {
if (isScribble == 2) {

if (x == 0 && y == 0 && lastx == 0 && lasty == 0) {
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
lastx=x;
lasty=y;
} else {
lastx=x;
lasty=y;
if (event.pageX || event.pageY) {
x = event.pageX - elemLeft;
y = event.pageY - elemTop;
} else {
x = event.clientX - elemLeft;
y = event.clientY - elemTop;
}
}

if (x != lastx || y != lasty) {
document.getElementById('divannotation').style.display='block';
document.getElementById('myisubject').style.display = 'inline';
document.getElementById('myiemail').style.display = 'inline';
context.strokeStyle=document.getElementById('mycolour').value;
context.beginPath();
context.moveTo(x,y);
context.lineTo(lastx,lasty);
context.stroke();
}
}

});

}


setTimeout(tryit, 2000);

… as you can see from this link. Regarding some mobile platform issues we’d like to thank this really useful link … so, thanks. And if actions speak louder than words no doubt you’ll be wanting the live run link.

As for …

We “might” have genericized the world.html changes into other HTMLs of its ilk … well, we decided against that for now … but will later … and partly the reason is that there is more to do, and we just want to concentrate on world.html

… from last time’s Canvas Email Attachment New Image Tutorial as shown below, that still remains the case … there is more to do. Hope to see you back again for that then.


Previous relevant Canvas Email Attachment New Image Tutorial is shown below.

Canvas Email Attachment New Image Tutorial

Canvas Email Attachment New Image Tutorial

When we last left off with Canvas Image Email Attachment External Javascript Tutorial project we posed two ongoing “trailers”/”spoiler alerts” …

  • We “might” have genericized the world.html changes into other HTMLs of its ilk … well, we decided against that for now … but will later … and partly the reason is that there is more to do, and we just want to concentrate on world.html with …
  • Did you guess what functionality we might want to do next? We want to allow the user to “overlay” or “clobber” the existing canvas’s map image with an image of their choosing in one of two entry methods …
    1. via a Browse button selection of an image on their computer … or …
    2. via the specification of a URL pointing at an image (on the web, probably)

We’ve grappled with the relatively newly arrived brilliance of HTML5 with ideas off Browse buttons and their manipulation of file data, the methods of which don’t even need PHP or ASP.Net (or any other server side language) to proceed … cute, huh?! We referenced this great link when we presented PHP/HTML/Javascript Media & Document File Browse Tutorial, and you may want to reference that regarding the useful Javascript HTML5 FileReader methods. Another really useful link for today’s work is … what we just linked … we presume … thanks. We find FileReader.readAsDataURL() method to be just what we want today to take the data of a file as a data URL and be able to use the canvas.drawImage() to place that image data onto the canvas by “overlaying” it or “clobbering” it.

Our world.html did not need to change for this new image friendly functionality but our external Javascript you could call world.js changed quite a bit as you can see from this link.

To envisage all this, you really should try a live run of our interactive World Map (with Annotation and Email Attachment functionality) web application. We hope some Browse button thoughts start springing forth from the bit below the hair (or if you’re standing on your head right now … the bit above the hair).


Previous relevant Canvas Image Email Attachment External Javascript Tutorial is shown below.

Canvas Image Email Attachment External Javascript Tutorial

Canvas Image Email Attachment External Javascript Tutorial

Rome wasn’t built in a day … just read “SPQR A History of Ancient Rome” by Mary Beard, to confirm that. And software takes time, and often revisits and rethinks, in between, running it past people, perhaps. So it is with the build up of our “cause”, which we’ll eventually reveal, that started with Canvas Image Email Attachment Primer Tutorial as shown below, and moves on today, in two directions …

  • Organization wise … we move some of the “Annotation++” functionality specifics to external Javascript … via …

    <script type='text/javascript' src='world.js' defer></script>

    … to be more modular, and to apply it to other web applications like world.html that aren’t world.html (which we will also do event-U-al-ly … maybe even today?! … you’ll see at the end of this blog posting if we have)
  • Functionality wise … we allow for more than “Annotations” now … hence the “Annotation++” notation above … we’ve been delving into our HTML canvas codes for logic to draw lines and rectangles (including a “huge white rectangle” to “clear” the canvas) and circles today

When you redesign arrangements this way, you should retest all the functionality combinations to make sure you haven’t broken anything … because that would be kinda’ stUpid. The adage should be that you leave things better than when you start, to do a good job … doh!

So there’s still an important bit of “base” functionality missing, and we’ll get to that next time, though maybe you’ve guessed what it would be yourself?!

So take a look at our HTML and Javascript and CSS world.html which changed as per this link which now calls on new external Javascript you could call world.js if you like. Unchanged is the concept (and the content) regarding the HTML using PHP server side code you could call world.php within an HTML iframe element. Again, please don’t think you’ll be able to achieve this functionality just with client-side Javascript. It involves server data. So here is a live run link in order for you to try this new functionality, which kicks into action from the second canvas click/touch, and on.

Hint: Don’t be shy to try some “rgba([red0-255],[blue0-255],[green0-255],[opacity0.0-1.0])” colour field possibilities in combination with the filled in rectangle option to improve your “overlay” functionality possibilities, as with today’s main tutorial picture.


Previous relevant Canvas Image Email Attachment Primer Tutorial is shown below.

Canvas Image Email Attachment Primer Tutorial

Canvas Image Email Attachment Primer Tutorial

Maybe you remember the series of blog postings that we last visited with HTML5 Canvas Map Clickaround Onresize Tutorial some time ago? We’ve been, over the last couple of days, working out how to …

  • take an HTML canvas element’s [canvasContext].drawImage() image
  • be able to overlay some interactively entered textual annotations over the top of user entered rectangle corners
  • take a snapshot of this canvas with its annotations via [canvasContext].toDataURL() (woh!)
  • use an HTML form element with method=POST target=myiframetwo to post the data to our (new) PHP (featuring the use of php://input for the first time, for us anyway) … which …
  • emails that snapshot to someone

We allow for …

  1. non-mobile platforms to use their email clients, perhaps, via a body link to an image file stored on the rjmprogramming.com.au domain web server … or, because such functionality is awkward for mobile platforms, we …

  2. allow for the canvas contents be turned into image data that can be used as the data for an email attachment, thus allowing the web server to not have to store the data (there) now

Here’s some of the PHP code to create that email with its attachment, for your perusal (where $idata has that data URL data of the canvas’s contents, that is image/png data (in base64)) …


//$headers = 'From: ' . 'rmetcalfe@rjmprogramming.com.au' . $eol;
$headers = 'Reply-To: ' . 'rmetcalfe@rjmprogramming.com.au' . $eol;
// 'X-Mailer: PHP/' . phpversion();
$contents = "";
if ($idata != "") $contents = $idata;
if (strpos('~' . $mybody, '~http') !== false || $contents != "") {
if ($contents == "") $contents = @file_get_contents($mybody);
if ($contents != '') {
//
date_default_timezone_set('Australia/Perth');
//
//$mysubject .= ' ... ' . $mybody;
$fs = explode("/", $mybody);
$filename = $fs[-1 + sizeof($fs)];
$content = chunk_split(base64_encode($contents));
//
// a random hash will be necessary to send mixed content
$separator = md5(time());
//
$headers .= "MIME-Version: 1.0" . $eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol . $eol;
$headers .= "Content-Transfer-Encoding: 7bit" . $eol;
$headers .= "This is a MIME encoded message." . $eol . $eol;
//
// message
$headers .= "--" . $separator . $eol;
$headers .= "Content-Type: text/plain; charset=\"iso-8859-1\"" . $eol;
$headers .= "Content-Transfer-Encoding: 8bit" . $eol . $eol;
//
$headers .= "Please see attached image below:" . $eol . $eol;
//
// attachment
$headers .= "--" . $separator . $eol;
$headers .= "Content-Type: application/octet-stream; name=\"" . $filename . "\"" . $eol;
$headers .= "Content-Transfer-Encoding: base64" . $eol;
$headers .= "Content-Disposition: attachment;filename=\"" . $filename . "\"" . $eol;
$headers .= $content . $eol . $eol;
$headers .= "--" . $separator . "--";
//
ourpremail($tem, $mysubject, "", $headers); // emails to $tem
}
}

And so, with our proof of concept ideas, the world becomes (hopefully, lots of) our (collective) oyster(s), given a little imagination, here. Really, take a look at our HTML and Javascript and CSS world.html which changed as per this link. It has new PHP server side code you could call world.php within an HTML iframe element. Please don’t think you’ll be able to achieve this functionality just with client-side Javascript. It involves server data. So here is a live run link in order for you to try this new functionality, which kicks into action from the second canvas click/touch, and on.


Previous relevant HTML5 Canvas Map Clickaround Onresize Tutorial is shown below.

HTML5 Canvas Map Clickaround Overlay Tutorial

HTML5 Canvas Map Clickaround Overlay Tutorial

Yesterday we came back after quite some time in the (PHP) server world to some client (Javascript and HTML) work, and today, after yesterday’s HTML5 Canvas Map Clickaround Overlay Tutorial as shown below, we tackle a client Javascript event, the “onresize” event (best intervened with in terms of looking at the Javascript DOM “window” object rather than the “document” object), that is often “left until last” in a programmer’s mind … and often not thought about at all. That’s often me … but not today.

Perhaps the reason it is (often) neglected is that the design (you’ve come up with) leaves lots of room, and the styling “position:absolute;” concept is not used at all with your web application. Yesterday, though, “position:absolute;” is pivotal to the working of the web application, as is the positioning of the HTML canvas element at (0,0) … why? … the slightly glib answer here is that to complicate life is to complicate your web application, and if you can cater for the simple case, why not work with that simple case, with its simplified coding logic?

Okay, so what’s the scenario with yesterday’s HTML5 Canvas Map Clickaround Overlay Tutorial where the Javascript “onresize” event gets triggered. On a laptop or desktop computer, it is when you “drag” (a window corner) and, we anticipate, shrink your window (by then “dropping” (a window corner)) to end up with a window smaller than the set established size, width or height, we cater for with the HTML canvas element’s width or height.

Now we currently rely on the right hand side being the user controlling side, but if a user shrinks the window, and we refuse to get into any “zooming” logic … my strong advice is not to go there … you have two choices to my mind …

  1. “copy” the right hand HTML (into an existant blank HTML div element’s innerHTML) and “overlay” at (0,0) (with less opacity than the rest)
  2. “copy” the right hand HTML and use Javascript (where myWidth is calculated width of the HTML canvas element … remember this functionality from yesterday?) … and use window.open(“”,”Title”,”top=0px,left=” + eval(20 + myWidth) + “px,width=350px,height=600px”) (along with a global variable wadd) … for a popup window, as per …

    wadd = window.open("","Your Place and Airports Map Goes Here ...","top=0px,left=" + eval(20 + myWidth) + "px,width=350px,height=600px");
    and then use wadd.document.write([someHTML]) … as per …

    var newhtml="<!doctype html><html><head>" + document.head.innerHTML + "</head><body>" + document.getElementById('dhuh').innerHTML.replace(/opacity:0.0;/g, "opacity:1.0;").replace('"Cloudy"', '').replace('id="myqiframe', 'id="myiframe').replace('id="mypqiframe', 'id="mypiframe').replace('id="myqa', 'id="mya');
    wadd.document.write(newhtml);

You’ve probably guessed by the added detail in the second of above, the first idea was awkward, but if you want to pursue it yourself, via leads, look for the (left in) if (additional != ”) { } logic parts in the HTML/Javascript coding of cloudy_world.html (or try the live run).

We later use a Javascript setTimeout() call to wait a while while the hidden right hand side’s HTML iframe element is filled out with the Airport Data Near Your World Map Clicked Position, and through that knowledge over to the “wadd” window (where it is viewable, presumably … unless you’ve repositioned again (which is okay to test if you want)).

So, today, everything should be as per yesterday with no “resizing” (and of course the programmer adage to “not make things backward in functionality” would tell you that to hold onto this “tooth and nail” should be thought of as extremely important … probably of higher priority than any new functionality … think probably users get pretty annoyed by things that used to work, not working later, because of your own newly introduced bug).

It behoves me, my liege, to leave you with the HTML/Javascript code differences, to make this happen, from yesterday, here, and we hope it helps you in some small way. We also want to thank the “powers that be” for the excellent advice at this link, for this topic … thanks, as always.


Previous relevant HTML5 Canvas Map Clickaround Overlay Tutorial is shown below.

HTML5 Canvas Map Clickaround Overlay Tutorial

HTML5 Canvas Map Clickaround Overlay Tutorial

After some time in the (PHP) server world, it’s time to dive back into some client (Javascript and HTML) work, in this client/server world of web applications.

Today we revisit the “overlay” theme of blog postings, as the web application world is full of possibilities for overlay ideas.

This time we overlay an HTML div element completely on top of an HTML canvas element, with some opacity (or some transparency), during the body “onload” event. We do not adjust the DOM “z-index” style property for either element. So what happens in this scenario when you click on this “multiple” HTML element combination? Well, it pans out you click on the HTML div element, so we have another task to do at the body “onload” event, to see things right, regarding the working of this web application, which starts where we left off with HTML5 Canvas Map Clickaround Follow Up Tutorial as shown below.

From this basis, this is how we got to today … there was HTML cloudy_world.html that changed like here.

You’ll see in the code above some great code presented at useful link (thanks) which is great for defining an HTML element’s size via …


function SetBox(what) {
var div = document.getElementById(what);
if (div.getBoundingClientRect) { // Internet Explorer, Firefox 3+, Google Chrome, Opera 9.5+, Safari 4+
// do stuff
}
}

… and we hope you can see that the implications for “overlay” ideas you have are huge … and that is fine … but you may wonder how the HTML div element is made to drape right over all the canvas element … well, it uses styling as per …

  • position: absolute;
  • top and left and width and height parameters are all defined
  • borderTop defined as having a size the same as height above as per our HTML div id=’boxdiv’ element …

    document.getElementById('boxdiv').style.position = 'absolute';
    document.getElementById('boxdiv').style.top = y + "px";
    document.getElementById('boxdiv').style.left = x + "px";
    document.getElementById('boxdiv').style.width = w + "px";
    document.getElementById('boxdiv').style.height = h + "px";
    document.getElementById('boxdiv').style.borderTop = h + 'px solid rgba(255,255,255,0.5)';

… and you’ll also see with the code how the HTML div id=’boxdiv’ element’s “onclick” details are transferred to the (effectively underlying) HTML canvas element, where all the previous business logic of the web application resided, and continues to function (once you make variables “x” and “y” global and control how they are derived at the HTML div id=’boxdiv’ element’s “onclick” event logic).

So please try the live run to see all this in action.


Previous relevant HTML5 Canvas Map Clickaround Follow Up Tutorial is shown below.

HTML5 Canvas Map Clickaround Follow Up Tutorial

HTML5 Canvas Map Clickaround Follow Up Tutorial

HTML5 brought in the incredibly useful “canvas” element, for the first time. Its existence opens up a whole new world of possibilities for web applications that are graphical by nature, as we saw yesterday with HTML5 Canvas Map Clickaround Primer Tutorial as shown below. Today, we extend that functionality as of yesterday, by adding the use of a public data feed to enhance the information we present with the Google Map “iframe” we use, and for this we need to thank, profusely, The Global Airport Database project by Arash Partow … thanks very much. Now this database (really a file), as you can imagine, has data that changes over time, so is probably best used as a data feed. Nevertheless, the exercise of using it as a snapshot is useful, and we go ahead and show the nearest 4 airports on the database, in that Google Map “iframe” as of April, 2015.

This involved the use of PHP (intair.php) to read the file and parse it, which wasn’t hard as it contains well formed “:” delimited data, and there is just the check needed for security hidden data given a latitude and longitude of zero … unless I’m mistaken, and where the water goes down the sink the other way as you cross the equator due south of London has several hundred microscopic airports run by ants … what a movie script?!

With the canvas element’s drawImage() method, we use to position the image map of interest, you can draw more than your own geometrical constructs, you can have an image, and that image could be a map, as for today’s “World Clickaround” web application (with access to maps of Brazil and Ireland and United States of America too), where you click on the map (and thanks to mapsofworld.com for downloadable free maps here) to show a Google Map of interest via Google Chart Map Chart. Maybe you can use the map of the World to …

  • plan a trip
  • look up where relatives live
  • count the fire hydrants in Monaco

This web application calls on tiny bits of mapping knowledge, namely the “orientation” of your “map”, as you are effectively digitizing to show where you want your Google Map to zoom in on.

Please have a go of our live run or download the HTML programming source code you could call world.htm (brazil.htm, ireland.htm, united_states.htm), or do both?!

From yesterday, this is how we got to today … there was new PHP you could call intair.php … and then there was changed HTML, the changes for which look like … world.htm, brazil.htm, ireland.htm, united_states.htm


Previous relevant HTML5 Canvas Map Clickaround Primer Tutorial is shown below.

HTML5 Canvas Map Clickaround Primer Tutorial

HTML5 Canvas Map Clickaround Primer Tutorial

HTML5 brought in the incredibly useful “canvas” element, for the first time. Its existence opens up a whole new world of possibilities for web applications that are graphical by nature.

With the canvas element’s drawImage() method you can draw more than your own geometrical constructs, you can have an image, and that image could be a map, as for today’s “Ireland Clickaround” web application (with access to maps of Brazil and United States of America and the World too), where you click on the map (and thanks to mapsofworld.com for downloadable free maps here) to show a Google Map of interest via Google Chart Map Chart. Maybe you can use the map of Ireland to …

  • plan a trip
  • look up where relatives live
  • imagine you’re in O’Connell Street

This web application calls on tiny bits of mapping knowledge, namely the “orientation” of your “map”, as you are effectively digitizing to show where you want your Google Map to zoom in on.

This is one of those occasions that your (simple) software is a lot more effective using the Mercator map projection (that exaggerates the polar areas (like you might have had at school) because the simple latitude and longitude distances everywhere are the same (but relative areas definitely are not (ie. much bigger than reality near the poles))). Unfortunately, our United States of America projection is not Mercator, but you’ll still get a “ball park” Google Maps feel.

So we can have it that if the user doesn’t zoom, they need no orientation checks, but otherwise we need to determine a scale, by the user clicking on Dublin, on the map, and from that, we can work out the scaling that needs to be applied, as the top left co-ordinate is arranged to be (0,0) via the style=”position: absolute; top:0; left:0; “ part of …


<canvas id="canvaselement" width=600 height=600 style="position: absolute; top:0; left:0; " />

Please have a go of our live run or download the HTML programming source code you could call ireland.html (brazil.html, united_states.html, world.html), or do both?!

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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

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

PHP/Javascript SVG Animations Tutorial

PHP/Javascript SVG Animations Tutorial

PHP/Javascript SVG Animations Tutorial

We’ve added to the functionality of yesterday’s PHP/Javascript SVG Transformations Tutorial with

  1. … adding to the tranformation functionalities … as well as a …

  2. new SVG (element) type path is introduced today … and within its (new) logic it facilitates
  3. three different types of SVG animation
    • animateMotion … related to animation over an SVG path (element)
    • animateTransform … related to animation over changing SVG transform (over time) scenarios
    • animate … related to animation over changing SVG element settings (over time) scenarios

… those last two animation modes reliant on a tactic we ask of the user helping us out with the delimiter (in this case, dot “.”) we use to differentiate via …

  • non-animation SVG elements never use “.” in their (user interactively set) setting definitions … meaning that for scale and matrix transform animations for instance …
  • for the first time ever that we can recall, we encourage users to enter “no decimal place Scientific Notation” entries (eg. 0.005 can be expressed as 5e-3 in “no decimal place Scientific Notation“) when they have a setting that is not an integer … yet allow an entry like “9e-3.5e-3″ express an “animation from 0.009 to 0.005″

That way, you never see any buttons related to animation, and just a passing “Path (animation)” dropdown mention of animateMotion work, rather leaving it up to users as they enter settings to make all these animation “differentiations” themselves.

Three new PHP functions crucial to this new animation functionality are shown below (showing an oft used thing for us to do here, adding an “our” in front of a reworked generic PHP (in this case “oururldecode”) function name, and using instead of that generic function to be “multi-purpose” feeling) …


function oururldecode($inth) {
global $fld, $animateothers;
$outh=str_replace("+"," ",urldecode($inth));
if (strpos($outh, ".") !== false && $fld != "") {
$animateothers.='<animate attributeName="' . $fld . '" attributeType="XML"
from="' . explode('.', $outh)[0] . '" to="' . explode('.', $outh)[1] . '"
begin="0s" dur="5s"
fill="remove" repeatCount="indefinite"/>';
}
return $outh; //explode('.', $outh)[0];
}

function animateg($inthing) {
global $animatemode, $animatefrom, $animateto, $animatepath, $animateothers;
$z=0;
$extras="";
$toend="/>";
$outthing=$inthing;
if ($animatemode == "" && ($animatepath != "" || $animateothers != "")) {
$animatemode="path";
$animsfrom=$animatepath;
} else if (($animatepath != "" || $animateothers != "")) {
$animatemode.=";path";
$animsfrom.=";" . $animatepath;
$animsto.=";";
}
if ($animatemode != "") {
$anims=explode(";", $animatemode);
$animsfrom=explode(";", $animatefrom);
$animsto=explode(";", $animateto);

for ($ir=0; $ir<sizeof($anims); $ir++) {
if ($anims[$ir] != "") {
if ($anims[$ir] == "path") {
if ($animatepath != "") {
$extras='<animateMotion
path="' . $animatepath . '"
begin="0s" dur="10s" repeatCount="indefinite" />';
}
$extras.=$animateothers;
} else {
$extras='<animateTransform attributeName="transform"
type="' . $anims[$ir] . '"
from="' . $animsfrom[$ir] . '"
to="' . $animsto[$ir] . '"
begin="0s"
dur="10s"
repeatCount="indefinite"
additive="sum" />';
}

if (strpos($inthing, "</g>") !== false) {
$outthing=str_replace("</g>", $extras . "</g>", $outthing);
} else if (strpos($inthing, "</defs>") !== false) {
$rest=explode("</defs>", $inthing)[1];
$toend="</" . explode(">", explode(" ", substr($rest,1))[0])[0] . ">";
if (strpos($rest, "/>") !== false) {
$outthing=str_replace($rest, explode("/>", $rest)[0] . ">" . $extras . $toend, $outthing);
} else {
$outthing=str_replace("</defs>", "</defs>" . $extras, $outthing);
}
} else if (strpos(substr($inthing,$z), "/>") !== false) {
$toend="</" . explode(">", explode(" ", substr($inthing,1))[0])[0] . ">";
$outthing=str_replace("/>", ">" . $extras . $toend, $outthing);
} else if (strpos($inthing, "</text>") !== false) {
$outthing=str_replace("</text>", $extras . "</text>", $outthing);
}
}
}
}
return $outthing;
}

function animateperhaps($inmode, $inthing) {
global $animatemode, $animatefrom, $animateto, $animatepath, $animateothers;
$delim="";
$indelim="";
if ($animatemode != "") { $delim=";"; }
if (strpos($inthing, ".") !== false) {
$ofinterest="." . explode(".", $inthing)[1];
if ($inmode == "rotate") {
if (strlen(trim( explode(",", $ofinterest)[0] )) == 3 && strpos($ofinterest, ".0") !== false) {
$animatemode=$animatemode;
} else {
$animatemode.=$delim . $inmode;
$animateto.=$delim . trim(explode(",", substr($ofinterest,1))[0]);
$animatefrom.=$delim . str_replace("." . trim(explode(",", substr($ofinterest,1))[0]), "", $inthing);
//return "";
}
} else { //if (strpos($inthing, ",") !== false) {
$animatemode.=$delim . $inmode;
$ofs=explode(",", $inthing);
$animateto.=$delim . explode(".", $ofs[0])[1];
$animatefrom.=$delim . str_replace("." . explode(".", $ofs[0])[1], "", $ofs[0]);
$indelim=",";
for ($j=1; $j<sizeof($ofs); $j++) {
$animateto.=$indelim . explode(".", $ofs[$j])[1];
$animatefrom.=$indelim . str_replace("." . explode(".", $ofs[$j])[1], "", $ofs[$j]);
}
//} else {
}
}
return $inthing;
}

For today’s live run‘s animation work SVG_Primer.php changed in this way, for your perusal.


Previous relevant PHP/Javascript SVG Transformations Tutorial is shown below.

PHP/Javascript SVG Transformations Tutorial

PHP/Javascript SVG Transformations Tutorial

Yesterday’s PHP/Javascript SVG Text and Group Tutorial started us off on the concept of SVG g groups, and it is natural from there we should discuss the SVG transform transformations …

… and what is important to the end result of a combination of these, the order in which we decide the user should control. With that order in mind, though we were sorely tempted to introduce an HTML select (dropdown) element, to be the user interface selecting these transformations, we instead opted for input type=button elements where the advantage is the user sees all before their very eyes. Non-mobile people could see all too via a size=6 argument to a select element, but this is not honoured in mobile platforms, so we persevere with buttons.

More scope with settings data length, and you will not be surprised us telling you we can easily get “REQUEST-URI too long” errors without a test of the length of a proposed ? and & based (web browser address bar) URL, in which case we can handle this, having written the web application in serverside PHP, to then revert to navigation via …

  • form style=display:none; action=[here’sLookingAtYouKid] method=POST … versus GET (is the ? and & way) …
  • input type=hidden elements whose values cover that same settings data requirements … and …
  • input style=display:none; type=submit element clicked, programmatically

… as required.

For today’s live run‘s transformational work SVG_Primer.php changed in this way.


Previous relevant PHP/Javascript SVG Text and Group Tutorial is shown below.

PHP/Javascript SVG Text and Group Tutorial

PHP/Javascript SVG Text and Group Tutorial

It’s well overdue for us to revisit SVG (Scalable Vector Graphics) …

SVG is short for Scalable Vector Graphics. It is a graphic format in which the shapes are specified in XML. The XML is then rendered by an SVG viewer. Today most web browser can display SVG just like they can display PNG, GIF, and JPG.

… issues last talked about, for us, with PHP/Javascript SVG YUI Geometry Tracing Tutorial some time ago.

We first became aware of SVG “Groups” by examining the innards of Google Chart charts. Many of this great series of online chart functionalities by Google use the SVG g elements as a means by which you can conglomerate other SVG graphical bits and pieces into another graphical entity, shall we say, that can have a transformation applied to it (as a whole), if you like, and we like today, allowing for a very rudimentary rotation option. All this happened via a newly introduced button labelled “Group and draw shape(s) above”. Cute, huh?! And a bit oh, oh O.O.ish, as in another approach à la …

Another new aspect to SVG usage we add into our SVG Primer web application live run functionality is the ability to place text, using the anyone, anyone … yes, Teodoro Obiang Nguema the SVG text element.

As far as text goes, in particular, you may find it like holding a hose three quarters of the way up with a heavy stream of water passing through it! It’s hard to control exact placement, but who knows whether that is the be all and end all, for you, and its use with SVG you need to apply to a project you have on your plate.

For today’s work SVG_Primer.php changed in this way.


Previous relevant PHP/Javascript SVG YUI Geometry Tracing Tutorial is shown below.

PHP/Javascript SVG YUI Geometry Tracing Tutorial

PHP/Javascript SVG YUI Geometry Tracing Tutorial

We came across another great “Geometry Tracing” functionality possibility the other day. It revolved around using the excellent YUI (by Yahoo) library of Javascript functionality, and we wanted to integrate it into yesterday’s PHP/Javascript SVG Geometry Tracing Tutorial start to our software integration journey of late. Before going on, we’d like to thank Graphics: Path Drawing Tool – YUI Library for the basis in code of today’s supervised additions in HTML and Javascript and CSS web application components.

To involve Javascript libraries like YUI is more than a Javascript dynamic HTML “workings” experience. Built in, if you choose to access it … all free, thanks … are a lot of aesthetically pleasing stylesheet ideas, and this shows with our “better than usual” look to our supervised YUI web application components.

What we have now is as below, with the bold section new for today’s work.

We like YUI’s pencil as the draggable cursor that the user can use to trace around their SVG … again via …

  • ?area=[parent determined area of SVG element]
  • &svg=[data URI of SVG xml]

… GET call of the YUI magic!

Yesterday’s work, as well as not working for Firefox (web browser), didn’t work for Internet Explorer nor Microsoft Edge (so I found out today), so, in order to solve the cross-browser issues once and for all, today, (after we realized that bullets don’t taste very good) we use the “data:image/svg+xml;base64,” prefixed Data URI for SVGs across the board … ditching the HTML(5) canvas element’s drawImage() method … and, instead, instituting a background image (to the canvas (is elem below, and ourtowhat equates to the base64 headed Data URI for SVG content)) approach as for …


elem.style.backgroundRepeat='no-repeat';
elem.style.backgroundPosition='20px 20px';
elem.style.backgroundImage='url(' + ourtowhat + ')';

… and this started working for Firefox, at least. Hopefully the Windows browsers as well?!


Previous relevant PHP/Javascript SVG Geometry Tracing Tutorial is shown below.

PHP/Javascript SVG Geometry Tracing Tutorial

PHP/Javascript SVG Geometry Tracing Tutorial

The tutorial today is about software (web application) integration that is value adding but in an optional way. The software integration is between …

We integrate these two in quite a neat way, allowing for the extension of the supervised’s static arrays which go …


var imageo=[];
var ourareawas=[36213.0, 25382.0, 19608.0, 39366.5, 24471.5, 43679.5, 37633.5, 45130.5, 40987.5, 51842.5];
var image_array=["one_sided.jpg", "two_sided.jpg", "three_sided.jpg", "four_sided.jpg", "five_sided.jpg", "six_sided.jpg", "seven_sided.jpg", "eight_sided.jpg", "nine_sided.jpg", "ten_sided.jpg"];

… extended by Javascript’s [array].push method (often good for those dynamic Javascript DOM driven extensions of functionality) … to establish the (communication protocol) ideas for the “Geometry” the user can be “Tracing” around, by allowing new GET parameters …

  • ?area=[parent determined area of SVG element]
  • &svg=[data URI of SVG xml]

… the latter of which we’re using for the first time in this project, and want to thank the Data URI’s for SVG paragraph for great ideas here. As you do software integration, sometimes you think of it as a slog, and yes, it usually is a bit of a slog. When the slog is more a neat data efficient form of integration, that Data URIs for SVG seems to us to be, then it all seems worthwhile.

However, in this early days integration, we still have to iron out some cross-browser issue aspects that don’t work in Firefox, for us not working with “data:image/svg+xml;base64,” nor “data:image/svg+xml;utf8,” prefixed Data URI for SVG forms. Possibly it’s to do with using it via GET arguments. Time will tell, we hope.

And so you can see us integrating the display of an SVG piece of geometry to offering the user the (optional) chance to play a game seeing how accurately they can trace around that shape and match the supervisor calculated mathematics (Area of a Polygon) algorithm (we use a lot in various web applications) generated area value. Value adding, and entertainment adding, we think … we hope.

You can also see this play out at WordPress 4.1.1’s PHP/Javascript SVG Geometry Tracing Tutorial.


Previous relevant PHP/Javascript SVG Colour Picker Tutorial is shown below.

PHP/Javascript SVG Colour Picker Tutorial

PHP/Javascript SVG Colour Picker Tutorial

Today’s posting hooks up two HTML5 concepts, as described below …

  • The HTML5 specification allows for the display of 2D-graphics via SVG HTML tags which use graphical applications in XML and the XML is then rendered by a SVG viewer. SVG stands for Scalable Vector Graphics.
  • The HTML5 specification added some new very useful HTML input element types, and today, we’re talking about the type=color element type that brings up a pretty suave colour picker helper, in some browsers

There are alternative colour pickers out there, in addition to what HTML5 has given us, and you may want to read YUI UI Colour Picker Primer Tutorial about that.

Today, we’ll leave you with SVG_Primer.php changed from PHP GD and Image Functions Primer Tutorial‘s version in this way. And before you leave, you could create your own SVG elements via this live run link.


Previous relevant PHP/Javascript SVG Primer Tutorial is shown below.

PHP/Javascript SVG Primer Tutorial

PHP/Javascript SVG Primer Tutorial

The HTML5 specification allows for the display of 2D-graphics via SVG HTML tags which use graphical applications in XML and the XML is then rendered by an SVG viewer. SVG stands for Scalable Vector Graphics.

We’ve talked about the HTML canvas element as another means to come to this end, but the SVG methods are more straightforward in their creation.

For today’s tutorial we follow the advice at this wonderful tutorial and wrap it in PHP, so that you can specify your own parameters. Hope you find it very useful, and easy.

This demonstrates to you that if you have some great static HTML you can keep that great static content and present a dynamic version the user can play around with, and learn from, by adding that PHP server-side content. For today’s PHP interface we got the HTML to use an HTML form of the relevant shape’s characteristics and post this data back to the same PHP webpage, analyzing the $_POST[] data to fill in the static HTML parameter values with user-defined parameter alternatives.

Today we have PHP and Javascript programmable source code you could call SVG_Primer.php and here is its 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 Animation, eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , | Leave a comment

PHP/Javascript SVG Transformations Tutorial

PHP/Javascript SVG Transformations Tutorial

PHP/Javascript SVG Transformations Tutorial

Yesterday’s PHP/Javascript SVG Text and Group Tutorial started us off on the concept of SVG g groups, and it is natural from there we should discuss the SVG transform transformations …

… and what is important to the end result of a combination of these, the order in which we decide the user should control. With that order in mind, though we were sorely tempted to introduce an HTML select (dropdown) element, to be the user interface selecting these transformations, we instead opted for input type=button elements where the advantage is the user sees all before their very eyes. Non-mobile people could see all too via a size=6 argument to a select element, but this is not honoured in mobile platforms, so we persevere with buttons.

More scope with settings data length, and you will not be surprised us telling you we can easily get “REQUEST-URI too long” errors without a test of the length of a proposed ? and & based (web browser address bar) URL, in which case we can handle this, having written the web application in serverside PHP, to then revert to navigation via …

  • form style=display:none; action=[here’sLookingAtYouKid] method=POST … versus GET (is the ? and & way) …
  • input type=hidden elements whose values cover that same settings data requirements … and …
  • input style=display:none; type=submit element clicked, programmatically

… as required.

For today’s live run‘s transformational work SVG_Primer.php changed in this way.


Previous relevant PHP/Javascript SVG Text and Group Tutorial is shown below.

PHP/Javascript SVG Text and Group Tutorial

PHP/Javascript SVG Text and Group Tutorial

It’s well overdue for us to revisit SVG (Scalable Vector Graphics) …

SVG is short for Scalable Vector Graphics. It is a graphic format in which the shapes are specified in XML. The XML is then rendered by an SVG viewer. Today most web browser can display SVG just like they can display PNG, GIF, and JPG.

… issues last talked about, for us, with PHP/Javascript SVG YUI Geometry Tracing Tutorial some time ago.

We first became aware of SVG “Groups” by examining the innards of Google Chart charts. Many of this great series of online chart functionalities by Google use the SVG g elements as a means by which you can conglomerate other SVG graphical bits and pieces into another graphical entity, shall we say, that can have a transformation applied to it (as a whole), if you like, and we like today, allowing for a very rudimentary rotation option. All this happened via a newly introduced button labelled “Group and draw shape(s) above”. Cute, huh?! And a bit oh, oh O.O.ish, as in another approach à la …

Another new aspect to SVG usage we add into our SVG Primer web application live run functionality is the ability to place text, using the anyone, anyone … yes, Teodoro Obiang Nguema the SVG text element.

As far as text goes, in particular, you may find it like holding a hose three quarters of the way up with a heavy stream of water passing through it! It’s hard to control exact placement, but who knows whether that is the be all and end all, for you, and its use with SVG you need to apply to a project you have on your plate.

For today’s work SVG_Primer.php changed in this way.


Previous relevant PHP/Javascript SVG YUI Geometry Tracing Tutorial is shown below.

PHP/Javascript SVG YUI Geometry Tracing Tutorial

PHP/Javascript SVG YUI Geometry Tracing Tutorial

We came across another great “Geometry Tracing” functionality possibility the other day. It revolved around using the excellent YUI (by Yahoo) library of Javascript functionality, and we wanted to integrate it into yesterday’s PHP/Javascript SVG Geometry Tracing Tutorial start to our software integration journey of late. Before going on, we’d like to thank Graphics: Path Drawing Tool – YUI Library for the basis in code of today’s supervised additions in HTML and Javascript and CSS web application components.

To involve Javascript libraries like YUI is more than a Javascript dynamic HTML “workings” experience. Built in, if you choose to access it … all free, thanks … are a lot of aesthetically pleasing stylesheet ideas, and this shows with our “better than usual” look to our supervised YUI web application components.

What we have now is as below, with the bold section new for today’s work.

We like YUI’s pencil as the draggable cursor that the user can use to trace around their SVG … again via …

  • ?area=[parent determined area of SVG element]
  • &svg=[data URI of SVG xml]

… GET call of the YUI magic!

Yesterday’s work, as well as not working for Firefox (web browser), didn’t work for Internet Explorer nor Microsoft Edge (so I found out today), so, in order to solve the cross-browser issues once and for all, today, (after we realized that bullets don’t taste very good) we use the “data:image/svg+xml;base64,” prefixed Data URI for SVGs across the board … ditching the HTML(5) canvas element’s drawImage() method … and, instead, instituting a background image (to the canvas (is elem below, and ourtowhat equates to the base64 headed Data URI for SVG content)) approach as for …


elem.style.backgroundRepeat='no-repeat';
elem.style.backgroundPosition='20px 20px';
elem.style.backgroundImage='url(' + ourtowhat + ')';

… and this started working for Firefox, at least. Hopefully the Windows browsers as well?!


Previous relevant PHP/Javascript SVG Geometry Tracing Tutorial is shown below.

PHP/Javascript SVG Geometry Tracing Tutorial

PHP/Javascript SVG Geometry Tracing Tutorial

The tutorial today is about software (web application) integration that is value adding but in an optional way. The software integration is between …

We integrate these two in quite a neat way, allowing for the extension of the supervised’s static arrays which go …


var imageo=[];
var ourareawas=[36213.0, 25382.0, 19608.0, 39366.5, 24471.5, 43679.5, 37633.5, 45130.5, 40987.5, 51842.5];
var image_array=["one_sided.jpg", "two_sided.jpg", "three_sided.jpg", "four_sided.jpg", "five_sided.jpg", "six_sided.jpg", "seven_sided.jpg", "eight_sided.jpg", "nine_sided.jpg", "ten_sided.jpg"];

… extended by Javascript’s [array].push method (often good for those dynamic Javascript DOM driven extensions of functionality) … to establish the (communication protocol) ideas for the “Geometry” the user can be “Tracing” around, by allowing new GET parameters …

  • ?area=[parent determined area of SVG element]
  • &svg=[data URI of SVG xml]

… the latter of which we’re using for the first time in this project, and want to thank the Data URI’s for SVG paragraph for great ideas here. As you do software integration, sometimes you think of it as a slog, and yes, it usually is a bit of a slog. When the slog is more a neat data efficient form of integration, that Data URIs for SVG seems to us to be, then it all seems worthwhile.

However, in this early days integration, we still have to iron out some cross-browser issue aspects that don’t work in Firefox, for us not working with “data:image/svg+xml;base64,” nor “data:image/svg+xml;utf8,” prefixed Data URI for SVG forms. Possibly it’s to do with using it via GET arguments. Time will tell, we hope.

And so you can see us integrating the display of an SVG piece of geometry to offering the user the (optional) chance to play a game seeing how accurately they can trace around that shape and match the supervisor calculated mathematics (Area of a Polygon) algorithm (we use a lot in various web applications) generated area value. Value adding, and entertainment adding, we think … we hope.

You can also see this play out at WordPress 4.1.1’s PHP/Javascript SVG Geometry Tracing Tutorial.


Previous relevant PHP/Javascript SVG Colour Picker Tutorial is shown below.

PHP/Javascript SVG Colour Picker Tutorial

PHP/Javascript SVG Colour Picker Tutorial

Today’s posting hooks up two HTML5 concepts, as described below …

  • The HTML5 specification allows for the display of 2D-graphics via SVG HTML tags which use graphical applications in XML and the XML is then rendered by a SVG viewer. SVG stands for Scalable Vector Graphics.
  • The HTML5 specification added some new very useful HTML input element types, and today, we’re talking about the type=color element type that brings up a pretty suave colour picker helper, in some browsers

There are alternative colour pickers out there, in addition to what HTML5 has given us, and you may want to read YUI UI Colour Picker Primer Tutorial about that.

Today, we’ll leave you with SVG_Primer.php changed from PHP GD and Image Functions Primer Tutorial‘s version in this way. And before you leave, you could create your own SVG elements via this live run link.


Previous relevant PHP/Javascript SVG Primer Tutorial is shown below.

PHP/Javascript SVG Primer Tutorial

PHP/Javascript SVG Primer Tutorial

The HTML5 specification allows for the display of 2D-graphics via SVG HTML tags which use graphical applications in XML and the XML is then rendered by an SVG viewer. SVG stands for Scalable Vector Graphics.

We’ve talked about the HTML canvas element as another means to come to this end, but the SVG methods are more straightforward in their creation.

For today’s tutorial we follow the advice at this wonderful tutorial and wrap it in PHP, so that you can specify your own parameters. Hope you find it very useful, and easy.

This demonstrates to you that if you have some great static HTML you can keep that great static content and present a dynamic version the user can play around with, and learn from, by adding that PHP server-side content. For today’s PHP interface we got the HTML to use an HTML form of the relevant shape’s characteristics and post this data back to the same PHP webpage, analyzing the $_POST[] data to fill in the static HTML parameter values with user-defined parameter alternatives.

Today we have PHP and Javascript programmable source code you could call SVG_Primer.php and here is its 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

PHP/Javascript SVG Text and Group Tutorial

PHP/Javascript SVG Text and Group Tutorial

PHP/Javascript SVG Text and Group Tutorial

It’s well overdue for us to revisit SVG (Scalable Vector Graphics) …

SVG is short for Scalable Vector Graphics. It is a graphic format in which the shapes are specified in XML. The XML is then rendered by an SVG viewer. Today most web browser can display SVG just like they can display PNG, GIF, and JPG.

… issues last talked about, for us, with PHP/Javascript SVG YUI Geometry Tracing Tutorial some time ago.

We first became aware of SVG “Groups” by examining the innards of Google Chart charts. Many of this great series of online chart functionalities by Google use the SVG g elements as a means by which you can conglomerate other SVG graphical bits and pieces into another graphical entity, shall we say, that can have a transformation applied to it (as a whole), if you like, and we like today, allowing for a very rudimentary rotation option. All this happened via a newly introduced button labelled “Group and draw shape(s) above”. Cute, huh?! And a bit oh, oh O.O.ish, as in another approach à la …

Another new aspect to SVG usage we add into our SVG Primer web application live run functionality is the ability to place text, using the anyone, anyone … yes, Teodoro Obiang Nguema the SVG text element.

As far as text goes, in particular, you may find it like holding a hose three quarters of the way up with a heavy stream of water passing through it! It’s hard to control exact placement, but who knows whether that is the be all and end all, for you, and its use with SVG you need to apply to a project you have on your plate.

For today’s work SVG_Primer.php changed in this way.


Previous relevant PHP/Javascript SVG YUI Geometry Tracing Tutorial is shown below.

PHP/Javascript SVG YUI Geometry Tracing Tutorial

PHP/Javascript SVG YUI Geometry Tracing Tutorial

We came across another great “Geometry Tracing” functionality possibility the other day. It revolved around using the excellent YUI (by Yahoo) library of Javascript functionality, and we wanted to integrate it into yesterday’s PHP/Javascript SVG Geometry Tracing Tutorial start to our software integration journey of late. Before going on, we’d like to thank Graphics: Path Drawing Tool – YUI Library for the basis in code of today’s supervised additions in HTML and Javascript and CSS web application components.

To involve Javascript libraries like YUI is more than a Javascript dynamic HTML “workings” experience. Built in, if you choose to access it … all free, thanks … are a lot of aesthetically pleasing stylesheet ideas, and this shows with our “better than usual” look to our supervised YUI web application components.

What we have now is as below, with the bold section new for today’s work.

We like YUI’s pencil as the draggable cursor that the user can use to trace around their SVG … again via …

  • ?area=[parent determined area of SVG element]
  • &svg=[data URI of SVG xml]

… GET call of the YUI magic!

Yesterday’s work, as well as not working for Firefox (web browser), didn’t work for Internet Explorer nor Microsoft Edge (so I found out today), so, in order to solve the cross-browser issues once and for all, today, (after we realized that bullets don’t taste very good) we use the “data:image/svg+xml;base64,” prefixed Data URI for SVGs across the board … ditching the HTML(5) canvas element’s drawImage() method … and, instead, instituting a background image (to the canvas (is elem below, and ourtowhat equates to the base64 headed Data URI for SVG content)) approach as for …


elem.style.backgroundRepeat='no-repeat';
elem.style.backgroundPosition='20px 20px';
elem.style.backgroundImage='url(' + ourtowhat + ')';

… and this started working for Firefox, at least. Hopefully the Windows browsers as well?!


Previous relevant PHP/Javascript SVG Geometry Tracing Tutorial is shown below.

PHP/Javascript SVG Geometry Tracing Tutorial

PHP/Javascript SVG Geometry Tracing Tutorial

The tutorial today is about software (web application) integration that is value adding but in an optional way. The software integration is between …

We integrate these two in quite a neat way, allowing for the extension of the supervised’s static arrays which go …


var imageo=[];
var ourareawas=[36213.0, 25382.0, 19608.0, 39366.5, 24471.5, 43679.5, 37633.5, 45130.5, 40987.5, 51842.5];
var image_array=["one_sided.jpg", "two_sided.jpg", "three_sided.jpg", "four_sided.jpg", "five_sided.jpg", "six_sided.jpg", "seven_sided.jpg", "eight_sided.jpg", "nine_sided.jpg", "ten_sided.jpg"];

… extended by Javascript’s [array].push method (often good for those dynamic Javascript DOM driven extensions of functionality) … to establish the (communication protocol) ideas for the “Geometry” the user can be “Tracing” around, by allowing new GET parameters …

  • ?area=[parent determined area of SVG element]
  • &svg=[data URI of SVG xml]

… the latter of which we’re using for the first time in this project, and want to thank the Data URI’s for SVG paragraph for great ideas here. As you do software integration, sometimes you think of it as a slog, and yes, it usually is a bit of a slog. When the slog is more a neat data efficient form of integration, that Data URIs for SVG seems to us to be, then it all seems worthwhile.

However, in this early days integration, we still have to iron out some cross-browser issue aspects that don’t work in Firefox, for us not working with “data:image/svg+xml;base64,” nor “data:image/svg+xml;utf8,” prefixed Data URI for SVG forms. Possibly it’s to do with using it via GET arguments. Time will tell, we hope.

And so you can see us integrating the display of an SVG piece of geometry to offering the user the (optional) chance to play a game seeing how accurately they can trace around that shape and match the supervisor calculated mathematics (Area of a Polygon) algorithm (we use a lot in various web applications) generated area value. Value adding, and entertainment adding, we think … we hope.

You can also see this play out at WordPress 4.1.1’s PHP/Javascript SVG Geometry Tracing Tutorial.


Previous relevant PHP/Javascript SVG Colour Picker Tutorial is shown below.

PHP/Javascript SVG Colour Picker Tutorial

PHP/Javascript SVG Colour Picker Tutorial

Today’s posting hooks up two HTML5 concepts, as described below …

  • The HTML5 specification allows for the display of 2D-graphics via SVG HTML tags which use graphical applications in XML and the XML is then rendered by a SVG viewer. SVG stands for Scalable Vector Graphics.
  • The HTML5 specification added some new very useful HTML input element types, and today, we’re talking about the type=color element type that brings up a pretty suave colour picker helper, in some browsers

There are alternative colour pickers out there, in addition to what HTML5 has given us, and you may want to read YUI UI Colour Picker Primer Tutorial about that.

Today, we’ll leave you with SVG_Primer.php changed from PHP GD and Image Functions Primer Tutorial‘s version in this way. And before you leave, you could create your own SVG elements via this live run link.


Previous relevant PHP/Javascript SVG Primer Tutorial is shown below.

PHP/Javascript SVG Primer Tutorial

PHP/Javascript SVG Primer Tutorial

The HTML5 specification allows for the display of 2D-graphics via SVG HTML tags which use graphical applications in XML and the XML is then rendered by an SVG viewer. SVG stands for Scalable Vector Graphics.

We’ve talked about the HTML canvas element as another means to come to this end, but the SVG methods are more straightforward in their creation.

For today’s tutorial we follow the advice at this wonderful tutorial and wrap it in PHP, so that you can specify your own parameters. Hope you find it very useful, and easy.

This demonstrates to you that if you have some great static HTML you can keep that great static content and present a dynamic version the user can play around with, and learn from, by adding that PHP server-side content. For today’s PHP interface we got the HTML to use an HTML form of the relevant shape’s characteristics and post this data back to the same PHP webpage, analyzing the $_POST[] data to fill in the static HTML parameter values with user-defined parameter alternatives.

Today we have PHP and Javascript programmable source code you could call SVG_Primer.php and here is its 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.

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

Circular Text or Emoji Periodic Table Quiz Tutorial

Circular Text or Emoji Periodic Table Quiz Tutorial

Circular Text or Emoji Periodic Table Quiz Tutorial

Meanwhile, back at Circular Text ideas we were wondering if we could add more interest to a quiz by making the circular ends to a similar wheel as the roulette wheel (as discussed with Circular Text or Emoji Roulette Animation Tutorial) be clickable as the user’s way to learn about some Periodic Table symbols and correspondent names.

We are forever wondering about ways to hide answers from users, for quizzes and games. Well, at least for those users not venturing to any Webpage -> View Source ideas, that is. Today’s sort of clunky, yet satisfying, way is to hide the Periodic Table element names, along with their symbols, in a single dimension array. Then we use that, scouring the whole <head> </head> using the DOM document.head.innerHTML reference approach, in the way below (and we warn that if you do not want help with the game avert your gaze below 1.734523417cm down the webpage)


var pts=['H:Hydrogen','He:Helium','Li:Lithium','Be:Beryllium','B:Boron','C:Carbon','N:Nitrogen','O:Oxygen','F:Fluorine','Ne:Neon','Na:Sodium','Mg:Magnesium','Al:Aluminium','Si:Silicon','P:Phosphorus','S:Sulphur','Cl:Chlorine','Ar:Argon','K:Potassium','Ca:Calcium','Sc:Scandium','Ti:Titanium','V:Vanadium','Cr:Chromium','Mn:Manganese','Fe:Iron','Co:Cobalt','Ni:Nickel','Cu:Copper','Zn:Zinc','Ga:Gallium','Ge:Germanium','As:Arsenic','Se:Selenium','Br:Bromine','Kr:Krypton'];

function huhd(dv) {
var answer='',ans='',wasih='';
if (isThirtySeven) { // Periodic Table Quiz logic
if (dv.trim().length <= 2 && dv.indexOf('/') == -1) {
answer=prompt('What is the name of the element in the Period Table with the symbol ' + dv.trim() + '? To just find out, but not score, enter a question mark.', '');
if (answer == null) { answer='' }
goes++;
if (answer == '?') {
answer='';
ans=document.head.innerHTML.replace(/\"/g,"'").split("'" + dv.trim() + ":")[1].split("'")[0];
}
if (document.head.innerHTML.toLowerCase().replace(/\"/g,"'").indexOf("'" + dv.trim().toLowerCase() + ":" + (answer + ans).toLowerCase() + "'") != -1) {
if (answer != '') { score++; }
wasih=lastois.innerHTML;
lastois.innerHTML='<font size=1><a title="Click here for Google search" target=_blank style="color:white;text-decoration:none;cursor:pointer;" href="https://www.google.com/search?q=' + encodeURIComponent(answer + ans) + '">' + answer + ans + '</a></font><br>' + wasih;
}
document.getElementById('pscore').innerHTML='Score: ' + score + '/' + goes;
document.getElementById('p36').innerHTML='' + score + '/' + goes;
}
userpicked='';
}
// rest for Roulette logic
}

… and the other way this array is used is to populate the content of the wheel outer rim, starting with the Roulette Wheel content as a template, via …


function reworked(intis) { // RE: pts array Period Table symbol/name quiz
// 3<span>2</span>1<span>5</span>1<span>9</span>42<span>1</span>22<span>5</span>1<span>7</span>3<span>4</span>62<span>7</span>1<span>3</span>3<span>6</span>1<span>1</span>3<span>0</span>82<span>3</span>1<span>0</span>52<span>4</span>1<span>6</span>3<span>3</span>12<span>0</span>1<span>4</span>3<span>1</span>92<span>2</span>1<span>8</span>2<span>9</span>72<span>8</span>1<span>2</span>3<span>5</span>32<span>6</span>0
var okayis=false, outtis=intis + '<span>/0</span>', sofar=',', iso=-1;
var outtisa='3<span>2</span>;1<span>5</span>;1<span>9</span>;4;2<span>1</span>;2;2<span>5</span>;1<span>7</span>;3<span>4</span>;6;2<span>7</span>;1<span>3</span>;3<span>6</span>;1<span>1</span>;3<span>0</span>;8;2<span>3</span>;1<span>0</span>;5;2<span>4</span>;1<span>6</span>;3<span>3</span>;1;2<span>0</span>;1<span>4</span>;3<span>1</span>;9;2<span>2</span>;1<span>8</span>;2<span>9</span>;7;2<span>8</span>;1<span>2</span>;3<span>5</span>;3;2<span>6</span>'.split(';'); //;0<span>/0</span>';
for (var i=0; i<pts.length; i++) {
okayis=false;
while (!okayis) {
iso=Math.floor(Math.random() * pts.length);
if (sofar.indexOf(',' + iso + ',') == -1) { okayis=true; sofar+='' + iso + ','; }
}
if (pts[iso].split(':')[0].length == 1) {
outtis=outtis.replace(outtisa[i], pts[iso].split(':')[0]);
} else {
outtis=outtis.replace(outtisa[i], pts[iso].split(':')[0].substring(0,1) + '<span>' + pts[iso].split(':')[0].substring(1) + '</span>');
}
}
return outtis;
}

… also illustrating our sofar variable oft used technique of appending to a delimited single string that is “indexOf”ed against to determine if an action has previously been taken, and, in this case here, not do it more than once.

Today’s changed HTML and CSS circular_text.html‘s live run link for you to try the Periodic Table Quiz part of the functionality yourself at a link up the top of the webpage.


Previous relevant Circular Text or Emoji Roulette Animation Tutorial is shown below.

Circular Text or Emoji Roulette Animation Tutorial

Circular Text or Emoji Roulette Animation Tutorial

As we left off with the recent Circular Text or Emoji Roulette Game Tutorial we wanted to improve on the animation aspects to representing the roulette wheel ball, but still only involve …

… and it was this in orbit bit that daunted us most. That is, until we …

  • read the great advice of this link, thanks … and enjoyed the wonder of …
  • how dynamic and easy dynamic CSS styling can be simply by adding <style> </style> encased styling to the end of document.body.innerHTML … via …

    function animateonorbit(bid, ccl, cct, anrad, fhl) { // thanks to https://www.useragentman.com/blog/2013/03/03/animating-circular-paths-using-css3-transitions/
    var dba='<style> #' + bid + ' { display:block; top:' + cct + 'px; ';
    dba+=' left:' + ccl + 'px; position:absolute; -moz-border-radius: 12px; border-radius: 12px; ';
    dba+=' filter: alpha(opacity=80); -moz-opacity:0.8; -khtml-opacity: 0.8; opacity: 0.8; transform: rotate(45deg) translateX(' + anrad + 'px) rotate(-45deg); ';
    dba+=' animation:animateonorbit ' + fhl + 's linear infinite; -webkit-animation:animateonorbit ' + fhl + 's linear infinite; z-index:79; } ';
    dba+=' @keyframes animateonorbit { from { transform: rotate(0deg) translateX(' + anrad + 'px) rotate(0deg); } ';
    dba+=' to { transform: rotate(360deg) translateX(' + anrad + 'px) rotate(-360deg); } ';
    dba+=' @-webkit-keyframes animateonorbit { from { -webkit-transform: rotate(0deg) translateX(' + anrad + 'px) rotate(0deg); } ';
    dba+=' to { -webkit-transform: rotate(360deg) translateX(' + anrad + 'px) rotate(-360deg); } </style> ';
    document.body.innerHTML+=dba;
    lasto=document.getElementById(bid);
    document.getElementById(bid).style.display='block';
    }

Today’s changed HTML and CSS circular_text.html‘s live run link for you to try the Roulette Wheel (and its animated ball) part of the functionality yourself at a link up the top of the webpage.


Previous relevant Circular Text or Emoji Roulette Game Tutorial is shown below.

Circular Text or Emoji Roulette Game Tutorial

Circular Text or Emoji Roulette Game Tutorial

Extending the recent Circular Text or Emoji Onclick Tutorial circular text ideas, today we are starting out on a game that uses a Roulette Wheel as its basic web page component. To all those “graphically challenged” users, like me, we do not use any homegrown imagery of any sort, instead just use …

  • HTML basis of design …
  • CSS as …
    1. <head> </head> styling …

      <style>
      .roulettered { color:white; background:linear-gradient(to top,orange 92%,red 8%); }
      .rouletteblack { color:white; background:linear-gradient(to top,orange 92%,black 8%); }
      .roulettegreen { color:white; background:linear-gradient(to top,orange 92%,green 8%); }
      </style>
    2. inline HTML styling
  • Javascript DOM dynamic styling and animation (the roulette wheel is sent spinning via setTimeout Javascript timer logic)

… involving our original …

  • “circular text” as the numbers near the outer rim of the roulette wheel
  • background border-radius parts in the middle (‘atend’ element) as the ribbing bits that form the rest of the roulette wheel

… and, so far, the one ball emoji at the end of a user turn. This last bit is where we feel we shall work at more improvement.

Today’s changed HTML circular_text.html‘s live run link for you to try the Roulette Wheel part of the functionality yourself at a link up the top of the webpage. You can guess a number or red or black or green colours, and odds based scoring is applied.


Previous relevant Circular Text or Emoji Onclick Tutorial is shown below.

Circular Text or Emoji Onclick Tutorial

Circular Text or Emoji Onclick Tutorial

In this increasingly connected online world, it can be surprising when an image looking part of a webpage cannot be linked to. The unusual thing about emojis is their way to …

  • be part of the textual web armoury … yet …
  • look like an image

… and, as such, it would definitely not offend, maybe even “tickle pink” the user to have an emoji be linked to further information. In the case of the emojis featuring in yesterday’s Circular Text or Emojis Genericity Tutorial which are country flags (that are compound emojis) you can query the Google search engine with the contents of the Iemoji website webpages (such as Japan’s flag emoji one) with the right column data next to the “Decimal HTML Entity” left column. In fact, as we often urge our students, just copy this Decimal HTML Entity value straight up into the address bar, and your favourite search engine is likely to come up with a (in my case Google) search engine URL like …


https://www.google.com/search?client=firefox-b-ab&q=%26%23127471%3B+%26%23127477%3B

… getting you (emoji onclick event) links to some pretty pertinent information about Japan within seconds, let alone what you might find under the Images and/or Videos menu subsearches. Notice how integrated this is with the Google search engine webpages …

The Flag: Japan emoji is a sequence of the 🇯 Regional Indicator Symbol Letter J and 🇵 Regional Indicator Symbol Letter P emojis. These display as a single emoji on supported platforms.

… showing you how ISO 2-letter codes are linked to emoji country flag Decimal HTML Entity creation construction rules.

Today’s changed HTML circular_text.html‘s live run link for you to try yourself (or try the changed PHP circular_text.php‘s live run), then, features …

  • changed emoji linking, the one thing left to say about this being, that the “missing link” between text and link HTML elements can be that elements that start as text can be made to act like linked elements (later) via (definitely the first, and sometimes, but not today, the second) CSS styling (via inline HTML CSS style=””) …
    1. cursor:pointer;
    2. text-decoration:underline;

    … we make happen within the webpage’s Javascript (DOM) code

  • functionality to be able to increase or decease the circular text’s font size (that being the way to control an emoji size as well, that reminds you that emojis are text, just not that very small part of the text world with ascii codes less than 256)
  • a very subtle radial gradient background replaces the single colour background colour for the HTML ‘atend’ div element within the circular text as per

    if (document.getElementById('atend').innerHTML != '') { document.getElementById('atend').style.background='radial-gradient(circle,#c0d0f0,#c3d3f3)'; } //#c0d0f0'; } //'transparent';

Previous relevant Circular Text or Emojis Genericity Tutorial is shown below.

Circular Text or Emojis Genericity Tutorial

Circular Text or Emojis Genericity Tutorial

A major consideration in any “genericity” drive you have for your web applications is to allow for a large amount of user entered data, perhaps a surprising amount. If you offer a textbox to enter data, then a user may enter a hugely long, and perhaps valid, field. If we’d left it at the scenario of yesterday’s Circular Text or Emojis Analogue Clock Tutorial, though, we’d have been restricted to a textbox entry of about 800 characters for the rjmprogramming.com.au domain. In the first of the improvements below, then, we try to cater for this via …

  • for textbox entries that are long we now populate an HTML form method=POST action=circular_text.php where we intervene at appropriate places with the large data items … and today we also …
  • make sure compound emojis like the country flags work (where the great Iemoji website webpages such as Japan’s flag emoji one, become so useful) … and we test that out with a …
  • Google Chart Pie Chart content inside the circular text

… and an interesting thing happened with the “getting to work” of today’s textbox entry (for a radius value of 570) you can try …


                        &amp;#127464;&amp;#127475;                        &amp;#127470;&amp;#127475;       &amp;#127482;&amp;#127480;     &amp;#127470;&amp;#127465;     &amp;#127463;&amp;#127479;    &amp;#127477;&amp;#127472;    &amp;#127475;&amp;#127468;    &amp;#127463;&amp;#127465;    &amp;#127479;&amp;#127482;   &amp;#127471;&amp;#127477;   &amp;#127474;&amp;#127485;   &amp;#127477;&amp;#127469;  &amp;#127483;&amp;#127475;  &amp;#127466;&amp;#127481;  &amp;#127465;&amp;#127466;  &amp;#127466;&amp;#127468; &amp;#127470;&amp;#127479; &amp;#127481;&amp;#127479; &amp;#127481;&amp;#127469; &amp;#127464;&amp;#127465; &amp;#127467;&amp;#127479; &amp;#127468;&amp;#127463; &amp;#127470;&amp;#127481;<iframe frameborder=0 style=border-radius:600px;width:900px;height:600px;z-index:23;margin-left:87px;margin-top:270px; src=HTTPs://www.rjmprogramming.com.au/PHP/PieChart/pie_chart.php?title=%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0%c2%a0Country%20Populations&onclick=y&task=Country&desc=Populations&data=,%20[~https;China,1347000000,India,1241000000,United%20States,312000000,Indonesia,238000000,Brazil,197000000,Pakistan,177000000,Nigeria,162000000,Bangladesh,151000000,Russia,143000000,Japan,128000000,Mexico,115000000,Philippines,96000000,Vietnam,88000000,Ethiopia,87000000,Germany,81800000,Egypt,82600000,Iran,78000000,Turkey,74000000,Thailand,69500000,Congo,67800000,France,63300000,United%20Kingdom,62700000,Italy,60800000~,100]#bitsatend></iframe>

… where the use of %c2%a0 creates whitespace but isn’t cleared by your normal trim functions, which is how we managed to get our Pie Chart title centralized enough not to be cut off by the HTML iframe border-radius applied to it. Cute, huh?!

Here is today’s changed circular_text.html‘s live run link for you to try yourself.


Previous relevant Circular Text or Emojis Analogue Clock Tutorial is shown below.

Circular Text or Emojis Analogue Clock Tutorial

Circular Text or Emojis Analogue Clock Tutorial

Often a good way to proceed to challenge genericity issues with a web application you think has potential to be more than it appears is to make it be the missing piece to another web application and interface to it. This is the scenario, today, putting together yesterday’s …

This interfacing match is great, as it fills in a gap, but there are a couple of things to overcome, those being …

  1. allow for a circular text component consist of more than one character, and here we allow the user to put …

    1<span>2</span>

    … to show “12” for example
  2. allow for an element like the HTML iframe “child” element be the contents within a newly introduced HTML div element for today’s changed circular_text.html‘s live run placed into the … anyone, anyone? … yes, Franklin D. Roosevelt, that would be in the circle the circular text goes around, and we do that stylewise via (on the fly Javascript) code making use of the centrally justified circular text element (curiously causing rect.width and rect.height below to be zero) …


    var rect=document.getElementById('test').getBoundingClientRect();
    document.getElementById('atend').style.position='absolute';
    document.getElementById('atend').style.left=eval(-rad + 20 + rect.left) + 'px';
    document.getElementById('atend').style.top=eval(38 + rect.top) + 'px';
    document.getElementById('atend').style.width=eval(2 * rad - 38) + 'px';
    document.getElementById('atend').style.height=eval(2 * rad - 38) + 'px';
    document.getElementById('atend').style.borderRadius=eval(2 * rad - 28) + 'px';
    if (document.getElementById('atend').innerHTML != '') { document.getElementById('atend').style.backgroundColor='#c0d0f0'; } //'transparent';

    … and ahead of this our user entered data needed for the Analogue Clock has an HTML (child) iframe element part …


    1<span>2</span>1234567891<span>0</span>1<span>1</span><iframe frameborder=0 style='z-index:23;margin-left:127px;margin-top:130px;height:400px;' src=analogue_clock.htm#xbody></iframe>

    … that we figure, because it is HTML containing spaces in its non-innerHTML parts, is meant as content for that new ‘atend’ HTML div element located in the middle of the circular text, and created via the codeline reached in this scenario …


    function justinnertextish(intx, within) {
    var sone=1, tagis='', iit=0, less=false, ioffset=0;
    outx=intx;
    it=[];
    if (intx.indexOf('</') != -1) {
    outx="";
    for (iit=0; iit<intx.length; iit+=sone) {
    if (intx.substring(iit, eval(1 + iit)) == '<') {
    tagis=intx.substring(iit).substring(1).split('>')[0];
    less=false;
    if (tagis.indexOf(' ') != -1 || within) {
    less=true;
    document.getElementById('atend').innerHTML='<' + tagis + '>' + intx.substring(eval(iit + 2 + tagis.length)).split('>')[0] + '>';

    // etcetera etcetera etcetera

Got the time?


Previous relevant Circular Text or Emojis Primer Tutorial is shown below.

Circular Text or Emojis Primer Tutorial

Circular Text or Emojis Primer Tutorial

We’ve got a “proof of concept” tutorial for you today, because we got put onto an idea for something by How to Make Circular/Curved Text with JavaScript, thanks. We wanted to extend the logic of that …

  • ascii codes (of characters) less than 256, text handling … to, now, be able to handle …
  • emoji data (or that’s what we like to “nickname” it … sorry if this annoys, but it really concerns UTF-8 characters really

We resisted the Sushi Train Circuit Game Tutorial ideas, because it isn’t lunchtime, and opted to allow the user to enter their own text (including any emojis (available via Command-Control-Space menu here at Mac OS X) or via &#[CodePoint]; HTML Entity (decimal or hexidecimal (CodePoint)) entries (where we’d like you to put &amp; rather than just & if you are going to do this, and if you want to do this, but need tips on how you might approach this, please consult our previous Karaoke via YouTube API in Iframe Emoji Tutorial where we often start at good ol’ emojipedia).

Maybe there will be some sequels, but for the meantime you can examine the HTML and Javascript circular_text.html code (including more thank you links), that you can try for yourself at this live run link.

With that in mind, take a look at us creeping through the text characters you enter, and notice how an emoji will have two bytes in a row with ascii code greater than 255 …


var etxt=intxt.replace(/\&amp\;/g,'&').replace(/\;\&\#/g,',').split('&#'); // intxt is your text
var txt=[], zero=0; // changed elsewhere as well

var one=1;
for (kk=zero; kk<etxt[k].length; kk+=one) {
if (etxt[k].substring(kk, eval(1 + kk)).charCodeAt(0) > 255) { // emoji found
txt.push(String.fromCodePoint(eval('' + etxt[k].substring(kk).charCodeAt(0)),eval('' + etxt[k].substring(kk).substring(1).charCodeAt(0)) ));
one=2;
} else { // normal ascii text
txt.push(etxt[k].substring(kk, eval(1 + kk)));
one=1;
}
}
}
one=1;
zero=0;

You can also see this play out at WordPress 4.1.1’s Circular Text or Emojis Primer Tutorial.

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

HTML Square Horizontal Rule Tracing Image Reveal Game Tutorial

HTML Square Horizontal Rule Tracing Image Reveal Game Tutorial

HTML Square Horizontal Rule Tracing Image Reveal Game Tutorial

Rest assured all of yesterday’s HTML Square Horizontal Rule Tracing iOS Mobile App Tutorial thoughts will continue on with any extended functionality with our “HTML Square Horizontal Rule Tracing” inspired web application’s dropdown list of games and puzzles. With that in mind, today’s extended functionality is an Image Revealing Game. Are you a regular, and know about our design belief in categorizing (a lot of) web design ideas into one of …

… concepts? Well, today, our Image Revealing Game uses a bit of both to create its workings.

What’s the gist of the game? It’s a game for two players and the players take it in turns, with …

  • One player picking an image via either …
    1. image URL … or
    2. browsed for image file on disk

    … and this image is the background image for the table element consisting of that 5×5 grid of the earliest days (still) of this project’s concepts … and …

  • the other player is clicking on overlayed buttons placed on top of this image to reveal 1/100th (as each table cell has four such buttons) of the image, and at any time, via the “guess” HTML “a” link means of guessing what the image contains, a correct guess, as judged by the first (image choosing) player scores that guessing player (100 – number of clicked buttons) points

To test this new game out, you could try today’s changed square_hr_tracing.htm‘s Image Revealing Game live run.


Previous relevant HTML Square Horizontal Rule Tracing iOS Mobile App Tutorial is shown below.

HTML Square Horizontal Rule Tracing iOS Mobile App Tutorial

HTML Square Horizontal Rule Tracing iOS Mobile App Tutorial

The design of our recent “HTML Square Horizontal Rule Tracing” suite of functionalities, with their navigational arrangements using …

  • web browser (address bar) URL involving ? and & arguments … and …
  • hashtags (using #)

… all possible, because the amounts of passed data is small (and so we don’t need to post to a serverside piece of code written in a language like PHP or Perl or Python (the three “P”‘s)), lends itself to (iOS) …

  • on the iPad or iPhone in a web browser such as Safari …
  • arrange navigation to a web application “snapshot” of the (game or puzzle or whatever) functionality of interest at its instigation …
  • touch the Share link up near the top right …
  • touch the “Add to Home Screen” button …
  • fill in a suitable name (you can “long touch” Select All to effectively highlight what’s there already, ready) for the …
  • icon you create in the Home Screen by touching the Add link at the top right

Then, from then on, those icons you create in the Home Screen could be your instant access method of “Cutting to the Chase”.

To show this, we used QuickTime Player on a MacBook Pro connected to an iPad by the (ubiquitous) Apple white lead via its New Movie Recording dropdown to “Robert’s iPad” option, to create a video called “iOS Mobile App and Web Application Nexus via Share’s Add to Home” uploaded to YouTube, and with the “blurb” …

We demonstrate some web applications that use the one HTML and Javascript and CSS codeset partitioned off to many functionalities (such as games and puzzles) visited by a Safari web browser user the once, and at instigation, are hived off to iPad Home screen icons as iOS Mobile Apps to a large degree, via the Share link’s Add to Home.

… that you can play for yourself below …

… resulting in the (best part of, but nobody’s saying “totally”) iOS Mobile App looking icons pointing at …

You can also see this play out at WordPress 4.1.1’s HTML Square Horizontal Rule Tracing iOS Mobile App Tutorial.


Previous relevant HTML Square Horizontal Rule Tracing SOS Game Tutorial is shown below.

HTML Square Horizontal Rule Tracing SOS Game Tutorial

HTML Square Horizontal Rule Tracing SOS Game Tutorial

The new development today on top of yesterday’s HTML Square Horizontal Rule Tracing Maths Grid Paper Tutorial is the coding for a game we used to play at school called the SOS Game.

If the grid is filled up and the number of SOSs for each player is the same, then the game is a draw. The game can also be played where the player who creates an SOS is the winner and if no SOSs are created the game is a draw.

A technique that came into play with this as far as user interaction is concerned was to involve select (dropdown) elements (surprise, surprise) with “size=3″ for the three choices ” ” (initially) or “S” or “O”. Once the user makes a non-blank choice we adjust that select (dropdown) element’s innerHTML to still be a dropdown but just with your selected value, nullifying any duplicate “onchange” event logics, on the understanding that the “onchange” event can’t be fired from a select (dropdown) element with only one option subelement.

This is a game designed for more than one player so we organize two players to play the game in turns.

Here is the initial drawing of the SOS Game grid …


function sosize() {
var itds=0; tds=document.getElementsByTagName('td');
var sqsi=0, ioffset=0;
document.getElementById('myh4').innerHTML+=' ... turn of Player1' + score1 + ' versus Player2' + score2;
for (var itrs=0; itrs<5; itrs++) {
for (var itds=eval(5 * itrs); itds<eval(5 + eval(5 * itrs)); itds++) {
thisrect=tds[itds].getBoundingClientRect();
tds[itds].style.verticalAlign='top';
sqsi=eval(2 * itds + ioffset);
tds[itds].innerHTML='<select title="" style=vertical-align:top;width:50%;height:50%;text-align:center; size=3 id=sqsi' + sqsi + ' onchange=sosmove(this);><option value=" "> </option><option value="S">S</option><option value="O">O</option></select>';
tds[itds].innerHTML+='<select title="" style=vertical-align:top;width:50%;height:50%;text-align:center; size=3 id=sqsi' + eval(1 + sqsi) + ' onchange=sosmove(this);><option value=" "> </option><option value="S">S</option><option value="O">O</option></select>';
tds[itds].innerHTML+='<br><select title="" style=vertical-align:bottom;width:50%;height:50%;text-align:center; size=3 id=sqsi' + eval(10 + sqsi) + ' onchange=sosmove(this);><option value=" "> </option><option value="S">S</option><option value="O">O</option></select>';
tds[itds].innerHTML+='<select title="" style=vertical-align:bottom;width:50%;height:50%;text-align:center; size=3 id=sqsi' + eval(11 + sqsi) + ' onchange=sosmove(this);><option value=" "> </option><option value="S">S</option><option value="O">O</option></select>';
}
ioffset+=10;
}
}

Here is the analysis of a player’s SOS Game select (dropdown) element interaction …


function checkifsos(t1, t2, t3) { //, camv) {
//var score1=' (0)', score2=' (0)';
//var amv=camv.split('.')[0];
var retv=false;
if (t1 >= 0 && t1 < 100 && t2 >= 0 && t2 < 100 && t3 >= 0 && t3 < 100) {
if (document.getElementById('sqsi' + t1).value == 'S' && document.getElementById('sqsi' + t2).value == 'O' && document.getElementById('sqsi' + t3).value == 'S') {
if (thisplayer == 1) {
document.getElementById('sqsi' + t1).style.border='1px inset red';
document.getElementById('sqsi' + t2).style.border='1px inset red';
document.getElementById('sqsi' + t3).style.border='1px inset red';


if (document.getElementById('sqsi' + t1).title.indexOf('2') != -1) {
document.getElementById('sqsi' + t1).style.backgroundColor='';
document.getElementById('sqsi' + t1).className='bicol'; //style.backgroundColor="linear-gradient(top, pink, yellow)";
} else {
document.getElementById('sqsi' + t1).style.backgroundColor='pink';
}
if (document.getElementById('sqsi' + t2).title.indexOf('2') != -1) {
document.getElementById('sqsi' + t2).style.backgroundColor='';
document.getElementById('sqsi' + t2).className='bicol'; //style.backgroundColor="linear-gradient(top, pink, yellow)";
} else {
document.getElementById('sqsi' + t2).style.backgroundColor='pink';
}
if (document.getElementById('sqsi' + t3).title.indexOf('2') != -1) {
document.getElementById('sqsi' + t3).style.backgroundColor='';
document.getElementById('sqsi' + t3).className='bicol'; //style.backgroundColor="linear-gradient(top, pink, yellow)";
} else {
document.getElementById('sqsi' + t3).style.backgroundColor='pink';
}
document.getElementById('sqsi' + t1).title+='1';
document.getElementById('sqsi' + t2).title+='1';
document.getElementById('sqsi' + t3).title+='1';
} else {
document.getElementById('sqsi' + t1).style.border='1px inset olive';
document.getElementById('sqsi' + t2).style.border='1px inset olive';
document.getElementById('sqsi' + t3).style.border='1px inset olive';
if (document.getElementById('sqsi' + t1).title.indexOf('1') != -1) {
document.getElementById('sqsi' + t1).style.backgroundColor='';
document.getElementById('sqsi' + t1).className='bicol'; //style.backgroundColor="linear-gradient(top, pink, yellow)";
} else {
document.getElementById('sqsi' + t1).style.backgroundColor='yellow';
}
if (document.getElementById('sqsi' + t2).title.indexOf('1') != -1) {
document.getElementById('sqsi' + t2).style.backgroundColor='';
document.getElementById('sqsi' + t2).className='bicol'; //style.backgroundColor="linear-gradient(top, pink, yellow)";
} else {
document.getElementById('sqsi' + t2).style.backgroundColor='yellow';
}
if (document.getElementById('sqsi' + t3).title.indexOf('1') != -1) {
document.getElementById('sqsi' + t3).style.backgroundColor='';
document.getElementById('sqsi' + t3).className='bicol'; //style.backgroundColor="linear-gradient(top, pink, yellow)";
} else {
document.getElementById('sqsi' + t3).style.backgroundColor='yellow';
}
document.getElementById('sqsi' + t1).title+='2';
document.getElementById('sqsi' + t2).title+='2';
document.getElementById('sqsi' + t3).title+='2';
}
retv=true;
if (thisplayer == 1) {
score1=' (' + eval(eval(score1.split('(')[1].split(')')[0]) + 1) + ')';
} else {
score2=' (' + eval(eval(score2.split('(')[1].split(')')[0]) + 1) + ')';
}
}
}
return retv;
}

function sosmove(osel) {
var cosel=osel.value, anothergo=false, prevplayer=thisplayer;
var thistile=eval(osel.id.replace('sqsi',''));
var surrounds='';
var prevscore1=score1;
var prevscore2=score2;
if (cosel.trim() != '') {
osel.size=1;
osel.style.border='1px inset blue';
osel.innerHTML='<option value=' + cosel + '>' + cosel + '</option>';
document.getElementById('myh4').innerHTML=document.getElementById('myh4').innerHTML.replace(' Player1' + score1 + ' versus Player2' + score2,' Player02' + score2 + ' versus Player01' + score1).replace(' Player2' + score2 + ' versus Player1' + score1,' Player01' + score1 + ' versus Player02' + score2).replace(' Player0',' Player').replace(' Player0',' Player');
// hmiddle -1 me +1
// hend -2 -1 me
// hstart me +1 +2
// vmiddle -10 me +10
// vend -20 -10 me
// vstart me +10 +20
// ddmiddle -11 me +11
// ddend -22 -11 me
// ddstart me +11 +22
// udmiddle -9 me +9
// udend -18 -9 me
// udstart me +9 +18
if (eval(thistile % 10) > 0 && eval(thistile % 10) < 9) {
anothergo|=checkifsos(eval(-1 + thistile), thistile, eval(1 + thistile));
}
if (eval(thistile % 10) > 1) {
anothergo|=checkifsos(eval(-2 + thistile), eval(-1 + thistile), thistile);
}
if (eval(thistile % 10) < 8 ) {
anothergo|=checkifsos(thistile, eval(1 + thistile), eval(2 + thistile));
}


if (eval(thistile / 10) > 0 && eval(thistile / 10) < 9) {
anothergo|=checkifsos(eval(-10 + thistile), thistile, eval(10 + thistile));
}
if (eval(thistile / 10) > 1) {
anothergo|=checkifsos(eval(-20 + thistile), eval(-10 + thistile), thistile);
}
if (eval(thistile / 10) < 8 ) {
anothergo|=checkifsos(thistile, eval(10 + thistile), eval(20 + thistile));
}


if (eval(thistile % 10) > 0 && eval(thistile % 10) < 9 && eval(thistile / 10) > 0 && eval(thistile / 10) < 9) {
anothergo|=checkifsos(eval(-11 + thistile), thistile, eval(11 + thistile));
}
if (eval(thistile % 10) > 1 && eval(thistile / 10) > 2) {
anothergo|=checkifsos(eval(-22 + thistile), eval(-11 + thistile), thistile);
}
if (eval(thistile % 10) < 8 && eval(thistile / 10) < 8 ) {
anothergo|=checkifsos(thistile, eval(11 + thistile), eval(22 + thistile));
}


if (eval(thistile % 10) > 0 && eval(thistile % 10) < 9 && eval(thistile / 10) > 0 && eval(thistile / 10) < 9) {
anothergo|=checkifsos(eval(-9 + thistile), thistile, eval(9 + thistile));
}
if (eval(thistile % 10) >= 0 && eval(thistile / 10) < 8 ) {
anothergo|=checkifsos(eval(-18 + thistile), eval(-9 + thistile), thistile);
}
if (eval(thistile % 10) > 2 && eval(thistile / 10) < 8 ) {
anothergo|=checkifsos(thistile, eval(9 + thistile), eval(18 + thistile));
}


if (!anothergo) { thisplayer=eval(eval('' + 3) - eval('' + prevplayer)); } else { document.getElementById('myh4').innerHTML=document.getElementById('myh4').innerHTML.replace(' Player1' + prevscore1 + ' versus Player2' + prevscore2,' Player02' + score2 + ' versus Player01' + score1).replace(' Player2' + prevscore2 + ' versus Player1' + prevscore1,' Player01' + score1 + ' versus Player02' + score2).replace(' Player0',' Player').replace(' Player0',' Player'); }
}
}

… being simplified, considerably, via the advice of this great link, thanks, regarding CSS linear-gradient usage …


<style>
.bicol {
background: rgb(255,255,255); /* Old browsers */
background: -moz-linear-gradient(top, pink 0%, pink 50%, yellow 51%, yellow 100%); /* FF3.6-15 */
background: -webkit-linear-gradient(top, pink 0%,pink 50%,yellow 51%,yellow 100%); /* Chrome10-25,Safari5.1-6 */
background: linear-gradient(to bottom, pink 0%,pink 50%,yellow 51%,yellow 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=pink, endColorstr=yellow,GradientType=0 ); /* IE6-9 */
}
</style>

You could try today’s changed square_hr_tracing.htm‘s SOS Game live run.


Previous relevant HTML Square Horizontal Rule Tracing Maths Grid Paper Tutorial is shown below.

HTML Square Horizontal Rule Tracing Maths Grid Paper Tutorial

HTML Square Horizontal Rule Tracing Maths Grid Paper Tutorial

Yesterday’s HTML Square Horizontal Rule Tracing Hangman Game Tutorial set us up for today’s Maths Grid Paper web application part that involves …

  • Hangman Game background is the look we want, as we want the vertices as guides for today’s grid paper work … teamed with a new idea that is …
  • the top.document parent of two children that are …
    1. specially (hashtag #hangman-0.0) called child iframe Hangman Game peered with other child x,y positionally but slightly behind on z-index to …
    2. today’s changed user_of_signature_signature.html‘s User of Signature Signature live run (last changed with Email Subject Line Emojis Primer Tutorial) child iframe featuring an HTML5 canvas element overlaying the vertices … by way of (square_hr_tracing.htm’s) …

      document.getElementById('myh1').innerHTML=' ';
      document.getElementById('myh3').innerHTML=' ';
      document.getElementById('myh4').innerHTML=' ';
      document.getElementById('dhangman').innerHTML+="<iframe name=iback id=iback style='background-color:transparent;z-index:23;position:absolute;top:200px;left:0px;width:580px;height:100vh;' src=//www.rjmprogramming.com.au/HTMLCSS/user_of_signature_signature.html?rand=" + Math.floor(Math.random() * 123456) + "></iframe>";
      document.getElementById('dhangman').innerHTML+="<iframe name=ifront id=ifront style='background-color:transparent;z-index:22;position:absolute;top:0px;left:0px;width:100%;height:100vh;' src=//www.rjmprogramming.com.au/HTMLCSS/square_hr_tracing.htm#hangman-0.0></iframe>";

      document.getElementById('dhangman').innerHTML+="<div id=dback title='' style='background-color:transparent;z-index:24;position:absolute;top:200px;left:580px;'></div>";

    … and along the way to get this all timed so that a child iframe (canvas) can be like a background image (that is clickably intelligent) …

  • multiple hashtagging in that top.document parent is used … #mathsgrid#hangman …

    if ((' ' + location.hash).split('#').length > 2 || (' ' + location.hash).indexOf('hangman-0.0') != -1) {
    document.getElementById('myh1').innerHTML='Maths Grid Paper';
    }
    // ...
    if (bpointsx.length >= 4 && (' ' + location.hash).split('#').length > 2 || (' ' + location.hash).indexOf('hangman-0.0') != -1) {
    if (parent.document.getElementById('dback')) {
    parent.document.getElementById('dback').title='' + bpointsx[0] +',' + eval(-200 + bpointsy[0]) + ',' + bpointsx[1] +',' + eval(-200 + bpointsy[1]) + ',' + bpointsx[2] + ',' + eval(-200 + bpointsy[2]) + ',' + bpointsx[3] +',' + eval(-200 + bpointsy[3]);
    bpointsx=[];
    bpointsy=[];
    }
    }

    … to get the best of both worlds

That’s a discussion more with the focus on looks. Doing this, we found it to be that one stage better than (just) “looks” though, as we discovered even though the child iframe Hangman Game was “slightly behind on z-index” we could still differentiate the …

  • specially (hashtag #hangman-0.0) called child iframe Hangman Game discrete vertex clicks and touches … from …
  • today’s changed user_of_signature_signature.html‘s User of Signature Signature live run child iframe featuring an HTML5 canvas element (onmousemove and ontouchmove) scribbling …

    function checkdback() {
    var rco='', rcos=[];
    if (parent.document.getElementById('dback')) {
    if (imgd != '') {
    if (parent.document.getElementById('cback')) {
    parent.document.getElementById('cback').getContext('2d').putImageData(imgd,0,0);
    imgd=parent.document.getElementById('cback').toDataURL();
    parent.document.getElementById('dback').innerHTML="<img style='z-index:24;border:2px solid orange;' id=imgback src='" + imgd + "'></img>";
    imgd='';
    }
    }
    if (parent.document.getElementById('dback').title != '') {
    rco=parent.document.getElementById('dback').title;
    parent.document.getElementById('dback').title='';
    setTimeout(checkdback, 2000);
    } else {
    setTimeout(checkdback, 2000);
    }
    }
    if (rco != '') {
    rcos=rco.split(',');
    var x1=eval('' + rcos[0]);
    x1=Math.min(x1, eval('' + rcos[2]));
    x1=Math.min(x1, eval('' + rcos[4]));
    x1=Math.min(x1, eval('' + rcos[6]));
    var y1=eval('' + rcos[1]);
    y1=Math.min(y1, eval('' + rcos[3]));
    y1=Math.min(y1, eval('' + rcos[5]));
    y1=Math.min(y1, eval('' + rcos[7]));
    var x2=eval('' + rcos[0]);
    x2=Math.max(x2, eval('' + rcos[2]));
    x2=Math.max(x2, eval('' + rcos[4]));
    x2=Math.max(x2, eval('' + rcos[6]));
    var y2=eval('' + rcos[1]);
    y2=Math.max(y2, eval('' + rcos[3]));
    y2=Math.max(y2, eval('' + rcos[5]));
    y2=Math.max(y2, eval('' + rcos[7]));
    imgd=document.getElementById('topcanvas').getContext('2d').getImageData(x1,y1,x2,y2);
    parent.document.getElementById('dback').style.width='' + Math.round(eval(x2 - x1)) + 'px';
    parent.document.getElementById('dback').style.height='' + Math.round(eval(y2 - y1)) + 'px';
    parent.document.getElementById('dback').innerHTML="<canvas style=z-index:24; width='" + Math.round(eval(x2 - x1)) + "' height='" + Math.round(eval(y2 - y1)) + "' id=cback></canvas>";
    }
    }

    setTimeout(checkdback,2000);

    … so …

… could also allow the user to do some Math Grid Paper scribbling and then click/touch four vertices to define a window of extraction from which a sharable image is created, ready for an email attachment or some other purpose. We weren’t sure that both data capture methods above could live in the one interfacing arrangement, so we were happy to see this working, especially as this opens the door to sharing and collaboration possibilities with this new Maths Grid Paper functionality.

Again, try today’s changed square_hr_tracing.htm‘s Maths Grid Paper live run tool.


Previous relevant HTML Square Horizontal Rule Tracing Hangman Game Tutorial is shown below.

HTML Square Horizontal Rule Tracing Hangman Game Tutorial

HTML Square Horizontal Rule Tracing Hangman Game Tutorial

Our new Hangman Game extension to functionality (on top of HTML Square Horizontal Rule Tracing Propogation Tutorial) makes use of both …

  • HTML Square Horizontal Rule Tracing … and …
  • Emoji overlay … two of our usual suspect …
    1. position:absolute property
    2. z-index

    … ideas

… the latter of which aids us with the head 🙂 and noose 🎀 drawing requirements … but still no purpose built imagery is required. We hope you can see how these emojis can help we graphically challenged ones … both …

  • get on with projects despite that lack of image based work … and …
  • work with a more and more accepted form of communication that is more Internationally understood

Of interest as far as the Javascript code for this goes is our approach of setting up some static array records consisting of multiple Javascript lines of code (separated by ; (semicolon)) that are executed via Javascript eval functionality as per …


var ihangman=0;
var hangmanc=[
" document.getElementById('dhangman').innerHTML+='<p id=phead class=face style=z-index:90;position:absolute;top:248px;left:142px;font-size:56px;>&#128578;</p>'; ",
" document.getElementById('hr77').click(); document.getElementById('hr137').click(); ",
" document.getElementById('hr119').click(); document.getElementById('hr77').click(); ",
" document.getElementById('hr131').click(); document.getElementById('hr77').click(); ",
" document.getElementById('hr137').click(); document.getElementById('hr234').click(); ",
" document.getElementById('hr137').click(); document.getElementById('hr246').click(); ",
" document.getElementById('hr235').click(); document.getElementById('hr256').click(); ",
" document.getElementById('hr260').click(); document.getElementById('hr256').click(); ",
" document.getElementById('hr230').click(); document.getElementById('hr235').click(); ",
" document.getElementById('hr235').click(); document.getElementById('hr20').click(); ",
" document.getElementById('hr290').style.display='none'; document.getElementById('hr260').click(); document.getElementById('hr235').click(); document.getElementById('phead').innerHTML='&#129314;'; document.getElementById('dhangman').innerHTML+='<p id=pnoose class=face style=background-color:blank;z-index:95;position:absolute;top:195px;left:168px;font-size:6px;>&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;&lt;br&gt;&#127872;</p>'; "
];


function hguess(gthis,othis) {
var ifnd=0, fnd=false, newval='';
for (ifnd=0; ifnd<vocabulary[0].length; ifnd++) {
if (vocabulary[0].substring(ifnd,eval(1 + ifnd)).toLowerCase() == gthis.toLowerCase()) {
fnd=true;
newval+=gthis;
} else {
newval+=document.getElementById('sletters').innerHTML.substring(ifnd,eval(1 + ifnd));
}
}
document.getElementById('sletters').innerHTML=newval;
document.getElementById('sletters').title=newval;
othis.style.visibility='hidden';


if (!fnd) {
eval(hangmanc[ihangman]);
ihangman++;
}
if (ihangman >= hangmanc.length) {
goes++;
newval='';
for (ifnd=0; ifnd<vocabulary[0].length; ifnd++) {
if (document.getElementById('sletters').innerHTML.substring(ifnd,eval(1 + ifnd)).toLowerCase() == "_") {
newval+='<font color=red>' + vocabulary[0].substring(ifnd,eval(1 + ifnd)) + '</font>';
} else {
newval+=document.getElementById('sletters').innerHTML.substring(ifnd,eval(1 + ifnd));
}
}
document.getElementById('sletters').innerHTML=newval;
document.getElementById('sletters').title=vocabulary[0];
setTimeout(handon, 5000);
} else if (document.getElementById('sletters').innerHTML.indexOf('_') != -1) {
} else {
score+=document.getElementById('sletters').innerHTML.length;
goes++;
setTimeout(handon, 5000);
}
}

And where do we get our English words to challenge you? We get them from the server’s English Ispell dictionary. Other servers would have other language Ispell dictionaries. Either way, you will find these dictionaries invaluable for word games.

Try today’s changed square_hr_tracing.htm‘s Hangman live run game to test your English vocabulary skills. You may find the Speech to Text Speech to Text Hangman Game Tutorial‘s Hangman Game of interest too.


Previous relevant HTML Square Horizontal Rule Tracing Propogation Tutorial is shown below.

HTML Square Horizontal Rule Tracing Propogation Tutorial

HTML Square Horizontal Rule Tracing Propogation Tutorial

Yesterday’s HTML Square Horizontal Rule Tracing Game Tutorial continued on with the …

  • HTML hr and div elements made up to be …
    1. lines
    2. vertices

    … only needing the underlying …

  • table cell elements as graphical position markers only (made to have intelligence derived via use of Javascript getBoundingClientRect()), but pretty “dumb” markers at that

… but HTML and Javascript are capable of very sophisticated event propogation, and there is no reason you have to have those underlying table cell elements remaining “dumb” that way. You can, amongst many things, in Javascript, dynamically add …

  • ID on the fly

    var tds=document.getElementsByTagName('td');
    for (var itds=0; itds<tds.length; itds++) {
    tds[itds].id='td' + eval(1 + itds);
    }
  • onclick event logic on the fly

    var lastsquare=-1;
    var tds=document.getElementsByTagName('td');
    for (var itds=0; itds<tds.length; itds++) {
    tds[itds].id='td' + eval(1 + itds);
    tds[itds].onclick=function(event) { lastsquare=eval(('' + this.id).replace('td','')); goes++; if (lastsquare == sqchoice) { score++; } if (('' + location.hash).indexOf('square') != -1) { picksq(); } else if (('' + location.hash).indexOf('grid') != -1) { gridinfo(' in square number ' + lastsquare); } };
    }

We’ve started with some other game ideas using event propogation, with the last one, in today’s changed square_hr_tracing.htm‘s live run game, that now has game options …

  • Chinese Brain Twisters
  • Vertex Pointing Game … just shows vertices and on a set of 4 clicks or touches, will plot a Bezier Curve (thanks to this useful link, thanks)
  • Square Pointing Game … just shows the table and its numbered cells … with a number quiz
  • Grid Pointing Game … shows border lines, and vertices and table cells with their thinner borders … where information is presented, relying on event propogation orders to show information from two hierarchies of event propogation

To differentiate between these forms of game (selected via a new HTML select (dropdown) element) we did not choose to use our usual address bar URL argument (via ? and &) navigation method, but rather use hashtag (via #) address bar URL methods, and in the Javascript (DOM) examine location.hash to know which “game” is applicable to a web application session.

Food for thought, we hope!


Previous relevant HTML Square Horizontal Rule Tracing Game Tutorial is shown below.

HTML Square Horizontal Rule Tracing Game Tutorial

HTML Square Horizontal Rule Tracing Game Tutorial

The first application of the (online web application) line drawing we started with yesterday’s HTML Square Horizontal Rule Tracing Primer Tutorial is today’s online (web application) game version of some of the excellent puzzles in the book “Chinese Brain Twisters” by Baifang (ISBN: 0-471-59505-5). It was the “stick” rearrangement puzzles in this excellent book that were the inspiration to getting together a display and user interaction set of HTML and CSS and Javascript code logics to turn a hardcopy concept into an online game.

Of course, when you start with a “proof of concept” it can need quite a bit of “tweaking” (in this case, fitting it into those concept paradigms we talk about a couple of paragraphs on) when the reality of making it practical for the user comes into play with a project like this. We, at first thought, that …

  • we would display a question (about matches, rather than sticks, because we remember many a holiday game that involved the use of matches (… no, not that way) regarding patterns and counting, and because a match gives us an excuse to add some red colour as per CSS

    <style>
    hr {
    height: 4px;
    border: 2px solid black;
    background: linear-gradient(to right, yellow 80%, rgba(255,0,0,1) 20%);
    }
    </style>

    ) and then with a button controlled by the user, “slap on” the screen the answer … then we had a mild epiphany (you had to be there) …
  • we would display a question and then animate the answer … which can be achieved by “slapping on” that same question, and click/touch the actions of a successful user after 2 second delays between the clicks/touches (via a setTimeout timer controlled set of Javascript calls)

We hope it gives the game a more interactive feel, and a better way to learn perhaps, because geometry can be an “ahhhh haaa” type of thing to learn, when you see graphically the steps involved.

As with many a game we’ve written we again fall back to two tried and true (and very simple) concepts …

  • gather question data into simple (single dimension) arrays, additional complexity controlled within members by web application specific delimitation rules (or more singular dimensioned arrays (such as today, where there are two)) …
  • get the user a randomized question for the game via Javascript code like (where “inquestions” variable below is just such an array) …

    var choice=Math.floor(Math.random() * inquestions.length);

    … leading to “”inquestions[choice]” containing the data required to piece together the question … along with the “inwordings[choice]” of the other such array “inwordings” that contains “Chinese Brain Twisters” instructional text

Another “game chestnut” concept for us is to have some sort of scoring mechanism, which we may attend to in upcoming posts. For now, we’ll let you “cheat in the comfort of your own conscience” when bragging about your “Chinese Brain Twisters” prowess!

Feel free to try out the changed square_hr_tracing.htm‘s live run game, and challenge yourself!

You can also see this play out at WordPress 4.1.1’s HTML Square Horizontal Rule Tracing Primer Tutorial.


Previous relevant HTML Square Horizontal Rule Tracing Primer Tutorial is shown below.

HTML Square Horizontal Rule Tracing Primer Tutorial

HTML Square Horizontal Rule Tracing Primer Tutorial

One sad thing about today’s blog posting title is it gives the game away. We’re tackling a proof of concept web application for a future venture. We want to be able to draw a grid of lines (or you could see them as matches) and we’ll want to …

  • graphically present them (ie. grid square border lines (or matches)) around the edges of each grid square … and …
  • graphically present vertices at match end points and half way between, and well as in the middle of squares … then let the user …
  • click/touch a match … then …
  • click/touch two vertices to reposition that match to the clicked vertex positioning

Now, it seems to me, off the top of the head, you could proceed along the lines of …

  • HTML5 canvas element graphics … or
  • SVG graphics … but we prefer … you guessed it
  • HR (Horizontal Rule) HTML elements, transformed as required, to suit our purposes

Interested?! Why not try the HTML/Javascript/CSS square_hr_tracing.html‘s live run to see what we mean here.

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