We’ve gone from “n to “z” today, completing yesterday’s CSS Function Ideas Tutorial‘s “a” to “m” start creating an inhouse look at CSS Functions usage converted into a web application you can try yourself, and inspired by the great W3school’s CSS Functions webpage, thanks.
Now a tad sideways? That’s almost it. If you’d just, now, stand on your head. Okay, that’s it, thank you kindly?!
We’re just reacclimatizing ourselves here, having had our eyes fully opened, having stumbled onto W3school’s CSS Functions webpage, thanks. We’ve only tipped our toes into the variety of CSS (Javascript script like) capabilities that are out there. And yes, we covered “invert” so you can stand up again now … ta, muchly.
We’re showing Keyboard Based Cursor Image CSS Filter Tutorial below because CSS Functions cover a lot of image (ie. img element) CSS styling smarts, and we have touched on this, as well as good ol’ “calc”.
In today’s two day project start we’ve allowed users the chance to try CSS Functions from “a” to “m”. In today’s work …
we started the first draft a bit non-generically … and then …
The user access all hangs off a first Shift key press followed by a numeric key (on QWERTY keyboard the “0123456789” correspond to “)!@#$%^&*(” characters) point at the first ten entries in …
var kcmap=["filter: blur(5px);","filter: brightness(0.4);","filter: contrast(200%);","filter: drop-shadow(16px 16px 20px blue);","filter: grayscale(50%);","filter: hue-rotate(90deg);","filter: invert(75%);","filter: opacity(25%);","filter: saturate(30%);","filter: sepia(60%);","filter: none;];"]; // thanks to https://developer.mozilla.org/en-US/docs/Web/CSS/filter
… used in amongst the “onkeypress” event Javascript function …
Thinking on arrangements above we figured it would give the user more control so that if they repeatedly pressed the same numerical key that would increment or decrement numerical components within the CSS filter specification requiring a changed call …
function doublecheck(infid) {
var outfid=infid;
var within=infid.split('(')[1].split(')')[0];
var entries=within.split(',');
if (entries[0].replace(/^\ /g,'').indexOf(' ') != -1) { entries=within.replace(/\(\ /g,'(').split(' '); }
var withind='';
if (document.title.indexOf('(') != -1) { withind=document.title.split('(')[1].split(')')[0]; }
var entriesd=withind.split(',');
if (entriesd[0].replace(/^\ /g,'').indexOf(' ') != -1) { entriesd=withind.replace(/\(\ /g,'(').split(' '); }
var anum=0.0, bnum=0.0;
var isdeg=false;
if ((entriesd[0] + 'x').indexOf(' ') != -1) { isdeg=true; }
multiple background image functionality … could be today’s …
image source choice to add to the generous Lorem Picsum image resource … thanks … that of a resource of the tutorial images amongst those of this RJM Programming WordPress Blog you are reading
… channelling the ever nuanced start we made in this regard when we presented Image Pair Fitting into a Given Dimension Sources Tutorial, with its interfacing to an increasing role for the WordPress codex TwentyTen theme 404.php role dealing with the HTTP error 404 well known as “Webpage Not Found”.
To make this happen, in code, we had to start breaking up (parameterizing, if you prefer) the hardcoding …
Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content … RJM Programming … May, 2022 … thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements. With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji. Optionally make emojis bigger after \ with + two time multipliers. Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can work. If first key is (+ is RJM image else) from 1 to 9 that will be number of background images displayed.
So, how to make it be able to be controlled by those users? Well, those previous keyboard logics involving emojis always involved a leading “\” backslash, so that leaves open numbers from 1 to 9 entered as a first keyboard character entered meaning that that is how many background images is wanted by that user …
Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content … RJM Programming … May, 2022 … thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements. With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji. Optionally make emojis bigger after \ with + two time multipliers. Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can remove pasted part as required. If first key is from 1 to 9 that will be number of background images displayed.
… supported by …
var numbi=location.search.split('numbi=')[1] ? reduce(decodeURIComponent(location.search.split('numbi=')[1].split('&')[0])) : '1';
if (numbi != '') {
if (eval('' + numbi) == 2) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top right; background-size: 50% 100%, 50% 100%; background-repeat: no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 3) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right; background-size: 33% 100%, 34% 100%, 33% 100%; background-repeat: no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 4) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top right, bottom left, bottom right; background-size: 50% 50%, 50% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 5) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, bottom left, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 6) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 33% 50%, 34% 50%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 7) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center center, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 33%, 33% 50%, 34% 34%, 33% 50%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 8) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=87123646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center left, center center, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 50%, 33% 34%, 34% 34%, 33% 33%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 9) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=67143446), url(//picsum.photos/1000/1000?random=87123646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center left, center center, center right, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 33%, 33% 34%, 34% 34%, 33% 34%, 33% 33%, 34% 33%, 33% 33%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
}
}
function reduce(invl) {
if (('' + invl).trim() == '') { return '1'; }
if (('' + invl).trim().replace(/0/g,'').replace(/1/g,'').replace(/0/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') != '') { return '1'; }
var retval=0, ij=0;
var cinvl='' + invl;
var xcinvl='';
for (ij=0; ij<cinvl.length; ij++) {
if (cinvl.substring(ij).substring(0,1) != '-') {
retval+=eval(cinvl.substring(ij).substring(0,1));
}
}
xcinvl='' + retval;
while (xcinvl.length > 1) {
retval=0;
for (ij=0; ij<xcinvl.length; ij++) {
if (xcinvl.substring(ij).substring(0,1) != '-') {
retval+=eval(xcinvl.substring(ij).substring(0,1));
}
}
xcinvl='' + retval;
}
if (retval == 0) { retval=1; }
return '' + retval;
}
Keyboard Based Cursor Canvas Content Copy Tutorial
You may have noticed with yesterday’s Keyboard Based Cursor Share Content Copy Tutorial, crucial to the sharing code, was the use of the incredible HTML5 introduced canvas element, helped by that middleperson link to those public email and SMS sharing conduits, overseeing the great random Lorem Picsum background images and user created emoji and/or text initial annotations.
And this got us wondering whether there was a private (ie. inhouse) web application of the past that could further value add as another optional middleperson tool for (user) personalization (of the content) purposes. And yes, do you remember the canvas work involved in the featured web application of Emoji Borders and Backgrounds Canvas Annotation Tutorial?
var awo=null;
awo=window.open('./user_of_signature_signature.htm','_blank','top=100,left=100,width=800,height=800');
… for the “child” canvas annotator to effectively “suck up” the canvas data into its canvas via …
var cancont='';
var elemode=location.search.split('elemode=')[1] ? (location.search.split('elemode=')[1].split('&')[0]) : "canvas";
if (('' + window.opener).replace('null','') != '') {
var cans=window.opener.document.getElementsByTagName(elemode);
if (cans.length > 0) {
if (elemode == 'img') {
cancont=cans[0].src;
} else {
cancont=cans[0].toDataURL('image/png');
}
if (cancontw < 0 && canconth < 0) {
cancontw=cans[0].width;
canconth=cans[0].height;
}
}
}
... possible because both "parent" and "child" exist on the same RJM Programming domain (web server).
Once there, another woooooorrrrrlllddd of image manipulations, via canvas, can await the user, perhaps ready for ongoing sharing possibilities with that "child".
Yesterday's Keyboard Based Cursor Personalized Content Copy Tutorial has probably reached a point where some sharing mechanism is apt, for accountability and usefulness purposes, at the very least, regarding our recent web application allowing for foreground content on top of a random Lorem Picsum background image.
function renderNoImage(canvas, blob) { // thanks to https://stackoverflow.com/questions/38004917/how-to-render-a-blob-on-a-canvas-element
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = (event) => {
URL.revokeObjectURL(event.target.src) // This is important. If you are not using the blob, you should release it if you don't want to reuse it. It's good for memory.
ctx.drawImage(event.target, 0, 0)
img.style.display='none';
img.style.zIndex='-123';
};
img.src = URL.createObjectURL(blob);
}
function renderImage(canvas, blob) { // thanks to https://stackoverflow.com/questions/38004917/how-to-render-a-blob-on-a-canvas-element
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = (event) => {
URL.revokeObjectURL(event.target.src) // This is important. If you are not using the blob, you should release it if you don't want to reuse it. It's good for memory.
ctx.drawImage(event.target, 0, 0)
};
img.src = URL.createObjectURL(blob);
}
addEventListener("paste", ev => { // thanks to https://stackoverflow.com/questions/55559432/can-i-take-a-screenshot-from-the-clipboard
for(const item of ev.clipboardData.items) { /// Clipboard may contain multiple elements of different type -- text, image, etc
if(item.type.startsWith("image/")) { /// We are only interested in clipboard data that is an image
if (emailee == '') {
emailee=prompt('Your clipboard has a useful image you could share the image with. Optionally, please enter an email address or SMS number to share with.');
if (emailee == null) { emailee=''; }
}
if (emailee.indexOf('@') != -1) {
document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="position:absolute;z-index:98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('aemail').href=document.getElementById('aemail').href.replace(':?', ':' + emailee + '?');
document.getElementById('aemail').click();
document.getElementById('mycanvas').innerHTML='';
} else if (emailee != '' && emailee.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') == '') {
document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="position:absolute;z-index:98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('asms').href=document.getElementById('asms').href.replace(':&', ':' + emailee + '&');
document.getElementById('asms').click();
document.getElementById('mycanvas').innerHTML='';
} else {
//document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="display:none;position:absolute;z-index:-98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderNoImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('mycanvas').innerHTML='';
}
}
}
});
... which is explained to the user in the following way ...
Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can remove pasted part as required.
The user can enter this via the keyboard because there is an HTML div contenteditable=true pallette to work with ...
<div id=mydiv onfocus='setTimeout(alte, 1000);' ondblclick="this.innerHTML='';" onclick='stamp(event);' title='Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content ... RJM Programming ... May, 2022 ... thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements.' spellcheck='false' contenteditable=true style='width:100vw;height:100%;color:transparent;text-color:transparent;' onkeypress=kpcursorlook(event); onkeydown=cursorlook(event); onmousemove=xycursorlook(event); ontouchmove=xycursorlook(event);></div>
It's "title" attribute now talks about two new pieces of functionality, those being ...
You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji).
Double click existant foreground emoji element to clear all the foreground emoji elements.
The choice of keyboard input methodology also suits CSS "content" property definitions as one backslash followed by a hexidecimal value left padded with zeroes to a length of six. See us doing this below for an umbrella emoji (which could also be expressed in an HTML hexadecimal entity way ☂ ☂ the information for which you can find at Unicode Character 'UMBRELLA' (U+2602) we normally get to by entering "U+2602" at a web browser address bar, the knowledge for which we arrive at via entering "umbrella emojipedia" and moving down the top link's webpage to find the "U+2602") ...
Two more "title" attribute pieces of functionality are now ...
With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji.
Optionally make emojis bigger after \ with + two time multipliers.
The choice of keyboard input methodology also suits CSS "content" property definitions as one backslash followed by "first off" sets of HTML entities they should not left zero pad in their entry, followed by a last HTML entity hexidecimal value left padded with zeroes to a length of six to finish up with. See us doing this below for a woman rowing emoji (which could also be expressed in an HTML hexadecimal entity way 🚣‍♀️ the information for which you can find at 🚣♀️ Woman Rowing Boat Emoji we normally get to by entering "woman rowing emoji" at the web browser address bar) ...
... and we wanted to have "keyboard" meets "mouse" events, along with the brilliance of Lorem Picsum regarding background image randomosity and quality, working with HTML ...
<div id=mydiv onfocus='setTimeout(alte, 1000);' onclick='stamp(this);' title='Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content ... RJM Programming ... May, 2022 ... thanks to https://picsum.photos/ Lorem Picsum' spellcheck='false' contenteditable=true style='width:100vw;height:100%;color:transparent;text-color:transparent;' data-onkeypress=xycursorlook(event); onkeydown=cursorlook(event); onmousemove=xycursorlook(event); ontouchmove=xycursorlook(event);></div>
... in a way we hadn't tried before that called on some inhouse cursor SVG creations (and so is, alas, just a non-mobile fully featured experience), in the sense that ...
keyboard helps creating the "what" regarding content ...
<script type='text/javascript'>
var lastkeymodifier=''
var lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
var pos3=-1, pos4=-1;
var subdiv=1;
var lastpos3=-2, lastpos4=-1;
var allowable=false;
mouse "onmousemove" or "ontouchmove" helps with the "where" regarding content above ...
<script type='text/javascript'>
var pos3=-1, pos4=-1;
var subdiv=1;
var lastpos3=-2, lastpos4=-1;
var allowable=false;
function xycursorlook(e) {
e = e || window.event;
e.preventDefault();
preparations for "onclick" way a cursor can be plonked into (real lasting) content ...
<script type='text/javascript'>
var lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
var pos3=-1, pos4=-1;
var subdiv=1;
var lastpos3=-2, lastpos4=-1;
var allowable=false;
Now a tad sideways? That’s almost it. If you’d just, now, stand on your head. Okay, that’s it, thank you kindly?!
We’re just reacclimatizing ourselves here, having had our eyes fully opened, having stumbled onto W3school’s CSS Functions webpage, thanks. We’ve only tipped our toes into the variety of CSS (Javascript script like) capabilities that are out there. And yes, we covered “invert” so you can stand up again now … ta, muchly.
We’re showing Keyboard Based Cursor Image CSS Filter Tutorial below because CSS Functions cover a lot of image (ie. img element) CSS styling smarts, and we have touched on this, as well as good ol’ “calc”.
In today’s two day project start we’ve allowed users the chance to try CSS Functions from “a” to “m”. In today’s work …
we started the first draft a bit non-generically … and then …
The user access all hangs off a first Shift key press followed by a numeric key (on QWERTY keyboard the “0123456789” correspond to “)!@#$%^&*(” characters) point at the first ten entries in …
var kcmap=["filter: blur(5px);","filter: brightness(0.4);","filter: contrast(200%);","filter: drop-shadow(16px 16px 20px blue);","filter: grayscale(50%);","filter: hue-rotate(90deg);","filter: invert(75%);","filter: opacity(25%);","filter: saturate(30%);","filter: sepia(60%);","filter: none;];"]; // thanks to https://developer.mozilla.org/en-US/docs/Web/CSS/filter
… used in amongst the “onkeypress” event Javascript function …
Thinking on arrangements above we figured it would give the user more control so that if they repeatedly pressed the same numerical key that would increment or decrement numerical components within the CSS filter specification requiring a changed call …
function doublecheck(infid) {
var outfid=infid;
var within=infid.split('(')[1].split(')')[0];
var entries=within.split(',');
if (entries[0].replace(/^\ /g,'').indexOf(' ') != -1) { entries=within.replace(/\(\ /g,'(').split(' '); }
var withind='';
if (document.title.indexOf('(') != -1) { withind=document.title.split('(')[1].split(')')[0]; }
var entriesd=withind.split(',');
if (entriesd[0].replace(/^\ /g,'').indexOf(' ') != -1) { entriesd=withind.replace(/\(\ /g,'(').split(' '); }
var anum=0.0, bnum=0.0;
var isdeg=false;
if ((entriesd[0] + 'x').indexOf(' ') != -1) { isdeg=true; }
multiple background image functionality … could be today’s …
image source choice to add to the generous Lorem Picsum image resource … thanks … that of a resource of the tutorial images amongst those of this RJM Programming WordPress Blog you are reading
… channelling the ever nuanced start we made in this regard when we presented Image Pair Fitting into a Given Dimension Sources Tutorial, with its interfacing to an increasing role for the WordPress codex TwentyTen theme 404.php role dealing with the HTTP error 404 well known as “Webpage Not Found”.
To make this happen, in code, we had to start breaking up (parameterizing, if you prefer) the hardcoding …
Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content … RJM Programming … May, 2022 … thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements. With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji. Optionally make emojis bigger after \ with + two time multipliers. Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can work. If first key is (+ is RJM image else) from 1 to 9 that will be number of background images displayed.
So, how to make it be able to be controlled by those users? Well, those previous keyboard logics involving emojis always involved a leading “\” backslash, so that leaves open numbers from 1 to 9 entered as a first keyboard character entered meaning that that is how many background images is wanted by that user …
Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content … RJM Programming … May, 2022 … thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements. With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji. Optionally make emojis bigger after \ with + two time multipliers. Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can remove pasted part as required. If first key is from 1 to 9 that will be number of background images displayed.
… supported by …
var numbi=location.search.split('numbi=')[1] ? reduce(decodeURIComponent(location.search.split('numbi=')[1].split('&')[0])) : '1';
if (numbi != '') {
if (eval('' + numbi) == 2) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top right; background-size: 50% 100%, 50% 100%; background-repeat: no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 3) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right; background-size: 33% 100%, 34% 100%, 33% 100%; background-repeat: no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 4) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top right, bottom left, bottom right; background-size: 50% 50%, 50% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 5) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, bottom left, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 50% 50%, 50% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 6) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 50%, 33% 50%, 33% 50%, 34% 50%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 7) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center center, bottom left, bottom center, bottom right; background-size: 33% 50%, 34% 33%, 33% 50%, 34% 34%, 33% 50%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 8) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=87123646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center left, center center, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 50%, 33% 34%, 34% 34%, 33% 33%, 34% 33%, 33% 50%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
} else if (eval('' + numbi) == 9) {
document.head.innerHTML+='<style> body { background: url(//picsum.photos/1000/1000?random=76547646), url(//picsum.photos/1000/1000?random=27143646), url(//picsum.photos/1000/1000?random=67143446), url(//picsum.photos/1000/1000?random=87123646), url(//picsum.photos/1000/1000?random=10143646), url(//picsum.photos/1000/1000?random=70143646), url(//picsum.photos/1000/1000?random=50147646), url(//picsum.photos/1000/1000?random=70147646), url(//picsum.photos/1000/1000?random=76147646); background-position: top left, top center, top right, center left, center center, center right, bottom left, bottom center, bottom right; background-size: 33% 33%, 34% 33%, 33% 33%, 33% 34%, 34% 34%, 33% 34%, 33% 33%, 34% 33%, 33% 33%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat; } </style>';
}
}
function reduce(invl) {
if (('' + invl).trim() == '') { return '1'; }
if (('' + invl).trim().replace(/0/g,'').replace(/1/g,'').replace(/0/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') != '') { return '1'; }
var retval=0, ij=0;
var cinvl='' + invl;
var xcinvl='';
for (ij=0; ij<cinvl.length; ij++) {
if (cinvl.substring(ij).substring(0,1) != '-') {
retval+=eval(cinvl.substring(ij).substring(0,1));
}
}
xcinvl='' + retval;
while (xcinvl.length > 1) {
retval=0;
for (ij=0; ij<xcinvl.length; ij++) {
if (xcinvl.substring(ij).substring(0,1) != '-') {
retval+=eval(xcinvl.substring(ij).substring(0,1));
}
}
xcinvl='' + retval;
}
if (retval == 0) { retval=1; }
return '' + retval;
}
Keyboard Based Cursor Canvas Content Copy Tutorial
You may have noticed with yesterday’s Keyboard Based Cursor Share Content Copy Tutorial, crucial to the sharing code, was the use of the incredible HTML5 introduced canvas element, helped by that middleperson link to those public email and SMS sharing conduits, overseeing the great random Lorem Picsum background images and user created emoji and/or text initial annotations.
And this got us wondering whether there was a private (ie. inhouse) web application of the past that could further value add as another optional middleperson tool for (user) personalization (of the content) purposes. And yes, do you remember the canvas work involved in the featured web application of Emoji Borders and Backgrounds Canvas Annotation Tutorial?
var awo=null;
awo=window.open('./user_of_signature_signature.htm','_blank','top=100,left=100,width=800,height=800');
… for the “child” canvas annotator to effectively “suck up” the canvas data into its canvas via …
var cancont='';
var elemode=location.search.split('elemode=')[1] ? (location.search.split('elemode=')[1].split('&')[0]) : "canvas";
if (('' + window.opener).replace('null','') != '') {
var cans=window.opener.document.getElementsByTagName(elemode);
if (cans.length > 0) {
if (elemode == 'img') {
cancont=cans[0].src;
} else {
cancont=cans[0].toDataURL('image/png');
}
if (cancontw < 0 && canconth < 0) {
cancontw=cans[0].width;
canconth=cans[0].height;
}
}
}
... possible because both "parent" and "child" exist on the same RJM Programming domain (web server).
Once there, another woooooorrrrrlllddd of image manipulations, via canvas, can await the user, perhaps ready for ongoing sharing possibilities with that "child".
Yesterday's Keyboard Based Cursor Personalized Content Copy Tutorial has probably reached a point where some sharing mechanism is apt, for accountability and usefulness purposes, at the very least, regarding our recent web application allowing for foreground content on top of a random Lorem Picsum background image.
function renderNoImage(canvas, blob) { // thanks to https://stackoverflow.com/questions/38004917/how-to-render-a-blob-on-a-canvas-element
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = (event) => {
URL.revokeObjectURL(event.target.src) // This is important. If you are not using the blob, you should release it if you don't want to reuse it. It's good for memory.
ctx.drawImage(event.target, 0, 0)
img.style.display='none';
img.style.zIndex='-123';
};
img.src = URL.createObjectURL(blob);
}
function renderImage(canvas, blob) { // thanks to https://stackoverflow.com/questions/38004917/how-to-render-a-blob-on-a-canvas-element
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = (event) => {
URL.revokeObjectURL(event.target.src) // This is important. If you are not using the blob, you should release it if you don't want to reuse it. It's good for memory.
ctx.drawImage(event.target, 0, 0)
};
img.src = URL.createObjectURL(blob);
}
addEventListener("paste", ev => { // thanks to https://stackoverflow.com/questions/55559432/can-i-take-a-screenshot-from-the-clipboard
for(const item of ev.clipboardData.items) { /// Clipboard may contain multiple elements of different type -- text, image, etc
if(item.type.startsWith("image/")) { /// We are only interested in clipboard data that is an image
if (emailee == '') {
emailee=prompt('Your clipboard has a useful image you could share the image with. Optionally, please enter an email address or SMS number to share with.');
if (emailee == null) { emailee=''; }
}
if (emailee.indexOf('@') != -1) {
document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="position:absolute;z-index:98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('aemail').href=document.getElementById('aemail').href.replace(':?', ':' + emailee + '?');
document.getElementById('aemail').click();
document.getElementById('mycanvas').innerHTML='';
} else if (emailee != '' && emailee.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') == '') {
document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="position:absolute;z-index:98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('asms').href=document.getElementById('asms').href.replace(':&', ':' + emailee + '&');
document.getElementById('asms').click();
document.getElementById('mycanvas').innerHTML='';
} else {
//document.getElementById('mydiv').style.overflow='scroll';
document.getElementById('mycanvas').innerHTML='<br><canvas style="display:none;position:absolute;z-index:-98;top:0px;left:0px;" id=thecanvas width=' + screen.width + ' height=' + screen.height + '></canvas>';
elem=document.getElementById('thecanvas');
context=elem.getContext('2d');
renderNoImage(elem, item.getAsFile()); //context.drawImage(item.getAsFile(), 0, 0);
document.getElementById('mycanvas').innerHTML='';
}
}
}
});
... which is explained to the user in the following way ...
Share with email or SMS happens via screenshots (macOS control-command-shift-3 or Windows Prnt-Scrn) followed by File menu Paste option causing chance to share after which File menu Undo can remove pasted part as required.
The user can enter this via the keyboard because there is an HTML div contenteditable=true pallette to work with ...
<div id=mydiv onfocus='setTimeout(alte, 1000);' ondblclick="this.innerHTML='';" onclick='stamp(event);' title='Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content ... RJM Programming ... May, 2022 ... thanks to https://picsum.photos/ Lorem Picsum You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji). Double click existant foreground emoji element to clear all the foreground emoji elements.' spellcheck='false' contenteditable=true style='width:100vw;height:100%;color:transparent;text-color:transparent;' onkeypress=kpcursorlook(event); onkeydown=cursorlook(event); onmousemove=xycursorlook(event); ontouchmove=xycursorlook(event);></div>
It's "title" attribute now talks about two new pieces of functionality, those being ...
You can change emojis if you know the \002602 form of UTF-16 (hex) entry (our example is umbrella and if you express it as \\002602 that leaves cursor just as your emoji).
Double click existant foreground emoji element to clear all the foreground emoji elements.
The choice of keyboard input methodology also suits CSS "content" property definitions as one backslash followed by a hexidecimal value left padded with zeroes to a length of six. See us doing this below for an umbrella emoji (which could also be expressed in an HTML hexadecimal entity way ☂ ☂ the information for which you can find at Unicode Character 'UMBRELLA' (U+2602) we normally get to by entering "U+2602" at a web browser address bar, the knowledge for which we arrive at via entering "umbrella emojipedia" and moving down the top link's webpage to find the "U+2602") ...
Two more "title" attribute pieces of functionality are now ...
With complex emoji entries do not zero leftpad until your last simple entity eg. \\1F6A3\200D\2640\00FE0F could define a Woman Rowing complex emoji.
Optionally make emojis bigger after \ with + two time multipliers.
The choice of keyboard input methodology also suits CSS "content" property definitions as one backslash followed by "first off" sets of HTML entities they should not left zero pad in their entry, followed by a last HTML entity hexidecimal value left padded with zeroes to a length of six to finish up with. See us doing this below for a woman rowing emoji (which could also be expressed in an HTML hexadecimal entity way 🚣‍♀️ the information for which you can find at 🚣♀️ Woman Rowing Boat Emoji we normally get to by entering "woman rowing emoji" at the web browser address bar) ...
... and we wanted to have "keyboard" meets "mouse" events, along with the brilliance of Lorem Picsum regarding background image randomosity and quality, working with HTML ...
<div id=mydiv onfocus='setTimeout(alte, 1000);' onclick='stamp(this);' title='Click and type and see the cursor change as you use Alt or Shift or Control that can be reset via Caps Lock with a click copying cursor into content ... RJM Programming ... May, 2022 ... thanks to https://picsum.photos/ Lorem Picsum' spellcheck='false' contenteditable=true style='width:100vw;height:100%;color:transparent;text-color:transparent;' data-onkeypress=xycursorlook(event); onkeydown=cursorlook(event); onmousemove=xycursorlook(event); ontouchmove=xycursorlook(event);></div>
... in a way we hadn't tried before that called on some inhouse cursor SVG creations (and so is, alas, just a non-mobile fully featured experience), in the sense that ...
keyboard helps creating the "what" regarding content ...
<script type='text/javascript'>
var lastkeymodifier=''
var lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
var pos3=-1, pos4=-1;
var subdiv=1;
var lastpos3=-2, lastpos4=-1;
var allowable=false;
mouse "onmousemove" or "ontouchmove" helps with the "where" regarding content above ...
<script type='text/javascript'>
var pos3=-1, pos4=-1;
var subdiv=1;
var lastpos3=-2, lastpos4=-1;
var allowable=false;
function xycursorlook(e) {
e = e || window.event;
e.preventDefault();
preparations for "onclick" way a cursor can be plonked into (real lasting) content ...
<script type='text/javascript'>
var lastcursor="Url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='126' height='48' viewport='0 0 100 100' style='border-radius:15px;background-color:rgba(0,255,0,0.3);fill:black;font-family:Verdana;font-size:16px;'><text y='80%'>Shift/Alt/Ctrl\\002753</text></svg>\") 16 0, crosshair";
var pos3=-1, pos4=-1;
var subdiv=1;
var lastpos3=-2, lastpos4=-1;
var allowable=false;
we wanted to add some HTML textarea element onkeydown keyboard event logic to be able to, via some element title attributes, show a preview view of the “Text to Emoji” conversion ideas … and …
improved the sharing logic accordingly, being able that way, to include these preview views in the email and/or SMS body
yesterday’s work HTML iframe destination was populated via some HTML via that iframe’s “srcdoc” attribute … whereas with …
today’s work switches the “target” attribute of an HTML form (POSTing data to some PHP) to our “overlay preview” HTML iframe before putting that form’s “target” attribute back to the normal flow of work … achieved as simply as adding HTML snippets …
<form id="iform" onsubmit="this.target=document.getElementById('itarget').value; setTimeout(latback, 3000); return true;" target='iftext' method='POST' action='./fillin_gaps_with_emojis.php'><input type=hidden name=itarget id=itarget value=iftext></input>
<|-- rest of form follows would include submit button used by "document.getElementById('mysubm').click();" code below to submit form -->
</form>
… with associated Javascript (after) …
function latback() {
document.getElementById('itarget').value='iftext';
}
Both techniques work to further emphasise just how useful and flexible are HTML iframe elements regarding HTML navigation choices.
Team that HTML iframe navigation talent with the CSS “overlay” talents of …
… effectively controlling the “overlay” CSS (inferred, via rgba) friend …
opacity … teamed with other “overlay” CSS property friends …
z-index … and …
position:absolute; top:[matchedTopOfUnderlay]px; left:[matchedLeftOfUnderlay]px; (as well as width:[matchedWidthOfUnderlay]px; height:[matchedHeightOfUnderlay]px; today)
… and you have quite a powerful combination to work with to “jazz up” the “display smarts” of your web applications, a bit reminiscent of “rubber banding” previews of graphic element creations.
… specifically the use of the “rotate([numDegrees]deg)” “transform-function” and helped out considerably by a big friend of recent times … style=position:fixed
And today we delve into two more of those “transform-functions” to facilitate flip (mirror image in X) and flop (mirror image in Y), adding to yesterday’s …
rotation of text … “transform-function” “rotate([numDegrees]deg)” … with today’s and/or based …
flip of text … “transform-function” “scaleX(-1)” … and/or …
flop of text … “transform-function” “scaleY(-1)”
… all funnelled through that same Javascript prompt user access point of yesterday where the “prompt” of the prompt now goes …
Rotate text by your entry degrees. Negative entry (including -0) additionally flips. Appending a space additionally flops.
As you can imagine if you gyrate yourself thinking about “transformations” (eg. the Twister game) order can be important, and we found a simplistic idea like …
style=" transform: scale(-1,-1); "
… (ie. flipping and flopping) applied to one “div” element could not be made to work, for us. So here’s the lesson here. If you have nested elements, where this style=” transform: scale(-1,-1); “ fails (and yes, we also failed with style=” transform: scaleX(-1) scaleY(-1); “) we found …
apply to parent element style=” transform: scaleX(-1); “
apply to child element style=” transform: scaleY(-1); “
Text to Emoji Short Code Translation Textarea Rotation Tutorial
When you look around you at advertisements and signage you may see lots of ways to represent text, and here we include emojis in that thinking. And that is another reason we think emojis are useful. For we graphically challenged, to learn about emojis opens up a whole new area of (self) expression.
As such, onto yesterday’s Text to Emoji Short Code Translation Textarea Sharing Tutorial work we wanted to offer a text rotation additional (and optional) piece of functionality that you can access via a “Text” hardcoding becomes “a” link to prompt window piece of functionality that gets you to some new PHP code …
… on a regular basis you will probably have seen mention of Emoji “Short codes” of the form “:[short_code]:” (eg. :e-mail: or :grinning_face:) used by Github and Slack (and, we think, Facebook) which we want to get into today, as an idea for our players in our Emoji in Sector game be able to personalize their player names
The concept of emoji short codes gives us a foot in the door to English Phrase “emoji translation” albeit tiny phrases … still?! Do you remember the work of the reasonably recent Text to Emoji Translation Textarea Sharing Tutorial? Well, rather than …
“word by word” emoji translation principles (as used previously) … we can now offer …
emoji short code translation of recognised English Phrases (with one underscored emoji short code representing an emoji for those words of an English Phrase) … eg. “man running” or “disappointed face” … all the way back to single word short code translation “fall throughs” left (like above) …
<?php
if (file_exists('../PHP/short_codes/php')) {
if ($intext != '') {
$outtext=$intext;
$outtxt=file_get_contents('../PHP/short_codes/php?intext=' . urlencode($intext));
if (strpos($outtxt, '</body>') !== false) {
$bod='<body' . explode('>', explode('<body', $outtxt)[1])[0] . '>';
$outtext=str_replace('<p>', '', str_replace('</p>', '', explode($bod, explode('</body>', $outtxt)[0])[1]));
if ($outtext != $intext) {
echo "<html><head><title>Emoji-ize Text - RJM Programming - June, 2021</title><meta charset='UTF-8'></head><body style='width:100%;'><p>" . str_replace("\n","<br>",str_replace("$@!"," ",trim($outtext))) . "</p></body></html>";
exit;
}
}
}
}
Text to Emoji Translation Textarea Sharing Tutorial
The recent Text to Emoji Translation Textarea PHP Sort Tutorial got to “selfish point status”. Huh?! Well, that is the status with a web application that “creates” or “converts” or can be thought of as “useful” or being a “tool” but makes no “internal use” functionality to help with sharing your creativity with anybody else. Of course, any sharing is optional, but it’s good to include it in the logic, where possible, and with this particular web application it is “hugely possible” using four modes of sharing conduit into play …
email emoji-izing text via an inline HTML email form sent via PHP mail
email emoji-izing text via a downloadable HTML attachment sent via PHP mail
email emoji-izing text via a URL link in a client email via “a” “mailto:” link (that you can amend further at the client email application end)
SMS emoji-izing text via a URL link in a client email via “a” “sms:” link
… and the newly added “Email or SMS” input type=submit button added can be used in email emoji-izing text via an inline HTML email form sent via PHP mail so as, if required, to continue on with the chain of communication.
Interesting things we needed to do, and surprised us (some of which just constantly surprise me, but perhaps not you), were …
email emoji-izing text via an inline HTML email form sent via PHP mail …
we needed to allow GET (only way inline HTML email forms work) logic (work the more widely distributed “name” attributes for input type=submit elements) …
var intext=location.search.split('intext=')[1] ? decodeURIComponent(location.search.split('intext=')[1].split('&')[0]).replace(/\+/g,' ') : '';
var emailsms=location.search.split('emailsms=')[1] ? decodeURIComponent(location.search.split('emailsms=')[1].split('&')[0]).replace(/\+/g,' ') : '';
var myaltb=location.search.split('myaltb=')[1] ? decodeURIComponent(location.search.split('myaltb=')[1].split('&')[0]).replace(/\+/g,' ') : '';
email emoji-izing text via a downloadable HTML attachment sent via PHP mail …
need for … <meta charset="UTF-8">
email emoji-izing text via a URL link in a client email via “a” “mailto:” link (that you can amend further at the client email application end) …
no need for double encodeURIComponent usage (whereas SMS below does need) as per …
function dummyencodeURIComponent(invl) {
return invl;
}
SMS emoji-izing text via a URL link in a client email via “a” “sms:” link …
need for double encodeURIComponent usage as per …
ais.href='sms:' + etois + '&body=' + encodeURIComponent('HTTPS://www.rjmprogramming.com.au/HTMLCSS/fillin_gaps_with_emojis.html?intext=' + encodeURIComponent(encodeURIComponent(document.getElementById('intext').value)));
Text to Emoji Translation Textarea PHP Sort Tutorial
You can definitely benefit, as a programmer, with a sceptical outlook. The way we developed the recent Text to Emoji Translation Textarea Tutorial‘s web application was a case in point. It felt too simplistic by half, and so it panned out to be. But here again, revisits help. Trying things out, and honestly trying to break it. This “trying to break it” started out with us trying “face” and “smile” and combinations to no avail. No emoji description is that simple. But then we tried …
smile, Grinning Face with Sweat
… and that’s where we discovered the source of our unease. Before the fix it “Emoji-ized” this to …
smile, 😀 with Sweat
… whereas it would have been better to have “Emoji-ized” that to …
smile, 😅
So, where to fix this? It’s the PHP helper responsible. Could it be as simple as presenting the ~[Emoji]|[Text] array pairings in an order whereby the longer [Text] lengths appear first? So far, with our testing, it appears … “Yup”.
And so we involve PHP’s sort function, in context, in the changed PHP code below …
Have you noticed other types of “sort” functions in PHP? Why not use those? Well, when possible, we like to work with the “no frills” versions of language choices, rather than the obverse idea of “making the code less verbose”. We like to fit in with “what has always been there” we’d guess you’d say. And so that is where that codeline …
we entered “data” into a “textarea” element … no complaints … very suitable … but …
we translated into an “iframe” element … huh?!
Yes, this is not the best approach, we concur. And yet, it is not all bad. Let’s tabularize what we mean here (including macOS two finger gesture or Windows right click menu functionality possibilities), below …
Element type
Description
Pro
Con
Textarea
Repository of Text data
✔✔
Iframe
Repository of Text data
✔
Textarea
Resizable
✔
Iframe
Resizable
❌
Textarea
Paragraph direction control
✔
Iframe
Paragraph direction control
❌
Textarea
Printing of Text data
❌
Iframe
Printing of Text data
✔
Textarea
Copy/paste of Text data
✔
Iframe
Copy/paste of Text data
✔
Textarea
New tab
❌
Iframe
New tab
✔
Textarea
New window
❌
Iframe
New window
✔
Textarea
Spelling and grammar check
✔
Iframe
Spelling and grammar check
❌
Textarea
Text to speech (macOS)
✔
Iframe
Text to speech (macOS)
❌
Textarea
Uppercase/lowercase (macOS)
✔
Iframe
Uppercase/lowercase (macOS)
❌
Textarea
Text services (macOS eg. iTunes Text to Speech recordings)
✔
Iframe
Text services (macOS eg. iTunes Text to Speech recordings)
❌
Textarea
Search engine lookup (macOS)
✔
Iframe
Search engine lookup (macOS)
❌
Textarea
Element source code
❌
Iframe
Element source code
✔
Textarea
Emoji specific title on non-mobile hover
❌
Iframe
Emoji specific title on non-mobile hover
✔
And so, we allow for the old “Iframe” element approach to still be accessed, but turn the default workflow into a design whereby “Emoji-ize” textual results end up in a “Textarea” element for a changed parent HTML/Javascriptfillin_gaps_with_emojis.html ready for you to (re-)try at this live run link.
We’re starting a new coding project, today, calling on the genius of Emojipedia for an …
Emoji-ize Text
… mangling of English … as well as an interesting substitutional feeling web tool.
Admittedly we started the day wondering about that “bluetooth icon” Spotify tutorial of recent times, wondering about how we could have improved the presentation via …
delayed iPhone photo technique … yes, but what if there was …
an emoji for that Bluetooth icon look a lot of us know by now
… and looking into that second idea was surprised that the Bluetooth icon, let alone emojis for concepts like WiFi or “Power On” (ie. concepts, by and large, we guess) will either never become emojis or will be slow to get to becoming an emoji. More, emojis suit our real object nouns in our languages, and so we wanted to write a substitutional web application to see whether my theorizing carries any weight.
Yesterday’s CSS 3D Transform Selector Rotations Tutorial “worked into” what we want to hone in on, today, regarding more CSS ideas. Additionally to yesterday’s honing in on CSS selectors, there are two categories of selector sophistication (you’d have only reached, yesterday, had you entered some of your own selectors) that being …
… as that : or :: respectively, appended, conditional and optional part to your CSS selector syntax part (ie. the part before the { and then followed by the styling CSS yesterday’s Rotations in 3D web application was filling with transform 3D rotation clauses but here, today, we are asking for within a textbox, followed by a } “end of CSS clause”).
Yesterday’s CSS 3D Transform Rotations Tutorial was interfacing to CSS 3D transform rotations, sure, but there is room for more sophistication regarding …
multiple rotation CSS styling axis definitions … meaning …
context
order
… can be harnessed to create a myriad more of display possibilities (where different results can happen regarding the order an axis rotation comes in your “up to three” parts to the complete CSS styling rotation definition), among the three X or/and Y or/and Z axis rotation choices.
To allow for this, we …
retain the one display change intervention point as the onchange event of the leftmost select (ie. dropdown) element … but …
if the number of axis rotations is larger than one, utilize a Javascript prompt window to allow for the larger than one number of degree rotations that can come into play …
function anal(osel) {
var newval='', pmore='', pblurb='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + document.getElementById('degval').value + 'deg) ' + pmore + '; </style>';
var sugblurb=') rotateY(' + document.getElementById('degval').value + 'deg) rotateZ(' + document.getElementById('degval').value + 'deg)';
if (osel.value == 'X') {
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + document.getElementById('degval').value + 'deg); } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'Y') {
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + document.getElementById('degval').value + 'deg); } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'Z') {
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + document.getElementById('degval').value + 'deg); } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XY') {
pblurb=pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','Y').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XZ') {
pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','Z').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YX') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','X').split(' r')[0];
pmore=prompt('Please enter 3D rotation in X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YZ') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','Z').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZX') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Y','X').split(' r')[0];
pmore=prompt('Please enter 3D rotation in X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZY') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Y','Y').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + document.getElementById('degval').value + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XYZ') {
pblurb=pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','Y').replace('Z','Z');
pmore=prompt('Please enter 3D rotations in Y,Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XZY') {
pblurb=pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','@').replace('Z','Y').replace('@','Z');
pmore=prompt('Please enter 3D rotations in Z,Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YXZ') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','X');
pmore=prompt('Please enter 3D rotations in X,Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YZX') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','@').replace('Z','X').replace('@','Z');
pmore=prompt('Please enter 3D rotations in Z,X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + ')', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + ')', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZXY') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Y','@').replace('Z','Y').replace('@','X');
pmore=prompt('Please enter 3D rotations in X,Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZYX') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Z','X');
pmore=prompt('Please enter 3D rotations in Y,X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
}
if (newval != '') { document.getElementById('degval').value=newval.split('.')[0]; }
}
Regarding the recent CSS Outline and Background Tutorial‘s “Outline & Background” web application, and it’s “iframe” try below modes of use, we wondered, being a bit in awe of what CSS can achieve these days in the category of …
… to confirm our initial thoughts on this, those being “not by itself” … which of course means … that 🄲 t-shirt … we’ll be having to pack away for now again.
But we followed that link’s advice quite closely (as well as being more diligent adding that trailing ? question mark … just in cases), affecting that “Outline & Background” web application’s layout via …
… to add more dropdown styling options into the mix (inspired a lot by this Google search, thanks) where the “outline” concept may have a role in amongst “border” and “background” concept webpage CSS styling ideas.
The CSS “border” emphasis of the previous Emoji Borders and Backgrounds Canvas Annotation Tutorial has concepts, we see online, confusing people, and myself, regarding what the CSS “outline” feature is capable of (or not capable of). Here is W3school‘s pertinent paragraph on this …
Note: Outline differs from borders! The outline is drawn outside the element’s border, and may overlap other content. Also, the outline is NOT a part of the element’s dimensions; the element’s total width and height is not affected by the width of the outline.
The CSS “outline” concept is not the panacea to as many web design requirements as the “border” concept is. For instance, even seeing within the purview of making our “proof of concept” web application …
no linear gradients can be worked in the “outline” realm
no such properties as “outline-top” or “outline-left” or “outline-bottom” or “outline-right” exist within the “outline” realm
no such property as “outline-radius” (though will mimic any roundedness applied to border)
no outline images in the “outline” realm
If we were to summarize, the CSS “outline” concept’s talents can lie with …
being around an HTML element (and not part of it … perhaps in web design, useful as “a place of rest” (including non-mobile on hover element title displays) for users?!)
decorative colour around an HTML element (perhaps to get the user’s attention to hone in on that element, or perhaps a dynamic conduit towards “thickening” an existant HTML element border (especially as Javascript DOM such as [element].style.outline=’2px solid green’; // is available to programmers))
can form a replacement nesting HTML element background colour means
in it’s simplest CSS syntax ( eg: outline: 2px solid green; ) can be easily remembered next to the simplest syntax of border (probably very familiar to you) CSS syntax ( eg: border: 2px solid green; ) … just differently located on the webpage
… contents in synch as far as looks go. That ignores the reason CANVAS (element) was invented when HTML5 came out. It was invented to not only contain image graphical data, but be able to amend that data. So we also allow it with our web application from today on, integrating with our inhouse “User of Signature” web application last talked about at Local Fonts Revisited Middle Tutorial, to amend (initially image via [canvas].toDataURL(‘image/png’) via SVG streams of data which may include emoji borders and backgrounds) graphical data.
We integrate via a same domain window.open scenario. Before you all start groaning, consider the advantages of a …
… albeit non-mobile window.open (ie. popup window) call. Not only are you …
(on non-mobile) seeing two windows on top of each other … but …
the “window.opener” (acting like “parent” does for an “iframe” arrangement) reference can have you, via Javascript DOM, share the data of the popup window canvas element with that of the “window.opener” (window) canvas element
… and then, we arrange for a “reset” (to ignore these annotation changes), via the “middle-element” IMG element, should the “Undo” functionality of our HTML changeduser_of_signature_signature.html‘s User of Signature Signature (standalone) live run not be enough flexibility to the functionality, which has a new document.body onload event triggering of Javascript function cancontlook below …
var cancont='';
var cancontw=-1, canconth=-1;
if (('' + window.opener).replace('null','') != '') {
var cans=window.opener.document.getElementsByTagName('canvas');
if (cans.length > 0) { cancont=cans[0].toDataURL('image/png'); cancontw=cans[0].width; canconth=cans[0].height; }
}
function cancontlook() {
if (cancont != '') { // called via SVG - IMG - CANVAS
celem=document.getElementById('topcanvas');
ccontext = celem.getContext("2d");
celem.width=cancontw;
celem.height=canconth;
cimg=new Image;
cimg.onload = function(){
ccontext.drawImage(cimg,0,0);
};
cimg.src=cancont;
if (document.getElementById('toptd')) {
document.getElementById('toptd').style.left='' + cancontw + 'px';
var recttoptd=document.getElementById('toptd').getBoundingClientRect();
document.getElementById('topcbutton').innerHTML='⬅';
document.getElementById('topcbutton').style.position='fixed';
document.getElementById('topcbutton').style.top='' + recttoptd.top + 'px';
//document.getElementById('topcbutton').style.left='' + recttoptd.left + 'px';
document.getElementById('topcbutton').style.left='' + eval(0.98 * eval('' + screen.width)) + 'px';
document.getElementById('topcbutton').style.zIndex='89';
document.getElementById('topcbutton').title='Back to SVG - IMG - CANVAS web application caller';
//document.getElementById('topcbutton').onclick=function() { window.opener.focus(); };
}
if (document.getElementById('toppixellate')) {
document.getElementById('toppixellate').style.top='' + canconth + 'px';
}
if (('' + location.hash).replace(/^\#/g,'') != '') {
document.getElementById('topcstyle').innerHTML='
function iysh() {
if (document.getElementById('topcbutton').innerHTML.indexOf(' ') != -1) {
document.getElementById('topcbutton').innerHTML=document.getElementById('topcbutton').innerHTML.replace(' ','');
alert('Please do this manually');
}
}
function woff() {
document.getElementById('topcbutton').innerHTML+=' ';
setTimeout(iysh, 2000);
window.opener.focus();
}
… that might help you “look back at yourself from outside” as we use it to interface to Google PageSpeed Insights webpage screenshot functionality (which can look at a designated URL and effectively screenshot it for you) … thanks.
We used to restrict our curl usage thinking to “only ?” first argument use too, arguing (with ourselves) that the Linux and Unix and macOS and Mac OS X “&” character command line meaning of “process in the background” would be a constraint. Of course it isn’t, because … anyone, anyone? Yes, Henry, you should use a “curl” command line command, using double quotes, of the form …
… and the “&”‘s are understood to be URL “GET” argument delimiters, and not a “process in the background” designator.
And here’s the thing exemplified above. The alternative file_get_contents PHP function cannot do that https: protocol type of URL, yet Google PageSpeed Insights webpage screenshot functionality demands such URLs … hence the “curl” interest.
$extis='.xxx';
if (strpos(('' . $_SERVER['QUERY_STRING']), 'howpagespeedseesme=') !== false) {
if (file_exists('/tmp/')) {
if (file_exists('/tmp/pscs.xxx')) {
unlink('/tmp/pscs.xxx');
}
}
exec($psbig);
while (!file_exists('/tmp/pscs' . $extis)) {
sleep(4);
}
while (filesize('/tmp/pscs' . $extis) == 0) {
sleep(4);
}
$scx=file_get_contents('/tmp/pscs' . $extis);
$scxs=explode('"screenshot":', $scx);
if (sizeof($scxs) > 1) {
$postscxs=explode('"data": ', $scxs[1]);
if (sizeof($postscxs) > 1) {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This ...</h2><img src=' . substr($postscxs[1],0,1) . explode(substr($postscxs[1],0,1), substr($postscxs[1],1))[0] . substr($postscxs[1],0,1) . '></img></body></html>';
} else {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This ...</h2><p>Sorry, resource exhausted. Could try again later.</p></body></html>';
}
} else {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This</h2><p>Sorry, resource exhausted. Could try again later.</p></body></html>';
}
exit;
}
?>
… working with the new HTML div <div id=readyforiframe></div> element, along with <span title=’Google PageSpeed Insights webpage screenshot view of this web browser address URL’ onclick=’psit();’> 📸 </span> 📸 “emoji button” in the HTML static code … with associated Javascript function …
Emoji Borders and Backgrounds Web Browser Tutorial
Yesterday’s Emoji Borders and Backgrounds Shape Sharing Tutorial had us sharing via email or SMS our “Emoji Borders and Backgrounds” creations via inhouse organized arrangements. But many people are used to just right-clicking (for Windows) and two finger gesturing (for macOS and Mac OS X) on …
SVG
IMG
CANVAS
… graphical elements, which can be made to “look” the same, and sort of “suck it and see” as far as menu options presented, helping them out sharing graphical information. In many cases, users don’t care what form of element the image comes contained in. But, if you involve “background-image” CSS along the way to achieve a (consistent) “look”, as we had done before today, (some of) the output of those menu options could be lacking (because they look for “foreground data”), and so we do away with the need for a “background-image” …
<?php
function ctoilater() {
img.src=canvas.toDataURL('data/png');
}
An example of how having web browser (right-clicking (for Windows) and two finger gesturing (for macOS and Mac OS X)) menu options be useful, consider an image menu option such as “Copy image” be used by the user. The user can compose their own (email client (or get to email client via all uppercase web application “to” email “address” definition)) email then, and just Edit -> Paste the results, as an image, into the email body, ahead of sending off that email.
Emoji Borders and Backgrounds Shape Sharing Tutorial
The code “shape shifting” of recent times morphs into “shape sharing” together in amongst the parent users of our PHP tool “Emoji Borders and Backgrounds” web application featuring in yesterday’s Emoji Borders and Backgrounds Shape Numerics Tutorial.
We found the “SVG+XML” mimetype data not accepted by Gmail for an Inline HTML Email, so we have coded for the Downloadable HTML Attachment “way to go”.
<?php
function emailit() {
var fbit='';
var tois=prompt('Please enter an email address to email to (all uppercase uses email client rather than PHP mail and all numerical sends an SMS).','');
if (tois == null) { tois=''; }
if (tois.trim() != '') {
if (tois.indexOf('@') != -1) {
if (tois.toUpperCase() == tois) {
document.getElementById('divemail').innerHTML='<a id=aemail style=display:none; href=mailto:' + tois + '?subject=My%20Emoji%20Border%20and%20Background%20Creation&body=' + encodeURIComponent(document.URL) + '>Email</a>';
//fbit=('' + document.getElementById('aemail').href).split('?')[1];
//document.getElementById('aemail').href='mailto:' + tois + '?' + fbit;
document.getElementById('aemail').click();
} else {
var zhr = new XMLHttpRequest();
var zform=new FormData();
if (1 == 2) { zform.append('inline', ''); }
zform.append('to', tois);
zform.append('subj', 'My Emoji Borders and Background Creation ... at [date] ...');
//alert(encodeURIComponent('<html><body><img src=\"<?php echo $bemb; ?>\"></img></body></html>'));
zform.append('tdhuhta', encodeURIComponent('<html>' + '<?php echo $headstyle; ?>' + '<body><img src="<?php echo $bemb; ?>"></img></body></html>'));
zhr.open('post', '//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php', true);
zhr.send(zform);
alert('Email sent to ' + tois);
}
} else if (tois.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') == '') {
document.getElementById('divsms').innerHTML='<a id=asms style=display:none; href=sms:' + tois + '&body=' + encodeURIComponent(document.URL) + '>SMS</a>';
//document.getElementById('asms').href='sms:' + tois + '&body=' + encodeURIComponent(document.URL);
document.getElementById('asms').click();
}
}
}
Emoji Borders and Backgrounds Shape Numerics Tutorial
If you are familiar with the geometry of shapes, it is full of numbers, with the implications as to how the shape is represented and displayed, that those numbers can affect. And so, onto yesterday’s Emoji Borders and Backgrounds Shapes Tutorial‘s start with …
SVG ellipse element functionality today … and for all these, as well as the …
SVG text element we start allowing “shape numerics” as being a user definable thaing
These “shape numerics” can help the user control (that SVG element’s) …
position
size
opacity
font size … (for text elements) on top of that non-numeric control yesterday’s work gave us, being (that SVG element’s fill) …
colour
This is all handled, still, within that “image” argument definition, and we allow a decimal (ie. “.”) delimiter be the way a user separates their integer values (where an opacity value becomes “0.” + [integerValue]).
Onto yesterday’s Emoji Borders and Backgrounds Text Justification Tutorial we add some consideration of SVG shape creations into the mix of the Emoji Borders and Backgrounds work, starting just with the PHP tool, at this stage, and just considering …
… to start off with, and feeding off yesterday’s …
width=[designatedPxWidth] and height=[designatedPxHeight] … and/or …
image=[someImageUrl] (width and height)
… breakdown as to how a user can define a box of interest, as a great “line in the sand” for us to work around with this new “Shapes functionality”. It’s an interfacing job, for tomorrow, getting parents to work with this “image” argument based way a user can define these shapes, including a “noimage” option that uses an image’s width and height (to help out with the shape definition) but does not display that image.
Along the way we also mildly rearrange PHP code for inline_svg.php‘s live run so as to allow for more than one user text to be added via justification prefixing methodologies.
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&css=opacity:0.9;&textcss=font-size:20px;&ultext=Hello%0AThere
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;&ultext=Hello%0AThere
Day before yesterday’s (third parent (to our PHP tool) “cab off the rank”) SVG -> IMG -> CANVAS changed PHPcanvas_svg.phplive run now prompts …
Please enter comma separated HTML decimal entity(s) for your Emoji Border to graphics. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &iurl=[newImageURL] to change base image. Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;&ultext=Hello%0AThere
… via a new “text” argument arranged for the PHP and in readiness for some more aesthetic improvements in the display side of things with our emoji borders and backgrounds
Well, what gives? Eh, wot’s up ‘guv? Yes, indeed … all we can say is …
We got sidetracted.
… and applying spell checker to get around an expression that amuses us …
We got sidetracked.
So, “being ‘guv” … eh, wot … today we’re having a posting catch up with all the parents and PHP tool child allowing for some CSS styling to be a possibility with the web applications around the theme of “Emoji Borders and Backgrounds”, onto yesterday’s Emoji Borders and Backgrounds in Canvas Tutorial.
And so wotwhat’s the go with styling in SVG “land”? Is SVG classy? It’s not that much different to HTML and CSS, in that “style” elements are allowed, and SVG allows you to define a “class” attribute for SVG elements, so that’s kind of classy … eh, wot, ‘guv?! Thanks to this great link for the heads up on this.
… to add the means by which the SVG’s optional “style” elements be populated, leaving it up to the various parents to inform the users of the possibilities here.
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&css=opacity:0.9;&textcss=font-size:20px;
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;
Yesterday’s (third parent (to our PHP tool) “cab off the rank”) SVG -> IMG -> CANVAS changed PHPcanvas_svg.phplive run now prompts …
Please enter comma separated HTML decimal entity(s) for your Emoji Border to graphics. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &iurl=[newImageURL] to change base image. Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;
Can we start with SVG+XML data and get to populate CANVAS data via IMG data via data URIs? Well, not everything works, but enough works to have a lot of what you’d want to do “in this neck of the woods” be possible.
<?php
var svg = document.querySelector('svg');
var img = document.querySelector('img');
var canvas = document.querySelector('canvas');
// get svg data
var xml = new XMLSerializer().serializeToString(svg);
//alert(xml);
// make it base64
var svg64 = ''; //btoa(xml);
var b64Start = ''; //'data:image/svg+xml;base64,';
Well, it’s our “second cab off the rank” regarding a parent idea to oversee our current PHP tool idea for Emoji Borders and Backgrounds.
Anything new? Well, yes, quite a big concept too. With our PHP tool, today, we are allowing it, for a PHP parent (today’s changedimagegridmap.php‘s live run), to fill in a …
It meant a division of two “threads” of modus operandi (possible by “overriding” the PHP echo function into an inhouse “ourecho” (wrapper style of) function), now, for our changedinline_svg.php PHP tool’s PHP tool live run …
“Inhouse Slideshow” functionality can not avoid the serverside PHP (ie. the changedindex.php PHP clone “original” and clone) in all its aspects, and so we still need …
for your more ephemeral “clientside only” tweaks we’ve started, today, with inhouse_slideshow.js to use Javascript junction “overrides” (of PHP Javascript ones above) are possible as a “single external Javascript code file” maintenance ongoing possibility for “Inhouse Slideshow” functionality …
// inhouse_slideshow.js
// RJM Programming
// January, 2022
// Help out with ephemeral aspects to Inhouse Slideshow PHPs
function changeto(tvis) {
if (tvis.toLowerCase().indexOf('exif') == 0) {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?exif=y');
} else {
location.href=posturl(document.URL.split('#')[0].replace(/pdf\=/g, 'pdTf=') + '&exif=y');
}
} else if (tvis.toLowerCase().indexOf('pdf') == 0) {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?pdf=y');
} else {
location.href=posturl(document.URL.split('#')[0].replace(/exif\=/g, 'exTif=') + '&pdf=y');
}
} else if (tvis.toLowerCase().indexOf('emoji') == 0) {
//var borderis=prompt('Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry.', '');
borderblurb='Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control=space for iOS, top left + for Android keyboard). ';
var borderis=prompt(borderblurb, '');
var emojiy='';
if (borderis == null) { borderis=''; } else { borderis=postbb(borderis); }
if (borderis != '') { emojiy='emoji=' + encodeURIComponent(borderis); }
if (emojiy != '') {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?' + emojiy);
} else {
location.href=posturl(document.URL.split('#')[0].replace(/emoji\=/g, 'emojTi=') + '&' + emojiy);
}
}
} else {
if (document.URL.indexOf('exif=') != -1 || document.URL.indexOf('pdf=') != -1) {
location.href=posturl(document.URL.split('#')[0].replace(/exif\=/g, 'exTif=').replace(/pdf\=/g, 'pdTf='));
} else {
location.href=posturl(document.URL.split('#')[0] + '&eHuhxif=y');
}
}
}
… including that one change to Javascript prompt popup window wording as an example of an ephemeral “clientside only” tweak … becomes a possibility (which is optional … ie. the PHP won’t fail if such an external Javascript does not exist, as those of you actively trying our guinea pig Inhouse Slideshow yesterday might attest to?!)
… the functionalities that would be “cool” at the HTML/Javascript/CSS parent side, and then work out how to implement similar functionality, as possible, in SVG, and if possible, we should be able to pass arguments over to the “PHP tool” to eventually code it to be standalone to help other “parenting arrangements”.
… today’s “theme” concerns the first of those other “parenting arrangements” mentioned above, our PHP for Inhouse Slideshow presentation display options …
… the new “Emoji Border Slideshow” display option above calling into play our inline_svg.php PHP tool’s live run (“Are we there yet, as a tool, I mean … Mum … Dad … anyone?”) web application.
And in so doing, to use an Emoji Menu methodology of selecting your emoji border decoration is “right up your street, Inhouse Slideshow supervisor”.
… into the mix. Why? Well, perhaps, first off, you should read some history of this “Inhouse Slideshow” project over time at Inhouse Slideshow Temporary Unzip Tutorial and then see that this “external Javascript lark” could be better for a way to “future proof” the venture, with some improvements being changeable through one (into your chosen Document Root folder, wherever that may be (that is what the leading “/” infers)) external Javascript codefile rather than a myriad number of identical PHP codefiles.
Emoji Borders and Backgrounds via Emoji Menu Tutorial
On this macOS MacBook Air we’re used to …
control-command-space
… bringing up an Emoji Menu from which an emoji can be selected and placed wherever the cursor had been placed before that menu display. That could be …
on an address bar where the cursor is placed
in a Javascript prompt window that is focussed
… both scenarios (amongst many others, no doubt) of which we will be interested with our current Emoji Borders and Background web application project. Today’s work develops our PHP tool ahead of its supervisory web application, and so we are interested in the first scenario above, as far as testing it goes with our changed underlyinginline_svg.php PHP tool live run web application.
The argument “text” is already catered for from yesterday but the nature of the data this $_GET[‘text’] might contain had not catered for …
unicode data (via Emoji Menus) … but rather had catered for …
Javascript call of String.fromCodePoint([comma separated list of HTML Decimal Entity(s)]);
… only, as of yesterday’s Emoji Borders and Backgrounds Image Text PHP SVG Tutorial. As you would probably concur, yesterday’s setup was quite user unfriendly, as so many of us now are used to those Emoji Menus being used to fill in your emoji data requirements.
The main gist of the PHP code changes goes …
<?php
$innards='';
$preinnards='';
function ingp($m) { // thanks to https://pretagteam.com/question/how-do-i-convert-unicode-special-characters-to-html-entities
global $innards, $preinnards;
if ($innards != '') {
$entity = preg_replace_callback('/[\x{80}-\x{10FFFF}]/u', function ($m) {
$char = current($m);
$utf = iconv('UTF-8', 'UCS-4', $char);
return sprintf("%s;", ltrim(strtoupper(bin2hex($utf)), "0"));
}, $innards);
$preinnards=htmlentities($entity);
$innards='';
}
}
// And then later we change ...
if (isset($_GET['insvg'])) {
$innards=str_replace('+','',urldecode($_GET['insvg']));
if (trim(str_replace(',','',str_replace('0','',str_replace('1','',str_replace('2','',str_replace('3','',str_replace('4','',str_replace('5','',str_replace('6','',str_replace('7','',str_replace('8','',str_replace('9','',$innards)))))))))))) != '') {
ingp($innards);
}
if ($preinnards == '') {
$preinnards='&#' . str_replace(',',';&#',$innards) . ';';
}
// rest of if block code uses $preinnards as SVG text innerHTML ... but UTF-16 Surrogate pair scenarios can fail
}
emoji border … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
emoji background … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
centralized text (in foreground) … now with wording control via HTML span contenteditable=true elements … not yet argumented to PHP tool
<?php
if (isset($_GET['text'])) {
$txt=str_replace("\n","<br>", str_replace(' ',' ',str_replace('+', ' ', urldecode($_GET['text']))));
$minus30=($w / 2.0) - strlen(explode('<br>', $txt)[0]) * 3.1;
$top30=($h / 2.0) + 25 - (sizeof(explode('<br>', $txt)) * 8);
$lines=explode('<br>', $txt);
for ($il=0; $il<sizeof($lines); $il++) {
$textcontent.='<text x="' . $minus30 . '" y="' . $top30 . '">' . $lines[$il] . '</text>';
$top30+=15;
}
} else if (isset($_POST['text'])) {
$txt=str_replace("\n","<br>", str_replace(' ',' ',str_replace('+', ' ', urldecode($_POST['text']))));
$minus30=($w / 2.0) - strlen(explode('<br>', $txt)[0]) * 3.1;
$top30=($h / 2.0) + 25 - (sizeof(explode('<br>', $txt)) * 8);
$lines=explode('<br>', $txt);
for ($il=0; $il<sizeof($lines); $il++) {
$textcontent.='<text x="' . $minus30 . '" y="' . $top30 . '">' . $lines[$il] . '</text>';
$top30+=15;
}
}
?>
centralized image (in foreground) … including some width and height control … argumented to PHP tool
… via a new “text” argument arranged for the PHP and in readiness for some more aesthetic improvements in the display side of things with our emoji borders and backgrounds changed underlyinginline_svg.php PHP tool live run web application (or in iframe).
… partnership during testing. Our final aim is to make the “underlying PHP” a proper standalone tool, but “that’s a ways off”, as they say. Why this extra level of complication? It’s easier to …
see
test
debug (via web browser web inspectors)
… the functionalities that would be “cool” at the HTML/Javascript/CSS parent side, and then work out how to implement similar functionality, as possible, in SVG, and if possible, we should be able to pass arguments over to the “PHP tool” to eventually code it to be standalone to help other “parenting arrangements”.
And so, today, we “get functional” the combination of parental control through to PHP SVG child display …
Optionally enter an image URL ( as needs be, suffix by &width=[preferredWidth]&height=[preferredHeight] and/or &background=y ) and/or # prefixed comma separated list of emoji HTML decimal Entity(s) ( eg. #127462,127465 ) ? Cancel if it is wording you want to change to the left there.
emoji border … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
emoji background … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
centralized text (in foreground) … now with wording control via HTML span contenteditable=true elements … not yet argumented to PHP tool
centralized image (in foreground) … including some width and height control … argumented to PHP tool
function ask(sois) {
var huhi=prompt('Optionally enter an image URL ( as needs be, suffix by &width=[preferredWidth]&height=[preferredHeight] and/or &background=y ) and/or # prefixed comma separated list of emoji HTML decimal Entity(s) ( eg. #127462,127465 ) ? Cancel if it is wording you want to change to the left there.','');
if (huhi == null) { huhi=''; }
if (huhi.trim() != '') {
if (document.URL.indexOf('rjmprogramming.com.au') == -1 && sois.title.indexOf('rjmprogramming.com.au') != -1) {
sois.title=document.URL.substring(0,8) + document.URL.substring(8).split('/')[0] + sois.title.split('rjmprogramming.com.au')[1];
}
if (huhi.indexOf('#') != -1) {
var huhis=huhi.split('#')[1];
for (var ihuhis=0; ihuhis<huhis.length; ihuhis++) {
if (eval('' + ihuhis) < eval('' + huhis.length)) {
if (huhis.substring(ihuhis).substring(0,1).replace('0','').replace('1','').replace('2','').replace('3','').replace('4','').replace('5','').replace('6','').replace('7','').replace('8','').replace('9','').replace(',','') != '') {
huhi=huhi.replace('#' + huhis.split(huhis.substring(ihuhis).substring(0,1))[0], '');
huhis=huhis.split(huhis.substring(ihuhis).substring(0,1))[0];
}
}
}
if (huhis == '') {
if (sois.title.indexOf('?insvg=') != -1) {
sois.title=sois.title.replace('?insvg=' + sois.title.split('?insvg=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&insvg=') != -1) {
sois.title=sois.title.replace('&insvg=' + sois.title.split('&insvg=')[1].split('&')[0].split('#')[0],'');
}
} else if (sois.title.indexOf('?insvg=') != -1) {
sois.title=sois.title.replace('?insvg=' + sois.title.split('?insvg=')[1].split('&')[0].split('#')[0],'?insvg=' + encodeURIComponent(huhis));
} else if (sois.title.indexOf('&insvg=') != -1) {
sois.title=sois.title.replace('&insvg=' + sois.title.split('&insvg=')[1].split('&')[0].split('#')[0],'&insvg=' + encodeURIComponent(huhis));
} else if (sois.title.indexOf('?') != -1) {
sois.title=sois.title.replace('?','?insvg=' + encodeURIComponent(huhis) + '&');
} else {
sois.title=sois.title.split('#')[0] + '?insvg=' + encodeURIComponent(huhis);
}
}
if (huhi.split('&')[0].split('#')[0].trim() != '') {
if (sois.title.indexOf('?image=') != -1) {
sois.title=sois.title.replace('?image=' + sois.title.split('?image=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&image=') != -1) {
sois.title=sois.title.replace('&image=' + sois.title.split('&image=')[1].split('&')[0].split('#')[0],'');
}
sois.title+='&image=' + encodeURIComponent(huhi.split('&')[0]) + huhi.replace(huhi.split('&')[0],'');
} else if (sois.title.indexOf('?image=') != -1) {
sois.title=sois.title.replace('?image=' + sois.title.split('?image=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&image=') != -1) {
sois.title=sois.title.replace('&image=' + sois.title.split('&image=')[1].split('&')[0].split('#')[0],'');
}
document.getElementById(sois.id.replace('span','if')).src=sois.title; //+='&image=' + encodeURIComponent(huhi.split('&')[0]) + huhi.replace(huhi.split('&')[0],'');
}
}
function snapshot(sio) {
lastih=sio.innerHTML;
lastio=-1;
for (var iuh=0; iuh<cds.length; iuh++) {
if (lastih == cds[iuh]) { lastio=iuh; } else if (sio.innerHTML.indexOf(' of ') != -1) { if (lastih.split(' of ')[0] == cds[iuh].split(' of ')[0]) { lastio=iuh; } }
}
}
It’s all fine and good creating the Emoji Borders and Backgrounds of yesterday’s Emoji Borders and Backgrounds Primer Tutorial, but it’s the context of their use that we are starting to take an interest in with today’s …
“making use of” “proof of concept” emoji_border_background.htmllive run link for you to contextualize and make use of those table’s iframe contents from yesterday …
… as we figure out, perhaps, some better “tool like generics” here. We’ll see (we hope)!
But, so far, how would we assess the approach, here? Well, what we had to do today reminded us a lot of what we do here, often, at this blog, when we talk about “overlay” webpage design approaches. CSS position:absolute and opacity and Javascript [element].getBoundingClientRect() all made guest appearances!
Yesterday’s CSS 3D Transform Rotations Tutorial was interfacing to CSS 3D transform rotations, sure, but there is room for more sophistication regarding …
multiple rotation CSS styling axis definitions … meaning …
context
order
… can be harnessed to create a myriad more of display possibilities (where different results can happen regarding the order an axis rotation comes in your “up to three” parts to the complete CSS styling rotation definition), among the three X or/and Y or/and Z axis rotation choices.
To allow for this, we …
retain the one display change intervention point as the onchange event of the leftmost select (ie. dropdown) element … but …
if the number of axis rotations is larger than one, utilize a Javascript prompt window to allow for the larger than one number of degree rotations that can come into play …
function anal(osel) {
var newval='', pmore='', pblurb='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + document.getElementById('degval').value + 'deg) ' + pmore + '; </style>';
var sugblurb=') rotateY(' + document.getElementById('degval').value + 'deg) rotateZ(' + document.getElementById('degval').value + 'deg)';
if (osel.value == 'X') {
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + document.getElementById('degval').value + 'deg); } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'Y') {
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + document.getElementById('degval').value + 'deg); } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'Z') {
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + document.getElementById('degval').value + 'deg); } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XY') {
pblurb=pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','Y').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XZ') {
pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','Z').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YX') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','X').split(' r')[0];
pmore=prompt('Please enter 3D rotation in X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YZ') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','Z').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZX') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Y','X').split(' r')[0];
pmore=prompt('Please enter 3D rotation in X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZY') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Y','Y').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + document.getElementById('degval').value + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XYZ') {
pblurb=pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','Y').replace('Z','Z');
pmore=prompt('Please enter 3D rotations in Y,Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XZY') {
pblurb=pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','@').replace('Z','Y').replace('@','Z');
pmore=prompt('Please enter 3D rotations in Z,Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YXZ') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','X');
pmore=prompt('Please enter 3D rotations in X,Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YZX') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','@').replace('Z','X').replace('@','Z');
pmore=prompt('Please enter 3D rotations in Z,X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + ')', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + ')', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZXY') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Y','@').replace('Z','Y').replace('@','X');
pmore=prompt('Please enter 3D rotations in X,Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZYX') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Z','X');
pmore=prompt('Please enter 3D rotations in Y,X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
}
if (newval != '') { document.getElementById('degval').value=newval.split('.')[0]; }
}
Regarding the recent CSS Outline and Background Tutorial‘s “Outline & Background” web application, and it’s “iframe” try below modes of use, we wondered, being a bit in awe of what CSS can achieve these days in the category of …
… to confirm our initial thoughts on this, those being “not by itself” … which of course means … that 🄲 t-shirt … we’ll be having to pack away for now again.
But we followed that link’s advice quite closely (as well as being more diligent adding that trailing ? question mark … just in cases), affecting that “Outline & Background” web application’s layout via …
… to add more dropdown styling options into the mix (inspired a lot by this Google search, thanks) where the “outline” concept may have a role in amongst “border” and “background” concept webpage CSS styling ideas.
The CSS “border” emphasis of the previous Emoji Borders and Backgrounds Canvas Annotation Tutorial has concepts, we see online, confusing people, and myself, regarding what the CSS “outline” feature is capable of (or not capable of). Here is W3school‘s pertinent paragraph on this …
Note: Outline differs from borders! The outline is drawn outside the element’s border, and may overlap other content. Also, the outline is NOT a part of the element’s dimensions; the element’s total width and height is not affected by the width of the outline.
The CSS “outline” concept is not the panacea to as many web design requirements as the “border” concept is. For instance, even seeing within the purview of making our “proof of concept” web application …
no linear gradients can be worked in the “outline” realm
no such properties as “outline-top” or “outline-left” or “outline-bottom” or “outline-right” exist within the “outline” realm
no such property as “outline-radius” (though will mimic any roundedness applied to border)
no outline images in the “outline” realm
If we were to summarize, the CSS “outline” concept’s talents can lie with …
being around an HTML element (and not part of it … perhaps in web design, useful as “a place of rest” (including non-mobile on hover element title displays) for users?!)
decorative colour around an HTML element (perhaps to get the user’s attention to hone in on that element, or perhaps a dynamic conduit towards “thickening” an existant HTML element border (especially as Javascript DOM such as [element].style.outline=’2px solid green’; // is available to programmers))
can form a replacement nesting HTML element background colour means
in it’s simplest CSS syntax ( eg: outline: 2px solid green; ) can be easily remembered next to the simplest syntax of border (probably very familiar to you) CSS syntax ( eg: border: 2px solid green; ) … just differently located on the webpage
… contents in synch as far as looks go. That ignores the reason CANVAS (element) was invented when HTML5 came out. It was invented to not only contain image graphical data, but be able to amend that data. So we also allow it with our web application from today on, integrating with our inhouse “User of Signature” web application last talked about at Local Fonts Revisited Middle Tutorial, to amend (initially image via [canvas].toDataURL(‘image/png’) via SVG streams of data which may include emoji borders and backgrounds) graphical data.
We integrate via a same domain window.open scenario. Before you all start groaning, consider the advantages of a …
… albeit non-mobile window.open (ie. popup window) call. Not only are you …
(on non-mobile) seeing two windows on top of each other … but …
the “window.opener” (acting like “parent” does for an “iframe” arrangement) reference can have you, via Javascript DOM, share the data of the popup window canvas element with that of the “window.opener” (window) canvas element
… and then, we arrange for a “reset” (to ignore these annotation changes), via the “middle-element” IMG element, should the “Undo” functionality of our HTML changeduser_of_signature_signature.html‘s User of Signature Signature (standalone) live run not be enough flexibility to the functionality, which has a new document.body onload event triggering of Javascript function cancontlook below …
var cancont='';
var cancontw=-1, canconth=-1;
if (('' + window.opener).replace('null','') != '') {
var cans=window.opener.document.getElementsByTagName('canvas');
if (cans.length > 0) { cancont=cans[0].toDataURL('image/png'); cancontw=cans[0].width; canconth=cans[0].height; }
}
function cancontlook() {
if (cancont != '') { // called via SVG - IMG - CANVAS
celem=document.getElementById('topcanvas');
ccontext = celem.getContext("2d");
celem.width=cancontw;
celem.height=canconth;
cimg=new Image;
cimg.onload = function(){
ccontext.drawImage(cimg,0,0);
};
cimg.src=cancont;
if (document.getElementById('toptd')) {
document.getElementById('toptd').style.left='' + cancontw + 'px';
var recttoptd=document.getElementById('toptd').getBoundingClientRect();
document.getElementById('topcbutton').innerHTML='⬅';
document.getElementById('topcbutton').style.position='fixed';
document.getElementById('topcbutton').style.top='' + recttoptd.top + 'px';
//document.getElementById('topcbutton').style.left='' + recttoptd.left + 'px';
document.getElementById('topcbutton').style.left='' + eval(0.98 * eval('' + screen.width)) + 'px';
document.getElementById('topcbutton').style.zIndex='89';
document.getElementById('topcbutton').title='Back to SVG - IMG - CANVAS web application caller';
//document.getElementById('topcbutton').onclick=function() { window.opener.focus(); };
}
if (document.getElementById('toppixellate')) {
document.getElementById('toppixellate').style.top='' + canconth + 'px';
}
if (('' + location.hash).replace(/^\#/g,'') != '') {
document.getElementById('topcstyle').innerHTML='
function iysh() {
if (document.getElementById('topcbutton').innerHTML.indexOf(' ') != -1) {
document.getElementById('topcbutton').innerHTML=document.getElementById('topcbutton').innerHTML.replace(' ','');
alert('Please do this manually');
}
}
function woff() {
document.getElementById('topcbutton').innerHTML+=' ';
setTimeout(iysh, 2000);
window.opener.focus();
}
… that might help you “look back at yourself from outside” as we use it to interface to Google PageSpeed Insights webpage screenshot functionality (which can look at a designated URL and effectively screenshot it for you) … thanks.
We used to restrict our curl usage thinking to “only ?” first argument use too, arguing (with ourselves) that the Linux and Unix and macOS and Mac OS X “&” character command line meaning of “process in the background” would be a constraint. Of course it isn’t, because … anyone, anyone? Yes, Henry, you should use a “curl” command line command, using double quotes, of the form …
… and the “&”‘s are understood to be URL “GET” argument delimiters, and not a “process in the background” designator.
And here’s the thing exemplified above. The alternative file_get_contents PHP function cannot do that https: protocol type of URL, yet Google PageSpeed Insights webpage screenshot functionality demands such URLs … hence the “curl” interest.
$extis='.xxx';
if (strpos(('' . $_SERVER['QUERY_STRING']), 'howpagespeedseesme=') !== false) {
if (file_exists('/tmp/')) {
if (file_exists('/tmp/pscs.xxx')) {
unlink('/tmp/pscs.xxx');
}
}
exec($psbig);
while (!file_exists('/tmp/pscs' . $extis)) {
sleep(4);
}
while (filesize('/tmp/pscs' . $extis) == 0) {
sleep(4);
}
$scx=file_get_contents('/tmp/pscs' . $extis);
$scxs=explode('"screenshot":', $scx);
if (sizeof($scxs) > 1) {
$postscxs=explode('"data": ', $scxs[1]);
if (sizeof($postscxs) > 1) {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This ...</h2><img src=' . substr($postscxs[1],0,1) . explode(substr($postscxs[1],0,1), substr($postscxs[1],1))[0] . substr($postscxs[1],0,1) . '></img></body></html>';
} else {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This ...</h2><p>Sorry, resource exhausted. Could try again later.</p></body></html>';
}
} else {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This</h2><p>Sorry, resource exhausted. Could try again later.</p></body></html>';
}
exit;
}
?>
… working with the new HTML div <div id=readyforiframe></div> element, along with <span title=’Google PageSpeed Insights webpage screenshot view of this web browser address URL’ onclick=’psit();’> 📸 </span> 📸 “emoji button” in the HTML static code … with associated Javascript function …
Emoji Borders and Backgrounds Web Browser Tutorial
Yesterday’s Emoji Borders and Backgrounds Shape Sharing Tutorial had us sharing via email or SMS our “Emoji Borders and Backgrounds” creations via inhouse organized arrangements. But many people are used to just right-clicking (for Windows) and two finger gesturing (for macOS and Mac OS X) on …
SVG
IMG
CANVAS
… graphical elements, which can be made to “look” the same, and sort of “suck it and see” as far as menu options presented, helping them out sharing graphical information. In many cases, users don’t care what form of element the image comes contained in. But, if you involve “background-image” CSS along the way to achieve a (consistent) “look”, as we had done before today, (some of) the output of those menu options could be lacking (because they look for “foreground data”), and so we do away with the need for a “background-image” …
<?php
function ctoilater() {
img.src=canvas.toDataURL('data/png');
}
An example of how having web browser (right-clicking (for Windows) and two finger gesturing (for macOS and Mac OS X)) menu options be useful, consider an image menu option such as “Copy image” be used by the user. The user can compose their own (email client (or get to email client via all uppercase web application “to” email “address” definition)) email then, and just Edit -> Paste the results, as an image, into the email body, ahead of sending off that email.
Emoji Borders and Backgrounds Shape Sharing Tutorial
The code “shape shifting” of recent times morphs into “shape sharing” together in amongst the parent users of our PHP tool “Emoji Borders and Backgrounds” web application featuring in yesterday’s Emoji Borders and Backgrounds Shape Numerics Tutorial.
We found the “SVG+XML” mimetype data not accepted by Gmail for an Inline HTML Email, so we have coded for the Downloadable HTML Attachment “way to go”.
<?php
function emailit() {
var fbit='';
var tois=prompt('Please enter an email address to email to (all uppercase uses email client rather than PHP mail and all numerical sends an SMS).','');
if (tois == null) { tois=''; }
if (tois.trim() != '') {
if (tois.indexOf('@') != -1) {
if (tois.toUpperCase() == tois) {
document.getElementById('divemail').innerHTML='<a id=aemail style=display:none; href=mailto:' + tois + '?subject=My%20Emoji%20Border%20and%20Background%20Creation&body=' + encodeURIComponent(document.URL) + '>Email</a>';
//fbit=('' + document.getElementById('aemail').href).split('?')[1];
//document.getElementById('aemail').href='mailto:' + tois + '?' + fbit;
document.getElementById('aemail').click();
} else {
var zhr = new XMLHttpRequest();
var zform=new FormData();
if (1 == 2) { zform.append('inline', ''); }
zform.append('to', tois);
zform.append('subj', 'My Emoji Borders and Background Creation ... at [date] ...');
//alert(encodeURIComponent('<html><body><img src=\"<?php echo $bemb; ?>\"></img></body></html>'));
zform.append('tdhuhta', encodeURIComponent('<html>' + '<?php echo $headstyle; ?>' + '<body><img src="<?php echo $bemb; ?>"></img></body></html>'));
zhr.open('post', '//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php', true);
zhr.send(zform);
alert('Email sent to ' + tois);
}
} else if (tois.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') == '') {
document.getElementById('divsms').innerHTML='<a id=asms style=display:none; href=sms:' + tois + '&body=' + encodeURIComponent(document.URL) + '>SMS</a>';
//document.getElementById('asms').href='sms:' + tois + '&body=' + encodeURIComponent(document.URL);
document.getElementById('asms').click();
}
}
}
Emoji Borders and Backgrounds Shape Numerics Tutorial
If you are familiar with the geometry of shapes, it is full of numbers, with the implications as to how the shape is represented and displayed, that those numbers can affect. And so, onto yesterday’s Emoji Borders and Backgrounds Shapes Tutorial‘s start with …
SVG ellipse element functionality today … and for all these, as well as the …
SVG text element we start allowing “shape numerics” as being a user definable thaing
These “shape numerics” can help the user control (that SVG element’s) …
position
size
opacity
font size … (for text elements) on top of that non-numeric control yesterday’s work gave us, being (that SVG element’s fill) …
colour
This is all handled, still, within that “image” argument definition, and we allow a decimal (ie. “.”) delimiter be the way a user separates their integer values (where an opacity value becomes “0.” + [integerValue]).
Onto yesterday’s Emoji Borders and Backgrounds Text Justification Tutorial we add some consideration of SVG shape creations into the mix of the Emoji Borders and Backgrounds work, starting just with the PHP tool, at this stage, and just considering …
… to start off with, and feeding off yesterday’s …
width=[designatedPxWidth] and height=[designatedPxHeight] … and/or …
image=[someImageUrl] (width and height)
… breakdown as to how a user can define a box of interest, as a great “line in the sand” for us to work around with this new “Shapes functionality”. It’s an interfacing job, for tomorrow, getting parents to work with this “image” argument based way a user can define these shapes, including a “noimage” option that uses an image’s width and height (to help out with the shape definition) but does not display that image.
Along the way we also mildly rearrange PHP code for inline_svg.php‘s live run so as to allow for more than one user text to be added via justification prefixing methodologies.
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&css=opacity:0.9;&textcss=font-size:20px;&ultext=Hello%0AThere
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;&ultext=Hello%0AThere
Day before yesterday’s (third parent (to our PHP tool) “cab off the rank”) SVG -> IMG -> CANVAS changed PHPcanvas_svg.phplive run now prompts …
Please enter comma separated HTML decimal entity(s) for your Emoji Border to graphics. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &iurl=[newImageURL] to change base image. Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;&ultext=Hello%0AThere
… via a new “text” argument arranged for the PHP and in readiness for some more aesthetic improvements in the display side of things with our emoji borders and backgrounds
Well, what gives? Eh, wot’s up ‘guv? Yes, indeed … all we can say is …
We got sidetracted.
… and applying spell checker to get around an expression that amuses us …
We got sidetracked.
So, “being ‘guv” … eh, wot … today we’re having a posting catch up with all the parents and PHP tool child allowing for some CSS styling to be a possibility with the web applications around the theme of “Emoji Borders and Backgrounds”, onto yesterday’s Emoji Borders and Backgrounds in Canvas Tutorial.
And so wotwhat’s the go with styling in SVG “land”? Is SVG classy? It’s not that much different to HTML and CSS, in that “style” elements are allowed, and SVG allows you to define a “class” attribute for SVG elements, so that’s kind of classy … eh, wot, ‘guv?! Thanks to this great link for the heads up on this.
… to add the means by which the SVG’s optional “style” elements be populated, leaving it up to the various parents to inform the users of the possibilities here.
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&css=opacity:0.9;&textcss=font-size:20px;
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;
Yesterday’s (third parent (to our PHP tool) “cab off the rank”) SVG -> IMG -> CANVAS changed PHPcanvas_svg.phplive run now prompts …
Please enter comma separated HTML decimal entity(s) for your Emoji Border to graphics. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &iurl=[newImageURL] to change base image. Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;
Can we start with SVG+XML data and get to populate CANVAS data via IMG data via data URIs? Well, not everything works, but enough works to have a lot of what you’d want to do “in this neck of the woods” be possible.
<?php
var svg = document.querySelector('svg');
var img = document.querySelector('img');
var canvas = document.querySelector('canvas');
// get svg data
var xml = new XMLSerializer().serializeToString(svg);
//alert(xml);
// make it base64
var svg64 = ''; //btoa(xml);
var b64Start = ''; //'data:image/svg+xml;base64,';
Well, it’s our “second cab off the rank” regarding a parent idea to oversee our current PHP tool idea for Emoji Borders and Backgrounds.
Anything new? Well, yes, quite a big concept too. With our PHP tool, today, we are allowing it, for a PHP parent (today’s changedimagegridmap.php‘s live run), to fill in a …
It meant a division of two “threads” of modus operandi (possible by “overriding” the PHP echo function into an inhouse “ourecho” (wrapper style of) function), now, for our changedinline_svg.php PHP tool’s PHP tool live run …
“Inhouse Slideshow” functionality can not avoid the serverside PHP (ie. the changedindex.php PHP clone “original” and clone) in all its aspects, and so we still need …
for your more ephemeral “clientside only” tweaks we’ve started, today, with inhouse_slideshow.js to use Javascript junction “overrides” (of PHP Javascript ones above) are possible as a “single external Javascript code file” maintenance ongoing possibility for “Inhouse Slideshow” functionality …
// inhouse_slideshow.js
// RJM Programming
// January, 2022
// Help out with ephemeral aspects to Inhouse Slideshow PHPs
function changeto(tvis) {
if (tvis.toLowerCase().indexOf('exif') == 0) {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?exif=y');
} else {
location.href=posturl(document.URL.split('#')[0].replace(/pdf\=/g, 'pdTf=') + '&exif=y');
}
} else if (tvis.toLowerCase().indexOf('pdf') == 0) {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?pdf=y');
} else {
location.href=posturl(document.URL.split('#')[0].replace(/exif\=/g, 'exTif=') + '&pdf=y');
}
} else if (tvis.toLowerCase().indexOf('emoji') == 0) {
//var borderis=prompt('Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry.', '');
borderblurb='Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control=space for iOS, top left + for Android keyboard). ';
var borderis=prompt(borderblurb, '');
var emojiy='';
if (borderis == null) { borderis=''; } else { borderis=postbb(borderis); }
if (borderis != '') { emojiy='emoji=' + encodeURIComponent(borderis); }
if (emojiy != '') {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?' + emojiy);
} else {
location.href=posturl(document.URL.split('#')[0].replace(/emoji\=/g, 'emojTi=') + '&' + emojiy);
}
}
} else {
if (document.URL.indexOf('exif=') != -1 || document.URL.indexOf('pdf=') != -1) {
location.href=posturl(document.URL.split('#')[0].replace(/exif\=/g, 'exTif=').replace(/pdf\=/g, 'pdTf='));
} else {
location.href=posturl(document.URL.split('#')[0] + '&eHuhxif=y');
}
}
}
… including that one change to Javascript prompt popup window wording as an example of an ephemeral “clientside only” tweak … becomes a possibility (which is optional … ie. the PHP won’t fail if such an external Javascript does not exist, as those of you actively trying our guinea pig Inhouse Slideshow yesterday might attest to?!)
… the functionalities that would be “cool” at the HTML/Javascript/CSS parent side, and then work out how to implement similar functionality, as possible, in SVG, and if possible, we should be able to pass arguments over to the “PHP tool” to eventually code it to be standalone to help other “parenting arrangements”.
… today’s “theme” concerns the first of those other “parenting arrangements” mentioned above, our PHP for Inhouse Slideshow presentation display options …
… the new “Emoji Border Slideshow” display option above calling into play our inline_svg.php PHP tool’s live run (“Are we there yet, as a tool, I mean … Mum … Dad … anyone?”) web application.
And in so doing, to use an Emoji Menu methodology of selecting your emoji border decoration is “right up your street, Inhouse Slideshow supervisor”.
… into the mix. Why? Well, perhaps, first off, you should read some history of this “Inhouse Slideshow” project over time at Inhouse Slideshow Temporary Unzip Tutorial and then see that this “external Javascript lark” could be better for a way to “future proof” the venture, with some improvements being changeable through one (into your chosen Document Root folder, wherever that may be (that is what the leading “/” infers)) external Javascript codefile rather than a myriad number of identical PHP codefiles.
Emoji Borders and Backgrounds via Emoji Menu Tutorial
On this macOS MacBook Air we’re used to …
control-command-space
… bringing up an Emoji Menu from which an emoji can be selected and placed wherever the cursor had been placed before that menu display. That could be …
on an address bar where the cursor is placed
in a Javascript prompt window that is focussed
… both scenarios (amongst many others, no doubt) of which we will be interested with our current Emoji Borders and Background web application project. Today’s work develops our PHP tool ahead of its supervisory web application, and so we are interested in the first scenario above, as far as testing it goes with our changed underlyinginline_svg.php PHP tool live run web application.
The argument “text” is already catered for from yesterday but the nature of the data this $_GET[‘text’] might contain had not catered for …
unicode data (via Emoji Menus) … but rather had catered for …
Javascript call of String.fromCodePoint([comma separated list of HTML Decimal Entity(s)]);
… only, as of yesterday’s Emoji Borders and Backgrounds Image Text PHP SVG Tutorial. As you would probably concur, yesterday’s setup was quite user unfriendly, as so many of us now are used to those Emoji Menus being used to fill in your emoji data requirements.
The main gist of the PHP code changes goes …
<?php
$innards='';
$preinnards='';
function ingp($m) { // thanks to https://pretagteam.com/question/how-do-i-convert-unicode-special-characters-to-html-entities
global $innards, $preinnards;
if ($innards != '') {
$entity = preg_replace_callback('/[\x{80}-\x{10FFFF}]/u', function ($m) {
$char = current($m);
$utf = iconv('UTF-8', 'UCS-4', $char);
return sprintf("%s;", ltrim(strtoupper(bin2hex($utf)), "0"));
}, $innards);
$preinnards=htmlentities($entity);
$innards='';
}
}
// And then later we change ...
if (isset($_GET['insvg'])) {
$innards=str_replace('+','',urldecode($_GET['insvg']));
if (trim(str_replace(',','',str_replace('0','',str_replace('1','',str_replace('2','',str_replace('3','',str_replace('4','',str_replace('5','',str_replace('6','',str_replace('7','',str_replace('8','',str_replace('9','',$innards)))))))))))) != '') {
ingp($innards);
}
if ($preinnards == '') {
$preinnards='&#' . str_replace(',',';&#',$innards) . ';';
}
// rest of if block code uses $preinnards as SVG text innerHTML ... but UTF-16 Surrogate pair scenarios can fail
}
emoji border … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
emoji background … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
centralized text (in foreground) … now with wording control via HTML span contenteditable=true elements … not yet argumented to PHP tool
<?php
if (isset($_GET['text'])) {
$txt=str_replace("\n","<br>", str_replace(' ',' ',str_replace('+', ' ', urldecode($_GET['text']))));
$minus30=($w / 2.0) - strlen(explode('<br>', $txt)[0]) * 3.1;
$top30=($h / 2.0) + 25 - (sizeof(explode('<br>', $txt)) * 8);
$lines=explode('<br>', $txt);
for ($il=0; $il<sizeof($lines); $il++) {
$textcontent.='<text x="' . $minus30 . '" y="' . $top30 . '">' . $lines[$il] . '</text>';
$top30+=15;
}
} else if (isset($_POST['text'])) {
$txt=str_replace("\n","<br>", str_replace(' ',' ',str_replace('+', ' ', urldecode($_POST['text']))));
$minus30=($w / 2.0) - strlen(explode('<br>', $txt)[0]) * 3.1;
$top30=($h / 2.0) + 25 - (sizeof(explode('<br>', $txt)) * 8);
$lines=explode('<br>', $txt);
for ($il=0; $il<sizeof($lines); $il++) {
$textcontent.='<text x="' . $minus30 . '" y="' . $top30 . '">' . $lines[$il] . '</text>';
$top30+=15;
}
}
?>
centralized image (in foreground) … including some width and height control … argumented to PHP tool
… via a new “text” argument arranged for the PHP and in readiness for some more aesthetic improvements in the display side of things with our emoji borders and backgrounds changed underlyinginline_svg.php PHP tool live run web application (or in iframe).
… partnership during testing. Our final aim is to make the “underlying PHP” a proper standalone tool, but “that’s a ways off”, as they say. Why this extra level of complication? It’s easier to …
see
test
debug (via web browser web inspectors)
… the functionalities that would be “cool” at the HTML/Javascript/CSS parent side, and then work out how to implement similar functionality, as possible, in SVG, and if possible, we should be able to pass arguments over to the “PHP tool” to eventually code it to be standalone to help other “parenting arrangements”.
And so, today, we “get functional” the combination of parental control through to PHP SVG child display …
Optionally enter an image URL ( as needs be, suffix by &width=[preferredWidth]&height=[preferredHeight] and/or &background=y ) and/or # prefixed comma separated list of emoji HTML decimal Entity(s) ( eg. #127462,127465 ) ? Cancel if it is wording you want to change to the left there.
emoji border … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
emoji background … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
centralized text (in foreground) … now with wording control via HTML span contenteditable=true elements … not yet argumented to PHP tool
centralized image (in foreground) … including some width and height control … argumented to PHP tool
function ask(sois) {
var huhi=prompt('Optionally enter an image URL ( as needs be, suffix by &width=[preferredWidth]&height=[preferredHeight] and/or &background=y ) and/or # prefixed comma separated list of emoji HTML decimal Entity(s) ( eg. #127462,127465 ) ? Cancel if it is wording you want to change to the left there.','');
if (huhi == null) { huhi=''; }
if (huhi.trim() != '') {
if (document.URL.indexOf('rjmprogramming.com.au') == -1 && sois.title.indexOf('rjmprogramming.com.au') != -1) {
sois.title=document.URL.substring(0,8) + document.URL.substring(8).split('/')[0] + sois.title.split('rjmprogramming.com.au')[1];
}
if (huhi.indexOf('#') != -1) {
var huhis=huhi.split('#')[1];
for (var ihuhis=0; ihuhis<huhis.length; ihuhis++) {
if (eval('' + ihuhis) < eval('' + huhis.length)) {
if (huhis.substring(ihuhis).substring(0,1).replace('0','').replace('1','').replace('2','').replace('3','').replace('4','').replace('5','').replace('6','').replace('7','').replace('8','').replace('9','').replace(',','') != '') {
huhi=huhi.replace('#' + huhis.split(huhis.substring(ihuhis).substring(0,1))[0], '');
huhis=huhis.split(huhis.substring(ihuhis).substring(0,1))[0];
}
}
}
if (huhis == '') {
if (sois.title.indexOf('?insvg=') != -1) {
sois.title=sois.title.replace('?insvg=' + sois.title.split('?insvg=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&insvg=') != -1) {
sois.title=sois.title.replace('&insvg=' + sois.title.split('&insvg=')[1].split('&')[0].split('#')[0],'');
}
} else if (sois.title.indexOf('?insvg=') != -1) {
sois.title=sois.title.replace('?insvg=' + sois.title.split('?insvg=')[1].split('&')[0].split('#')[0],'?insvg=' + encodeURIComponent(huhis));
} else if (sois.title.indexOf('&insvg=') != -1) {
sois.title=sois.title.replace('&insvg=' + sois.title.split('&insvg=')[1].split('&')[0].split('#')[0],'&insvg=' + encodeURIComponent(huhis));
} else if (sois.title.indexOf('?') != -1) {
sois.title=sois.title.replace('?','?insvg=' + encodeURIComponent(huhis) + '&');
} else {
sois.title=sois.title.split('#')[0] + '?insvg=' + encodeURIComponent(huhis);
}
}
if (huhi.split('&')[0].split('#')[0].trim() != '') {
if (sois.title.indexOf('?image=') != -1) {
sois.title=sois.title.replace('?image=' + sois.title.split('?image=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&image=') != -1) {
sois.title=sois.title.replace('&image=' + sois.title.split('&image=')[1].split('&')[0].split('#')[0],'');
}
sois.title+='&image=' + encodeURIComponent(huhi.split('&')[0]) + huhi.replace(huhi.split('&')[0],'');
} else if (sois.title.indexOf('?image=') != -1) {
sois.title=sois.title.replace('?image=' + sois.title.split('?image=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&image=') != -1) {
sois.title=sois.title.replace('&image=' + sois.title.split('&image=')[1].split('&')[0].split('#')[0],'');
}
document.getElementById(sois.id.replace('span','if')).src=sois.title; //+='&image=' + encodeURIComponent(huhi.split('&')[0]) + huhi.replace(huhi.split('&')[0],'');
}
}
function snapshot(sio) {
lastih=sio.innerHTML;
lastio=-1;
for (var iuh=0; iuh<cds.length; iuh++) {
if (lastih == cds[iuh]) { lastio=iuh; } else if (sio.innerHTML.indexOf(' of ') != -1) { if (lastih.split(' of ')[0] == cds[iuh].split(' of ')[0]) { lastio=iuh; } }
}
}
It’s all fine and good creating the Emoji Borders and Backgrounds of yesterday’s Emoji Borders and Backgrounds Primer Tutorial, but it’s the context of their use that we are starting to take an interest in with today’s …
“making use of” “proof of concept” emoji_border_background.htmllive run link for you to contextualize and make use of those table’s iframe contents from yesterday …
… as we figure out, perhaps, some better “tool like generics” here. We’ll see (we hope)!
But, so far, how would we assess the approach, here? Well, what we had to do today reminded us a lot of what we do here, often, at this blog, when we talk about “overlay” webpage design approaches. CSS position:absolute and opacity and Javascript [element].getBoundingClientRect() all made guest appearances!
Yesterday’s CSS 3D Transform Rotations Tutorial was interfacing to CSS 3D transform rotations, sure, but there is room for more sophistication regarding …
multiple rotation CSS styling axis definitions … meaning …
context
order
… can be harnessed to create a myriad more of display possibilities (where different results can happen regarding the order an axis rotation comes in your “up to three” parts to the complete CSS styling rotation definition), among the three X or/and Y or/and Z axis rotation choices.
To allow for this, we …
retain the one display change intervention point as the onchange event of the leftmost select (ie. dropdown) element … but …
if the number of axis rotations is larger than one, utilize a Javascript prompt window to allow for the larger than one number of degree rotations that can come into play …
function anal(osel) {
var newval='', pmore='', pblurb='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + document.getElementById('degval').value + 'deg) ' + pmore + '; </style>';
var sugblurb=') rotateY(' + document.getElementById('degval').value + 'deg) rotateZ(' + document.getElementById('degval').value + 'deg)';
if (osel.value == 'X') {
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + document.getElementById('degval').value + 'deg); } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'Y') {
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + document.getElementById('degval').value + 'deg); } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'Z') {
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + document.getElementById('degval').value + 'deg); } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XY') {
pblurb=pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','Y').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XZ') {
pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','Z').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YX') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','X').split(' r')[0];
pmore=prompt('Please enter 3D rotation in X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YZ') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','Z').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZX') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Y','X').split(' r')[0];
pmore=prompt('Please enter 3D rotation in X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZY') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Y','Y').split(' r')[0];
pmore=prompt('Please enter 3D rotation in Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 1) { newval=pmore.split(',')[0]; pmore=pmore.split(',')[eval(-1 + pmore.split(',').length)]; } pmore=sugblurb.substring(1).split(' r')[0].replace(document.getElementById('degval').value, pmore); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + document.getElementById('degval').value + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XYZ') {
pblurb=pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','Y').replace('Z','Z');
pmore=prompt('Please enter 3D rotations in Y,Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'XZY') {
pblurb=pblurb.replace('X','X');
sugblurb=sugblurb.replace('Y','@').replace('Z','Y').replace('@','Z');
pmore=prompt('Please enter 3D rotations in Z,Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateX(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YXZ') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','X');
pmore=prompt('Please enter 3D rotations in X,Z in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'YZX') {
pblurb=pblurb.replace('X','Y');
sugblurb=sugblurb.replace('Y','@').replace('Z','X').replace('@','Z');
pmore=prompt('Please enter 3D rotations in Z,X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + ')', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + ')', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateY(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZXY') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Y','@').replace('Z','Y').replace('@','X');
pmore=prompt('Please enter 3D rotations in X,Y in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
} else if (osel.value == 'ZYX') {
pblurb=pblurb.replace('X','Z');
sugblurb=sugblurb.replace('Z','X');
pmore=prompt('Please enter 3D rotations in Y,X in degrees which if defaulted will result in ... ' + String.fromCharCode(10) + String.fromCharCode(10) + pblurb.replace(')', sugblurb) + String.fromCharCode(10) + String.fromCharCode(10) + ' ... ?', document.getElementById('degval').value + ',' + document.getElementById('degval').value);
if (pmore == null) { pmore=''; } else { if (eval('' + pmore.split(',').length) > 2) { newval=pmore.split(',')[0]; pmore=pmore.replace(pmore.split(',')[0] + ',', ''); } pmore=sugblurb.substring(1).replace(document.getElementById('degval').value + 'deg)', pmore.split(',')[0].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)').replace(document.getElementById('degval').value + 'deg)', (pmore + ',' + pmore).split(',')[1].split('.')[0] + '.0deg)'); }
document.getElementById('dstyle').innerHTML+='<style> ' + document.getElementById('selthing').value + ' { transform: rotateZ(' + (newval != '' ? newval : document.getElementById('degval').value) + 'deg) ' + pmore + '; } </style>' + String.fromCharCode(10);
osel.value='';
document.getElementById('myta').value=document.getElementById('dstyle').innerHTML;
document.getElementById('mydet').style.display='block';
}
if (newval != '') { document.getElementById('degval').value=newval.split('.')[0]; }
}
Regarding the recent CSS Outline and Background Tutorial‘s “Outline & Background” web application, and it’s “iframe” try below modes of use, we wondered, being a bit in awe of what CSS can achieve these days in the category of …
… to confirm our initial thoughts on this, those being “not by itself” … which of course means … that 🄲 t-shirt … we’ll be having to pack away for now again.
But we followed that link’s advice quite closely (as well as being more diligent adding that trailing ? question mark … just in cases), affecting that “Outline & Background” web application’s layout via …
… to add more dropdown styling options into the mix (inspired a lot by this Google search, thanks) where the “outline” concept may have a role in amongst “border” and “background” concept webpage CSS styling ideas.
The CSS “border” emphasis of the previous Emoji Borders and Backgrounds Canvas Annotation Tutorial has concepts, we see online, confusing people, and myself, regarding what the CSS “outline” feature is capable of (or not capable of). Here is W3school‘s pertinent paragraph on this …
Note: Outline differs from borders! The outline is drawn outside the element’s border, and may overlap other content. Also, the outline is NOT a part of the element’s dimensions; the element’s total width and height is not affected by the width of the outline.
The CSS “outline” concept is not the panacea to as many web design requirements as the “border” concept is. For instance, even seeing within the purview of making our “proof of concept” web application …
no linear gradients can be worked in the “outline” realm
no such properties as “outline-top” or “outline-left” or “outline-bottom” or “outline-right” exist within the “outline” realm
no such property as “outline-radius” (though will mimic any roundedness applied to border)
no outline images in the “outline” realm
If we were to summarize, the CSS “outline” concept’s talents can lie with …
being around an HTML element (and not part of it … perhaps in web design, useful as “a place of rest” (including non-mobile on hover element title displays) for users?!)
decorative colour around an HTML element (perhaps to get the user’s attention to hone in on that element, or perhaps a dynamic conduit towards “thickening” an existant HTML element border (especially as Javascript DOM such as [element].style.outline=’2px solid green’; // is available to programmers))
can form a replacement nesting HTML element background colour means
in it’s simplest CSS syntax ( eg: outline: 2px solid green; ) can be easily remembered next to the simplest syntax of border (probably very familiar to you) CSS syntax ( eg: border: 2px solid green; ) … just differently located on the webpage
… contents in synch as far as looks go. That ignores the reason CANVAS (element) was invented when HTML5 came out. It was invented to not only contain image graphical data, but be able to amend that data. So we also allow it with our web application from today on, integrating with our inhouse “User of Signature” web application last talked about at Local Fonts Revisited Middle Tutorial, to amend (initially image via [canvas].toDataURL(‘image/png’) via SVG streams of data which may include emoji borders and backgrounds) graphical data.
We integrate via a same domain window.open scenario. Before you all start groaning, consider the advantages of a …
… albeit non-mobile window.open (ie. popup window) call. Not only are you …
(on non-mobile) seeing two windows on top of each other … but …
the “window.opener” (acting like “parent” does for an “iframe” arrangement) reference can have you, via Javascript DOM, share the data of the popup window canvas element with that of the “window.opener” (window) canvas element
… and then, we arrange for a “reset” (to ignore these annotation changes), via the “middle-element” IMG element, should the “Undo” functionality of our HTML changeduser_of_signature_signature.html‘s User of Signature Signature (standalone) live run not be enough flexibility to the functionality, which has a new document.body onload event triggering of Javascript function cancontlook below …
var cancont='';
var cancontw=-1, canconth=-1;
if (('' + window.opener).replace('null','') != '') {
var cans=window.opener.document.getElementsByTagName('canvas');
if (cans.length > 0) { cancont=cans[0].toDataURL('image/png'); cancontw=cans[0].width; canconth=cans[0].height; }
}
function cancontlook() {
if (cancont != '') { // called via SVG - IMG - CANVAS
celem=document.getElementById('topcanvas');
ccontext = celem.getContext("2d");
celem.width=cancontw;
celem.height=canconth;
cimg=new Image;
cimg.onload = function(){
ccontext.drawImage(cimg,0,0);
};
cimg.src=cancont;
if (document.getElementById('toptd')) {
document.getElementById('toptd').style.left='' + cancontw + 'px';
var recttoptd=document.getElementById('toptd').getBoundingClientRect();
document.getElementById('topcbutton').innerHTML='⬅';
document.getElementById('topcbutton').style.position='fixed';
document.getElementById('topcbutton').style.top='' + recttoptd.top + 'px';
//document.getElementById('topcbutton').style.left='' + recttoptd.left + 'px';
document.getElementById('topcbutton').style.left='' + eval(0.98 * eval('' + screen.width)) + 'px';
document.getElementById('topcbutton').style.zIndex='89';
document.getElementById('topcbutton').title='Back to SVG - IMG - CANVAS web application caller';
//document.getElementById('topcbutton').onclick=function() { window.opener.focus(); };
}
if (document.getElementById('toppixellate')) {
document.getElementById('toppixellate').style.top='' + canconth + 'px';
}
if (('' + location.hash).replace(/^\#/g,'') != '') {
document.getElementById('topcstyle').innerHTML='
function iysh() {
if (document.getElementById('topcbutton').innerHTML.indexOf(' ') != -1) {
document.getElementById('topcbutton').innerHTML=document.getElementById('topcbutton').innerHTML.replace(' ','');
alert('Please do this manually');
}
}
function woff() {
document.getElementById('topcbutton').innerHTML+=' ';
setTimeout(iysh, 2000);
window.opener.focus();
}
… that might help you “look back at yourself from outside” as we use it to interface to Google PageSpeed Insights webpage screenshot functionality (which can look at a designated URL and effectively screenshot it for you) … thanks.
We used to restrict our curl usage thinking to “only ?” first argument use too, arguing (with ourselves) that the Linux and Unix and macOS and Mac OS X “&” character command line meaning of “process in the background” would be a constraint. Of course it isn’t, because … anyone, anyone? Yes, Henry, you should use a “curl” command line command, using double quotes, of the form …
… and the “&”‘s are understood to be URL “GET” argument delimiters, and not a “process in the background” designator.
And here’s the thing exemplified above. The alternative file_get_contents PHP function cannot do that https: protocol type of URL, yet Google PageSpeed Insights webpage screenshot functionality demands such URLs … hence the “curl” interest.
$extis='.xxx';
if (strpos(('' . $_SERVER['QUERY_STRING']), 'howpagespeedseesme=') !== false) {
if (file_exists('/tmp/')) {
if (file_exists('/tmp/pscs.xxx')) {
unlink('/tmp/pscs.xxx');
}
}
exec($psbig);
while (!file_exists('/tmp/pscs' . $extis)) {
sleep(4);
}
while (filesize('/tmp/pscs' . $extis) == 0) {
sleep(4);
}
$scx=file_get_contents('/tmp/pscs' . $extis);
$scxs=explode('"screenshot":', $scx);
if (sizeof($scxs) > 1) {
$postscxs=explode('"data": ', $scxs[1]);
if (sizeof($postscxs) > 1) {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This ...</h2><img src=' . substr($postscxs[1],0,1) . explode(substr($postscxs[1],0,1), substr($postscxs[1],1))[0] . substr($postscxs[1],0,1) . '></img></body></html>';
} else {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This ...</h2><p>Sorry, resource exhausted. Could try again later.</p></body></html>';
}
} else {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This</h2><p>Sorry, resource exhausted. Could try again later.</p></body></html>';
}
exit;
}
?>
… working with the new HTML div <div id=readyforiframe></div> element, along with <span title=’Google PageSpeed Insights webpage screenshot view of this web browser address URL’ onclick=’psit();’> 📸 </span> 📸 “emoji button” in the HTML static code … with associated Javascript function …
Emoji Borders and Backgrounds Web Browser Tutorial
Yesterday’s Emoji Borders and Backgrounds Shape Sharing Tutorial had us sharing via email or SMS our “Emoji Borders and Backgrounds” creations via inhouse organized arrangements. But many people are used to just right-clicking (for Windows) and two finger gesturing (for macOS and Mac OS X) on …
SVG
IMG
CANVAS
… graphical elements, which can be made to “look” the same, and sort of “suck it and see” as far as menu options presented, helping them out sharing graphical information. In many cases, users don’t care what form of element the image comes contained in. But, if you involve “background-image” CSS along the way to achieve a (consistent) “look”, as we had done before today, (some of) the output of those menu options could be lacking (because they look for “foreground data”), and so we do away with the need for a “background-image” …
<?php
function ctoilater() {
img.src=canvas.toDataURL('data/png');
}
An example of how having web browser (right-clicking (for Windows) and two finger gesturing (for macOS and Mac OS X)) menu options be useful, consider an image menu option such as “Copy image” be used by the user. The user can compose their own (email client (or get to email client via all uppercase web application “to” email “address” definition)) email then, and just Edit -> Paste the results, as an image, into the email body, ahead of sending off that email.
Emoji Borders and Backgrounds Shape Sharing Tutorial
The code “shape shifting” of recent times morphs into “shape sharing” together in amongst the parent users of our PHP tool “Emoji Borders and Backgrounds” web application featuring in yesterday’s Emoji Borders and Backgrounds Shape Numerics Tutorial.
We found the “SVG+XML” mimetype data not accepted by Gmail for an Inline HTML Email, so we have coded for the Downloadable HTML Attachment “way to go”.
<?php
function emailit() {
var fbit='';
var tois=prompt('Please enter an email address to email to (all uppercase uses email client rather than PHP mail and all numerical sends an SMS).','');
if (tois == null) { tois=''; }
if (tois.trim() != '') {
if (tois.indexOf('@') != -1) {
if (tois.toUpperCase() == tois) {
document.getElementById('divemail').innerHTML='<a id=aemail style=display:none; href=mailto:' + tois + '?subject=My%20Emoji%20Border%20and%20Background%20Creation&body=' + encodeURIComponent(document.URL) + '>Email</a>';
//fbit=('' + document.getElementById('aemail').href).split('?')[1];
//document.getElementById('aemail').href='mailto:' + tois + '?' + fbit;
document.getElementById('aemail').click();
} else {
var zhr = new XMLHttpRequest();
var zform=new FormData();
if (1 == 2) { zform.append('inline', ''); }
zform.append('to', tois);
zform.append('subj', 'My Emoji Borders and Background Creation ... at [date] ...');
//alert(encodeURIComponent('<html><body><img src=\"<?php echo $bemb; ?>\"></img></body></html>'));
zform.append('tdhuhta', encodeURIComponent('<html>' + '<?php echo $headstyle; ?>' + '<body><img src="<?php echo $bemb; ?>"></img></body></html>'));
zhr.open('post', '//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php', true);
zhr.send(zform);
alert('Email sent to ' + tois);
}
} else if (tois.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') == '') {
document.getElementById('divsms').innerHTML='<a id=asms style=display:none; href=sms:' + tois + '&body=' + encodeURIComponent(document.URL) + '>SMS</a>';
//document.getElementById('asms').href='sms:' + tois + '&body=' + encodeURIComponent(document.URL);
document.getElementById('asms').click();
}
}
}
Emoji Borders and Backgrounds Shape Numerics Tutorial
If you are familiar with the geometry of shapes, it is full of numbers, with the implications as to how the shape is represented and displayed, that those numbers can affect. And so, onto yesterday’s Emoji Borders and Backgrounds Shapes Tutorial‘s start with …
SVG ellipse element functionality today … and for all these, as well as the …
SVG text element we start allowing “shape numerics” as being a user definable thaing
These “shape numerics” can help the user control (that SVG element’s) …
position
size
opacity
font size … (for text elements) on top of that non-numeric control yesterday’s work gave us, being (that SVG element’s fill) …
colour
This is all handled, still, within that “image” argument definition, and we allow a decimal (ie. “.”) delimiter be the way a user separates their integer values (where an opacity value becomes “0.” + [integerValue]).
Onto yesterday’s Emoji Borders and Backgrounds Text Justification Tutorial we add some consideration of SVG shape creations into the mix of the Emoji Borders and Backgrounds work, starting just with the PHP tool, at this stage, and just considering …
… to start off with, and feeding off yesterday’s …
width=[designatedPxWidth] and height=[designatedPxHeight] … and/or …
image=[someImageUrl] (width and height)
… breakdown as to how a user can define a box of interest, as a great “line in the sand” for us to work around with this new “Shapes functionality”. It’s an interfacing job, for tomorrow, getting parents to work with this “image” argument based way a user can define these shapes, including a “noimage” option that uses an image’s width and height (to help out with the shape definition) but does not display that image.
Along the way we also mildly rearrange PHP code for inline_svg.php‘s live run so as to allow for more than one user text to be added via justification prefixing methodologies.
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&css=opacity:0.9;&textcss=font-size:20px;&ultext=Hello%0AThere
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;&ultext=Hello%0AThere
Day before yesterday’s (third parent (to our PHP tool) “cab off the rank”) SVG -> IMG -> CANVAS changed PHPcanvas_svg.phplive run now prompts …
Please enter comma separated HTML decimal entity(s) for your Emoji Border to graphics. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &iurl=[newImageURL] to change base image. Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;&ultext=Hello%0AThere
… via a new “text” argument arranged for the PHP and in readiness for some more aesthetic improvements in the display side of things with our emoji borders and backgrounds
Well, what gives? Eh, wot’s up ‘guv? Yes, indeed … all we can say is …
We got sidetracted.
… and applying spell checker to get around an expression that amuses us …
We got sidetracked.
So, “being ‘guv” … eh, wot … today we’re having a posting catch up with all the parents and PHP tool child allowing for some CSS styling to be a possibility with the web applications around the theme of “Emoji Borders and Backgrounds”, onto yesterday’s Emoji Borders and Backgrounds in Canvas Tutorial.
And so wotwhat’s the go with styling in SVG “land”? Is SVG classy? It’s not that much different to HTML and CSS, in that “style” elements are allowed, and SVG allows you to define a “class” attribute for SVG elements, so that’s kind of classy … eh, wot, ‘guv?! Thanks to this great link for the heads up on this.
… to add the means by which the SVG’s optional “style” elements be populated, leaving it up to the various parents to inform the users of the possibilities here.
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&css=opacity:0.9;&textcss=font-size:20px;
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;
Yesterday’s (third parent (to our PHP tool) “cab off the rank”) SVG -> IMG -> CANVAS changed PHPcanvas_svg.phplive run now prompts …
Please enter comma separated HTML decimal entity(s) for your Emoji Border to graphics. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &iurl=[newImageURL] to change base image. Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;
Can we start with SVG+XML data and get to populate CANVAS data via IMG data via data URIs? Well, not everything works, but enough works to have a lot of what you’d want to do “in this neck of the woods” be possible.
<?php
var svg = document.querySelector('svg');
var img = document.querySelector('img');
var canvas = document.querySelector('canvas');
// get svg data
var xml = new XMLSerializer().serializeToString(svg);
//alert(xml);
// make it base64
var svg64 = ''; //btoa(xml);
var b64Start = ''; //'data:image/svg+xml;base64,';
Well, it’s our “second cab off the rank” regarding a parent idea to oversee our current PHP tool idea for Emoji Borders and Backgrounds.
Anything new? Well, yes, quite a big concept too. With our PHP tool, today, we are allowing it, for a PHP parent (today’s changedimagegridmap.php‘s live run), to fill in a …
It meant a division of two “threads” of modus operandi (possible by “overriding” the PHP echo function into an inhouse “ourecho” (wrapper style of) function), now, for our changedinline_svg.php PHP tool’s PHP tool live run …
“Inhouse Slideshow” functionality can not avoid the serverside PHP (ie. the changedindex.php PHP clone “original” and clone) in all its aspects, and so we still need …
for your more ephemeral “clientside only” tweaks we’ve started, today, with inhouse_slideshow.js to use Javascript junction “overrides” (of PHP Javascript ones above) are possible as a “single external Javascript code file” maintenance ongoing possibility for “Inhouse Slideshow” functionality …
// inhouse_slideshow.js
// RJM Programming
// January, 2022
// Help out with ephemeral aspects to Inhouse Slideshow PHPs
function changeto(tvis) {
if (tvis.toLowerCase().indexOf('exif') == 0) {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?exif=y');
} else {
location.href=posturl(document.URL.split('#')[0].replace(/pdf\=/g, 'pdTf=') + '&exif=y');
}
} else if (tvis.toLowerCase().indexOf('pdf') == 0) {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?pdf=y');
} else {
location.href=posturl(document.URL.split('#')[0].replace(/exif\=/g, 'exTif=') + '&pdf=y');
}
} else if (tvis.toLowerCase().indexOf('emoji') == 0) {
//var borderis=prompt('Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry.', '');
borderblurb='Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control=space for iOS, top left + for Android keyboard). ';
var borderis=prompt(borderblurb, '');
var emojiy='';
if (borderis == null) { borderis=''; } else { borderis=postbb(borderis); }
if (borderis != '') { emojiy='emoji=' + encodeURIComponent(borderis); }
if (emojiy != '') {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?' + emojiy);
} else {
location.href=posturl(document.URL.split('#')[0].replace(/emoji\=/g, 'emojTi=') + '&' + emojiy);
}
}
} else {
if (document.URL.indexOf('exif=') != -1 || document.URL.indexOf('pdf=') != -1) {
location.href=posturl(document.URL.split('#')[0].replace(/exif\=/g, 'exTif=').replace(/pdf\=/g, 'pdTf='));
} else {
location.href=posturl(document.URL.split('#')[0] + '&eHuhxif=y');
}
}
}
… including that one change to Javascript prompt popup window wording as an example of an ephemeral “clientside only” tweak … becomes a possibility (which is optional … ie. the PHP won’t fail if such an external Javascript does not exist, as those of you actively trying our guinea pig Inhouse Slideshow yesterday might attest to?!)
… the functionalities that would be “cool” at the HTML/Javascript/CSS parent side, and then work out how to implement similar functionality, as possible, in SVG, and if possible, we should be able to pass arguments over to the “PHP tool” to eventually code it to be standalone to help other “parenting arrangements”.
… today’s “theme” concerns the first of those other “parenting arrangements” mentioned above, our PHP for Inhouse Slideshow presentation display options …
… the new “Emoji Border Slideshow” display option above calling into play our inline_svg.php PHP tool’s live run (“Are we there yet, as a tool, I mean … Mum … Dad … anyone?”) web application.
And in so doing, to use an Emoji Menu methodology of selecting your emoji border decoration is “right up your street, Inhouse Slideshow supervisor”.
… into the mix. Why? Well, perhaps, first off, you should read some history of this “Inhouse Slideshow” project over time at Inhouse Slideshow Temporary Unzip Tutorial and then see that this “external Javascript lark” could be better for a way to “future proof” the venture, with some improvements being changeable through one (into your chosen Document Root folder, wherever that may be (that is what the leading “/” infers)) external Javascript codefile rather than a myriad number of identical PHP codefiles.
Emoji Borders and Backgrounds via Emoji Menu Tutorial
On this macOS MacBook Air we’re used to …
control-command-space
… bringing up an Emoji Menu from which an emoji can be selected and placed wherever the cursor had been placed before that menu display. That could be …
on an address bar where the cursor is placed
in a Javascript prompt window that is focussed
… both scenarios (amongst many others, no doubt) of which we will be interested with our current Emoji Borders and Background web application project. Today’s work develops our PHP tool ahead of its supervisory web application, and so we are interested in the first scenario above, as far as testing it goes with our changed underlyinginline_svg.php PHP tool live run web application.
The argument “text” is already catered for from yesterday but the nature of the data this $_GET[‘text’] might contain had not catered for …
unicode data (via Emoji Menus) … but rather had catered for …
Javascript call of String.fromCodePoint([comma separated list of HTML Decimal Entity(s)]);
… only, as of yesterday’s Emoji Borders and Backgrounds Image Text PHP SVG Tutorial. As you would probably concur, yesterday’s setup was quite user unfriendly, as so many of us now are used to those Emoji Menus being used to fill in your emoji data requirements.
The main gist of the PHP code changes goes …
<?php
$innards='';
$preinnards='';
function ingp($m) { // thanks to https://pretagteam.com/question/how-do-i-convert-unicode-special-characters-to-html-entities
global $innards, $preinnards;
if ($innards != '') {
$entity = preg_replace_callback('/[\x{80}-\x{10FFFF}]/u', function ($m) {
$char = current($m);
$utf = iconv('UTF-8', 'UCS-4', $char);
return sprintf("%s;", ltrim(strtoupper(bin2hex($utf)), "0"));
}, $innards);
$preinnards=htmlentities($entity);
$innards='';
}
}
// And then later we change ...
if (isset($_GET['insvg'])) {
$innards=str_replace('+','',urldecode($_GET['insvg']));
if (trim(str_replace(',','',str_replace('0','',str_replace('1','',str_replace('2','',str_replace('3','',str_replace('4','',str_replace('5','',str_replace('6','',str_replace('7','',str_replace('8','',str_replace('9','',$innards)))))))))))) != '') {
ingp($innards);
}
if ($preinnards == '') {
$preinnards='&#' . str_replace(',',';&#',$innards) . ';';
}
// rest of if block code uses $preinnards as SVG text innerHTML ... but UTF-16 Surrogate pair scenarios can fail
}
emoji border … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
emoji background … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
centralized text (in foreground) … now with wording control via HTML span contenteditable=true elements … not yet argumented to PHP tool
<?php
if (isset($_GET['text'])) {
$txt=str_replace("\n","<br>", str_replace(' ',' ',str_replace('+', ' ', urldecode($_GET['text']))));
$minus30=($w / 2.0) - strlen(explode('<br>', $txt)[0]) * 3.1;
$top30=($h / 2.0) + 25 - (sizeof(explode('<br>', $txt)) * 8);
$lines=explode('<br>', $txt);
for ($il=0; $il<sizeof($lines); $il++) {
$textcontent.='<text x="' . $minus30 . '" y="' . $top30 . '">' . $lines[$il] . '</text>';
$top30+=15;
}
} else if (isset($_POST['text'])) {
$txt=str_replace("\n","<br>", str_replace(' ',' ',str_replace('+', ' ', urldecode($_POST['text']))));
$minus30=($w / 2.0) - strlen(explode('<br>', $txt)[0]) * 3.1;
$top30=($h / 2.0) + 25 - (sizeof(explode('<br>', $txt)) * 8);
$lines=explode('<br>', $txt);
for ($il=0; $il<sizeof($lines); $il++) {
$textcontent.='<text x="' . $minus30 . '" y="' . $top30 . '">' . $lines[$il] . '</text>';
$top30+=15;
}
}
?>
centralized image (in foreground) … including some width and height control … argumented to PHP tool
… via a new “text” argument arranged for the PHP and in readiness for some more aesthetic improvements in the display side of things with our emoji borders and backgrounds changed underlyinginline_svg.php PHP tool live run web application (or in iframe).
… partnership during testing. Our final aim is to make the “underlying PHP” a proper standalone tool, but “that’s a ways off”, as they say. Why this extra level of complication? It’s easier to …
see
test
debug (via web browser web inspectors)
… the functionalities that would be “cool” at the HTML/Javascript/CSS parent side, and then work out how to implement similar functionality, as possible, in SVG, and if possible, we should be able to pass arguments over to the “PHP tool” to eventually code it to be standalone to help other “parenting arrangements”.
And so, today, we “get functional” the combination of parental control through to PHP SVG child display …
Optionally enter an image URL ( as needs be, suffix by &width=[preferredWidth]&height=[preferredHeight] and/or &background=y ) and/or # prefixed comma separated list of emoji HTML decimal Entity(s) ( eg. #127462,127465 ) ? Cancel if it is wording you want to change to the left there.
emoji border … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
emoji background … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
centralized text (in foreground) … now with wording control via HTML span contenteditable=true elements … not yet argumented to PHP tool
centralized image (in foreground) … including some width and height control … argumented to PHP tool
function ask(sois) {
var huhi=prompt('Optionally enter an image URL ( as needs be, suffix by &width=[preferredWidth]&height=[preferredHeight] and/or &background=y ) and/or # prefixed comma separated list of emoji HTML decimal Entity(s) ( eg. #127462,127465 ) ? Cancel if it is wording you want to change to the left there.','');
if (huhi == null) { huhi=''; }
if (huhi.trim() != '') {
if (document.URL.indexOf('rjmprogramming.com.au') == -1 && sois.title.indexOf('rjmprogramming.com.au') != -1) {
sois.title=document.URL.substring(0,8) + document.URL.substring(8).split('/')[0] + sois.title.split('rjmprogramming.com.au')[1];
}
if (huhi.indexOf('#') != -1) {
var huhis=huhi.split('#')[1];
for (var ihuhis=0; ihuhis<huhis.length; ihuhis++) {
if (eval('' + ihuhis) < eval('' + huhis.length)) {
if (huhis.substring(ihuhis).substring(0,1).replace('0','').replace('1','').replace('2','').replace('3','').replace('4','').replace('5','').replace('6','').replace('7','').replace('8','').replace('9','').replace(',','') != '') {
huhi=huhi.replace('#' + huhis.split(huhis.substring(ihuhis).substring(0,1))[0], '');
huhis=huhis.split(huhis.substring(ihuhis).substring(0,1))[0];
}
}
}
if (huhis == '') {
if (sois.title.indexOf('?insvg=') != -1) {
sois.title=sois.title.replace('?insvg=' + sois.title.split('?insvg=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&insvg=') != -1) {
sois.title=sois.title.replace('&insvg=' + sois.title.split('&insvg=')[1].split('&')[0].split('#')[0],'');
}
} else if (sois.title.indexOf('?insvg=') != -1) {
sois.title=sois.title.replace('?insvg=' + sois.title.split('?insvg=')[1].split('&')[0].split('#')[0],'?insvg=' + encodeURIComponent(huhis));
} else if (sois.title.indexOf('&insvg=') != -1) {
sois.title=sois.title.replace('&insvg=' + sois.title.split('&insvg=')[1].split('&')[0].split('#')[0],'&insvg=' + encodeURIComponent(huhis));
} else if (sois.title.indexOf('?') != -1) {
sois.title=sois.title.replace('?','?insvg=' + encodeURIComponent(huhis) + '&');
} else {
sois.title=sois.title.split('#')[0] + '?insvg=' + encodeURIComponent(huhis);
}
}
if (huhi.split('&')[0].split('#')[0].trim() != '') {
if (sois.title.indexOf('?image=') != -1) {
sois.title=sois.title.replace('?image=' + sois.title.split('?image=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&image=') != -1) {
sois.title=sois.title.replace('&image=' + sois.title.split('&image=')[1].split('&')[0].split('#')[0],'');
}
sois.title+='&image=' + encodeURIComponent(huhi.split('&')[0]) + huhi.replace(huhi.split('&')[0],'');
} else if (sois.title.indexOf('?image=') != -1) {
sois.title=sois.title.replace('?image=' + sois.title.split('?image=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&image=') != -1) {
sois.title=sois.title.replace('&image=' + sois.title.split('&image=')[1].split('&')[0].split('#')[0],'');
}
document.getElementById(sois.id.replace('span','if')).src=sois.title; //+='&image=' + encodeURIComponent(huhi.split('&')[0]) + huhi.replace(huhi.split('&')[0],'');
}
}
function snapshot(sio) {
lastih=sio.innerHTML;
lastio=-1;
for (var iuh=0; iuh<cds.length; iuh++) {
if (lastih == cds[iuh]) { lastio=iuh; } else if (sio.innerHTML.indexOf(' of ') != -1) { if (lastih.split(' of ')[0] == cds[iuh].split(' of ')[0]) { lastio=iuh; } }
}
}
It’s all fine and good creating the Emoji Borders and Backgrounds of yesterday’s Emoji Borders and Backgrounds Primer Tutorial, but it’s the context of their use that we are starting to take an interest in with today’s …
“making use of” “proof of concept” emoji_border_background.htmllive run link for you to contextualize and make use of those table’s iframe contents from yesterday …
… as we figure out, perhaps, some better “tool like generics” here. We’ll see (we hope)!
But, so far, how would we assess the approach, here? Well, what we had to do today reminded us a lot of what we do here, often, at this blog, when we talk about “overlay” webpage design approaches. CSS position:absolute and opacity and Javascript [element].getBoundingClientRect() all made guest appearances!
Regarding the recent CSS Outline and Background Tutorial‘s “Outline & Background” web application, and it’s “iframe” try below modes of use, we wondered, being a bit in awe of what CSS can achieve these days in the category of …
… to confirm our initial thoughts on this, those being “not by itself” … which of course means … that 🄲 t-shirt … we’ll be having to pack away for now again.
But we followed that link’s advice quite closely (as well as being more diligent adding that trailing ? question mark … just in cases), affecting that “Outline & Background” web application’s layout via …
… to add more dropdown styling options into the mix (inspired a lot by this Google search, thanks) where the “outline” concept may have a role in amongst “border” and “background” concept webpage CSS styling ideas.
The CSS “border” emphasis of the previous Emoji Borders and Backgrounds Canvas Annotation Tutorial has concepts, we see online, confusing people, and myself, regarding what the CSS “outline” feature is capable of (or not capable of). Here is W3school‘s pertinent paragraph on this …
Note: Outline differs from borders! The outline is drawn outside the element’s border, and may overlap other content. Also, the outline is NOT a part of the element’s dimensions; the element’s total width and height is not affected by the width of the outline.
The CSS “outline” concept is not the panacea to as many web design requirements as the “border” concept is. For instance, even seeing within the purview of making our “proof of concept” web application …
no linear gradients can be worked in the “outline” realm
no such properties as “outline-top” or “outline-left” or “outline-bottom” or “outline-right” exist within the “outline” realm
no such property as “outline-radius” (though will mimic any roundedness applied to border)
no outline images in the “outline” realm
If we were to summarize, the CSS “outline” concept’s talents can lie with …
being around an HTML element (and not part of it … perhaps in web design, useful as “a place of rest” (including non-mobile on hover element title displays) for users?!)
decorative colour around an HTML element (perhaps to get the user’s attention to hone in on that element, or perhaps a dynamic conduit towards “thickening” an existant HTML element border (especially as Javascript DOM such as [element].style.outline=’2px solid green’; // is available to programmers))
can form a replacement nesting HTML element background colour means
in it’s simplest CSS syntax ( eg: outline: 2px solid green; ) can be easily remembered next to the simplest syntax of border (probably very familiar to you) CSS syntax ( eg: border: 2px solid green; ) … just differently located on the webpage
… contents in synch as far as looks go. That ignores the reason CANVAS (element) was invented when HTML5 came out. It was invented to not only contain image graphical data, but be able to amend that data. So we also allow it with our web application from today on, integrating with our inhouse “User of Signature” web application last talked about at Local Fonts Revisited Middle Tutorial, to amend (initially image via [canvas].toDataURL(‘image/png’) via SVG streams of data which may include emoji borders and backgrounds) graphical data.
We integrate via a same domain window.open scenario. Before you all start groaning, consider the advantages of a …
… albeit non-mobile window.open (ie. popup window) call. Not only are you …
(on non-mobile) seeing two windows on top of each other … but …
the “window.opener” (acting like “parent” does for an “iframe” arrangement) reference can have you, via Javascript DOM, share the data of the popup window canvas element with that of the “window.opener” (window) canvas element
… and then, we arrange for a “reset” (to ignore these annotation changes), via the “middle-element” IMG element, should the “Undo” functionality of our HTML changeduser_of_signature_signature.html‘s User of Signature Signature (standalone) live run not be enough flexibility to the functionality, which has a new document.body onload event triggering of Javascript function cancontlook below …
var cancont='';
var cancontw=-1, canconth=-1;
if (('' + window.opener).replace('null','') != '') {
var cans=window.opener.document.getElementsByTagName('canvas');
if (cans.length > 0) { cancont=cans[0].toDataURL('image/png'); cancontw=cans[0].width; canconth=cans[0].height; }
}
function cancontlook() {
if (cancont != '') { // called via SVG - IMG - CANVAS
celem=document.getElementById('topcanvas');
ccontext = celem.getContext("2d");
celem.width=cancontw;
celem.height=canconth;
cimg=new Image;
cimg.onload = function(){
ccontext.drawImage(cimg,0,0);
};
cimg.src=cancont;
if (document.getElementById('toptd')) {
document.getElementById('toptd').style.left='' + cancontw + 'px';
var recttoptd=document.getElementById('toptd').getBoundingClientRect();
document.getElementById('topcbutton').innerHTML='⬅';
document.getElementById('topcbutton').style.position='fixed';
document.getElementById('topcbutton').style.top='' + recttoptd.top + 'px';
//document.getElementById('topcbutton').style.left='' + recttoptd.left + 'px';
document.getElementById('topcbutton').style.left='' + eval(0.98 * eval('' + screen.width)) + 'px';
document.getElementById('topcbutton').style.zIndex='89';
document.getElementById('topcbutton').title='Back to SVG - IMG - CANVAS web application caller';
//document.getElementById('topcbutton').onclick=function() { window.opener.focus(); };
}
if (document.getElementById('toppixellate')) {
document.getElementById('toppixellate').style.top='' + canconth + 'px';
}
if (('' + location.hash).replace(/^\#/g,'') != '') {
document.getElementById('topcstyle').innerHTML='
function iysh() {
if (document.getElementById('topcbutton').innerHTML.indexOf(' ') != -1) {
document.getElementById('topcbutton').innerHTML=document.getElementById('topcbutton').innerHTML.replace(' ','');
alert('Please do this manually');
}
}
function woff() {
document.getElementById('topcbutton').innerHTML+=' ';
setTimeout(iysh, 2000);
window.opener.focus();
}
… that might help you “look back at yourself from outside” as we use it to interface to Google PageSpeed Insights webpage screenshot functionality (which can look at a designated URL and effectively screenshot it for you) … thanks.
We used to restrict our curl usage thinking to “only ?” first argument use too, arguing (with ourselves) that the Linux and Unix and macOS and Mac OS X “&” character command line meaning of “process in the background” would be a constraint. Of course it isn’t, because … anyone, anyone? Yes, Henry, you should use a “curl” command line command, using double quotes, of the form …
… and the “&”‘s are understood to be URL “GET” argument delimiters, and not a “process in the background” designator.
And here’s the thing exemplified above. The alternative file_get_contents PHP function cannot do that https: protocol type of URL, yet Google PageSpeed Insights webpage screenshot functionality demands such URLs … hence the “curl” interest.
$extis='.xxx';
if (strpos(('' . $_SERVER['QUERY_STRING']), 'howpagespeedseesme=') !== false) {
if (file_exists('/tmp/')) {
if (file_exists('/tmp/pscs.xxx')) {
unlink('/tmp/pscs.xxx');
}
}
exec($psbig);
while (!file_exists('/tmp/pscs' . $extis)) {
sleep(4);
}
while (filesize('/tmp/pscs' . $extis) == 0) {
sleep(4);
}
$scx=file_get_contents('/tmp/pscs' . $extis);
$scxs=explode('"screenshot":', $scx);
if (sizeof($scxs) > 1) {
$postscxs=explode('"data": ', $scxs[1]);
if (sizeof($postscxs) > 1) {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This ...</h2><img src=' . substr($postscxs[1],0,1) . explode(substr($postscxs[1],0,1), substr($postscxs[1],1))[0] . substr($postscxs[1],0,1) . '></img></body></html>';
} else {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This ...</h2><p>Sorry, resource exhausted. Could try again later.</p></body></html>';
}
} else {
echo '<html><body><h2>How Google <a target=_blank title="Google PageSpeed Insights" href="https://pagespeed.web.dev/">PageSpeed Insights</a> Screenshots This</h2><p>Sorry, resource exhausted. Could try again later.</p></body></html>';
}
exit;
}
?>
… working with the new HTML div <div id=readyforiframe></div> element, along with <span title=’Google PageSpeed Insights webpage screenshot view of this web browser address URL’ onclick=’psit();’> 📸 </span> 📸 “emoji button” in the HTML static code … with associated Javascript function …
Emoji Borders and Backgrounds Web Browser Tutorial
Yesterday’s Emoji Borders and Backgrounds Shape Sharing Tutorial had us sharing via email or SMS our “Emoji Borders and Backgrounds” creations via inhouse organized arrangements. But many people are used to just right-clicking (for Windows) and two finger gesturing (for macOS and Mac OS X) on …
SVG
IMG
CANVAS
… graphical elements, which can be made to “look” the same, and sort of “suck it and see” as far as menu options presented, helping them out sharing graphical information. In many cases, users don’t care what form of element the image comes contained in. But, if you involve “background-image” CSS along the way to achieve a (consistent) “look”, as we had done before today, (some of) the output of those menu options could be lacking (because they look for “foreground data”), and so we do away with the need for a “background-image” …
<?php
function ctoilater() {
img.src=canvas.toDataURL('data/png');
}
An example of how having web browser (right-clicking (for Windows) and two finger gesturing (for macOS and Mac OS X)) menu options be useful, consider an image menu option such as “Copy image” be used by the user. The user can compose their own (email client (or get to email client via all uppercase web application “to” email “address” definition)) email then, and just Edit -> Paste the results, as an image, into the email body, ahead of sending off that email.
Emoji Borders and Backgrounds Shape Sharing Tutorial
The code “shape shifting” of recent times morphs into “shape sharing” together in amongst the parent users of our PHP tool “Emoji Borders and Backgrounds” web application featuring in yesterday’s Emoji Borders and Backgrounds Shape Numerics Tutorial.
We found the “SVG+XML” mimetype data not accepted by Gmail for an Inline HTML Email, so we have coded for the Downloadable HTML Attachment “way to go”.
<?php
function emailit() {
var fbit='';
var tois=prompt('Please enter an email address to email to (all uppercase uses email client rather than PHP mail and all numerical sends an SMS).','');
if (tois == null) { tois=''; }
if (tois.trim() != '') {
if (tois.indexOf('@') != -1) {
if (tois.toUpperCase() == tois) {
document.getElementById('divemail').innerHTML='<a id=aemail style=display:none; href=mailto:' + tois + '?subject=My%20Emoji%20Border%20and%20Background%20Creation&body=' + encodeURIComponent(document.URL) + '>Email</a>';
//fbit=('' + document.getElementById('aemail').href).split('?')[1];
//document.getElementById('aemail').href='mailto:' + tois + '?' + fbit;
document.getElementById('aemail').click();
} else {
var zhr = new XMLHttpRequest();
var zform=new FormData();
if (1 == 2) { zform.append('inline', ''); }
zform.append('to', tois);
zform.append('subj', 'My Emoji Borders and Background Creation ... at [date] ...');
//alert(encodeURIComponent('<html><body><img src=\"<?php echo $bemb; ?>\"></img></body></html>'));
zform.append('tdhuhta', encodeURIComponent('<html>' + '<?php echo $headstyle; ?>' + '<body><img src="<?php echo $bemb; ?>"></img></body></html>'));
zhr.open('post', '//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php', true);
zhr.send(zform);
alert('Email sent to ' + tois);
}
} else if (tois.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'') == '') {
document.getElementById('divsms').innerHTML='<a id=asms style=display:none; href=sms:' + tois + '&body=' + encodeURIComponent(document.URL) + '>SMS</a>';
//document.getElementById('asms').href='sms:' + tois + '&body=' + encodeURIComponent(document.URL);
document.getElementById('asms').click();
}
}
}
Emoji Borders and Backgrounds Shape Numerics Tutorial
If you are familiar with the geometry of shapes, it is full of numbers, with the implications as to how the shape is represented and displayed, that those numbers can affect. And so, onto yesterday’s Emoji Borders and Backgrounds Shapes Tutorial‘s start with …
SVG ellipse element functionality today … and for all these, as well as the …
SVG text element we start allowing “shape numerics” as being a user definable thaing
These “shape numerics” can help the user control (that SVG element’s) …
position
size
opacity
font size … (for text elements) on top of that non-numeric control yesterday’s work gave us, being (that SVG element’s fill) …
colour
This is all handled, still, within that “image” argument definition, and we allow a decimal (ie. “.”) delimiter be the way a user separates their integer values (where an opacity value becomes “0.” + [integerValue]).
Onto yesterday’s Emoji Borders and Backgrounds Text Justification Tutorial we add some consideration of SVG shape creations into the mix of the Emoji Borders and Backgrounds work, starting just with the PHP tool, at this stage, and just considering …
… to start off with, and feeding off yesterday’s …
width=[designatedPxWidth] and height=[designatedPxHeight] … and/or …
image=[someImageUrl] (width and height)
… breakdown as to how a user can define a box of interest, as a great “line in the sand” for us to work around with this new “Shapes functionality”. It’s an interfacing job, for tomorrow, getting parents to work with this “image” argument based way a user can define these shapes, including a “noimage” option that uses an image’s width and height (to help out with the shape definition) but does not display that image.
Along the way we also mildly rearrange PHP code for inline_svg.php‘s live run so as to allow for more than one user text to be added via justification prefixing methodologies.
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&css=opacity:0.9;&textcss=font-size:20px;&ultext=Hello%0AThere
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;&ultext=Hello%0AThere
Day before yesterday’s (third parent (to our PHP tool) “cab off the rank”) SVG -> IMG -> CANVAS changed PHPcanvas_svg.phplive run now prompts …
Please enter comma separated HTML decimal entity(s) for your Emoji Border to graphics. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &iurl=[newImageURL] to change base image. Optionally append &[text|image]css=[CSSstyle] to change styling. Optionally justify some text via &[ul|uc|ur|ml|[mc]|mr|bl|bc|br]text=[someText%0AsecondLine] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;&ultext=Hello%0AThere
… via a new “text” argument arranged for the PHP and in readiness for some more aesthetic improvements in the display side of things with our emoji borders and backgrounds
Well, what gives? Eh, wot’s up ‘guv? Yes, indeed … all we can say is …
We got sidetracted.
… and applying spell checker to get around an expression that amuses us …
We got sidetracked.
So, “being ‘guv” … eh, wot … today we’re having a posting catch up with all the parents and PHP tool child allowing for some CSS styling to be a possibility with the web applications around the theme of “Emoji Borders and Backgrounds”, onto yesterday’s Emoji Borders and Backgrounds in Canvas Tutorial.
And so wotwhat’s the go with styling in SVG “land”? Is SVG classy? It’s not that much different to HTML and CSS, in that “style” elements are allowed, and SVG allows you to define a “class” attribute for SVG elements, so that’s kind of classy … eh, wot, ‘guv?! Thanks to this great link for the heads up on this.
… to add the means by which the SVG’s optional “style” elements be populated, leaving it up to the various parents to inform the users of the possibilities here.
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&css=opacity:0.9;&textcss=font-size:20px;
Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;
Yesterday’s (third parent (to our PHP tool) “cab off the rank”) SVG -> IMG -> CANVAS changed PHPcanvas_svg.phplive run now prompts …
Please enter comma separated HTML decimal entity(s) for your Emoji Border to graphics. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control+space for iOS, top left + for Android keyboard). Optionally append &iurl=[newImageURL] to change base image. Optionally append &[text|image]css=[CSSstyle] to change styling. Eg. 🏖&iurl=four.jpg&css=opacity:0.9;font-size:20px;&textcss=text-shadow: -2px 2px 3px #ff2d95;
Can we start with SVG+XML data and get to populate CANVAS data via IMG data via data URIs? Well, not everything works, but enough works to have a lot of what you’d want to do “in this neck of the woods” be possible.
<?php
var svg = document.querySelector('svg');
var img = document.querySelector('img');
var canvas = document.querySelector('canvas');
// get svg data
var xml = new XMLSerializer().serializeToString(svg);
//alert(xml);
// make it base64
var svg64 = ''; //btoa(xml);
var b64Start = ''; //'data:image/svg+xml;base64,';
Well, it’s our “second cab off the rank” regarding a parent idea to oversee our current PHP tool idea for Emoji Borders and Backgrounds.
Anything new? Well, yes, quite a big concept too. With our PHP tool, today, we are allowing it, for a PHP parent (today’s changedimagegridmap.php‘s live run), to fill in a …
It meant a division of two “threads” of modus operandi (possible by “overriding” the PHP echo function into an inhouse “ourecho” (wrapper style of) function), now, for our changedinline_svg.php PHP tool’s PHP tool live run …
“Inhouse Slideshow” functionality can not avoid the serverside PHP (ie. the changedindex.php PHP clone “original” and clone) in all its aspects, and so we still need …
for your more ephemeral “clientside only” tweaks we’ve started, today, with inhouse_slideshow.js to use Javascript junction “overrides” (of PHP Javascript ones above) are possible as a “single external Javascript code file” maintenance ongoing possibility for “Inhouse Slideshow” functionality …
// inhouse_slideshow.js
// RJM Programming
// January, 2022
// Help out with ephemeral aspects to Inhouse Slideshow PHPs
function changeto(tvis) {
if (tvis.toLowerCase().indexOf('exif') == 0) {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?exif=y');
} else {
location.href=posturl(document.URL.split('#')[0].replace(/pdf\=/g, 'pdTf=') + '&exif=y');
}
} else if (tvis.toLowerCase().indexOf('pdf') == 0) {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?pdf=y');
} else {
location.href=posturl(document.URL.split('#')[0].replace(/exif\=/g, 'exTif=') + '&pdf=y');
}
} else if (tvis.toLowerCase().indexOf('emoji') == 0) {
//var borderis=prompt('Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry.', '');
borderblurb='Please enter comma separated HTML decimal entity(s) for your Emoji Border to slideshow. Can use an Emoji Menu entry (eg. control-command-space for macOS or Mac OS X, logo key + . (period) for Windows, control=space for iOS, top left + for Android keyboard). ';
var borderis=prompt(borderblurb, '');
var emojiy='';
if (borderis == null) { borderis=''; } else { borderis=postbb(borderis); }
if (borderis != '') { emojiy='emoji=' + encodeURIComponent(borderis); }
if (emojiy != '') {
if (document.URL.indexOf('?') == -1) {
location.href=posturl(document.URL.split('#')[0] + '?' + emojiy);
} else {
location.href=posturl(document.URL.split('#')[0].replace(/emoji\=/g, 'emojTi=') + '&' + emojiy);
}
}
} else {
if (document.URL.indexOf('exif=') != -1 || document.URL.indexOf('pdf=') != -1) {
location.href=posturl(document.URL.split('#')[0].replace(/exif\=/g, 'exTif=').replace(/pdf\=/g, 'pdTf='));
} else {
location.href=posturl(document.URL.split('#')[0] + '&eHuhxif=y');
}
}
}
… including that one change to Javascript prompt popup window wording as an example of an ephemeral “clientside only” tweak … becomes a possibility (which is optional … ie. the PHP won’t fail if such an external Javascript does not exist, as those of you actively trying our guinea pig Inhouse Slideshow yesterday might attest to?!)
… the functionalities that would be “cool” at the HTML/Javascript/CSS parent side, and then work out how to implement similar functionality, as possible, in SVG, and if possible, we should be able to pass arguments over to the “PHP tool” to eventually code it to be standalone to help other “parenting arrangements”.
… today’s “theme” concerns the first of those other “parenting arrangements” mentioned above, our PHP for Inhouse Slideshow presentation display options …
… the new “Emoji Border Slideshow” display option above calling into play our inline_svg.php PHP tool’s live run (“Are we there yet, as a tool, I mean … Mum … Dad … anyone?”) web application.
And in so doing, to use an Emoji Menu methodology of selecting your emoji border decoration is “right up your street, Inhouse Slideshow supervisor”.
… into the mix. Why? Well, perhaps, first off, you should read some history of this “Inhouse Slideshow” project over time at Inhouse Slideshow Temporary Unzip Tutorial and then see that this “external Javascript lark” could be better for a way to “future proof” the venture, with some improvements being changeable through one (into your chosen Document Root folder, wherever that may be (that is what the leading “/” infers)) external Javascript codefile rather than a myriad number of identical PHP codefiles.
Emoji Borders and Backgrounds via Emoji Menu Tutorial
On this macOS MacBook Air we’re used to …
control-command-space
… bringing up an Emoji Menu from which an emoji can be selected and placed wherever the cursor had been placed before that menu display. That could be …
on an address bar where the cursor is placed
in a Javascript prompt window that is focussed
… both scenarios (amongst many others, no doubt) of which we will be interested with our current Emoji Borders and Background web application project. Today’s work develops our PHP tool ahead of its supervisory web application, and so we are interested in the first scenario above, as far as testing it goes with our changed underlyinginline_svg.php PHP tool live run web application.
The argument “text” is already catered for from yesterday but the nature of the data this $_GET[‘text’] might contain had not catered for …
unicode data (via Emoji Menus) … but rather had catered for …
Javascript call of String.fromCodePoint([comma separated list of HTML Decimal Entity(s)]);
… only, as of yesterday’s Emoji Borders and Backgrounds Image Text PHP SVG Tutorial. As you would probably concur, yesterday’s setup was quite user unfriendly, as so many of us now are used to those Emoji Menus being used to fill in your emoji data requirements.
The main gist of the PHP code changes goes …
<?php
$innards='';
$preinnards='';
function ingp($m) { // thanks to https://pretagteam.com/question/how-do-i-convert-unicode-special-characters-to-html-entities
global $innards, $preinnards;
if ($innards != '') {
$entity = preg_replace_callback('/[\x{80}-\x{10FFFF}]/u', function ($m) {
$char = current($m);
$utf = iconv('UTF-8', 'UCS-4', $char);
return sprintf("%s;", ltrim(strtoupper(bin2hex($utf)), "0"));
}, $innards);
$preinnards=htmlentities($entity);
$innards='';
}
}
// And then later we change ...
if (isset($_GET['insvg'])) {
$innards=str_replace('+','',urldecode($_GET['insvg']));
if (trim(str_replace(',','',str_replace('0','',str_replace('1','',str_replace('2','',str_replace('3','',str_replace('4','',str_replace('5','',str_replace('6','',str_replace('7','',str_replace('8','',str_replace('9','',$innards)))))))))))) != '') {
ingp($innards);
}
if ($preinnards == '') {
$preinnards='&#' . str_replace(',',';&#',$innards) . ';';
}
// rest of if block code uses $preinnards as SVG text innerHTML ... but UTF-16 Surrogate pair scenarios can fail
}
emoji border … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
emoji background … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
centralized text (in foreground) … now with wording control via HTML span contenteditable=true elements … not yet argumented to PHP tool
<?php
if (isset($_GET['text'])) {
$txt=str_replace("\n","<br>", str_replace(' ',' ',str_replace('+', ' ', urldecode($_GET['text']))));
$minus30=($w / 2.0) - strlen(explode('<br>', $txt)[0]) * 3.1;
$top30=($h / 2.0) + 25 - (sizeof(explode('<br>', $txt)) * 8);
$lines=explode('<br>', $txt);
for ($il=0; $il<sizeof($lines); $il++) {
$textcontent.='<text x="' . $minus30 . '" y="' . $top30 . '">' . $lines[$il] . '</text>';
$top30+=15;
}
} else if (isset($_POST['text'])) {
$txt=str_replace("\n","<br>", str_replace(' ',' ',str_replace('+', ' ', urldecode($_POST['text']))));
$minus30=($w / 2.0) - strlen(explode('<br>', $txt)[0]) * 3.1;
$top30=($h / 2.0) + 25 - (sizeof(explode('<br>', $txt)) * 8);
$lines=explode('<br>', $txt);
for ($il=0; $il<sizeof($lines); $il++) {
$textcontent.='<text x="' . $minus30 . '" y="' . $top30 . '">' . $lines[$il] . '</text>';
$top30+=15;
}
}
?>
centralized image (in foreground) … including some width and height control … argumented to PHP tool
… via a new “text” argument arranged for the PHP and in readiness for some more aesthetic improvements in the display side of things with our emoji borders and backgrounds changed underlyinginline_svg.php PHP tool live run web application (or in iframe).
… partnership during testing. Our final aim is to make the “underlying PHP” a proper standalone tool, but “that’s a ways off”, as they say. Why this extra level of complication? It’s easier to …
see
test
debug (via web browser web inspectors)
… the functionalities that would be “cool” at the HTML/Javascript/CSS parent side, and then work out how to implement similar functionality, as possible, in SVG, and if possible, we should be able to pass arguments over to the “PHP tool” to eventually code it to be standalone to help other “parenting arrangements”.
And so, today, we “get functional” the combination of parental control through to PHP SVG child display …
Optionally enter an image URL ( as needs be, suffix by &width=[preferredWidth]&height=[preferredHeight] and/or &background=y ) and/or # prefixed comma separated list of emoji HTML decimal Entity(s) ( eg. #127462,127465 ) ? Cancel if it is wording you want to change to the left there.
emoji border … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
emoji background … now with content control via comma separated list of emoji HTML decimal Entity(s) … argumented to PHP tool
centralized text (in foreground) … now with wording control via HTML span contenteditable=true elements … not yet argumented to PHP tool
centralized image (in foreground) … including some width and height control … argumented to PHP tool
function ask(sois) {
var huhi=prompt('Optionally enter an image URL ( as needs be, suffix by &width=[preferredWidth]&height=[preferredHeight] and/or &background=y ) and/or # prefixed comma separated list of emoji HTML decimal Entity(s) ( eg. #127462,127465 ) ? Cancel if it is wording you want to change to the left there.','');
if (huhi == null) { huhi=''; }
if (huhi.trim() != '') {
if (document.URL.indexOf('rjmprogramming.com.au') == -1 && sois.title.indexOf('rjmprogramming.com.au') != -1) {
sois.title=document.URL.substring(0,8) + document.URL.substring(8).split('/')[0] + sois.title.split('rjmprogramming.com.au')[1];
}
if (huhi.indexOf('#') != -1) {
var huhis=huhi.split('#')[1];
for (var ihuhis=0; ihuhis<huhis.length; ihuhis++) {
if (eval('' + ihuhis) < eval('' + huhis.length)) {
if (huhis.substring(ihuhis).substring(0,1).replace('0','').replace('1','').replace('2','').replace('3','').replace('4','').replace('5','').replace('6','').replace('7','').replace('8','').replace('9','').replace(',','') != '') {
huhi=huhi.replace('#' + huhis.split(huhis.substring(ihuhis).substring(0,1))[0], '');
huhis=huhis.split(huhis.substring(ihuhis).substring(0,1))[0];
}
}
}
if (huhis == '') {
if (sois.title.indexOf('?insvg=') != -1) {
sois.title=sois.title.replace('?insvg=' + sois.title.split('?insvg=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&insvg=') != -1) {
sois.title=sois.title.replace('&insvg=' + sois.title.split('&insvg=')[1].split('&')[0].split('#')[0],'');
}
} else if (sois.title.indexOf('?insvg=') != -1) {
sois.title=sois.title.replace('?insvg=' + sois.title.split('?insvg=')[1].split('&')[0].split('#')[0],'?insvg=' + encodeURIComponent(huhis));
} else if (sois.title.indexOf('&insvg=') != -1) {
sois.title=sois.title.replace('&insvg=' + sois.title.split('&insvg=')[1].split('&')[0].split('#')[0],'&insvg=' + encodeURIComponent(huhis));
} else if (sois.title.indexOf('?') != -1) {
sois.title=sois.title.replace('?','?insvg=' + encodeURIComponent(huhis) + '&');
} else {
sois.title=sois.title.split('#')[0] + '?insvg=' + encodeURIComponent(huhis);
}
}
if (huhi.split('&')[0].split('#')[0].trim() != '') {
if (sois.title.indexOf('?image=') != -1) {
sois.title=sois.title.replace('?image=' + sois.title.split('?image=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&image=') != -1) {
sois.title=sois.title.replace('&image=' + sois.title.split('&image=')[1].split('&')[0].split('#')[0],'');
}
sois.title+='&image=' + encodeURIComponent(huhi.split('&')[0]) + huhi.replace(huhi.split('&')[0],'');
} else if (sois.title.indexOf('?image=') != -1) {
sois.title=sois.title.replace('?image=' + sois.title.split('?image=')[1].split('&')[0].split('#')[0],'');
} else if (sois.title.indexOf('&image=') != -1) {
sois.title=sois.title.replace('&image=' + sois.title.split('&image=')[1].split('&')[0].split('#')[0],'');
}
document.getElementById(sois.id.replace('span','if')).src=sois.title; //+='&image=' + encodeURIComponent(huhi.split('&')[0]) + huhi.replace(huhi.split('&')[0],'');
}
}
function snapshot(sio) {
lastih=sio.innerHTML;
lastio=-1;
for (var iuh=0; iuh<cds.length; iuh++) {
if (lastih == cds[iuh]) { lastio=iuh; } else if (sio.innerHTML.indexOf(' of ') != -1) { if (lastih.split(' of ')[0] == cds[iuh].split(' of ')[0]) { lastio=iuh; } }
}
}
It’s all fine and good creating the Emoji Borders and Backgrounds of yesterday’s Emoji Borders and Backgrounds Primer Tutorial, but it’s the context of their use that we are starting to take an interest in with today’s …
“making use of” “proof of concept” emoji_border_background.htmllive run link for you to contextualize and make use of those table’s iframe contents from yesterday …
… as we figure out, perhaps, some better “tool like generics” here. We’ll see (we hope)!
But, so far, how would we assess the approach, here? Well, what we had to do today reminded us a lot of what we do here, often, at this blog, when we talk about “overlay” webpage design approaches. CSS position:absolute and opacity and Javascript [element].getBoundingClientRect() all made guest appearances!
During yesterday’s Emulating Android on macOS Revisit Tutorial‘s Android emulations we noticed our Landing Page “Programming” word overflowed on the Android mobile device screen (we got going via an Android Studio Device Manager Pixel Sim emulation). Maybe we’d allow that through on occasions, but it grates with us when it happens on the Landing Page so the Javascript “at document.body onload event” intervention …
if (navigator.userAgent.match(/Android/i)) {
document.getElementById('toph1').innerHTML=document.getElementById('toph1').innerHTML.replace(' Programming', ' <h2>Programming</h2>');
}
… was deployed with less aaaarrrrgggghhh about it!
Did You Know
Quite often, confronted with a similar initial scenario where the HTML goes something like …
if (navigator.userAgent.match(/Android/i)) {
document.getElementById('toph1').innerHTML=document.getElementById('toph1').innerHTML.replace(' Programming', ' <span>Programming</span>');
}
… where the span element we see as the natural “inline” infilling HTML element type of choice. Here, though, we opted for h2 in preference, it being such an obvious header element scenario. Also, Javascript DOM could have been used to adjust font size via Javascript like …
Yes, we did once own an Android mobile device as Voicemail Disabling on Android Primer Tutorial can attest to below. But we haven’t had one, physically like this, functional, for some time now.
We primarily work on macOS with this MacBook Air and with an iOS iPhone and/or iPad. We know from mobile work in the past, that does not mean you do not have available to you options to …
Emulate an Android mobile device
… via two macOS IDE ideas we can think of, those being …
… and, we’re sure, there’d be others out there. We ended up, regarding today’s resurrection of such emulations, a successful Android Studio (Java basis) -> Device Manager -> Pixel Sim emulation, curious to catch up on what needed tweaking “aesthetics wise”.
And so, warts and all, we show you via today’s animated GIF presentation a catch up, involving an upgrade from macOS Sequoia 15 to macOS Tahoe 26.6 to allow Xcode 26.? be installed (and the Xcode 26.6 we installed may need a relook here, regarding it’s “curbing of enthusiasm” stance so far).
You can run an official Android emulator on macOS without Android Studio by installing the standalone command-line tools and Java via Homebrew.Install PrerequisitesOpen your terminal and install a Java JDK and the minimal command-line tools using
Setup and Run the EmulatorDownload Components: Use sdkmanager to download the emulator, platform tools, and a system image (e.g., ARM64 for Apple Silicon):
Was shocked the other day hearing of the prediction that eventually Voicemail will fadeaway as a communication tool. Nevertheless, it can irk, and know a student who feels like this with Voicemail on their Android mobile phone.
So we looked into disabling it, and found the third suggestion of three on How to Disable Voicemail on Android‘s “Method 3: Using your Android’s Settings” just the ticket.
For the curious, other methods here involved third-party software, but we’ve always preferred bare bones suggestions when they sound just as good (“the best things in life are free”), if not better … so … we did the suggested steps of this procedure successfully on the student’s Android mobile phone. Along the way we photographed the steps involved (on my iPhone) to make today’s stream of consciousness PDF presentation for your viewing, appraisal, filtering, mulling, obfuscating, “what Hamlet did”, reading and perhaps even applying?! In a single sentence we could advise “tap the Phone app” and “look for Settings option off the three dots menu” and proceed deep into the menu system looking for “Call Forwarding settings” and once there, “disabling” (a lot, and everywhere).
Did you know?
For all those horrified at the prospect (of disabling Voicemail) … you still end up with notifications of missed calls in the sense that the look of the Phone app icon on the desktop of your Android phone, even doing away with Voicemail. It will show up the top right of its icon as a ringed number (of, now, only, missed calls).
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.