WordPress Blog topics available via today’s changedinteractively_change_background_image_on_scroll.htmlweb application (and we hope you get to try way below) reminds the user …
var ansis=prompt('Optionally enter in background source URL prefix [' + prefix + midbit + suffix + '] ( or use Lorem Picsum or for blog posting images try //www.rjmprogramming.com.au/ITblog/' + sixhundred + '/' + fourhundred + '/ (and you can optionally wedge in a Topic of Interest appended to those numbers, where + is a space, if you wish eg. //www.rjmprogramming.com.au/ITblog/' + sixhundred + '/' + fourhundred + 'Google+Chart/ )), hashtag delimited from optional imagery refresh rate in seconds [' + ten + '], hashtag delimited from optional Text element background image (or use Lorem Picsum), hashtag delimited from optional Text wording [' + tcont + '] we will assume involves a space.', '');
… in its Javascript prompt popup window that these new WordPress Blog Topic ideas are available
What else has happened regarding the Inhouse WordPress Blog Posting Game above? Well …
we’ve introduced a “splash screen” page, if you will, ahead of the game loading (which is the default and original Drag and Drop webpage), in order to have something on the webpage ahead of the game loading …
if ($recallit == './inhouse_blog_game.php' && !isset($_GET['reload'])) {
echo "<html><head><title>Experimental Drag and Drop - RJM Programming- July, 2023 ... thanks to https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setData</title></head><body><iframe id=myihbqiframe frameborder=0 onload=\"if (this.src.indexOf('inhouse_blog_game.') == -1) { var aconto = (this.contentWindow || this.contentDocument); if (aconto.document) { aconto = aconto.document; } aconto.body.style.border='2px dotted olive'; aconto.body.style.cursor='progress'; setTimeout(function() { document.getElementById('myihbqiframe').src='//www.rjmprogramming.com.au/HTMLCSS/inhouse_blog_game.php?reload=y'; }, 7000); aconto.getElementById('score').innerHTML+=' ... awaiting Inhouse Blog Game loading ...'; }\" style=\"width:100%;height:900px;\" src=\"./experimental_drag_and_drop.htm\"></iframe></body></html>";
exit;
}
?>
we use a lot more document.body.style.cursor=’progress’; to help with the loading delays, as well …
<?php
$templategame=str_replace('RJM Programming <span id=spmore>-</span> ', 'RJM Programming <span id=spmore><a style=text-decoration:none;cursor:pointer; onclick="var topic=prompt(' . "'Optionally refine Blog Postings to ones regarding your enter Topic word(s).',''" . '); if (topic) { if (topic.trim().length != 0) { var documentURL=document.URL,dlm=String.fromCharCode(38); if (document.URL.indexOf(String.fromCharCode(63)) == -1) { dlm=String.fromCharCode(63); } else { documentURL=document.URL.replace(String.fromCharCode(99) + String.fromCharCode(61), String.fromCharCode(61)); } document.body.style.cursor=' . "'progress'; " . ' location.href=' . "documentURL + dlm + 'topic=' + encodeURIComponent(topic);" . ' } }" title=Topics>+</a></span> ', $templategame);
?>
we’ve now got a new span “used to be – content” that is now embedded with a + a link allowing users to specify their WordPress topic, in code above
allow for the game modus operandi be the other way around (to yesterday’s WordPress Blog titles and date in the “Drag” section and image backgrounds in the “Drop Zone” nine table cells) ( ie. image background in the “Drag” section and WordPress Blog titles and dates in the “Drop Zone” nine table cells ) as well
show the user, in the “Drag” section a WordPress Blog Posting Title (and date) … which the user should drag to the appropriate …
table cell, nine of which exist in the “Drop Zone”, and are numbered and backgrounded by a random WordPress Tutorial Picture image
… in alignment with the adage …
Every picture is worth a thousand words.
As well, today, both in terms of …
providing hints … and/or …
providing information
… those table cells are associated with …
double click event (“ondblclick”) logic that shows the “Cut to the Chase” underlying “action item” associated with the WordPress Blog Posting involved … and, just quietly …
right click event (“oncontextmenu”) logic that shows the associated WordPress Blog Posting involved itself
… into that newly minted Javascript prompt window designed for user interaction purposes? This populates the background images in our new Image Scrolling with Fixed Text web application with a random selection from the WordPress Blog you are reading. Because we have some control here, we researched whether our WordPress 404.php logic could be tweaked to help out more in this scenario. The way the PHP works here, detecting this situation, at the end of its workings, is to use an image header (exemplified by the GIF one below) …
… where $path would point at a GIF image file residing on the RJM Programming domain web server. This design restricts us from any echo functionality before this, so what can we achieve? Anyone? Anyone? Yes, Rasmus, we can write to other web server files that could be like middle-people between the server (supplier of image data) and client (the webpage that called the server). After the server work …
… back at that client (which called the server with that appended “591734” placed onto the URL to indicate the intention to want to examine this return data), we have Ajax based Javascript logic …
var ptc='#';
var iptc=0;
var btlist=[];
var vsbtlist=[];
var omo='';
var zhr=null;
var zform=null;
var rawhtml='';
function defmaybe(inu) {
var retomo=omo;
if (omo != '') {
omo='';
return retomo;
}
return inu;
}
function stateChanged() {
var inm=1, jnm=1, thebtitle='';
if (zhr.readyState == 4) {
if (zhr.status == 200) {
rawhtml = zhr.response;
console.log('rawhtml=' + rawhtml);
if (rawhtml.indexOf('random=') != -1 && vsbtlist.length > 0) {
var rawrs=rawhtml.split('random=');
for (inm=1; inm<rawrs.length; inm++) {
for (jnm=0; jnm<vsbtlist.length; jnm++) {
if (vsbtlist[jnm].indexOf('?random=' + rawrs[inm].split(String.fromCharCode(10))[0]) != -1) {
console.log('found ...');
thebtitle=rawhtml.split('?random=' + rawrs[inm].split(String.fromCharCode(10))[0])[0].split(String.fromCharCode(10))[eval(-1 + rawhtml.split('?random=' + rawrs[inm].split(String.fromCharCode(10))[0])[0].split(String.fromCharCode(10)).length)];
console.log(thebtitle);
document.getElementById(vsbtlist[jnm].split('?')[0]).title=thebtitle + ' ... you can right click to navigate there';
document.getElementById(vsbtlist[jnm].split('?')[0]).onmouseout=function(){ omo=''; };
document.getElementById(vsbtlist[jnm].split('?')[0]).onmouseover=function(){ omo='//www.rjmprogramming.com.au/ITblog/' + thebtitle.split(' (')[0].toLowerCase().replace(/\ /g,'-'); };
document.getElementById(vsbtlist[jnm].split('?')[0]).oncontextmenu=function(){ window.open(defmaybe('//www.rjmprogramming.com.au/ITblog/' + thebtitle.split(' (')[0].toLowerCase().replace(/\ /g,'-')),'_blank','top=50,left=50,width=800,height=800'); };
}
}
}
}
}
}
}
function ajaxit() {
zhr = new XMLHttpRequest();
zhr.onreadystatechange=stateChanged;
zhr.open('get', '//www.rjmprogramming.com.au/ptitledata.html?random=' + Math.floor(Math.random() * 196756453), true);
zhr.send(null);
}
… adding oncontextmenu (ie. right click) functionality to the background images, so as a popup window can open to show the associated WordPress Blog posting linked to the image data.
Interactively Change Background Image on Scroll User Settings Tutorial
If you are a regular reader, you’ll know with the web applications presented here, we usually try to allow the user to control …
how they function … and/or sometimes …
how they look
… in the ephemeral “this session” sense, and sometimes follow that up, depending, with recallable settings often calling on window.localStorage or HTTP Cookies, associated with the web browser being used.
… and regarding the use of that last one, we’ve decided, somewhat, to take over with the CSS regarding the Text Wording showing through amongst so many “image interests” with various opacities …
We use it more and more often to help out foreground text presented with a lot of “overlay imagery” going on behind it.
Here is the Javascript prompt window “blurb” presented to the user should they want to delve into this woooooorrrrrlllllldddd just by clicking or touching in the non-text part of the webpage …
var ansis=prompt(‘Optionally enter in background source URL prefix [‘ + prefix + midbit + suffix + ‘] ( or type Lorem Picsum or for blog posting images you could try //www.rjmprogramming.com.au/ITblog/’ + sixhundred + ‘/’ + fourhundred + ‘/ ), hashtag delimited from an optional imagery refresh rate in seconds [‘ + ten + ‘], hashtag delimited from an optional Text element background image (or type Lorem Picsum), hashtag delimited from optional Text wording [‘ + tcont + ‘] we will assume involves a space.‘, ”);
And did you know, at least for non-mobile platforms, you can set the focus (on non-mobile platforms only, as there are the “keyboard getting in the way” issues we’re thankful for with mobile platforms which preclude any thoughts of a programmed [element].focus() operation) to one of these “contenteditable=true style elements”? We’d never been sure, only focussing to HTML input textboxes and textareas up to now, we believe.
… whereby non-mobile focus to a contenteditable=true HTML div type (innerHTML style) element is possible, adding to the original W3School’s content ideas swirling around …
CSS position: fixed; … for foreground text, in relation to …
show the user, in the “Drag” section a WordPress Blog Posting Title (and date) … which the user should drag to the appropriate …
table cell, nine of which exist in the “Drop Zone”, and are numbered and backgrounded by a random WordPress Tutorial Picture image
… in alignment with the adage …
Every picture is worth a thousand words.
As well, today, both in terms of …
providing hints … and/or …
providing information
… those table cells are associated with …
double click event (“ondblclick”) logic that shows the “Cut to the Chase” underlying “action item” associated with the WordPress Blog Posting involved … and, just quietly …
right click event (“oncontextmenu”) logic that shows the associated WordPress Blog Posting involved itself
… into that newly minted Javascript prompt window designed for user interaction purposes? This populates the background images in our new Image Scrolling with Fixed Text web application with a random selection from the WordPress Blog you are reading. Because we have some control here, we researched whether our WordPress 404.php logic could be tweaked to help out more in this scenario. The way the PHP works here, detecting this situation, at the end of its workings, is to use an image header (exemplified by the GIF one below) …
… where $path would point at a GIF image file residing on the RJM Programming domain web server. This design restricts us from any echo functionality before this, so what can we achieve? Anyone? Anyone? Yes, Rasmus, we can write to other web server files that could be like middle-people between the server (supplier of image data) and client (the webpage that called the server). After the server work …
… back at that client (which called the server with that appended “591734” placed onto the URL to indicate the intention to want to examine this return data), we have Ajax based Javascript logic …
var ptc='#';
var iptc=0;
var btlist=[];
var vsbtlist=[];
var omo='';
var zhr=null;
var zform=null;
var rawhtml='';
function defmaybe(inu) {
var retomo=omo;
if (omo != '') {
omo='';
return retomo;
}
return inu;
}
function stateChanged() {
var inm=1, jnm=1, thebtitle='';
if (zhr.readyState == 4) {
if (zhr.status == 200) {
rawhtml = zhr.response;
console.log('rawhtml=' + rawhtml);
if (rawhtml.indexOf('random=') != -1 && vsbtlist.length > 0) {
var rawrs=rawhtml.split('random=');
for (inm=1; inm<rawrs.length; inm++) {
for (jnm=0; jnm<vsbtlist.length; jnm++) {
if (vsbtlist[jnm].indexOf('?random=' + rawrs[inm].split(String.fromCharCode(10))[0]) != -1) {
console.log('found ...');
thebtitle=rawhtml.split('?random=' + rawrs[inm].split(String.fromCharCode(10))[0])[0].split(String.fromCharCode(10))[eval(-1 + rawhtml.split('?random=' + rawrs[inm].split(String.fromCharCode(10))[0])[0].split(String.fromCharCode(10)).length)];
console.log(thebtitle);
document.getElementById(vsbtlist[jnm].split('?')[0]).title=thebtitle + ' ... you can right click to navigate there';
document.getElementById(vsbtlist[jnm].split('?')[0]).onmouseout=function(){ omo=''; };
document.getElementById(vsbtlist[jnm].split('?')[0]).onmouseover=function(){ omo='//www.rjmprogramming.com.au/ITblog/' + thebtitle.split(' (')[0].toLowerCase().replace(/\ /g,'-'); };
document.getElementById(vsbtlist[jnm].split('?')[0]).oncontextmenu=function(){ window.open(defmaybe('//www.rjmprogramming.com.au/ITblog/' + thebtitle.split(' (')[0].toLowerCase().replace(/\ /g,'-')),'_blank','top=50,left=50,width=800,height=800'); };
}
}
}
}
}
}
}
function ajaxit() {
zhr = new XMLHttpRequest();
zhr.onreadystatechange=stateChanged;
zhr.open('get', '//www.rjmprogramming.com.au/ptitledata.html?random=' + Math.floor(Math.random() * 196756453), true);
zhr.send(null);
}
… adding oncontextmenu (ie. right click) functionality to the background images, so as a popup window can open to show the associated WordPress Blog posting linked to the image data.
Interactively Change Background Image on Scroll User Settings Tutorial
If you are a regular reader, you’ll know with the web applications presented here, we usually try to allow the user to control …
how they function … and/or sometimes …
how they look
… in the ephemeral “this session” sense, and sometimes follow that up, depending, with recallable settings often calling on window.localStorage or HTTP Cookies, associated with the web browser being used.
… and regarding the use of that last one, we’ve decided, somewhat, to take over with the CSS regarding the Text Wording showing through amongst so many “image interests” with various opacities …
We use it more and more often to help out foreground text presented with a lot of “overlay imagery” going on behind it.
Here is the Javascript prompt window “blurb” presented to the user should they want to delve into this woooooorrrrrlllllldddd just by clicking or touching in the non-text part of the webpage …
var ansis=prompt(‘Optionally enter in background source URL prefix [‘ + prefix + midbit + suffix + ‘] ( or type Lorem Picsum or for blog posting images you could try //www.rjmprogramming.com.au/ITblog/’ + sixhundred + ‘/’ + fourhundred + ‘/ ), hashtag delimited from an optional imagery refresh rate in seconds [‘ + ten + ‘], hashtag delimited from an optional Text element background image (or type Lorem Picsum), hashtag delimited from optional Text wording [‘ + tcont + ‘] we will assume involves a space.‘, ”);
And did you know, at least for non-mobile platforms, you can set the focus (on non-mobile platforms only, as there are the “keyboard getting in the way” issues we’re thankful for with mobile platforms which preclude any thoughts of a programmed [element].focus() operation) to one of these “contenteditable=true style elements”? We’d never been sure, only focussing to HTML input textboxes and textareas up to now, we believe.
… whereby non-mobile focus to a contenteditable=true HTML div type (innerHTML style) element is possible, adding to the original W3School’s content ideas swirling around …
CSS position: fixed; … for foreground text, in relation to …
… into that newly minted Javascript prompt window designed for user interaction purposes? This populates the background images in our new Image Scrolling with Fixed Text web application with a random selection from the WordPress Blog you are reading. Because we have some control here, we researched whether our WordPress 404.php logic could be tweaked to help out more in this scenario. The way the PHP works here, detecting this situation, at the end of its workings, is to use an image header (exemplified by the GIF one below) …
… where $path would point at a GIF image file residing on the RJM Programming domain web server. This design restricts us from any echo functionality before this, so what can we achieve? Anyone? Anyone? Yes, Rasmus, we can write to other web server files that could be like middle-people between the server (supplier of image data) and client (the webpage that called the server). After the server work …
… back at that client (which called the server with that appended “591734” placed onto the URL to indicate the intention to want to examine this return data), we have Ajax based Javascript logic …
var ptc='#';
var iptc=0;
var btlist=[];
var vsbtlist=[];
var omo='';
var zhr=null;
var zform=null;
var rawhtml='';
function defmaybe(inu) {
var retomo=omo;
if (omo != '') {
omo='';
return retomo;
}
return inu;
}
function stateChanged() {
var inm=1, jnm=1, thebtitle='';
if (zhr.readyState == 4) {
if (zhr.status == 200) {
rawhtml = zhr.response;
console.log('rawhtml=' + rawhtml);
if (rawhtml.indexOf('random=') != -1 && vsbtlist.length > 0) {
var rawrs=rawhtml.split('random=');
for (inm=1; inm<rawrs.length; inm++) {
for (jnm=0; jnm<vsbtlist.length; jnm++) {
if (vsbtlist[jnm].indexOf('?random=' + rawrs[inm].split(String.fromCharCode(10))[0]) != -1) {
console.log('found ...');
thebtitle=rawhtml.split('?random=' + rawrs[inm].split(String.fromCharCode(10))[0])[0].split(String.fromCharCode(10))[eval(-1 + rawhtml.split('?random=' + rawrs[inm].split(String.fromCharCode(10))[0])[0].split(String.fromCharCode(10)).length)];
console.log(thebtitle);
document.getElementById(vsbtlist[jnm].split('?')[0]).title=thebtitle + ' ... you can right click to navigate there';
document.getElementById(vsbtlist[jnm].split('?')[0]).onmouseout=function(){ omo=''; };
document.getElementById(vsbtlist[jnm].split('?')[0]).onmouseover=function(){ omo='//www.rjmprogramming.com.au/ITblog/' + thebtitle.split(' (')[0].toLowerCase().replace(/\ /g,'-'); };
document.getElementById(vsbtlist[jnm].split('?')[0]).oncontextmenu=function(){ window.open(defmaybe('//www.rjmprogramming.com.au/ITblog/' + thebtitle.split(' (')[0].toLowerCase().replace(/\ /g,'-')),'_blank','top=50,left=50,width=800,height=800'); };
}
}
}
}
}
}
}
function ajaxit() {
zhr = new XMLHttpRequest();
zhr.onreadystatechange=stateChanged;
zhr.open('get', '//www.rjmprogramming.com.au/ptitledata.html?random=' + Math.floor(Math.random() * 196756453), true);
zhr.send(null);
}
… adding oncontextmenu (ie. right click) functionality to the background images, so as a popup window can open to show the associated WordPress Blog posting linked to the image data.
Interactively Change Background Image on Scroll User Settings Tutorial
If you are a regular reader, you’ll know with the web applications presented here, we usually try to allow the user to control …
how they function … and/or sometimes …
how they look
… in the ephemeral “this session” sense, and sometimes follow that up, depending, with recallable settings often calling on window.localStorage or HTTP Cookies, associated with the web browser being used.
… and regarding the use of that last one, we’ve decided, somewhat, to take over with the CSS regarding the Text Wording showing through amongst so many “image interests” with various opacities …
We use it more and more often to help out foreground text presented with a lot of “overlay imagery” going on behind it.
Here is the Javascript prompt window “blurb” presented to the user should they want to delve into this woooooorrrrrlllllldddd just by clicking or touching in the non-text part of the webpage …
var ansis=prompt(‘Optionally enter in background source URL prefix [‘ + prefix + midbit + suffix + ‘] ( or type Lorem Picsum or for blog posting images you could try //www.rjmprogramming.com.au/ITblog/’ + sixhundred + ‘/’ + fourhundred + ‘/ ), hashtag delimited from an optional imagery refresh rate in seconds [‘ + ten + ‘], hashtag delimited from an optional Text element background image (or type Lorem Picsum), hashtag delimited from optional Text wording [‘ + tcont + ‘] we will assume involves a space.‘, ”);
And did you know, at least for non-mobile platforms, you can set the focus (on non-mobile platforms only, as there are the “keyboard getting in the way” issues we’re thankful for with mobile platforms which preclude any thoughts of a programmed [element].focus() operation) to one of these “contenteditable=true style elements”? We’d never been sure, only focussing to HTML input textboxes and textareas up to now, we believe.
… whereby non-mobile focus to a contenteditable=true HTML div type (innerHTML style) element is possible, adding to the original W3School’s content ideas swirling around …
CSS position: fixed; … for foreground text, in relation to …
Interactively Change Background Image on Scroll User Settings Tutorial
If you are a regular reader, you’ll know with the web applications presented here, we usually try to allow the user to control …
how they function … and/or sometimes …
how they look
… in the ephemeral “this session” sense, and sometimes follow that up, depending, with recallable settings often calling on window.localStorage or HTTP Cookies, associated with the web browser being used.
… and regarding the use of that last one, we’ve decided, somewhat, to take over with the CSS regarding the Text Wording showing through amongst so many “image interests” with various opacities …
We use it more and more often to help out foreground text presented with a lot of “overlay imagery” going on behind it.
Here is the Javascript prompt window “blurb” presented to the user should they want to delve into this woooooorrrrrlllllldddd just by clicking or touching in the non-text part of the webpage …
var ansis=prompt(‘Optionally enter in background source URL prefix [‘ + prefix + midbit + suffix + ‘] ( or type Lorem Picsum or for blog posting images you could try //www.rjmprogramming.com.au/ITblog/’ + sixhundred + ‘/’ + fourhundred + ‘/ ), hashtag delimited from an optional imagery refresh rate in seconds [‘ + ten + ‘], hashtag delimited from an optional Text element background image (or type Lorem Picsum), hashtag delimited from optional Text wording [‘ + tcont + ‘] we will assume involves a space.‘, ”);
And did you know, at least for non-mobile platforms, you can set the focus (on non-mobile platforms only, as there are the “keyboard getting in the way” issues we’re thankful for with mobile platforms which preclude any thoughts of a programmed [element].focus() operation) to one of these “contenteditable=true style elements”? We’d never been sure, only focussing to HTML input textboxes and textareas up to now, we believe.
… whereby non-mobile focus to a contenteditable=true HTML div type (innerHTML style) element is possible, adding to the original W3School’s content ideas swirling around …
CSS position: fixed; … for foreground text, in relation to …
And did you know, at least for non-mobile platforms, you can set the focus (on non-mobile platforms only, as there are the “keyboard getting in the way” issues we’re thankful for with mobile platforms which preclude any thoughts of a programmed [element].focus() operation) to one of these “contenteditable=true style elements”? We’d never been sure, only focussing to HTML input textboxes and textareas up to now, we believe.
… whereby non-mobile focus to a contenteditable=true HTML div type (innerHTML style) element is possible, adding to the original W3School’s content ideas swirling around …
CSS position: fixed; … for foreground text, in relation to …
We’re getting into componentry today, “spare parts” if you will, behind the creation of Animated GIF images, used in yesterday’s Animated GIF Slide Component Knowledge Tutorial‘s PHP web application.
We left you yesterday, during its “phase two” animated GIF creation phase …
a resultant animated GIF HTML img element … now responding to the …
oncontextmenu event (ie. like a right click) … whereby the …
relevant applicable “still” was displayed in a new popup window … and today we flesh out the contents of that skeletal popup window webpage design of yesterday …
You can be pretty sure this first foray will need more nuance into the coming daysweeks (off the Animated GIF theme tomorrow, it being “International Holiday for the Animated GIF Weary … Day”)! We hope you stay with it!
animated GIF, using its duration, for effect, adding user interaction onmouseover logic for our SVG Quiz scenarios … led us to, today …
the more obvious generic step to add oncontextmenu (ie. right click) logic to extract the slide image of the animated GIF showing at the time of the right click
Now, our solution to getting this thing to happen, is to …
not extend out … but rather to …
extend up
… with how the phase one collection of slide image data meets the phase two creation of animated GIF form navigation logic. Up to today, its default modus operandi was that this HTML form had a …
target='_self'
… attribute implied in its make up, and this, to us, is like “extending out” where your phase one “web application” has effectively …
left the building
… so that the phase two “web application” can take up residency.
But the fact is, the target attribute can also point to _blank (new tab) or _top or “the name of an HTML iframe element”. We use that last idea, along with …
… and if that variable dodt remains true (by you, the user, not clicking the “Delay(s)” span element), then the HTML form navigation result effectively slaps itself above (via that large CSS z-index property defined) and, though you (as the HTML form, of course … get with the plan!) do not see what’s below, does not mean that that image data in that “lower floor” is not available (because, surely, parents are allowed to live in the same building … just out of sight, but useful?!) …
… the reason this being interesting, is that if we send to the “second phase” PHP web application pass which creates the animated GIF …
the number of slides …
<?php
$tvalsn="-1";
$ttitled="";
if (isset($_GET['tvalsn'])) { $tvalsn=(str_replace("+"," ",urldecode($_GET['tvalsn']))); $ttitled=''; }
if (isset($_POST['tvalsn'])) { $tvalsn=(str_replace("+"," ",urldecode($_POST['tvalsn']))); $ttitled=''; }
?>
an indication of whether there are 2 slides or 3 slides per original SVG+xml based image …
a comma separated list of answers …
$tvalsa="";
$atitled="";
$detsum="";
$sumdet="";
if (isset($_GET['tvalsa'])) { $detsum="<details><summary>Show ...</summary>"; $sumdet="</details>"; $tvalsa=(str_replace("+"," ",urldecode($_GET['tvalsa']))); $atitled='<input type=hidden id=tvalsa name=tvalsa value="' . $tvalsa . '"></input>'; }
if (isset($_POST['tvalsa'])) { $detsum="<details><summary>Show ...</summary>"; $sumdet="</details>"; $tvalsa=(str_replace("+"," ",urldecode($_POST['tvalsa']))); $atitled='<input type=hidden id=tvalsa name=tvalsa value="' . $tvalsa . '"></input>'; }
?>
… we can use that “animated GIF duration” calculation to know, at any one point, which slide is showing, effectively giving “faux intelligence” enough to our operation, to the extent that we could, then, optionally, interactively ask for user entered answers to the SVG Quiz Questions asked (and keep track of a score for those “quiz interactives” out there).
function startyourengines(imgo) { // called as animated GIF onload event function
if (ctvalsn.split('.')[0].replace('-1','') != '') {
setInterval(sofard, 200);
totalsno=eval(ctvalsn.split('.')[0]);
if (ctvalsn.indexOf('.3') != -1) { setsof=3; } else { setsof=2; }
if (imgo.src.indexOf('/') == -1) {
prefetch(document.URL.replace('index.php', 'tutorial_to_animated_gif.php').split('tutorial_to_animated_gif.php')[0] + imgo.src.split('?')[0].split('#')[0]);
} else {
prefetch(imgo.src.split('?')[0].split('#')[0]);
}
setTimeout(function(){ document.getElementById('midway').scrollIntoView(); }, 500);
}
}
function prefetch(whatgifmaybe) { // thanks to https://stackoverflow.com/questions/69564118/how-to-get-duration-of-gif-image-in-javascript#:~:text=Mainly%20use%20parseGIF()%20%2C%20then,duration%20of%20a%20GIF%20image.
if ((whatgifmaybe.toLowerCase().trim().split('#')[0] + '?').indexOf('.gif?') != -1) {
ingif=whatgifmaybe;
document.body.style.cursor='progress';
fetch(whatgifmaybe)
.then(res => res.arrayBuffer())
.then(ab => isGifAnimated(new Uint8Array(ab)))
.then(console.log);
}
}
/** @param {Uint8Array} uint8 */
function isGifAnimated (uint8) { // thanks to https://stackoverflow.com/questions/69564118/how-to-get-duration-of-gif-image-in-javascript#:~:text=Mainly%20use%20parseGIF()%20%2C%20then,duration%20of%20a%20GIF%20image.
let duration = 0;
for (let i = 0, len = uint8.length; i < len; i++) {
if (uint8[i] == 0x21
&& uint8[i + 1] == 0xF9
&& uint8[i + 2] == 0x04
&& uint8[i + 7] == 0x00)
{
const delay = (uint8[i + 5] << 8) | (uint8[i + 4] & 0xFF);
duration += delay < 2 ? 10 : delay;
}
}
totaldur=eval(eval('' + duration) / 100);
if (totalsno > 0) {
eachdur=eval(totaldur / totalsno)
}
//document.getElementsByTagName('h1')[1].innerHTML='totalsno=' + totalsno + ' totaldur=' + totaldur + ' eachdur=' + eachdur + ' setsof=' + setsof + ' sofardur=' + sofardur;
return duration / 100; // if 0.1 is not an animated GIF
}
“; ?>
… using a newly introduced HTML span element with contenteditable=true to manage the user interaction. And did you know, at least for non-mobile platforms, you can set the focus (on non-mobile platforms only, as there are the “keyboard getting in the way” issues we’re thankful for with mobile platforms which preclude any thoughts of a programmed [element].focus() operation) to one of these “contenteditable=true style elements”? We’d never been sure, only focussing to HTML input textboxes and textareas up to now, we believe.
To usefully offer automation ideas for our Animated GIF Creator we need more flexibility regarding how the watermarks are presented. Get good with this, and this automation of Animated GIF creations could be quite productive. And so, in a similar line of thinking to yesterday’s Animated GIF SVG Quiz Argument Tutorial, today, we offer the user one new “get” titledown URL argument to work with a toggling Watermark Positioning arrangement, between the default top way and the new bottom way, with our input type=color Colour Picker we have going for the user to select a Watermark Colour. For the first time ever, we use …
input type=color ondblclick event
… logic. This event is both harmless regarding any other implications, and useful for toggling logic …
<?php echo ”
function bottomize(cpalo) {
if (document.getElementById('dtitled').innerHTML == '' && cpalo.title.indexOf('double click puts watermark near bottom of image rather than top of image') != -1) {
document.getElementById('dtitled').innerHTML='<input id=titledown name=titledown value=\"\" type=hidden></input>';
cpalo.title=cpalo.title.replace('double click puts watermark near bottom of image rather than top of image', 'double click puts watermark near top of image rather than bottom of image');
} else if (document.getElementById('dtitled').innerHTML != '' && cpalo.title.indexOf('double click puts watermark near top of image rather than bottom of image') != -1) {
document.getElementById('dtitled').innerHTML='';
cpalo.title=cpalo.title.replace('double click puts watermark near top of image rather than bottom of image', 'double click puts watermark near bottom of image rather than top of image');
}
}
In line with the URL arguments theme of yesterday’s Animated GIF Creation Automation Arguments Tutorial, today we wanted to try automating the Animated GIF Creator web application to serve as an agent to create a Quiz based on SVG input, as per …
… involving one new “get” delimquiz URL argument that we default to the value answer. The PHP code goes and looks above the place where it extracts the image information from that HTML circle_terminology.html source for where it mentions where the quiz answer aligned with that image can be found, in our case within a “get” part of a URL preceeded by “&answer=” …
<?php echo ”
var quizmode=false;
var atobis='';
//alert('Tval=' + tval);
if (tval.indexOf(encodeURIComponent('data:image/svg+xml')) != -1) {
tvals=tval.split(encodeURIComponent('data:image/svg+xml'));
if (blankend != '') { gtid='slideshow' + ('' + tid).replace('slideshow',''); addtotothers(); tid=gtid; }
thistval=1;
if (document.URL.indexOf('delimquiz=') != -1) { // typically &delimquiz=answer
if (document.getElementById('delay').value == '40') { document.getElementById('delay').value='800'; }
var svgshell='';
if (tvals[1].indexOf(encodeURIComponent(';utf8,')) == 0) {
svgshell=tvals[1].split(encodeURIComponent('>'))[0] + encodeURIComponent(' style=\"font-family:Verdana;font-size:24px;\"></svg>');
} else if (tvals[1].indexOf(encodeURIComponent(';base64,')) == 0) {
atobis=window.atob(tvals[1].substring(eval('' + encodeURIComponent(';base64,').length)).split(String.fromCharCode(34))[0].split(String.fromCharCode(39))[0].split(')')[0].split('&')[0].split('>')[0]);
svgshell=encodeURIComponent(';utf8,') + encodeURIComponent(atobis.split(encodeURIComponent('>'))[0].split('>')[0] + (' style=\"font-family:Verdana;font-size:24px;\"></svg>'));
} else {
svgshell=encodeURIComponent(';utf8,') + tvals[1].split(encodeURIComponent('>'))[0] + encodeURIComponent(' style=\"font-family:Verdana;font-size:24px;\"></svg>');
}
var dsvgshell=decodeURIComponent(svgshell);
var dlq=(decodeURIComponent(document.URL.split('delimquiz=')[1].split('&')[0].split('#')[0].split('>')[0]).replace(/\+/g,' ') + '=').replace(/\=\=$/g, '=');
if (dlq.replace('=','').trim() == '') { dlq='answer='; }
if (tvals[0].indexOf(dlq) != -1) {
// eg. answer= precursor idea to make into quiz
quizmode=true;
var sparetvals=tval.split(encodeURIComponent('data:image/svg+xml'));
tvals=[''];
for (var iipo=1; iipo<sparetvals.length; iipo++) {
tvals.push( svgshell.replace(encodeURIComponent('></svg>'), encodeURIComponent('><text y=\"12%\">What is this?</text></svg>')) + '><img SRC=\" data:image/svg+xml' + dsvgshell.replace('></svg>','><text y=\"22%\">What is this?</text></svg>').replace(/\\\"/g, String.fromCharCode(39)) + '\"></img>' ); // question
tvals.push(sparetvals[eval(0 + iipo)]); // image
tvals.push( svgshell.replace(encodeURIComponent('></svg>'), encodeURIComponent('><text y=\"12%\">' + decodeURIComponent(sparetvals[eval(-1 + iipo)].split(dlq)[1].split('&')[0].split('#')[0].split('>')[0]).replace(/\+/g,' ') + '</text></svg>')) + '><img SRC=\" data:image/svg+xml' + dsvgshell.replace('></svg>','><text y=\"22%\">' + decodeURIComponent(sparetvals[eval(-1 + iipo)].split(dlq)[1].split('&')[0].split('#')[0].split('>')[0]).replace(/\+/g,' ') + '</text></svg>').replace(/\\\"/g, String.fromCharCode(39)) + '\"></img>' ); // answer
}
}
}
// more code follows
}
“; ?>
… and we use that to end up with three animated GIF slides per image covering …
The automation measures in yesterday’s Animated GIF Creation Transparency Tutorial get an “arguments consideration” (maybe a five minute one, or perhaps ten minutes for “the outraged”) to help out ideas for our aspirational readers and users out there, who we are always keen to motivate, this Animated GIF Creator project potentially linked to user productivity, at its best.
If we want to improve automation ideas for these Animated GIF creations we need to use (initially ? and & “get”) arguments up at the web browser address bar for our exploratory user to not only allow for definition of …
their hTTp style animated GIF slide content basis (in a “get” irefresh labelled optional argument) … but as of today, how about …
new “get” dimensions labelled optional argument defines the output Animated GIF dimensions in terms of width,height … eg. 300,600
new “get” title labelled optional argument defines the wording of the watermark style Animated GIF title (basis) … eg. My+Animated+GIF
new “get” titlecolour labelled optional argument defines the colour of the watermark style Animated GIF title … eg. olive
new “get” titlemode labelled optional argument defines the watermark style Animated GIF title mode … eg. All
… and please do not forget an optional argument we’re always havingthat’s always been there …
the “get” delay labelled optional argument defining the delay between animated GIF slides … eg. 800
? That would complete some pictures out there, we’re hoping?!
Does this feel like a step sideways to you, “the regular reader”? We’d agree, and are a little surprised a revisit (to this project) shows this need, but there you are. Sometimes, revisits help clarify!
… deserves our consideration, we’ve decided, today … because …
Transparency begins at home.
We’ll just try our best here, but we have discovered a nuance that hadn’t tweaked with us before, considering “transparency” and using “canvas” elements. The …
[canvasElementContext].clearRect(0, 0, [canvasWidth], [canvasHeight]); // idea causes the canvas to become transparent ... different to the other concept like ...
[canvasElementContext].fillStyle='white'; [canvasElementContext].fillRect(0, 0, [canvasWidth], [canvasHeight]); // this example idea causes the canvas to become white
It’s affected two “avenues of effect” (or is this a book?!) with our Animated GIF Creator logic …
if a SVG+xml element data URI utf8 format representation mentions the word “transparent” we are now going to make the relevant helper canvas element background be transparent …
<?php echo ”
function drawInlineSVG(rawSVG, slidename) { // thanks to https://stackoverflow.com/questions/27230293/how-to-draw-an-inline-svg-in-dom-to-a-canvas
var rsvg = new Blob([rawSVG], {type:'image/svg+xml;charset=utf-8'}),
rdomURL = self.URL || self.webkitURL || self,
rurl = rdomURL.createObjectURL(rsvg),
rslidename=slidename,
imgc = new Image;
if (rawSVG.indexOf('transparent') != -1 || rawSVG.indexOf(window.btoa('transparent')) != -1) {
istransparent=true;
imgc.onload = function () {
if (istransparent) {
document.getElementById('mycanvas').width=imgc.width;
document.getElementById('mycanvas').height=imgc.height;
document.getElementById('mycanvas').getContext('2d').clearRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
} else if (1 == 1) {
document.getElementById('mycanvas').getContext('2d').fillStyle='white';
the “+” means by which we involve our Scribble and Annotation helper (of animated GIF slide content) now has a new button (with its onclick event function) to ask about its main canvas element background colour …
function colourize() {
var huhcol=prompt('Enter canvas background colour or Cancel to ignore.', 'transparent');
if (huhcol != null) {
if (huhcol.trim() != '') {
if (huhcol == 'transparent') {
//alert(987);
//alert('topielem.width=' + topielem.width);
parent.document.getElementById('topcanvas').getContext('2d').fillStyle = huhcol;
And so, we reckon it’s “transparent” (chortle, chortle) that yesterday’s Animated GIF Creation Automation Tutorial, created at home, and where (the vast majority of some readers know) …
Transparency begins at home. Can someone please hand me the lemon juice.
There are two competing issues going on with software development, of complexity, to challenge the skillset of the programmer …
keeping at an issue as it is fresh, and not letting go, as much as anything to keep up with where you are at, as with it being fresh in the mind … versus …
useful revisits after a bit of time to review the issue with fresher eyes, can often iron out issues not seen in “the heat of battle”
Today sees us relieved, undertaking a “second of the options above” scenario, regarding us creeping up on more Animated GIF Creation automation ideas we last talked about, with any depth, at Animated GIF Link Image Slide Tutorial.
[canvasElement].toDataURL(‘image/jpeg’, 10) … way to derive a data URI for …
textbox … representing an Animated GIF slide content mechanism
… rather than rely on ImageMagick converting from SVG to PNG was a bit of a game changer for us. We thought the extending of its use to other parts of the web application would be a good move. Along this way we also worked out that our Animated GIF dimensioning also needed some tweaking at a new HTML form onsubmit event function intervention point …
<?php echo ”
function dothem() {
for (var iijj=0; iijj<slidecmds.length; iijj++) {
eval(slidecmds[iijj]);
}
if (document.getElementById('selwhs')) {
if (document.getElementById('selwhs').value.indexOf(',') != -1) {
owoh(document.getElementById('selwhs'));
}
}
}
other image extraction from HTML user input via + … and today …
“a” link to either …
QR Code … via ++ … or …
Webpage Screenshot … via ++++
Do you see the pattern here? If you have a favoured character (ie. “+” here) involved in a user functionality behaviour decision you can give each a …
power of 2 number of characters
… (functionality meaning) and at the Javascript or PHP interpretive end of this arrangement you can know exactly what the user wants (in a way akin to how a bitmap can often be used) … so far this Javascript working (and tailorable into the future with some tweaking) as per …
<?php echo ”
function srchrefit(inbg) {
var outbg=inbg, outbis=[], ibis=0;
var ourblankend=blankend;
if (blankend != '') {
if (eval(eval('' + ourblankend.length) % 2) == 1) { // process img
ourblankend=ourblankend.substring(1);
outbg=outbg.replace(/data\:image\/svg\+xml/g, '!@#$%^&');
outbg=outbg.replace(/data\:image/g, ' SRC=\" data:image');
outbg=outbg.replace(/\!\@\#\$\%\^\&/g, 'data:image/svg+xml');
outbis=outbg.split('<img');
console.log('outbis.length=' + outbis.length + ' and outbg=' + outbg);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' src=\"') != -1) {
outbg=outbg.replace('<img' + outbis[ibis].split('>')[0], '<img' + outbis[ibis].split('>')[0].replace(' src=\"', ' SRC=\" '));
}
}
}
if (eval('' + ourblankend.length) == 4) { // process "a" links to Webpage Screenshot
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
} // ... or ...
} else if (eval('' + ourblankend.length) == 2) { // process "a" links to QR Code
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
}
}
return outbg;
}
return inbg;
}
… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a QR Code) …
… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a Webpage Screenshot).
The PHP GD library we use to help create animated GIFs (along with a whole lot of other help, it goes without saying) is not into vector graphics which is what …
… are really into … ooooohhh, aaaaahhhh … but luckily for us, the great ImageMagick offers functionality to convert a SVG image file into a PNG image file, via …
Non Windows
Windows
convert infile.svg outfile.png
magick.exe infile.svg outfile.png
… and we’re using that talent ImageMagick has to offer the user the chance, at any animated GIF slide textbox, the chance to enter encodeURIComponent and window.btoa sensitive entries whose (content) format could match (one of) …
… which fills in the slide data and then goes and tries to create the resultant animated GIF (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial)
Below is a new (PHP writes) Javascript iframe (iois object below) onload event function for recognizing hTTps://[HtmlWebpageWithSVG].html as above, and setting the iframe’s “src” attribute to its value …
<?php echo ”
var mm1='', mm2='', mm3='';
var gdgebimm='', gtval='', onealready='';
var tvals=[], thistval=0, thistdelim='', thistid='';
function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}
function svgmmcallol(iois, tid) {
//alert('TID=' + tid);
var tval='', it=0, dgebimm='';
var tis=document.getElementById(tid);
thistid=tid;
tvals=[];
thistval=0;
thistdelim='';
if (iois != null) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
tval=aconto.body.innerHTML;
//alert('Tval=' + tval);
if (tval.indexOf(encodeURIComponent('data:image/svg+xml')) != -1) {
thistval=1;
tvals=tval.split(encodeURIComponent('data:image/svg+xml'));
thistdelim=encodeURIComponent('data:image/svg+xml');
//alert('thistdeliM=' + thistdelim);
Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial
We wanted, today, to channel the (cruel might say “warped”) thinking behind the recent URL …
interactive entry of absolute URL starting with HtTp means you want a QR Code … and …
interactive entry of absolute URL starting with hTtP means you want (to involve, along the line, creating an animated QR Code scenario) a Webpage Screenshot
create animated GIF of QR Code means by which a smart device user using their Camera might navigate to a series of interesting webpage(s) … or …
create animated GIF of “current snapshot looks” of a series of URLs of interest (with even more currency than Google Earth shows your place!)
It might be you design an animated GIF chapter of slides and always want to follow it up with a “further reading” webpage you could present as a QR Code or Webpage Screenshot.
Anyway, at the “onblur” event Javascript function logic we intervened to end up with an image/png data URI substitute for the HtTp or hTtP URL the user enters to re-enter the normal animated GIF image definition workflow of the animated GIF creator …
<?php echo ”
var mm1='', mm2='', mm3='';
function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}
animated GIF, using its duration, for effect, adding user interaction onmouseover logic for our SVG Quiz scenarios … led us to, today …
the more obvious generic step to add oncontextmenu (ie. right click) logic to extract the slide image of the animated GIF showing at the time of the right click
Now, our solution to getting this thing to happen, is to …
not extend out … but rather to …
extend up
… with how the phase one collection of slide image data meets the phase two creation of animated GIF form navigation logic. Up to today, its default modus operandi was that this HTML form had a …
target='_self'
… attribute implied in its make up, and this, to us, is like “extending out” where your phase one “web application” has effectively …
left the building
… so that the phase two “web application” can take up residency.
But the fact is, the target attribute can also point to _blank (new tab) or _top or “the name of an HTML iframe element”. We use that last idea, along with …
… and if that variable dodt remains true (by you, the user, not clicking the “Delay(s)” span element), then the HTML form navigation result effectively slaps itself above (via that large CSS z-index property defined) and, though you (as the HTML form, of course … get with the plan!) do not see what’s below, does not mean that that image data in that “lower floor” is not available (because, surely, parents are allowed to live in the same building … just out of sight, but useful?!) …
… the reason this being interesting, is that if we send to the “second phase” PHP web application pass which creates the animated GIF …
the number of slides …
<?php
$tvalsn="-1";
$ttitled="";
if (isset($_GET['tvalsn'])) { $tvalsn=(str_replace("+"," ",urldecode($_GET['tvalsn']))); $ttitled=''; }
if (isset($_POST['tvalsn'])) { $tvalsn=(str_replace("+"," ",urldecode($_POST['tvalsn']))); $ttitled=''; }
?>
an indication of whether there are 2 slides or 3 slides per original SVG+xml based image …
a comma separated list of answers …
$tvalsa="";
$atitled="";
$detsum="";
$sumdet="";
if (isset($_GET['tvalsa'])) { $detsum="<details><summary>Show ...</summary>"; $sumdet="</details>"; $tvalsa=(str_replace("+"," ",urldecode($_GET['tvalsa']))); $atitled='<input type=hidden id=tvalsa name=tvalsa value="' . $tvalsa . '"></input>'; }
if (isset($_POST['tvalsa'])) { $detsum="<details><summary>Show ...</summary>"; $sumdet="</details>"; $tvalsa=(str_replace("+"," ",urldecode($_POST['tvalsa']))); $atitled='<input type=hidden id=tvalsa name=tvalsa value="' . $tvalsa . '"></input>'; }
?>
… we can use that “animated GIF duration” calculation to know, at any one point, which slide is showing, effectively giving “faux intelligence” enough to our operation, to the extent that we could, then, optionally, interactively ask for user entered answers to the SVG Quiz Questions asked (and keep track of a score for those “quiz interactives” out there).
function startyourengines(imgo) { // called as animated GIF onload event function
if (ctvalsn.split('.')[0].replace('-1','') != '') {
setInterval(sofard, 200);
totalsno=eval(ctvalsn.split('.')[0]);
if (ctvalsn.indexOf('.3') != -1) { setsof=3; } else { setsof=2; }
if (imgo.src.indexOf('/') == -1) {
prefetch(document.URL.replace('index.php', 'tutorial_to_animated_gif.php').split('tutorial_to_animated_gif.php')[0] + imgo.src.split('?')[0].split('#')[0]);
} else {
prefetch(imgo.src.split('?')[0].split('#')[0]);
}
setTimeout(function(){ document.getElementById('midway').scrollIntoView(); }, 500);
}
}
function prefetch(whatgifmaybe) { // thanks to https://stackoverflow.com/questions/69564118/how-to-get-duration-of-gif-image-in-javascript#:~:text=Mainly%20use%20parseGIF()%20%2C%20then,duration%20of%20a%20GIF%20image.
if ((whatgifmaybe.toLowerCase().trim().split('#')[0] + '?').indexOf('.gif?') != -1) {
ingif=whatgifmaybe;
document.body.style.cursor='progress';
fetch(whatgifmaybe)
.then(res => res.arrayBuffer())
.then(ab => isGifAnimated(new Uint8Array(ab)))
.then(console.log);
}
}
/** @param {Uint8Array} uint8 */
function isGifAnimated (uint8) { // thanks to https://stackoverflow.com/questions/69564118/how-to-get-duration-of-gif-image-in-javascript#:~:text=Mainly%20use%20parseGIF()%20%2C%20then,duration%20of%20a%20GIF%20image.
let duration = 0;
for (let i = 0, len = uint8.length; i < len; i++) {
if (uint8[i] == 0x21
&& uint8[i + 1] == 0xF9
&& uint8[i + 2] == 0x04
&& uint8[i + 7] == 0x00)
{
const delay = (uint8[i + 5] << 8) | (uint8[i + 4] & 0xFF);
duration += delay < 2 ? 10 : delay;
}
}
totaldur=eval(eval('' + duration) / 100);
if (totalsno > 0) {
eachdur=eval(totaldur / totalsno)
}
//document.getElementsByTagName('h1')[1].innerHTML='totalsno=' + totalsno + ' totaldur=' + totaldur + ' eachdur=' + eachdur + ' setsof=' + setsof + ' sofardur=' + sofardur;
return duration / 100; // if 0.1 is not an animated GIF
}
“; ?>
… using a newly introduced HTML span element with contenteditable=true to manage the user interaction. And did you know, at least for non-mobile platforms, you can set the focus (on non-mobile platforms only, as there are the “keyboard getting in the way” issues we’re thankful for with mobile platforms which preclude any thoughts of a programmed [element].focus() operation) to one of these “contenteditable=true style elements”? We’d never been sure, only focussing to HTML input textboxes and textareas up to now, we believe.
To usefully offer automation ideas for our Animated GIF Creator we need more flexibility regarding how the watermarks are presented. Get good with this, and this automation of Animated GIF creations could be quite productive. And so, in a similar line of thinking to yesterday’s Animated GIF SVG Quiz Argument Tutorial, today, we offer the user one new “get” titledown URL argument to work with a toggling Watermark Positioning arrangement, between the default top way and the new bottom way, with our input type=color Colour Picker we have going for the user to select a Watermark Colour. For the first time ever, we use …
input type=color ondblclick event
… logic. This event is both harmless regarding any other implications, and useful for toggling logic …
<?php echo ”
function bottomize(cpalo) {
if (document.getElementById('dtitled').innerHTML == '' && cpalo.title.indexOf('double click puts watermark near bottom of image rather than top of image') != -1) {
document.getElementById('dtitled').innerHTML='<input id=titledown name=titledown value=\"\" type=hidden></input>';
cpalo.title=cpalo.title.replace('double click puts watermark near bottom of image rather than top of image', 'double click puts watermark near top of image rather than bottom of image');
} else if (document.getElementById('dtitled').innerHTML != '' && cpalo.title.indexOf('double click puts watermark near top of image rather than bottom of image') != -1) {
document.getElementById('dtitled').innerHTML='';
cpalo.title=cpalo.title.replace('double click puts watermark near top of image rather than bottom of image', 'double click puts watermark near bottom of image rather than top of image');
}
}
In line with the URL arguments theme of yesterday’s Animated GIF Creation Automation Arguments Tutorial, today we wanted to try automating the Animated GIF Creator web application to serve as an agent to create a Quiz based on SVG input, as per …
… involving one new “get” delimquiz URL argument that we default to the value answer. The PHP code goes and looks above the place where it extracts the image information from that HTML circle_terminology.html source for where it mentions where the quiz answer aligned with that image can be found, in our case within a “get” part of a URL preceeded by “&answer=” …
<?php echo ”
var quizmode=false;
var atobis='';
//alert('Tval=' + tval);
if (tval.indexOf(encodeURIComponent('data:image/svg+xml')) != -1) {
tvals=tval.split(encodeURIComponent('data:image/svg+xml'));
if (blankend != '') { gtid='slideshow' + ('' + tid).replace('slideshow',''); addtotothers(); tid=gtid; }
thistval=1;
if (document.URL.indexOf('delimquiz=') != -1) { // typically &delimquiz=answer
if (document.getElementById('delay').value == '40') { document.getElementById('delay').value='800'; }
var svgshell='';
if (tvals[1].indexOf(encodeURIComponent(';utf8,')) == 0) {
svgshell=tvals[1].split(encodeURIComponent('>'))[0] + encodeURIComponent(' style=\"font-family:Verdana;font-size:24px;\"></svg>');
} else if (tvals[1].indexOf(encodeURIComponent(';base64,')) == 0) {
atobis=window.atob(tvals[1].substring(eval('' + encodeURIComponent(';base64,').length)).split(String.fromCharCode(34))[0].split(String.fromCharCode(39))[0].split(')')[0].split('&')[0].split('>')[0]);
svgshell=encodeURIComponent(';utf8,') + encodeURIComponent(atobis.split(encodeURIComponent('>'))[0].split('>')[0] + (' style=\"font-family:Verdana;font-size:24px;\"></svg>'));
} else {
svgshell=encodeURIComponent(';utf8,') + tvals[1].split(encodeURIComponent('>'))[0] + encodeURIComponent(' style=\"font-family:Verdana;font-size:24px;\"></svg>');
}
var dsvgshell=decodeURIComponent(svgshell);
var dlq=(decodeURIComponent(document.URL.split('delimquiz=')[1].split('&')[0].split('#')[0].split('>')[0]).replace(/\+/g,' ') + '=').replace(/\=\=$/g, '=');
if (dlq.replace('=','').trim() == '') { dlq='answer='; }
if (tvals[0].indexOf(dlq) != -1) {
// eg. answer= precursor idea to make into quiz
quizmode=true;
var sparetvals=tval.split(encodeURIComponent('data:image/svg+xml'));
tvals=[''];
for (var iipo=1; iipo<sparetvals.length; iipo++) {
tvals.push( svgshell.replace(encodeURIComponent('></svg>'), encodeURIComponent('><text y=\"12%\">What is this?</text></svg>')) + '><img SRC=\" data:image/svg+xml' + dsvgshell.replace('></svg>','><text y=\"22%\">What is this?</text></svg>').replace(/\\\"/g, String.fromCharCode(39)) + '\"></img>' ); // question
tvals.push(sparetvals[eval(0 + iipo)]); // image
tvals.push( svgshell.replace(encodeURIComponent('></svg>'), encodeURIComponent('><text y=\"12%\">' + decodeURIComponent(sparetvals[eval(-1 + iipo)].split(dlq)[1].split('&')[0].split('#')[0].split('>')[0]).replace(/\+/g,' ') + '</text></svg>')) + '><img SRC=\" data:image/svg+xml' + dsvgshell.replace('></svg>','><text y=\"22%\">' + decodeURIComponent(sparetvals[eval(-1 + iipo)].split(dlq)[1].split('&')[0].split('#')[0].split('>')[0]).replace(/\+/g,' ') + '</text></svg>').replace(/\\\"/g, String.fromCharCode(39)) + '\"></img>' ); // answer
}
}
}
// more code follows
}
“; ?>
… and we use that to end up with three animated GIF slides per image covering …
The automation measures in yesterday’s Animated GIF Creation Transparency Tutorial get an “arguments consideration” (maybe a five minute one, or perhaps ten minutes for “the outraged”) to help out ideas for our aspirational readers and users out there, who we are always keen to motivate, this Animated GIF Creator project potentially linked to user productivity, at its best.
If we want to improve automation ideas for these Animated GIF creations we need to use (initially ? and & “get”) arguments up at the web browser address bar for our exploratory user to not only allow for definition of …
their hTTp style animated GIF slide content basis (in a “get” irefresh labelled optional argument) … but as of today, how about …
new “get” dimensions labelled optional argument defines the output Animated GIF dimensions in terms of width,height … eg. 300,600
new “get” title labelled optional argument defines the wording of the watermark style Animated GIF title (basis) … eg. My+Animated+GIF
new “get” titlecolour labelled optional argument defines the colour of the watermark style Animated GIF title … eg. olive
new “get” titlemode labelled optional argument defines the watermark style Animated GIF title mode … eg. All
… and please do not forget an optional argument we’re always havingthat’s always been there …
the “get” delay labelled optional argument defining the delay between animated GIF slides … eg. 800
? That would complete some pictures out there, we’re hoping?!
Does this feel like a step sideways to you, “the regular reader”? We’d agree, and are a little surprised a revisit (to this project) shows this need, but there you are. Sometimes, revisits help clarify!
… deserves our consideration, we’ve decided, today … because …
Transparency begins at home.
We’ll just try our best here, but we have discovered a nuance that hadn’t tweaked with us before, considering “transparency” and using “canvas” elements. The …
[canvasElementContext].clearRect(0, 0, [canvasWidth], [canvasHeight]); // idea causes the canvas to become transparent ... different to the other concept like ...
[canvasElementContext].fillStyle='white'; [canvasElementContext].fillRect(0, 0, [canvasWidth], [canvasHeight]); // this example idea causes the canvas to become white
It’s affected two “avenues of effect” (or is this a book?!) with our Animated GIF Creator logic …
if a SVG+xml element data URI utf8 format representation mentions the word “transparent” we are now going to make the relevant helper canvas element background be transparent …
<?php echo ”
function drawInlineSVG(rawSVG, slidename) { // thanks to https://stackoverflow.com/questions/27230293/how-to-draw-an-inline-svg-in-dom-to-a-canvas
var rsvg = new Blob([rawSVG], {type:'image/svg+xml;charset=utf-8'}),
rdomURL = self.URL || self.webkitURL || self,
rurl = rdomURL.createObjectURL(rsvg),
rslidename=slidename,
imgc = new Image;
if (rawSVG.indexOf('transparent') != -1 || rawSVG.indexOf(window.btoa('transparent')) != -1) {
istransparent=true;
imgc.onload = function () {
if (istransparent) {
document.getElementById('mycanvas').width=imgc.width;
document.getElementById('mycanvas').height=imgc.height;
document.getElementById('mycanvas').getContext('2d').clearRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
} else if (1 == 1) {
document.getElementById('mycanvas').getContext('2d').fillStyle='white';
the “+” means by which we involve our Scribble and Annotation helper (of animated GIF slide content) now has a new button (with its onclick event function) to ask about its main canvas element background colour …
function colourize() {
var huhcol=prompt('Enter canvas background colour or Cancel to ignore.', 'transparent');
if (huhcol != null) {
if (huhcol.trim() != '') {
if (huhcol == 'transparent') {
//alert(987);
//alert('topielem.width=' + topielem.width);
parent.document.getElementById('topcanvas').getContext('2d').fillStyle = huhcol;
And so, we reckon it’s “transparent” (chortle, chortle) that yesterday’s Animated GIF Creation Automation Tutorial, created at home, and where (the vast majority of some readers know) …
Transparency begins at home. Can someone please hand me the lemon juice.
There are two competing issues going on with software development, of complexity, to challenge the skillset of the programmer …
keeping at an issue as it is fresh, and not letting go, as much as anything to keep up with where you are at, as with it being fresh in the mind … versus …
useful revisits after a bit of time to review the issue with fresher eyes, can often iron out issues not seen in “the heat of battle”
Today sees us relieved, undertaking a “second of the options above” scenario, regarding us creeping up on more Animated GIF Creation automation ideas we last talked about, with any depth, at Animated GIF Link Image Slide Tutorial.
[canvasElement].toDataURL(‘image/jpeg’, 10) … way to derive a data URI for …
textbox … representing an Animated GIF slide content mechanism
… rather than rely on ImageMagick converting from SVG to PNG was a bit of a game changer for us. We thought the extending of its use to other parts of the web application would be a good move. Along this way we also worked out that our Animated GIF dimensioning also needed some tweaking at a new HTML form onsubmit event function intervention point …
<?php echo ”
function dothem() {
for (var iijj=0; iijj<slidecmds.length; iijj++) {
eval(slidecmds[iijj]);
}
if (document.getElementById('selwhs')) {
if (document.getElementById('selwhs').value.indexOf(',') != -1) {
owoh(document.getElementById('selwhs'));
}
}
}
other image extraction from HTML user input via + … and today …
“a” link to either …
QR Code … via ++ … or …
Webpage Screenshot … via ++++
Do you see the pattern here? If you have a favoured character (ie. “+” here) involved in a user functionality behaviour decision you can give each a …
power of 2 number of characters
… (functionality meaning) and at the Javascript or PHP interpretive end of this arrangement you can know exactly what the user wants (in a way akin to how a bitmap can often be used) … so far this Javascript working (and tailorable into the future with some tweaking) as per …
<?php echo ”
function srchrefit(inbg) {
var outbg=inbg, outbis=[], ibis=0;
var ourblankend=blankend;
if (blankend != '') {
if (eval(eval('' + ourblankend.length) % 2) == 1) { // process img
ourblankend=ourblankend.substring(1);
outbg=outbg.replace(/data\:image\/svg\+xml/g, '!@#$%^&');
outbg=outbg.replace(/data\:image/g, ' SRC=\" data:image');
outbg=outbg.replace(/\!\@\#\$\%\^\&/g, 'data:image/svg+xml');
outbis=outbg.split('<img');
console.log('outbis.length=' + outbis.length + ' and outbg=' + outbg);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' src=\"') != -1) {
outbg=outbg.replace('<img' + outbis[ibis].split('>')[0], '<img' + outbis[ibis].split('>')[0].replace(' src=\"', ' SRC=\" '));
}
}
}
if (eval('' + ourblankend.length) == 4) { // process "a" links to Webpage Screenshot
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
} // ... or ...
} else if (eval('' + ourblankend.length) == 2) { // process "a" links to QR Code
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
}
}
return outbg;
}
return inbg;
}
… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a QR Code) …
… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a Webpage Screenshot).
The PHP GD library we use to help create animated GIFs (along with a whole lot of other help, it goes without saying) is not into vector graphics which is what …
… are really into … ooooohhh, aaaaahhhh … but luckily for us, the great ImageMagick offers functionality to convert a SVG image file into a PNG image file, via …
Non Windows
Windows
convert infile.svg outfile.png
magick.exe infile.svg outfile.png
… and we’re using that talent ImageMagick has to offer the user the chance, at any animated GIF slide textbox, the chance to enter encodeURIComponent and window.btoa sensitive entries whose (content) format could match (one of) …
… which fills in the slide data and then goes and tries to create the resultant animated GIF (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial)
Below is a new (PHP writes) Javascript iframe (iois object below) onload event function for recognizing hTTps://[HtmlWebpageWithSVG].html as above, and setting the iframe’s “src” attribute to its value …
<?php echo ”
var mm1='', mm2='', mm3='';
var gdgebimm='', gtval='', onealready='';
var tvals=[], thistval=0, thistdelim='', thistid='';
function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}
function svgmmcallol(iois, tid) {
//alert('TID=' + tid);
var tval='', it=0, dgebimm='';
var tis=document.getElementById(tid);
thistid=tid;
tvals=[];
thistval=0;
thistdelim='';
if (iois != null) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
tval=aconto.body.innerHTML;
//alert('Tval=' + tval);
if (tval.indexOf(encodeURIComponent('data:image/svg+xml')) != -1) {
thistval=1;
tvals=tval.split(encodeURIComponent('data:image/svg+xml'));
thistdelim=encodeURIComponent('data:image/svg+xml');
//alert('thistdeliM=' + thistdelim);
Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial
We wanted, today, to channel the (cruel might say “warped”) thinking behind the recent URL …
interactive entry of absolute URL starting with HtTp means you want a QR Code … and …
interactive entry of absolute URL starting with hTtP means you want (to involve, along the line, creating an animated QR Code scenario) a Webpage Screenshot
create animated GIF of QR Code means by which a smart device user using their Camera might navigate to a series of interesting webpage(s) … or …
create animated GIF of “current snapshot looks” of a series of URLs of interest (with even more currency than Google Earth shows your place!)
It might be you design an animated GIF chapter of slides and always want to follow it up with a “further reading” webpage you could present as a QR Code or Webpage Screenshot.
Anyway, at the “onblur” event Javascript function logic we intervened to end up with an image/png data URI substitute for the HtTp or hTtP URL the user enters to re-enter the normal animated GIF image definition workflow of the animated GIF creator …
<?php echo ”
var mm1='', mm2='', mm3='';
function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}
… the reason this being interesting, is that if we send to the “second phase” PHP web application pass which creates the animated GIF …
the number of slides …
<?php
$tvalsn="-1";
$ttitled="";
if (isset($_GET['tvalsn'])) { $tvalsn=(str_replace("+"," ",urldecode($_GET['tvalsn']))); $ttitled=''; }
if (isset($_POST['tvalsn'])) { $tvalsn=(str_replace("+"," ",urldecode($_POST['tvalsn']))); $ttitled=''; }
?>
an indication of whether there are 2 slides or 3 slides per original SVG+xml based image …
a comma separated list of answers …
$tvalsa="";
$atitled="";
$detsum="";
$sumdet="";
if (isset($_GET['tvalsa'])) { $detsum="<details><summary>Show ...</summary>"; $sumdet="</details>"; $tvalsa=(str_replace("+"," ",urldecode($_GET['tvalsa']))); $atitled='<input type=hidden id=tvalsa name=tvalsa value="' . $tvalsa . '"></input>'; }
if (isset($_POST['tvalsa'])) { $detsum="<details><summary>Show ...</summary>"; $sumdet="</details>"; $tvalsa=(str_replace("+"," ",urldecode($_POST['tvalsa']))); $atitled='<input type=hidden id=tvalsa name=tvalsa value="' . $tvalsa . '"></input>'; }
?>
… we can use that “animated GIF duration” calculation to know, at any one point, which slide is showing, effectively giving “faux intelligence” enough to our operation, to the extent that we could, then, optionally, interactively ask for user entered answers to the SVG Quiz Questions asked (and keep track of a score for those “quiz interactives” out there).
function startyourengines(imgo) { // called as animated GIF onload event function
if (ctvalsn.split('.')[0].replace('-1','') != '') {
setInterval(sofard, 200);
totalsno=eval(ctvalsn.split('.')[0]);
if (ctvalsn.indexOf('.3') != -1) { setsof=3; } else { setsof=2; }
if (imgo.src.indexOf('/') == -1) {
prefetch(document.URL.replace('index.php', 'tutorial_to_animated_gif.php').split('tutorial_to_animated_gif.php')[0] + imgo.src.split('?')[0].split('#')[0]);
} else {
prefetch(imgo.src.split('?')[0].split('#')[0]);
}
setTimeout(function(){ document.getElementById('midway').scrollIntoView(); }, 500);
}
}
function prefetch(whatgifmaybe) { // thanks to https://stackoverflow.com/questions/69564118/how-to-get-duration-of-gif-image-in-javascript#:~:text=Mainly%20use%20parseGIF()%20%2C%20then,duration%20of%20a%20GIF%20image.
if ((whatgifmaybe.toLowerCase().trim().split('#')[0] + '?').indexOf('.gif?') != -1) {
ingif=whatgifmaybe;
document.body.style.cursor='progress';
fetch(whatgifmaybe)
.then(res => res.arrayBuffer())
.then(ab => isGifAnimated(new Uint8Array(ab)))
.then(console.log);
}
}
/** @param {Uint8Array} uint8 */
function isGifAnimated (uint8) { // thanks to https://stackoverflow.com/questions/69564118/how-to-get-duration-of-gif-image-in-javascript#:~:text=Mainly%20use%20parseGIF()%20%2C%20then,duration%20of%20a%20GIF%20image.
let duration = 0;
for (let i = 0, len = uint8.length; i < len; i++) {
if (uint8[i] == 0x21
&& uint8[i + 1] == 0xF9
&& uint8[i + 2] == 0x04
&& uint8[i + 7] == 0x00)
{
const delay = (uint8[i + 5] << 8) | (uint8[i + 4] & 0xFF);
duration += delay < 2 ? 10 : delay;
}
}
totaldur=eval(eval('' + duration) / 100);
if (totalsno > 0) {
eachdur=eval(totaldur / totalsno)
}
//document.getElementsByTagName('h1')[1].innerHTML='totalsno=' + totalsno + ' totaldur=' + totaldur + ' eachdur=' + eachdur + ' setsof=' + setsof + ' sofardur=' + sofardur;
return duration / 100; // if 0.1 is not an animated GIF
}
“; ?>
… using a newly introduced HTML span element with contenteditable=true to manage the user interaction. And did you know, at least for non-mobile platforms, you can set the focus (on non-mobile platforms only, as there are the “keyboard getting in the way” issues we’re thankful for with mobile platforms which preclude any thoughts of a programmed [element].focus() operation) to one of these “contenteditable=true style elements”? We’d never been sure, only focussing to HTML input textboxes and textareas up to now, we believe.
To usefully offer automation ideas for our Animated GIF Creator we need more flexibility regarding how the watermarks are presented. Get good with this, and this automation of Animated GIF creations could be quite productive. And so, in a similar line of thinking to yesterday’s Animated GIF SVG Quiz Argument Tutorial, today, we offer the user one new “get” titledown URL argument to work with a toggling Watermark Positioning arrangement, between the default top way and the new bottom way, with our input type=color Colour Picker we have going for the user to select a Watermark Colour. For the first time ever, we use …
input type=color ondblclick event
… logic. This event is both harmless regarding any other implications, and useful for toggling logic …
<?php echo ”
function bottomize(cpalo) {
if (document.getElementById('dtitled').innerHTML == '' && cpalo.title.indexOf('double click puts watermark near bottom of image rather than top of image') != -1) {
document.getElementById('dtitled').innerHTML='<input id=titledown name=titledown value=\"\" type=hidden></input>';
cpalo.title=cpalo.title.replace('double click puts watermark near bottom of image rather than top of image', 'double click puts watermark near top of image rather than bottom of image');
} else if (document.getElementById('dtitled').innerHTML != '' && cpalo.title.indexOf('double click puts watermark near top of image rather than bottom of image') != -1) {
document.getElementById('dtitled').innerHTML='';
cpalo.title=cpalo.title.replace('double click puts watermark near top of image rather than bottom of image', 'double click puts watermark near bottom of image rather than top of image');
}
}
In line with the URL arguments theme of yesterday’s Animated GIF Creation Automation Arguments Tutorial, today we wanted to try automating the Animated GIF Creator web application to serve as an agent to create a Quiz based on SVG input, as per …
… involving one new “get” delimquiz URL argument that we default to the value answer. The PHP code goes and looks above the place where it extracts the image information from that HTML circle_terminology.html source for where it mentions where the quiz answer aligned with that image can be found, in our case within a “get” part of a URL preceeded by “&answer=” …
<?php echo ”
var quizmode=false;
var atobis='';
//alert('Tval=' + tval);
if (tval.indexOf(encodeURIComponent('data:image/svg+xml')) != -1) {
tvals=tval.split(encodeURIComponent('data:image/svg+xml'));
if (blankend != '') { gtid='slideshow' + ('' + tid).replace('slideshow',''); addtotothers(); tid=gtid; }
thistval=1;
if (document.URL.indexOf('delimquiz=') != -1) { // typically &delimquiz=answer
if (document.getElementById('delay').value == '40') { document.getElementById('delay').value='800'; }
var svgshell='';
if (tvals[1].indexOf(encodeURIComponent(';utf8,')) == 0) {
svgshell=tvals[1].split(encodeURIComponent('>'))[0] + encodeURIComponent(' style=\"font-family:Verdana;font-size:24px;\"></svg>');
} else if (tvals[1].indexOf(encodeURIComponent(';base64,')) == 0) {
atobis=window.atob(tvals[1].substring(eval('' + encodeURIComponent(';base64,').length)).split(String.fromCharCode(34))[0].split(String.fromCharCode(39))[0].split(')')[0].split('&')[0].split('>')[0]);
svgshell=encodeURIComponent(';utf8,') + encodeURIComponent(atobis.split(encodeURIComponent('>'))[0].split('>')[0] + (' style=\"font-family:Verdana;font-size:24px;\"></svg>'));
} else {
svgshell=encodeURIComponent(';utf8,') + tvals[1].split(encodeURIComponent('>'))[0] + encodeURIComponent(' style=\"font-family:Verdana;font-size:24px;\"></svg>');
}
var dsvgshell=decodeURIComponent(svgshell);
var dlq=(decodeURIComponent(document.URL.split('delimquiz=')[1].split('&')[0].split('#')[0].split('>')[0]).replace(/\+/g,' ') + '=').replace(/\=\=$/g, '=');
if (dlq.replace('=','').trim() == '') { dlq='answer='; }
if (tvals[0].indexOf(dlq) != -1) {
// eg. answer= precursor idea to make into quiz
quizmode=true;
var sparetvals=tval.split(encodeURIComponent('data:image/svg+xml'));
tvals=[''];
for (var iipo=1; iipo<sparetvals.length; iipo++) {
tvals.push( svgshell.replace(encodeURIComponent('></svg>'), encodeURIComponent('><text y=\"12%\">What is this?</text></svg>')) + '><img SRC=\" data:image/svg+xml' + dsvgshell.replace('></svg>','><text y=\"22%\">What is this?</text></svg>').replace(/\\\"/g, String.fromCharCode(39)) + '\"></img>' ); // question
tvals.push(sparetvals[eval(0 + iipo)]); // image
tvals.push( svgshell.replace(encodeURIComponent('></svg>'), encodeURIComponent('><text y=\"12%\">' + decodeURIComponent(sparetvals[eval(-1 + iipo)].split(dlq)[1].split('&')[0].split('#')[0].split('>')[0]).replace(/\+/g,' ') + '</text></svg>')) + '><img SRC=\" data:image/svg+xml' + dsvgshell.replace('></svg>','><text y=\"22%\">' + decodeURIComponent(sparetvals[eval(-1 + iipo)].split(dlq)[1].split('&')[0].split('#')[0].split('>')[0]).replace(/\+/g,' ') + '</text></svg>').replace(/\\\"/g, String.fromCharCode(39)) + '\"></img>' ); // answer
}
}
}
// more code follows
}
“; ?>
… and we use that to end up with three animated GIF slides per image covering …
The automation measures in yesterday’s Animated GIF Creation Transparency Tutorial get an “arguments consideration” (maybe a five minute one, or perhaps ten minutes for “the outraged”) to help out ideas for our aspirational readers and users out there, who we are always keen to motivate, this Animated GIF Creator project potentially linked to user productivity, at its best.
If we want to improve automation ideas for these Animated GIF creations we need to use (initially ? and & “get”) arguments up at the web browser address bar for our exploratory user to not only allow for definition of …
their hTTp style animated GIF slide content basis (in a “get” irefresh labelled optional argument) … but as of today, how about …
new “get” dimensions labelled optional argument defines the output Animated GIF dimensions in terms of width,height … eg. 300,600
new “get” title labelled optional argument defines the wording of the watermark style Animated GIF title (basis) … eg. My+Animated+GIF
new “get” titlecolour labelled optional argument defines the colour of the watermark style Animated GIF title … eg. olive
new “get” titlemode labelled optional argument defines the watermark style Animated GIF title mode … eg. All
… and please do not forget an optional argument we’re always havingthat’s always been there …
the “get” delay labelled optional argument defining the delay between animated GIF slides … eg. 800
? That would complete some pictures out there, we’re hoping?!
Does this feel like a step sideways to you, “the regular reader”? We’d agree, and are a little surprised a revisit (to this project) shows this need, but there you are. Sometimes, revisits help clarify!
… deserves our consideration, we’ve decided, today … because …
Transparency begins at home.
We’ll just try our best here, but we have discovered a nuance that hadn’t tweaked with us before, considering “transparency” and using “canvas” elements. The …
[canvasElementContext].clearRect(0, 0, [canvasWidth], [canvasHeight]); // idea causes the canvas to become transparent ... different to the other concept like ...
[canvasElementContext].fillStyle='white'; [canvasElementContext].fillRect(0, 0, [canvasWidth], [canvasHeight]); // this example idea causes the canvas to become white
It’s affected two “avenues of effect” (or is this a book?!) with our Animated GIF Creator logic …
if a SVG+xml element data URI utf8 format representation mentions the word “transparent” we are now going to make the relevant helper canvas element background be transparent …
<?php echo ”
function drawInlineSVG(rawSVG, slidename) { // thanks to https://stackoverflow.com/questions/27230293/how-to-draw-an-inline-svg-in-dom-to-a-canvas
var rsvg = new Blob([rawSVG], {type:'image/svg+xml;charset=utf-8'}),
rdomURL = self.URL || self.webkitURL || self,
rurl = rdomURL.createObjectURL(rsvg),
rslidename=slidename,
imgc = new Image;
if (rawSVG.indexOf('transparent') != -1 || rawSVG.indexOf(window.btoa('transparent')) != -1) {
istransparent=true;
imgc.onload = function () {
if (istransparent) {
document.getElementById('mycanvas').width=imgc.width;
document.getElementById('mycanvas').height=imgc.height;
document.getElementById('mycanvas').getContext('2d').clearRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
} else if (1 == 1) {
document.getElementById('mycanvas').getContext('2d').fillStyle='white';
the “+” means by which we involve our Scribble and Annotation helper (of animated GIF slide content) now has a new button (with its onclick event function) to ask about its main canvas element background colour …
function colourize() {
var huhcol=prompt('Enter canvas background colour or Cancel to ignore.', 'transparent');
if (huhcol != null) {
if (huhcol.trim() != '') {
if (huhcol == 'transparent') {
//alert(987);
//alert('topielem.width=' + topielem.width);
parent.document.getElementById('topcanvas').getContext('2d').fillStyle = huhcol;
And so, we reckon it’s “transparent” (chortle, chortle) that yesterday’s Animated GIF Creation Automation Tutorial, created at home, and where (the vast majority of some readers know) …
Transparency begins at home. Can someone please hand me the lemon juice.
There are two competing issues going on with software development, of complexity, to challenge the skillset of the programmer …
keeping at an issue as it is fresh, and not letting go, as much as anything to keep up with where you are at, as with it being fresh in the mind … versus …
useful revisits after a bit of time to review the issue with fresher eyes, can often iron out issues not seen in “the heat of battle”
Today sees us relieved, undertaking a “second of the options above” scenario, regarding us creeping up on more Animated GIF Creation automation ideas we last talked about, with any depth, at Animated GIF Link Image Slide Tutorial.
[canvasElement].toDataURL(‘image/jpeg’, 10) … way to derive a data URI for …
textbox … representing an Animated GIF slide content mechanism
… rather than rely on ImageMagick converting from SVG to PNG was a bit of a game changer for us. We thought the extending of its use to other parts of the web application would be a good move. Along this way we also worked out that our Animated GIF dimensioning also needed some tweaking at a new HTML form onsubmit event function intervention point …
<?php echo ”
function dothem() {
for (var iijj=0; iijj<slidecmds.length; iijj++) {
eval(slidecmds[iijj]);
}
if (document.getElementById('selwhs')) {
if (document.getElementById('selwhs').value.indexOf(',') != -1) {
owoh(document.getElementById('selwhs'));
}
}
}
other image extraction from HTML user input via + … and today …
“a” link to either …
QR Code … via ++ … or …
Webpage Screenshot … via ++++
Do you see the pattern here? If you have a favoured character (ie. “+” here) involved in a user functionality behaviour decision you can give each a …
power of 2 number of characters
… (functionality meaning) and at the Javascript or PHP interpretive end of this arrangement you can know exactly what the user wants (in a way akin to how a bitmap can often be used) … so far this Javascript working (and tailorable into the future with some tweaking) as per …
<?php echo ”
function srchrefit(inbg) {
var outbg=inbg, outbis=[], ibis=0;
var ourblankend=blankend;
if (blankend != '') {
if (eval(eval('' + ourblankend.length) % 2) == 1) { // process img
ourblankend=ourblankend.substring(1);
outbg=outbg.replace(/data\:image\/svg\+xml/g, '!@#$%^&');
outbg=outbg.replace(/data\:image/g, ' SRC=\" data:image');
outbg=outbg.replace(/\!\@\#\$\%\^\&/g, 'data:image/svg+xml');
outbis=outbg.split('<img');
console.log('outbis.length=' + outbis.length + ' and outbg=' + outbg);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' src=\"') != -1) {
outbg=outbg.replace('<img' + outbis[ibis].split('>')[0], '<img' + outbis[ibis].split('>')[0].replace(' src=\"', ' SRC=\" '));
}
}
}
if (eval('' + ourblankend.length) == 4) { // process "a" links to Webpage Screenshot
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
} // ... or ...
} else if (eval('' + ourblankend.length) == 2) { // process "a" links to QR Code
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
}
}
return outbg;
}
return inbg;
}
… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a QR Code) …
… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a Webpage Screenshot).
The PHP GD library we use to help create animated GIFs (along with a whole lot of other help, it goes without saying) is not into vector graphics which is what …
… are really into … ooooohhh, aaaaahhhh … but luckily for us, the great ImageMagick offers functionality to convert a SVG image file into a PNG image file, via …
Non Windows
Windows
convert infile.svg outfile.png
magick.exe infile.svg outfile.png
… and we’re using that talent ImageMagick has to offer the user the chance, at any animated GIF slide textbox, the chance to enter encodeURIComponent and window.btoa sensitive entries whose (content) format could match (one of) …
… which fills in the slide data and then goes and tries to create the resultant animated GIF (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial)
Below is a new (PHP writes) Javascript iframe (iois object below) onload event function for recognizing hTTps://[HtmlWebpageWithSVG].html as above, and setting the iframe’s “src” attribute to its value …
<?php echo ”
var mm1='', mm2='', mm3='';
var gdgebimm='', gtval='', onealready='';
var tvals=[], thistval=0, thistdelim='', thistid='';
function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}
function svgmmcallol(iois, tid) {
//alert('TID=' + tid);
var tval='', it=0, dgebimm='';
var tis=document.getElementById(tid);
thistid=tid;
tvals=[];
thistval=0;
thistdelim='';
if (iois != null) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
tval=aconto.body.innerHTML;
//alert('Tval=' + tval);
if (tval.indexOf(encodeURIComponent('data:image/svg+xml')) != -1) {
thistval=1;
tvals=tval.split(encodeURIComponent('data:image/svg+xml'));
thistdelim=encodeURIComponent('data:image/svg+xml');
//alert('thistdeliM=' + thistdelim);
Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial
We wanted, today, to channel the (cruel might say “warped”) thinking behind the recent URL …
interactive entry of absolute URL starting with HtTp means you want a QR Code … and …
interactive entry of absolute URL starting with hTtP means you want (to involve, along the line, creating an animated QR Code scenario) a Webpage Screenshot
create animated GIF of QR Code means by which a smart device user using their Camera might navigate to a series of interesting webpage(s) … or …
create animated GIF of “current snapshot looks” of a series of URLs of interest (with even more currency than Google Earth shows your place!)
It might be you design an animated GIF chapter of slides and always want to follow it up with a “further reading” webpage you could present as a QR Code or Webpage Screenshot.
Anyway, at the “onblur” event Javascript function logic we intervened to end up with an image/png data URI substitute for the HtTp or hTtP URL the user enters to re-enter the normal animated GIF image definition workflow of the animated GIF creator …
<?php echo ”
var mm1='', mm2='', mm3='';
function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}