Video to Amended Animated GIF Mobile Slide Swap Tutorial

Video to Amended Animated GIF Mobile Slide Swap Tutorial

Video to Amended Animated GIF Mobile Slide Swap Tutorial

The “drag” about yesterday’s Video to Amended Animated GIF Drag Slide Swap Tutorial‘s slide swapping functionality was that mobile platforms were left out. Sometimes there is no alternative modus operandi to offer a mobile user, but here, we did not need to …

  • simulate drag and drop with double clicking kind of logic … but, rather, just …
  • simulate drag and drop with single clicking kind of logic … and so, also not restrict the swapping to adjoining slides … via new “onclick” Javascript function logic …
    <?php echo ”

    function mspanhover(elmnt) {
    if (spanso.length == 0) {
    if (dragto.length == 0) {
    dragto.push(elmnt.id.replace('ours',''));
    } else {
    dragto[0]=elmnt.id.replace('ours','');
    }
    if (document.getElementById(('slideshow' + dragto[0]).replace(/slideshow1$/g,'slideshow')).value != '') {
    spanso.push(elmnt);
    }
    } else if (spanso.length == 1) {
    if (elmnt.id != spanso[0].id) {
    if (dragfrom.length == 0) {
    dragfrom.push(elmnt.id.replace('ours',''));
    } else {
    dragfrom[0]=elmnt.id.replace('ours','');
    }
    if (document.getElementById(('slideshow' + dragfrom[0]).replace(/slideshow1$/g,'slideshow')).value != '') {
    var yesdoit=confirm('Swap Image ' + dragto[0] + ' for Image ' + dragfrom[0] + ' content?');
    if (yesdoit) {
    var fromx=document.getElementById(('slideshow' + dragto[0]).replace(/slideshow1$/g,'slideshow')).value;
    var tox=document.getElementById(('slideshow' + dragfrom[0]).replace(/slideshow1$/g,'slideshow')).value;
    document.getElementById(('slideshow' + dragto[0]).replace(/slideshow1$/g,'slideshow')).value=tox;
    document.getElementById(('slideshow' + dragfrom[0]).replace(/slideshow1$/g,'slideshow')).value=fromx;
    var inthis=document.getElementById(('slideshow' + dragto[0]).replace(/slideshow1$/g,'slideshow'));
    inthis.style.color='black';
    inthis.style.opacity='1.0';
    inthis.style.background='';
    inthis.style.border='';
    inthis.style.outset='';
    inthis=document.getElementById(('slideshow' + dragfrom[0]).replace(/slideshow1$/g,'slideshow'));
    inthis.style.color='black';
    inthis.style.opacity='1.0';
    inthis.style.background='';
    inthis.style.border='';
    inthis.style.outset='';
    }
    spanso=[];
    dragfrom=[];
    dragto=[];
    }
    }
    }
    }

    “; ?>

Which, of course, begs the question, why not apply “single clicking kind of logic” for non-mobile platforms?

Irresistible arguments. Well presented. Joy to have in the class.

And so, is there any role going forward for the drag logic?

Interesting argument. But there are users who love drag and drop.

And so, for those non-mobile users we allow the two approaches to co-exist. One thing we do for mobile platforms, alone, though, is to set the “text-decoration” (CSS) styling of those “Tutorial Slideshow” elements be set to “underline” to make up for the lack of a span title attribute the user would see on a non-mobile platform as they hover over that span element for the changed tutorial_to_animated_gif.php our inhouse Animated GIF Creator helper PHP web application.


Previous relevant Video to Amended Animated GIF Drag Slide Swap Tutorial is shown below.

Video to Amended Animated GIF Drag Slide Swap Tutorial

Video to Amended Animated GIF Drag Slide Swap Tutorial

Today’s work improving on yesterday’s Video to Amended Animated GIF Alignment Tutorial, has, yet again, alas, only a non-mobile platform applicability, that being …

Drag and Drop

… methodologies to allow for Animated GIF slide swaps with an adjoining slide (slot) because

The reason we think those non-mobile users will enjoy this functionality, if anything like me, is that we might browse for images in a sorted bunch and assume all is well, but that order may not suit in the animated GIF order structure, and here is a mechanism that might help.

We got great help from How To Create a Draggable HTML Element (by W3Schools), thanks, piecing together the (PHP writes) Javascript benefitting from yesterday’s work lining up the “Tutorial Slideshow” span ( now including onmouseover=spanhover(this); onmouseout=spanunhover(this); ) elements over to the left of the webpage, with …

<?php echo ”

var dragfrom=[];
var dragto=[];

function spanhover(elmnt) {
var srectz=null, srecty=null, srectx=null, sifilter=null;
if (1 == 1) {
if (document.getElementById('y' + elmnt.id)) {
srecty=document.getElementById('y' + elmnt.id).getBoundingClientRect();
}
if (document.getElementById('z' + elmnt.id)) {
srectz=document.getElementById('z' + elmnt.id).getBoundingClientRect();
srectx=document.getElementById('x' + elmnt.id).getBoundingClientRect();
sifilter=document.getElementById('x' + elmnt.id).getBoundingClientRect();
document.getElementById('z' + elmnt.id).style.position='absolute';
//document.getElementById('z' + elmnt.id).style.left='' + srectz.left + 'px';
document.getElementById('x' + elmnt.id).style.position='absolute';
//document.getElementById('x' + elmnt.id).style.left='' + srectx.left + 'px';
document.getElementById('ifilter').style.position='absolute';
//document.getElementById('ifilter').style.left='' + sifilter.left + 'px';
}
if (document.getElementById('y' + elmnt.id)) {
document.getElementById('y' + elmnt.id).style.position='absolute';
//document.getElementById('y' + elmnt.id).style.left='' + srecty.left + 'px';
document.getElementById('y' + elmnt.id).style.color='blue';
}
}
elmnt.style.opacity='0.5';
elmnt.title='You can swap (or drag) this image content one down or up';
elmnt.style.position='absolute';
dragElement(elmnt);
}

function spanunhover(elmnt) {
if (1 == 1) {
if (document.getElementById('z' + elmnt.id)) {
document.getElementById('z' + elmnt.id).style.position='relative';
document.getElementById('x' + elmnt.id).style.position='relative';
document.getElementById('ifilter').style.position='relative';
}
if (document.getElementById('y' + elmnt.id)) {
document.getElementById('y' + elmnt.id).style.position='relative';
document.getElementById('y' + elmnt.id).style.color='black';
}
}
elmnt.style.opacity='1.0';
elmnt.style.position='relative';
elmnt.title='';
elmnt.onmousedown=function(evt){ evt=evt; };
elmnt.onmouseup=function(evt){ evt=evt; };
elmnt.onmousemove=function(evt){ evt=evt; };
}

function dragElement(elmnt) { // thanks to https://www.w3schools.com/howto/howto_js_draggable.asp
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + 'header')) {
// if present, the header is where you move the DIV from:
document.getElementById(elmnt.id + 'eader').onmousedown = dragMouseDown;
} else {
// otherwise, move the DIV from anywhere inside the DIV:
elmnt.onmousedown = dragMouseDown;
if (dragfrom.length == 1) {
closeDragElement();
//if (('dragfrom[0]=' + dragfrom[0] + ' and dragto[0]=' + dragto[0]).length <= 40) {
//alert('dragfrom[0]=' + dragfrom[0] + ' and dragto[0]=' + dragto[0]);
// //dragfrom[0]=eval('' + elmnt.target.id.replace('ours',''));
//}
}
}

function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}

function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
if (e.clientX) {
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
} else if (e.pageX) {
pos1 = pos3 - e.pageX;
pos2 = pos4 - e.pageY;
pos3 = e.pageX;
}
// set the element new position:
if (eval('' + pos2) > 0) {
if (dragfrom.length == 0) {
dragfrom.push(eval('' + e.target.id.replace('ours','')));
dragto.push(eval(1 + eval('' + e.target.id.replace('ours',''))));
} else {
dragfrom[0]=eval('' + e.target.id.replace('ours',''));
dragto[0]=eval(1 + eval('' + e.target.id.replace('ours','')));
}
//alert('heading south');
} else if (eval('' + pos2) < 0) {
//alert('heading north');
if (dragfrom.length == 0) {
dragfrom.push(eval('' + e.target.id.replace('ours','')));
dragto.push(eval(-1 + eval('' + e.target.id.replace('ours',''))));
} else {
dragfrom[0]=eval('' + e.target.id.replace('ours',''));
dragto[0]=eval(-1 + eval('' + e.target.id.replace('ours','')));
}
} else if (1 == 3) {
elmnt.style.top = (elmnt.offsetTop - pos2) + 'px';
elmnt.style.left = (elmnt.offsetLeft - pos1) + 'px';
}
}

function closeDragElement() {
// stop moving when mouse button is released:
if (dragfrom.length != 0) {
if (document.getElementById('ours' + dragto[0])) {
if (document.getElementById(('slideshow' + dragto[0]).replace(/slideshow1$/g,'slideshow')).value != '' && document.getElementById(('slideshow' + dragfrom[0]).replace(/slideshow1$/g,'slideshow')).value != '') {
var yesdoit=confirm('Swap Image ' + dragto[0] + ' for Image ' + dragfrom[0] + ' content?');
if (yesdoit) {
var fromx=document.getElementById(('slideshow' + dragto[0]).replace(/slideshow1$/g,'slideshow')).value;
var tox=document.getElementById(('slideshow' + dragfrom[0]).replace(/slideshow1$/g,'slideshow')).value;
document.getElementById(('slideshow' + dragto[0]).replace(/slideshow1$/g,'slideshow')).value=tox;
document.getElementById(('slideshow' + dragfrom[0]).replace(/slideshow1$/g,'slideshow')).value=fromx;
var inthis=document.getElementById(('slideshow' + dragto[0]).replace(/slideshow1$/g,'slideshow'));
inthis.style.color='black';
inthis.style.opacity='1.0';
inthis.style.background='';
inthis.style.border='';
inthis.style.outset='';
inthis=document.getElementById(('slideshow' + dragfrom[0]).replace(/slideshow1$/g,'slideshow'));
inthis.style.color='black';
inthis.style.opacity='1.0';
inthis.style.background='';
inthis.style.border='';
inthis.style.outset='';
}
}
}
dragfrom=[];
dragto=[];
}
document.onmouseup = null;
document.onmousemove = null;
document.onmousedown = null;
}
}

“; ?>

… to bring this about for the changed tutorial_to_animated_gif.php our inhouse Animated GIF Creator helper PHP web application.


Previous relevant Video to Amended Animated GIF Alignment Tutorial is shown below.

Video to Amended Animated GIF Preview Forever Tutorial

Video to Amended Animated GIF Alignment Tutorial

Around here when “alignment” thoughts are teamed with “web design” we still like the “oldy worldy” HTML table element approach, but such an idea felt a bit too extra kludgy regarding the “dynamically vertically expanding” ideas in the Animated GIF Creator (PHP) web application of yesterday’s Video to Amended Animated GIF Preview Forever Tutorial.

We could apply pretty complex CSS styling and use “div” elements, no doubt! But we opted for some application of new textbox applicable CSS that uses …

  1. percentage widths ( width: 80%; )
  2. float: right;
  3. margin-right: 1%;

… and then work at making other elements align around this “good start” having a neat right hand edge for the “delay(s)” and “slide(s)” textboxes. An impediment to good “alignment” results also had us revisiting our penchant for any CSS “align: center” ideas, instead making “alignment” on the left hand side of the web application be “to the left” (doh!)

Let’s take a look at (PHP writes) Javascript alignment related changes to “previewing” logic that augments the PHP variable change

<?php

$seventypc="80%;float:right;margin-right:1%";

?>

… is …

<?php echo ”

var lastiid='', relatedto=null;
var delaylastiid='', delayrelatedto=null, delayslidenum=-1, delaythisslide=-1, delaysare=[];


function prenext() {
if (delayrelatedto) {
if (delaythisslide >= delayslidenum) {
delaythisslide=1;
document.getElementById('delay').style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + document.getElementById('slideshow').value + '\")';
setTimeout(prenext, eval('' + delaysare[0]));
} else {
delaythisslide++;
document.getElementById('delay').style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + document.getElementById('slideshow' + eval(0 + eval(delaythisslide))).value + '\")';
if (delaythisslide <= delaysare.length) {
setTimeout(prenext, eval('' + delaysare[eval(-1 + eval('' + delaythisslide))]));
} else {
setTimeout(prenext, eval('' + delaysare[0]));
}
}
}
}


function preanimate(inthis, inthisvalue) {
var delaysuff='';
delaysare=inthisvalue.split(',');
if (delayslidenum == -1 || 1 == 1) {
delayslidenum=-1;
while (document.getElementById('slideshow' + delaysuff).value != '') {
if (delayslidenum == -1) {
delayslidenum=1;
delaysuff='' + eval(1 + eval('' + delayslidenum));
} else {
delayslidenum++;
delaysuff='' + eval(1 + eval('' + delayslidenum));
}
}
}
delaythisslide=1;
setTimeout(prenext, eval('' + delaysare[0]));
return document.getElementById('slideshow').value;
}


function preafterbithis() {
if (delayrelatedto) {
if (delaylastiid == ('' + delayrelatedto.id)) {
delaylastiid='';
//delayrelatedto=null;
}
} else {
delaylastiid='';
}
}


function preinrelatedto() {
var thisappi=1;
if (delayrelatedto) {
if (('' + delayrelatedto.title).indexOf('ong hover') != -1) {
var appiwords=('' + delayrelatedto.title).replace(' after losing focus', ' after losing focus 0').split(' ');
delayrelatedto.title+=' ' + eval(1 + eval(appiwords[eval(-1 + appiwords.length)]));
if (eval(1 + eval(appiwords[eval(-1 + appiwords.length)])) <= 7) { delayrelatedto.style.border='' + eval(1 + eval(appiwords[eval(-1 + appiwords.length)])) + 'px dotted yellow'; delayrelatedto.style.borderLeftStyle='solid'; }
setTimeout(preinrelatedto, 990);
}
}
}


function prebithis(inthis) {
if (inthis.value.trim() != '') {
if (delayrelatedto) {
if (('' + inthis.id) != ('' + delayrelatedto.id)) {
preunbithis(delayrelatedto);
delayrelatedto=null;
}
}
if (('' + inthis.getAttribute('data-oh')).replace(/^undefined$/g,'').replace(/^null$/g,'') == '') {
inthis.setAttribute('data-oh', '' + inthis.getBoundingClientRect().height);
if (document.getElementById('ours0')) { document.getElementById('ours0').setAttribute('data-oh', '' + document.getElementById('ours0').getBoundingClientRect().height); }
}
if (('' + inthis.title).indexOf('ong hover') == -1) {
inthis.title+=' ... long hover of 7 seconds keeps background image in place after losing focus';
} else {
inthis.title=inthis.title.split('ong hover')[0] + 'ong hover of 7 seconds keeps background image in place after losing focus';
}
inthis.style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + preanimate(inthis, inthis.value) + '\")';
inthis.style.height='80px';
if (document.getElementById('ours0')) {
document.getElementById('ours0').style.height='80px';
document.getElementById('ours0').style.display='inline-block';
}

inthis.style.backgroundSize='contain';
inthis.style.backgroundRepeat='no-repeat';
inthis.style.backgroundPosition='right top';
delaylastiid='' + inthis.id;
delayrelatedto=inthis;
setTimeout(preinrelatedto, 990);
setTimeout(preafterbithis, 7000);
}
}


function preunbithis(inthis) {
if (inthis.value.trim() != '' && delaylastiid == ('' + inthis.id)) {
if (('' + inthis.title).indexOf('ong hover') != -1) {
inthis.title=inthis.title.split('ong hover')[0] + 'ong hover keeps background animated GIF image in place after losing focus';
}
if (delayrelatedto) {
delayrelatedto=null;
}
if (('' + inthis.getAttribute('data-oh')).replace(/^undefined$/g,'').replace(/^null$/g,'') != '') {
inthis.style.height='' + inthis.getAttribute('data-oh') + 'px';
if (document.getElementById('ours0')) { document.getElementById('ours0').style.height='' + document.getElementById('ours0').getAttribute('data-oh') + 'px'; document.getElementById('ours0').style.display='inline'; }
}
inthis.style.color='black';
inthis.style.opacity='1.0';
inthis.style.background='';
inthis.style.border='';
inthis.style.outset='';
}
}


function afterbithis() {
if (relatedto) {
if (lastiid == ('' + relatedto.id)) {
lastiid='';
relatedto=null;
}
} else {
lastiid='';
}
}


function inrelatedto() {
var thisappi=1;
if (relatedto) {
if (('' + relatedto.title).indexOf('ong hover') != -1) {
var appiwords=('' + relatedto.title).replace(' after losing focus', ' after losing focus 0').split(' ');
relatedto.title+=' ' + eval(1 + eval(appiwords[eval(-1 + appiwords.length)]));
if (eval(1 + eval(appiwords[eval(-1 + appiwords.length)])) <= 7) { relatedto.style.border='' + eval(1 + eval(appiwords[eval(-1 + appiwords.length)])) + 'px dotted yellow'; relatedto.style.borderLeftStyle='solid'; }
setTimeout(inrelatedto, 990);
}
}
}


function bithis(inthis) {
if (inthis.value.trim() != '') {
if (relatedto) {
if (('' + inthis.id) != ('' + relatedto.id)) {
unbithis(relatedto);
relatedto=null;
}
}
if (('' + inthis.getAttribute('data-oh')).replace(/^undefined$/g,'').replace(/^null$/g,'') == '') {
inthis.setAttribute('data-oh', '' + inthis.getBoundingClientRect().height);
if (('' + inthis.id) == 'slideshow') {
if (document.getElementById('ours1')) { document.getElementById('ours1').setAttribute('data-oh', '' + document.getElementById('ours1').getBoundingClientRect().height); }
} else if (('' + inthis.id).indexOf('slideshow') == 0) {
document.getElementById('ours' + ('' + inthis.id).replace('slideshow','')).setAttribute('data-oh', '' + document.getElementById('ours' + ('' + inthis.id).replace('slideshow','')).getBoundingClientRect().height);
}

}
if (inthis.value.indexOf('data:') == 0) {
if (('' + inthis.title).indexOf('ong hover') == -1) {
inthis.title+=' ... long hover of 7 seconds keeps background image in place after losing focus';
} else {
inthis.title=inthis.title.split('ong hover')[0] + 'ong hover of 7 seconds keeps background image in place after losing focus';
}
inthis.style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + inthis.value + '\")';
inthis.style.color='rgba(240,240,240,0.2)';
inthis.style.height='80px';
if (('' + inthis.id) == 'slideshow') {
if (document.getElementById('ours1')) { document.getElementById('ours1').style.height='80px'; document.getElementById('ours1').style.display='inline-block'; }
} else if (('' + inthis.id).indexOf('slideshow') == 0) {
document.getElementById('ours' + ('' + inthis.id).replace('slideshow','')).style.height='80px';
document.getElementById('ours' + ('' + inthis.id).replace('slideshow','')).style.display='inline-block';
}

inthis.style.backgroundSize='contain';
inthis.style.backgroundRepeat='no-repeat';
inthis.style.backgroundPosition='right top';
lastiid='' + inthis.id;
relatedto=inthis;
setTimeout(inrelatedto, 1000);
} else if (inthis.value.indexOf('.') != -1) {
if (('' + inthis.title).indexOf('ong hover') == -1) {
inthis.title+=' ... long hover of 7 seconds keeps background image in place after losing focus';
} else {
inthis.title=inthis.title.split('ong hover')[0] + 'ong hover of 7 seconds keeps background image in place after losing focus';
}
inthis.style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + inthis.value + '\")';
inthis.style.height='80px';
if (('' + inthis.id) == 'slideshow') {
if (document.getElementById('ours1')) { document.getElementById('ours1').style.height='80px'; document.getElementById('ours1').style.display='inline-block'; }
} else if (('' + inthis.id).indexOf('slideshow') == 0) {
document.getElementById('ours' + ('' + inthis.id).replace('slideshow','')).style.height='80px';
document.getElementById('ours' + ('' + inthis.id).replace('slideshow','')).style.display='inline-block';
}

inthis.style.backgroundSize='contain';
inthis.style.backgroundRepeat='no-repeat';
inthis.style.backgroundPosition='right top';
lastiid='' + inthis.id;
relatedto=inthis;
setTimeout(inrelatedto, 990);
}
setTimeout(afterbithis, 7000);
}
}


function unbithis(inthis) {
if (inthis.value.trim() != '' && lastiid == ('' + inthis.id)) {
if (('' + inthis.title).indexOf('ong hover') != -1) {
inthis.title=inthis.title.split('ong hover')[0] + 'ong hover keeps background image in place after losing focus';
}
if (relatedto) {
relatedto=null;
}
if (('' + inthis.getAttribute('data-oh')).replace(/^undefined$/g,'').replace(/^null$/g,'') != '') {
inthis.style.height='' + inthis.getAttribute('data-oh') + 'px';
if (('' + inthis.id) == 'slideshow') {
if (document.getElementById('ours1')) { document.getElementById('ours1').style.height='' + document.getElementById('ours1').getAttribute('data-oh') + 'px'; document.getElementById('ours1').style.display='inline'; }
} else if (('' + inthis.id).indexOf('slideshow') == 0) {
document.getElementById('ours' + ('' + inthis.id).replace('slideshow','')).style.height='' + document.getElementById('ours' + ('' + inthis.id).replace('slideshow','')).getAttribute('data-oh') + 'px';
document.getElementById('ours' + ('' + inthis.id).replace('slideshow','')).style.display='inline';
}

}
inthis.style.color='black';
inthis.style.opacity='1.0';
inthis.style.background='';
inthis.style.border='';
inthis.style.outset='';
}
}

“; ?>

… for the changed tutorial_to_animated_gif.php our inhouse Animated GIF Creator helper PHP web application.


Previous relevant Video to Amended Animated GIF Preview Forever Tutorial is shown below.

Video to Amended Animated GIF Preview Forever Tutorial

Video to Amended Animated GIF Preview Forever Tutorial

Onto yesterday’s Video to Amended Animated GIF Slide Preview Forever Tutorial, am sure there are a lot of readers out there who’d like …

  • not only the possibility for a preview of individual slide images … but …
  • a preview approximation of the final animated GIF (we decide to offer in non-mobile hover and long hover scenarios for the “delay” textbox)

… positioned there because the delay is what makes an animated GIF be the “animation” it is.

If you saw this coming, you’ll not be too surprised by the PHP self contained work that complements the “delay” textbox’s onmouseover=prebithis(this); onmouseout=preunbithis(this); new Javascript functionality …

<?php echo ”

var delaylastiid='', delayrelatedto=null, delayslidenum=-1, delaythisslide=-1, delaysare=[];

function prenext() {
if (delayrelatedto) {
if (delaythisslide >= delayslidenum) {
delaythisslide=1;
document.getElementById('delay').style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + document.getElementById('slideshow').value + '\")';
setTimeout(prenext, eval('' + delaysare[0]));
} else {
delaythisslide++;
document.getElementById('delay').style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + document.getElementById('slideshow' + eval(0 + eval(delaythisslide))).value + '\")';
if (delaythisslide <= delaysare.length) {
setTimeout(prenext, eval('' + delaysare[eval(-1 + eval('' + delaythisslide))]));
} else {
setTimeout(prenext, eval('' + delaysare[0]));
}
}
}
}

function preanimate(inthis, inthisvalue) {
var delaysuff='';
delaysare=inthisvalue.split(',');
if (delayslidenum == -1 || 1 == 1) {
delayslidenum=-1;
while (document.getElementById('slideshow' + delaysuff).value != '') {
if (delayslidenum == -1) {
delayslidenum=1;
delaysuff='' + eval(1 + eval('' + delayslidenum));
} else {
delayslidenum++;
delaysuff='' + eval(1 + eval('' + delayslidenum));
}
}
}
delaythisslide=1;
setTimeout(prenext, eval('' + delaysare[0]));
return document.getElementById('slideshow').value;
}

function preafterbithis() {
if (delayrelatedto) {
if (delaylastiid == ('' + delayrelatedto.id)) {
delaylastiid='';
//delayrelatedto=null;
}
} else {
delaylastiid='';
}
}

function preinrelatedto() {
var thisappi=1;
if (delayrelatedto) {
if (('' + delayrelatedto.title).indexOf('ong hover') != -1) {
var appiwords=('' + delayrelatedto.title).replace(' after losing focus', ' after losing focus 0').split(' ');
delayrelatedto.title+=' ' + eval(1 + eval(appiwords[eval(-1 + appiwords.length)]));
if (eval(1 + eval(appiwords[eval(-1 + appiwords.length)])) <= 7) { delayrelatedto.style.border='' + eval(1 + eval(appiwords[eval(-1 + appiwords.length)])) + 'px dotted yellow'; }
setTimeout(preinrelatedto, 1000);
}
}
}


function prebithis(inthis) {
if (inthis.value.trim() != '') {
if (delayrelatedto) {
if (('' + inthis.id) != ('' + delayrelatedto.id)) {
preunbithis(delayrelatedto);
delayrelatedto=null;
}
}
if (('' + inthis.getAttribute('data-oh')).replace(/^undefined$/g,'').replace(/^null$/g,'') == '') {
inthis.setAttribute('data-oh', '' + inthis.getBoundingClientRect().height);
}
if (('' + inthis.title).indexOf('ong hover') == -1) {
inthis.title+=' ... long hover of 7 seconds keeps background image in place after losing focus';
} else {
inthis.title=inthis.title.split('ong hover')[0] + 'ong hover of 7 seconds keeps background image in place after losing focus';
}
inthis.style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + preanimate(inthis, inthis.value) + '\")';
inthis.style.height='80px';
inthis.style.backgroundSize='contain';
inthis.style.backgroundRepeat='no-repeat';
inthis.style.backgroundPosition='right top';
delaylastiid='' + inthis.id;
delayrelatedto=inthis;
setTimeout(preinrelatedto, 1000);
setTimeout(preafterbithis, 7000);
}
}


function preunbithis(inthis) {
if (inthis.value.trim() != '' && delaylastiid == ('' + inthis.id)) {
if (('' + inthis.title).indexOf('ong hover') != -1) {
inthis.title=inthis.title.split('ong hover')[0] + 'ong hover keeps background animated GIF image in place after losing focus';
}
if (delayrelatedto) {
delayrelatedto=null;
}
if (('' + inthis.getAttribute('data-oh')).replace(/^undefined$/g,'').replace(/^null$/g,'') != '') {
inthis.style.height='' + inthis.getAttribute('data-oh') + 'px';
}
inthis.style.color='black';
inthis.style.opacity='1.0';
inthis.style.background='';
inthis.style.border='';
}
}

“; ?>

… for the changed tutorial_to_animated_gif.php our inhouse Animated GIF Creator helper PHP web application.


Previous relevant Video to Amended Animated GIF Slide Preview Forever Tutorial is shown below.

Video to Amended Animated GIF Slide Preview Forever Tutorial

Video to Amended Animated GIF Slide Preview Forever Tutorial

Further to yesterday’s Video to Amended Animated GIF Slide Preview Tutorial

… and then, there’s the idea to leave the image thumbnail there

… concept. Wouldn’t you say? But, how to implement this? Well, as for the recent Landing Page Linked Background Images Long Hover Tutorial we figured that the “Long Hover” ideas form that independent and non-interfering (with existent non-mobile functionality) methodology we could look into, so that the “just hover” work became

<?php echo ”

var lastiid='', relatedto=null;


function afterbithis() {
if (relatedto) {
if (lastiid == ('' + relatedto.id)) {
lastiid='';
relatedto=null;
}
} else {
lastiid='';
}
}

function inrelatedto() {
var thisappi=1;
if (relatedto) {
if (('' + relatedto.title).indexOf('ong hover') != -1) {
var appiwords=('' + relatedto.title).replace(' after losing focus', ' after losing focus 0').split(' ');
relatedto.title+=' ' + eval(1 + eval(appiwords[eval(-1 + appiwords.length)]));
if (eval(1 + eval(appiwords[eval(-1 + appiwords.length)])) <= 7) { relatedto.style.border='' + eval(1 + eval(appiwords[eval(-1 + appiwords.length)])) + 'px dotted yellow'; }
setTimeout(inrelatedto, 1000);
}
}
}



function bithis(inthis) {
if (inthis.value.trim() != '') {
if (relatedto) {
if (('' + inthis.id) != ('' + relatedto.id)) {
unbithis(relatedto);
relatedto=null;
}
}

if (('' + inthis.getAttribute('data-oh')).replace(/^undefined$/g,'').replace(/^null$/g,'') == '') {
inthis.setAttribute('data-oh', '' + inthis.getBoundingClientRect().height);
}
if (inthis.value.indexOf('data:') == 0) {
if (('' + inthis.title).indexOf('ong hover') == -1) {
inthis.title+=' ... long hover of 7 seconds keeps background image in place after losing focus';
} else {
inthis.title=inthis.title.split('ong hover')[0] + 'ong hover of 7 seconds keeps background image in place after losing focus';
}

inthis.style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + inthis.value + '\")';
inthis.style.color='rgba(240,240,240,0.2)';
inthis.style.height='80px';
inthis.style.backgroundSize='contain';
inthis.style.backgroundRepeat='no-repeat';
inthis.style.backgroundPosition='right top';
lastiid='' + inthis.id;
relatedto=inthis;
setTimeout(inrelatedto, 1000);

} else if (inthis.value.indexOf('.') != -1) {
if (('' + inthis.title).indexOf('ong hover') == -1) {
inthis.title+=' ... long hover of 7 seconds keeps background image in place after losing focus';
} else {
inthis.title=inthis.title.split('ong hover')[0] + 'ong hover of 7 seconds keeps background image in place after losing focus';
}

inthis.style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + inthis.value + '\")';
inthis.style.height='80px';
inthis.style.backgroundSize='contain';
inthis.style.backgroundRepeat='no-repeat';
inthis.style.backgroundPosition='right top';
lastiid='' + inthis.id;
relatedto=inthis;
setTimeout(inrelatedto, 1000);

}
setTimeout(afterbithis, 7000);
}
}


function unbithis(inthis) {
if (inthis.value.trim() != '' && lastiid == ('' + inthis.id)) {
if (('' + inthis.title).indexOf('ong hover') != -1) {
inthis.title=inthis.title.split('ong hover')[0] + 'ong hover keeps background image in place after losing focus';
}
if (relatedto) {
relatedto=null;
}

if (('' + inthis.getAttribute('data-oh')).replace(/^undefined$/g,'').replace(/^null$/g,'') != '') {
inthis.style.height='' + inthis.getAttribute('data-oh') + 'px';
}
inthis.style.color='black';
inthis.style.opacity='1.0';
inthis.style.background='';
inthis.style.border='';
}
}

“; ?>

… to, again, accompany the (input type=text) slide textbox onmouseover=bithis(this); onmouseout=unbithis(this); “short hover” event logic callers, to get a taste for what is involved here, in the changed tutorial_to_animated_gif.php our inhouse Animated GIF Creator helper PHP web application.


Previous relevant Video to Amended Animated GIF Slide Preview Tutorial is shown below.

Video to Amended Animated GIF Slide Preview Tutorial

Video to Amended Animated GIF Slide Preview Tutorial

Keeping to the recent theme of interest in (the non-mobile) “onmouseover” (hover) and “onmouseout” events, today we improve our inhouse Animated GIF Creator helper PHP web application last talked about with Video to Amended Animated GIF via ffmpeg Tutorial.

The reason we think those non-mobile users will enjoy this functionality, if anything like me, is that we might browse for images in a sorted bunch and assume all is well, but that order may not suit in the animated GIF order structure, and here is a mechanism that might help.

And so take a look at the changed tutorial_to_animated_gif.php our inhouse Animated GIF Creator helper PHP web application

<?php echo ”

function bithis(inthis) {
if (inthis.value.trim() != '') {
if (('' + inthis.getAttribute('data-oh')).replace(/^undefined$/g,'').replace(/^null$/g,'') == '') {
inthis.setAttribute('data-oh', '' + inthis.getBoundingClientRect().height);
}
if (inthis.value.indexOf('data:') == 0) {
inthis.style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + inthis.value + '\")';
inthis.style.color='rgba(240,240,240,0.2)';
inthis.style.height='80px';
inthis.style.backgroundSize='contain';
inthis.style.backgroundRepeat='no-repeat';
inthis.style.backgroundPosition='right top';
} else if (inthis.value.indexOf('.') != -1) {
inthis.style.backgroundImage='linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)),URL(\"' + inthis.value + '\")';
inthis.style.height='80px';
inthis.style.backgroundSize='contain';
inthis.style.backgroundRepeat='no-repeat';
inthis.style.backgroundPosition='right top';
}
}
}

function unbithis(inthis) {
if (inthis.value.trim() != '') {
if (('' + inthis.getAttribute('data-oh')).replace(/^undefined$/g,'').replace(/^null$/g,'') != '') {
inthis.style.height='' + inthis.getAttribute('data-oh') + 'px';
}
inthis.style.color='black';
inthis.style.opacity='1.0';
inthis.style.background='';
}
}

“; ?>

… to accompany the (input type=text) slide textbox onmouseover=bithis(this); onmouseout=unbithis(this); event logic callers, to get a taste for what is involved here.


Previous relevant Video iPad Time Lapse Animated GIF via ffmpeg Tutorial is shown below.

Video iPad Time Lapse Animated GIF via ffmpeg Tutorial

Video iPad Time Lapse Animated GIF via ffmpeg Tutorial

We wanted to try out a small Time Lapse video …

Time-lapse photography is a technique whereby the frequency at which film frames are captured (the frame rate) is much more spread out than the frequency used to view the sequence. When played at normal speed, time appears to be moving faster and thus lapsing. For example, an image of a scene may be captured at 1 frame per second, but then played back at 30 frames per second; the result is an apparent 30 times speed increase. In a similar manner, film can also be played at a much lower rate than it was captured at, slowing down an otherwise fast action, as in slow motion or high-speed photography.

… created with the iPad Camera app “Video Time Lapse” option. Small being the operative word. So small in fact, that for a few seconds of video, it is possible to email your video off to an emailee receiver, the tradeoff being that when they play it at many speeds it is likely to play in the jerky fashion … like with our Nala Time Lapse (iPad Camera app created) video below

… which we downloaded to this MacBook Pro that has (the great opensource) ffmpeg installed ready to reconstitute some slides from the video via …


$ ffmpeg -i nala_timelapse.mov -r 5 nala_image-%04d.jpeg
ffmpeg version 4.1.1 Copyright (c) 2000-2019 the FFmpeg developers
built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1.1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-videotoolbox --disable-libjack --disable-indev=jack --enable-libaom --enable-libsoxr
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'nala_timelapse.mov':
Metadata:
major_brand : qt
minor_version : 0
compatible_brands: qt
creation_time : 2019-03-10T06:32:49.000000Z
com.apple.quicktime.location.ISO6709: -33.9074+151.1764+013.000/
com.apple.quicktime.make: Apple
com.apple.quicktime.model: iPad (5th generation)
com.apple.quicktime.software: 12.1.1
com.apple.quicktime.creationdate: 2019-03-10T17:32:19+1100
Duration: 00:00:01.23, start: 0.000000, bitrate: 20015 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc), 1920x1080, 20003 kb/s, 30 fps, 30 tbr, 600 tbn, 1200 tbc (default)
Metadata:
rotate : 180
creation_time : 2019-03-10T06:32:49.000000Z
handler_name : Core Media Video
encoder : H.264
Side data:
displaymatrix: rotation of -180.00 degrees
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> mjpeg (native))
Press [q] to stop, [?] for help
Output #0, image2, to 'nala_image-%04d.jpeg':
Metadata:
major_brand : qt
minor_version : 0
compatible_brands: qt
com.apple.quicktime.creationdate: 2019-03-10T17:32:19+1100
com.apple.quicktime.location.ISO6709: -33.9074+151.1764+013.000/
com.apple.quicktime.make: Apple
com.apple.quicktime.model: iPad (5th generation)
com.apple.quicktime.software: 12.1.1
encoder : Lavf58.20.100
Stream #0:0(und): Video: mjpeg, yuvj420p(pc), 1920x1080, q=2-31, 200 kb/s, 5 fps, 5 tbn, 5 tbc (default)
Metadata:
encoder : Lavc58.35.100 mjpeg
creation_time : 2019-03-10T06:32:49.000000Z
handler_name : Core Media Video
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
displaymatrix: rotation of -0.00 degrees
frame= 8 fps=0.0 q=12.5 Lsize=N/A time=00:00:01.60 bitrate=N/A dup=0 drop=29 speed=4.67x
video:974kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
$ ls -l nala_image-*.jpeg
-rw-r--r-- 1 user admin 124191 10 Mar 19:36 nala_image-0001.jpeg
-rw-r--r-- 1 user admin 174070 10 Mar 19:36 nala_image-0002.jpeg
-rw-r--r-- 1 user admin 190966 10 Mar 19:36 nala_image-0003.jpeg
-rw-r--r-- 1 user admin 150169 10 Mar 19:36 nala_image-0004.jpeg
-rw-r--r-- 1 user admin 141476 10 Mar 19:36 nala_image-0005.jpeg
-rw-r--r-- 1 user admin 91377 10 Mar 19:36 nala_image-0006.jpeg
-rw-r--r-- 1 user admin 69113 10 Mar 19:36 nala_image-0007.jpeg
-rw-r--r-- 1 user admin 56253 10 Mar 19:36 nala_image-0008.jpeg

$

And then to generate our Animated GIF animation used in today’s blog posting image we used the inhouse (with great help as you can read at Animated GIF and Video via PHP Writing PHP Data URI Tutorial) Animated GIF creator … “an animation cycle”.

Read more at Video via Slide Images and Back Again via ffmpeg Primer Tutorial below for more information, especially if you need to install ffmpeg yourself.


Previous relevant Video via Slide Images and Back Again via ffmpeg Primer Tutorial is shown below.

Video via Slide Images and Back Again via ffmpeg Primer Tutorial

Video via Slide Images and Back Again via ffmpeg Primer Tutorial

Reading yesterday’s LibreOffice Spreadsheet via dBase Primer Tutorial you can’t say I didn’t warn you about my interest in ants (and bees)? Glad you asked?

Did you know?

  • the queen ant (often just one per ant colony) is not a leader as such in thinking out strategies … believe it or not …
  • it is believed ant colony strategies are worked by what we might call “groupthink”
  • ants march in line often and the scent that the ants leave behind is pheromone, that non-leader ants follow off that left behind by the “leader ant” … ie. “leader” of position, rather than “leader” of hierarchy

So seeing some ants walking in line up a power pole, used an iPhone to capture a very short video (short enough to use the iPhone’s Photo app’s Share via Mail (attachment) method of emailing to the MacBook Pro, and then (Gmail website) downloading) of this, and later, buck the “ant” trend, and “anthropomorphise” a “star ant”, by honing in on an ant in this video and ring it (and its movement) before creating another “Star Ant Video”.

There are video editing approaches you could use, but what got us interested was the thought of …

  • break the video into its component parts … just like animations like “Bugs Bunny” … a series of (slide, or frame) images
  • edit those (slide) images to add the (we’ve decided should be) red ringing of our “Star Ant” … who we’ve decided you, the user can call whatever you so desire … aaaaaaarrrrrrr
  • reconstitute a new video from some new (slide) image components

That’s where one of our favourite Mac Os X friendly media players, which is also a command line “player” (yayyyyyy!) comes to the fore, for us. It’s the wonderful ffmpeg which we’ve had for a long time now on this MacBook Pro until a disk crash mentioned some weeks back. Could get it back off restore, but decided to reconsitute …

… as a fairly straightforward exercise (given you have Xcode installed already) via a How to install FFmpeg on Mac OS X webpage by René Calles, thanks, heaps, we discovered the commands that worked well for us that go …


ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install ffmpeg --with-fdk-aac --with-ffplay --with-freetype --with-frei0r --with-libass --with-libvo-aacenc --with-libvorbis --with-libvpx --with-opencore-amr --with-openjpeg --with-opus --with-rtmpdump --with-schroedinger --with-speex --with-theora --with-tools

… to (re)install ffmpeg so that, then …


ffmpeg -i IMG_0738.MOV -r 1 image-%04d.jpeg

… could create those original 7 (slide) images, though the use of a value bigger than 1 frames per second for the “-r” switch could be on the cards for your usages.

How to edit those images? We just used the Mac OS X version of PaintBrush and lined a lot of these images side by side across the screen to try to track our “Star Ant” and award it the “Red Ellipse PaintBrush Order of Merit” (for individualism … tee hee).

Reconstituting the new slides into a new video we remember was another talent of ffmpeg and found this useful webpage, thanks, on the topic of taking raw (slide) images to create a video via ffmpeg. Actually, though, we also had our previous very useful Animated GIF and Video via PHP Writing PHP Data URI Tutorial (presented below) to turn to to end up with the Mac OS X (Terminal session command line command …


ffmpeg -r 1 -i image-%04d.jpg ants.mp4

There are no worries with video file “workings” to do with uppercase and lowercase and names, so we …


cp IMG_0738.MOV ants.mov

… just for some consistency purposes (and could use “mv” to rename instead) so that we can show you …

Before … After … “Star Ant Video”

See a lot of all these goings on at today’s PDF slideshow.


Previous relevant Animated GIF and Video via PHP Writing PHP Data URI Tutorial is shown below.

Animated GIF and Video via PHP Writing PHP Data URI Tutorial

Animated GIF and Video via PHP Writing PHP Data URI Tutorial

There is a great open source command line application called “FFmpeg” that can create video (or convert video) from image slides (for instance), and so, if we merge functionality for this into yesterday’s Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial some “presentation” styles that our web application can process are now …

  • animated GIF
  • slideshow
  • video

As useful as “FFmpeg” is, it is not necessarily a default application existing on web server operating systems like our rjmprogramming.com.au’s CentOS server. But we do have it on our Mac OS X (MacBook Pro) operating system’s command line, so we write our PHP determining whether to …

  • create the video data there and then via “FFmpeg” and PHP’s exec method … or …
  • provide instructions to be able to create the video back at your client computer (that has “FFmpeg” perhaps) … to suit the …

    ffmpeg -r 1 -i %03d.jpg video.mp4

    … to create a video called video.mp4 with 1 second delays between (input) slides named 001.jpg then 002.jpg then 003.jpg etcetera … thanks useful webpage for the help … that in the command line can sometimes be played via …

    open video.mp4

    … or used in some HTML as per …

    <video controls id=ivideo type='video/mp4'><source src='video.mp4'></source></video>

    … that we show you, below, the Mac OS X local MAMP (Apache/PHP/MySql) web server running of today’s PHP to create …

If you are a regular at this blog and “FFmpeg” sounds a bit familiar to you, that’s probably because you’ve read FFmpeg Image Optimization Primer Tutorial on an earlier occasion … by candlelight … with the lights dimmed?!

See this in the context of how this PHP tutorial_to_animated_gif.php code changed for videos in this way or try it as a live run.


Previous relevant Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial is shown below.

Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial

Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial

To us, there are great similarities between animated GIFs and slideshows, as two forms of “presentation”, and so to extend yesterday’s Animated GIF via PHP Writing PHP Data URI Tutorial animated GIF creator “PHP Writes PHP” web application that now has the option for data URI “exports” we add the functionality for …

  • slideshow creation (using our inhouse methods) which defaults to a horizontal (hashtag type of) navigation … as well as adding a …
  • slideshow creation, with Data URI image data, using functionality as if CSS z-index (ie. slides stacked on top of each other in “overlay” style) was being used, but actually isn’t …

… that little bit different to another “stacked” (or z-index feeling) approach we talked about with Multiple Class Slideshow Details Tutorial, where HTML element “class” properties were changed so that the last class defined reflects the look of the slideshow slide desired at any given time. We just use an array, and a setTimeout timer to achieve the same ends today, with our work (or “presentation”). If this “horizontal versus stack” navigation choice interests you, also take a read of HTML Input Element Types Randomized History Tutorial.

Again, with all this added functionality, because it is “hosted” in an HTML iframe element all the existant web browser (Windows right click or Mac OS X two finger gesture) functionality can come into play, and make life quite interesting for your non-mobile users “collecting” data URIs … there are worse hobbies!

You can see this in the context of how this PHP tutorial_to_animated_gif.php code changed for slideshows in this way or try it as a live run.


Previous relevant Animated GIF via PHP Writing PHP Data URI Tutorial is shown below.

Animated GIF via PHP Writing PHP Data URI Tutorial

Animated GIF via PHP Writing PHP Data URI Tutorial

The previous relevant “PHP writes PHP” methodology animated GIF creator we talked about, first, with Animated GIF via PHP Writing PHP Primer Tutorial came back to mind yesterday with our Missing Javascript Audio on Unmute Tutorial, where we pondered on whether an animated GIF could be represented on a webpage by a data URI. Why take an interest in this? Data URIs are very important to do with …

  • future mobile development web form navigation benefits from their usage
  • the use of data URIs make your web pages independent of web server location issues, so make your web data more portable, and flexible

… and ideally, animated GIFs are also not just a decorative part of all this web application usage (as they can be a very efficient representation of an animation that could not be a more succinct way to show that animation or presentation), and if they can be made to be like any other GIF or image data file in the ways they can be represented (and used), then that is all for the good.

So we changed the Jeroen van Wissen’s inspired PHP (“PHP writes PHP” methodology) code tutorial_to_animated_gif.php code allow for this extra animated GIF data URI representation in a new additional HTML iframe (containing the animegif.html of code below) that when harnessing existant web browser (Windows right click or Mac OS X two finger gesture) functionality can glean for us, as required, that animated GIF’s data URI representation. But don’t get too excited about this being rocket science, in that with a bit of effort, and PHP, it could have been gleaned from what we already produced, in that (in PHP “land”) …


$lastbitto="\$fp = fopen('animegif.gif', 'w');
\$data = \$gif->GetAnimation();
\$dataUri = 'data:image/gif;base64,' . base64_encode(\$data);
fwrite(\$fp, \$data);
fclose(\$fp);
\$fp = fopen('animegif.html', 'w');
fwrite(\$fp, '<!doctype html><html><body><h1>Data URI version below<h1><br><h4> ... via web browser (Windows right click, Mac OS X two finger gesture ...</h4><br><img src=' . \"\\n\" . \$dataUri . \"\\n\" . ' title=DataURI></img></body></html>');
fclose(\$fp);";

You can see this in the context of how this PHP code changed in this way or try it as a live run.


Previous relevant Animated GIF via PHP Writing PHP Primer Tutorial is shown below.

Animated GIF via PHP Writing PHP Primer Tutorial

Animated GIF via PHP Writing PHP Primer Tutorial

We find another very useful reason for PHP to write PHP. Today we establish a PHP web application to dynamically create Animated GIF images via some still images, like Gifpal would do.

We have some great open source PHP code to thank for the basis of the functionality we found at Jeroen van Wissen’s very useful link, thanks.

Then we added a more user friendly interface to get the information off the user we need. We present this in an HTML form, which navigates to the same PHP to do the actual assembly of the Animated GIF via techniques where PHP writes PHP … and really needs to, to be useful.

Do you remember, last, when we did some PHP writing PHP functionality … PHP Writes PHP Vertical TextBoxes Primer Tutorial?

And inside the PHP it makes big use of the GD and Image Functions to read and write the image data we assemble via the user information.

This Animated GIF form of animation is the easiest to implement, as it consists of just the one GIF image file, but the user has very little control over the animation settings, such as the delay between stills, one of the settings we ask about in our web application.

Our PHP source code today you could call tutorial_to_animated_gif.php and we redirect you to some live run ideas …

  • normal run with HTML form which posts back to itself … live run
  • example GET parameters run (like our tutorial picture)

Hope you find this tutorial useful.

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


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


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


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


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


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


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


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


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


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


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


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


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

This entry was posted in eLearning, Event-Driven Programming, Tutorials and tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>