Animated GIF Creation Automation Arguments Tutorial

Animated GIF Creation Automation Arguments Tutorial

Animated GIF Creation Automation Arguments Tutorial

The automation measures in yesterday’s Animated GIF Creation Transparency Tutorial get an “arguments consideration” (maybe a five minute one, or perhaps ten minutes for “the outraged”) to help out ideas for our aspirational readers and users out there, who we are always keen to motivate, this Animated GIF Creator project potentially linked to user productivity, at its best.

If we want to improve automation ideas for these Animated GIF creations we need to use (initially ? and & “get”) arguments up at the web browser address bar for our exploratory user to not only allow for definition of …

  • their hTTp style animated GIF slide content basis (in a “get” irefresh labelled optional argument) … but as of today, how about …
    1. new “get” dimensions labelled optional argument defines the output Animated GIF dimensions in terms of width,height … eg. 300,600
    2. new “get” title labelled optional argument defines the wording of the watermark style Animated GIF title (basis) … eg. My+Animated+GIF
    3. new “get” titlecolour labelled optional argument defines the colour of the watermark style Animated GIF title … eg. olive
    4. new “get” titlemode labelled optional argument defines the watermark style Animated GIF title mode … eg. All

    … and please do not forget an optional argument we’re always havingthat’s always been there …

  • the “get” delay labelled optional argument defining the delay between animated GIF slides … eg. 800

? That would complete some pictures out there, we’re hoping?!

Does this feel like a step sideways to you, “the regular reader”? We’d agree, and are a little surprised a revisit (to this project) shows this need, but there you are. Sometimes, revisits help clarify!

This means a changed (in large part to reorganize “argument related” PHP code to the top, now) PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application can now handle

https://www.rjmprogramming.com.au/PHP/animegif/tutorial_to_animated_gif.php?title=Circular+Terminology&titlecolour=olive&titlemode=All
&dimensions=300,600&delay=800
&
irefresh=hTTps://www.rjmprogramming.com.au/HTMLCSS/circle_terminology.html+++++
#irefresh=hTTps://[HtmlWebpageWithSVG].html+++++


Previous relevant Animated GIF Creation Transparency Tutorial is shown below.

Animated GIF Creation Transparency Tutorial

Animated GIF Creation Transparency Tutorial

You might have heard …

Transparency begins at home.

… or not, because as far as we know, we just sprouted it?! Nevertheless, this matter of …

  • image transparency … in terms of the image being an Animated GIF slide … via …
  • SVG … or …
  • canvas

… deserves our consideration, we’ve decided, today … because …

Transparency begins at home.

We’ll just try our best here, but we have discovered a nuance that hadn’t tweaked with us before, considering “transparency” and using “canvas” elements. The …

  • [canvasElementContext].clearRect(0, 0, [canvasWidth], [canvasHeight]); // idea causes the canvas to become transparent ... different to the other concept like ...
  • [canvasElementContext].fillStyle='white';
    [canvasElementContext].fillRect(0, 0, [canvasWidth], [canvasHeight]); // this example idea causes the canvas to become white

It’s affected two “avenues of effect” (or is this a book?!) with our Animated GIF Creator logic …

  1. if a SVG+xml element data URI utf8 format representation mentions the word “transparent” we are now going to make the relevant helper canvas element background be transparent …
    <?php echo ”

    function drawInlineSVG(rawSVG, slidename) { // thanks to https://stackoverflow.com/questions/27230293/how-to-draw-an-inline-svg-in-dom-to-a-canvas
    var rsvg = new Blob([rawSVG], {type:'image/svg+xml;charset=utf-8'}),
    rdomURL = self.URL || self.webkitURL || self,
    rurl = rdomURL.createObjectURL(rsvg),
    rslidename=slidename,
    imgc = new Image;


    if (rawSVG.indexOf('transparent') != -1 || rawSVG.indexOf(window.btoa('transparent')) != -1) {
    istransparent=true;

    //document.getElementById('mycanvas').getContext('2d').clearRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
    } else {
    istransparent=false;
    //document.getElementById('mycanvas').getContext('2d').fillStyle='white';

    //document.getElementById('mycanvas').getContext('2d').fillRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
    }


    imgc.onload = function () {
    if (istransparent) {
    document.getElementById('mycanvas').width=imgc.width;
    document.getElementById('mycanvas').height=imgc.height;

    document.getElementById('mycanvas').getContext('2d').clearRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
    } else if (1 == 1) {
    document.getElementById('mycanvas').getContext('2d').fillStyle='white';

    document.getElementById('mycanvas').getContext('2d').fillRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
    }

    document.getElementById('mycanvas').getContext('2d').drawImage(this, 0, 0);
    rdomURL.revokeObjectURL(rurl);
    slideupdate(this, rslidename);
    };

    imgc.src = rurl;
    }

    “; ?>
    … and …
  2. the “+” means by which we involve our Scribble and Annotation helper (of animated GIF slide content) now has a new button (with its onclick event function) to ask about its main canvas element background colour …

    function colourize() {
    var huhcol=prompt('Enter canvas background colour or Cancel to ignore.', 'transparent');
    if (huhcol != null) {
    if (huhcol.trim() != '') {
    if (huhcol == 'transparent') {
    //alert(987);
    //alert('topielem.width=' + topielem.width);
    parent.document.getElementById('topcanvas').getContext('2d').fillStyle = huhcol;

    parent.document.getElementById('topcanvas').getContext('2d').clearRect(0,0,parent.document.getElementById('topcanvas').width,parent.document.getElementById('topcanvas').height);
    } else {
    parent.document.getElementById('topcanvas').getContext('2d').fillStyle = huhcol;

    parent.document.getElementById('topcanvas').getContext('2d').fillRect(0,0,parent.document.getElementById('topcanvas').width,parent.document.getElementById('topcanvas').height);
    }
    }
    }
    }

And so, we reckon it’s “transparent” (chortle, chortle) that yesterday’s Animated GIF Creation Automation Tutorial, created at home, and where (the vast majority of some readers know)

Transparency begins at home. Can someone please hand me the lemon juice.

… in …

… is worth a re-look.


Previous relevant Animated GIF Creation Automation Tutorial is shown below.

Animated GIF Creation Automation Tutorial

Animated GIF Creation Automation Tutorial

There are two competing issues going on with software development, of complexity, to challenge the skillset of the programmer …

  • keeping at an issue as it is fresh, and not letting go, as much as anything to keep up with where you are at, as with it being fresh in the mind … versus …
  • useful revisits after a bit of time to review the issue with fresher eyes, can often iron out issues not seen in “the heat of battle”

Today sees us relieved, undertaking a “second of the options above” scenario, regarding us creeping up on more Animated GIF Creation automation ideas we last talked about, with any depth, at Animated GIF Link Image Slide Tutorial.

What prompted the interest, just now, with this? Well, yesterday’s Animated GIF Creation Localhost Text Emoji Slide Tutorial‘s better and non-third-party and independent use of …

  • SVG … to …
  • canvas … via …
  • [canvasElement].toDataURL(‘image/jpeg’, 10) … way to derive a data URI for …
  • textbox … representing an Animated GIF slide content mechanism

… rather than rely on ImageMagick converting from SVG to PNG was a bit of a game changer for us. We thought the extending of its use to other parts of the web application would be a good move. Along this way we also worked out that our Animated GIF dimensioning also needed some tweaking at a new HTML form onsubmit event function intervention point …

<?php echo ”

function dothem() {
for (var iijj=0; iijj<slidecmds.length; iijj++) {
eval(slidecmds[iijj]);
}

if (document.getElementById('selwhs')) {
if (document.getElementById('selwhs').value.indexOf(',') != -1) {
owoh(document.getElementById('selwhs'));
}
}

}

“; ?>

… in our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application used in link below …

https://www.rjmprogramming.com.au/PHP/animegif/tutorial_to_animated_gif.php?irefresh=hTTps://[HtmlWebpageWithSVG].html+++++

… the revisiting of which showed us that the Circle Terminology circle_terminology.html SVG based HTML and Javascript also needed tweaking.


Previous relevant Animated GIF Link Image Slide Tutorial is shown below.

Animated GIF Link Image Slide Tutorial

Animated GIF Link Image Slide Tutorial

Yesterday’s Animated GIF SVG Slide Tutorial had us …

  • taking our animated GIF creator … starting with …
  • SVG user entry functionality … then allow for …
  • other image extraction from HTML user input via + … and today …
  • “a” link to either …
    1. QR Code … via ++ … or …
    2. Webpage Screenshot … via ++++

Do you see the pattern here? If you have a favoured character (ie. “+” here) involved in a user functionality behaviour decision you can give each a …


power of 2 number of characters

… (functionality meaning) and at the Javascript or PHP interpretive end of this arrangement you can know exactly what the user wants (in a way akin to how a bitmap can often be used) … so far this Javascript working (and tailorable into the future with some tweaking) as per …

<?php echo ”

function srchrefit(inbg) {
var outbg=inbg, outbis=[], ibis=0;
var ourblankend=blankend;
if (blankend != '') {
if (eval(eval('' + ourblankend.length) % 2) == 1) { // process img
ourblankend=ourblankend.substring(1);
outbg=outbg.replace(/data\:image\/svg\+xml/g, '!@#$%^&');
outbg=outbg.replace(/data\:image/g, ' SRC=\" data:image');
outbg=outbg.replace(/\!\@\#\$\%\^\&/g, 'data:image/svg+xml');
outbis=outbg.split('<img');
console.log('outbis.length=' + outbis.length + ' and outbg=' + outbg);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' src=\"') != -1) {
outbg=outbg.replace('<img' + outbis[ibis].split('>')[0], '<img' + outbis[ibis].split('>')[0].replace(' src=\"', ' SRC=\" '));
}
}
}
if (eval('' + ourblankend.length) == 4) { // process "a" links to Webpage Screenshot
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
} // ... or ...
} else if (eval('' + ourblankend.length) == 2) { // process "a" links to QR Code
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
}
}
return outbg;
}
return inbg;
}

“; ?>

… in our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application

https://www.rjmprogramming.com.au/PHP/animegif/tutorial_to_animated_gif.php?irefresh=hTTp://[HtmlWebpageWithSVG].html+++

… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a QR Code) …

https://www.rjmprogramming.com.au/PHP/animegif/tutorial_to_animated_gif.php?irefresh=hTTps://[HtmlWebpageWithSVG].html+++++

… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a Webpage Screenshot).


Previous relevant Animated GIF SVG Slide Tutorial is shown below.

Animated GIF SVG Slide Tutorial

Animated GIF SVG Slide Tutorial

The PHP GD library we use to help create animated GIFs (along with a whole lot of other help, it goes without saying) is not into vector graphics which is what …

  • Inkscape … as a vector graphics editor … and …
  • SVG … ie. Scalable Vector Graphics

… are really into … ooooohhh, aaaaahhhh … but luckily for us, the great ImageMagick offers functionality to convert a SVG image file into a PNG image file, via …

Non Windows Windows
convert infile.svg outfile.png magick.exe infile.svg outfile.png

… and we’re using that talent ImageMagick has to offer the user the chance, at any animated GIF slide textbox, the chance to enter encodeURIComponent and window.btoa sensitive entries whose (content) format could match (one of) …

… means by which a user can involve SVG input slides into their animated GIF creations in our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application further to yesterday’s Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial.

Below is a new (PHP writes) Javascript iframe (iois object below) onload event function for recognizing hTTps://[HtmlWebpageWithSVG].html as above, and setting the iframe’s “src” attribute to its value …

<?php echo ”

var mm1='', mm2='', mm3='';
var gdgebimm='', gtval='', onealready='';
var tvals=[], thistval=0, thistdelim='', thistid='';


function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}

function svgmmcallol(iois, tid) {
//alert('TID=' + tid);
var tval='', it=0, dgebimm='';
var tis=document.getElementById(tid);
thistid=tid;
tvals=[];
thistval=0;
thistdelim='';
if (iois != null) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
tval=aconto.body.innerHTML;
//alert('Tval=' + tval);
if (tval.indexOf(encodeURIComponent('data:image/svg+xml')) != -1) {
thistval=1;
tvals=tval.split(encodeURIComponent('data:image/svg+xml'));
thistdelim=encodeURIComponent('data:image/svg+xml');
//alert('thistdeliM=' + thistdelim);


tval='data:image/svg+xml' + decodeURIComponent(tvals[thistval].split(String.fromCharCode(34))[0].split(String.fromCharCode(39))[0].split(')')[0].split('&')[0].split('>')[0]);
//alert('tvAl=' + tval);
//alert('tId=' + tid);

mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf('data:image/svg+xml') != -1) {
thistval=1;
tvals=tval.split('data:image/svg+xml');
thistdelim='data:image/svg+xml';
tval='data:image/svg+xml' + tvals[thistval].split(String.fromCharCode(34))[0].split(String.fromCharCode(39))[0].split(')')[0].split('&')[0].split('>')[0];

mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf(encodeURIComponent('<svg')) != -1 || tval.indexOf(encodeURIComponent('<SVG')) != -1) {
thistval=1;
if (tval.indexOf(encodeURIComponent('<svg')) != -1) {
tvals=tval.split(encodeURIComponent('<svg'));
thistdelim=encodeURIComponent('<svg');
tval='data:image/svg+xml;utf8,<svg' + decodeURIComponent(tvals[thistval].split(encodeURIComponent('</svg>'))[0]) + '</svg>';
} else {
tvals=tval.split(encodeURIComponent('<SVG'));
thistdelim=encodeURIComponent('<SVG');
tval='data:image/svg+xml;utf8,<SVG' + decodeURIComponent(tvals[thistval].split(encodeURIComponent('</SVG>'))[0]) + '</SVG>';
}
mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf(window.btoa('<svg')) != -1 || tval.indexOf(window.btoa('<SVG')) != -1) {
thistval=1;
if (tval.indexOf(window.btoa('<svg')) != -1) {
tvals=tval.split(window.btoa('<svg'));
thistdelim=window.btoa('<svg');
tval='data:image/svg+xml;base64,' + window.btoa('<svg') + tvals[thistval].split(window.btoa('</svg>'))[0] + window.btoa('</svg>');
} else {
tvals=tval.split(window.btoa('<SVG'));
thistdelim=window.btoa('<SVG');
tval='data:image/svg+xml;base64,' + window.btoa('<SVG') + tvals[thistval].split(window.btoa('</SVG>'))[0] + window.btoa('</SVG>');
}
mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.toLowerCase().indexOf('<svg') != -1) {
if (tval.indexOf('<svg') != -1) {
thistdelim='<svg';
tval='data:image/svg+xml;utf8,<svg' + tvals[thistval].split('</svg>')[0] + '</svg>';
} else {
thistdelim='<SVG';
tval='data:image/svg+xml;utf8,<SVG' + tvals[thistval].split('</SVG>')[0] + '</SVG>';
}
//alert('Thistdelim=' + thistdelim);
tvals=tval.split('<svg');
thistval=1;
//alert('1:tval=' + tval);
mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
//alert('2:tval=' + tval);
if (eval('' + dgebimm.length) > 800) {
//alert('0: ' + dgebimm);
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
//alert('1: ' + dgebimm);
document.getElementById('mmcall').innerHTML=dgebimm;
}
//alert('3:tval=' + tval);
//setTimeout(latermm, 9000);
return '';
}
}
}
}
}

“; ?>


Previous relevant Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial is shown below.

Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial

Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial

We wanted, today, to channel the (cruel might say “warped”) thinking behind the recent URL …

  1. interactive entry of absolute URL starting with HtTp means you want a QR Code … and …
  2. interactive entry of absolute URL starting with hTtP means you want (to involve, along the line, creating an animated QR Code scenario) a Webpage Screenshot

… we last talked about at Circular Text Around Media Animated QR Code Tutorial, because we feel this is actually a good inhouse idea to hang on to as a principle. Why?! Glad you asked. It is another way to …

  • end up with an image …
  • from any old absolute (but we have not yet researched ? and & get argument(s) regarding) URL

… really suiting the purpose of today’s work, that being the integration of this idea into our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application we last talked about at PdfImages PDF Output Media Zipping via PHP Tutorial. After all, an animated GIF slide is also an image, and it could be used in this way, to …

  1. create animated GIF of QR Code means by which a smart device user using their Camera might navigate to a series of interesting webpage(s) … or …
  2. create animated GIF of “current snapshot looks” of a series of URLs of interest (with even more currency than Google Earth shows your place!)

It might be you design an animated GIF chapter of slides and always want to follow it up with a “further reading” webpage you could present as a QR Code or Webpage Screenshot.

Anyway, at the “onblur” event Javascript function logic we intervened to end up with an image/png data URI substitute for the HtTp or hTtP URL the user enters to re-enter the normal animated GIF image definition workflow of the animated GIF creator …

<?php echo ”

var mm1='', mm2='', mm3='';


function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}

function maybemore(tval, tid, tis) {
var newi=null, fo=null;
var inmb=0;
if (tval.indexOf('HtTp') == 0) {
mm1=tval;
mm2=tid;
mm3=tis;
document.getElementById('mmcall').innerHTML='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?justcontent=&askfor=' + encodeURIComponent(document.URL.split('//')[0] + '//chart.googleapis.com/chart?chs=300x300&cht=qr&chl=' + encodeURIComponent('http' + encodeURIComponent(tval.substring(4).replace('S:','s:'))) + '&choe=UTF-8') + '\"></iframe>';
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf('hTtP') == 0) {
mm1=tval;
mm2=tid;
mm3=tis;
document.getElementById('mmcall').innerHTML='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=&askyou=' + encodeURIComponent('http' + tval.substring(4).replace('S:','s:')) + '\"></iframe>';
//setTimeout(latermm, 9000);
return '';
}

// rest of maybemore follows ...
}

“; ?>

… to help introduce this new animated GIF slide functionality arrangement.

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


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


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


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


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


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

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

Animated GIF Creation Transparency Tutorial

Animated GIF Creation Transparency Tutorial

Animated GIF Creation Transparency Tutorial

You might have heard …

Transparency begins at home.

… or not, because as far as we know, we just sprouted it?! Nevertheless, this matter of …

  • image transparency … in terms of the image being an Animated GIF slide … via …
  • SVG … or …
  • canvas

… deserves our consideration, we’ve decided, today … because …

Transparency begins at home.

We’ll just try our best here, but we have discovered a nuance that hadn’t tweaked with us before, considering “transparency” and using “canvas” elements. The …

  • [canvasElementContext].clearRect(0, 0, [canvasWidth], [canvasHeight]); // idea causes the canvas to become transparent ... different to the other concept like ...
  • [canvasElementContext].fillStyle='white';
    [canvasElementContext].fillRect(0, 0, [canvasWidth], [canvasHeight]); // this example idea causes the canvas to become white

It’s affected two “avenues of effect” (or is this a book?!) with our Animated GIF Creator logic …

  1. if a SVG+xml element data URI utf8 format representation mentions the word “transparent” we are now going to make the relevant helper canvas element background be transparent …
    <?php echo ”

    function drawInlineSVG(rawSVG, slidename) { // thanks to https://stackoverflow.com/questions/27230293/how-to-draw-an-inline-svg-in-dom-to-a-canvas
    var rsvg = new Blob([rawSVG], {type:'image/svg+xml;charset=utf-8'}),
    rdomURL = self.URL || self.webkitURL || self,
    rurl = rdomURL.createObjectURL(rsvg),
    rslidename=slidename,
    imgc = new Image;


    if (rawSVG.indexOf('transparent') != -1 || rawSVG.indexOf(window.btoa('transparent')) != -1) {
    istransparent=true;

    //document.getElementById('mycanvas').getContext('2d').clearRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
    } else {
    istransparent=false;
    //document.getElementById('mycanvas').getContext('2d').fillStyle='white';

    //document.getElementById('mycanvas').getContext('2d').fillRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
    }


    imgc.onload = function () {
    if (istransparent) {
    document.getElementById('mycanvas').width=imgc.width;
    document.getElementById('mycanvas').height=imgc.height;

    document.getElementById('mycanvas').getContext('2d').clearRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
    } else if (1 == 1) {
    document.getElementById('mycanvas').getContext('2d').fillStyle='white';

    document.getElementById('mycanvas').getContext('2d').fillRect(0,0,document.getElementById('mycanvas').width,document.getElementById('mycanvas').height);
    }

    document.getElementById('mycanvas').getContext('2d').drawImage(this, 0, 0);
    rdomURL.revokeObjectURL(rurl);
    slideupdate(this, rslidename);
    };

    imgc.src = rurl;
    }

    “; ?>
    … and …
  2. the “+” means by which we involve our Scribble and Annotation helper (of animated GIF slide content) now has a new button (with its onclick event function) to ask about its main canvas element background colour …

    function colourize() {
    var huhcol=prompt('Enter canvas background colour or Cancel to ignore.', 'transparent');
    if (huhcol != null) {
    if (huhcol.trim() != '') {
    if (huhcol == 'transparent') {
    //alert(987);
    //alert('topielem.width=' + topielem.width);
    parent.document.getElementById('topcanvas').getContext('2d').fillStyle = huhcol;

    parent.document.getElementById('topcanvas').getContext('2d').clearRect(0,0,parent.document.getElementById('topcanvas').width,parent.document.getElementById('topcanvas').height);
    } else {
    parent.document.getElementById('topcanvas').getContext('2d').fillStyle = huhcol;

    parent.document.getElementById('topcanvas').getContext('2d').fillRect(0,0,parent.document.getElementById('topcanvas').width,parent.document.getElementById('topcanvas').height);
    }
    }
    }
    }

And so, we reckon it’s “transparent” (chortle, chortle) that yesterday’s Animated GIF Creation Automation Tutorial, created at home, and where (the vast majority of some readers know)

Transparency begins at home. Can someone please hand me the lemon juice.

… in …

… is worth a re-look.


Previous relevant Animated GIF Creation Automation Tutorial is shown below.

Animated GIF Creation Automation Tutorial

Animated GIF Creation Automation Tutorial

There are two competing issues going on with software development, of complexity, to challenge the skillset of the programmer …

  • keeping at an issue as it is fresh, and not letting go, as much as anything to keep up with where you are at, as with it being fresh in the mind … versus …
  • useful revisits after a bit of time to review the issue with fresher eyes, can often iron out issues not seen in “the heat of battle”

Today sees us relieved, undertaking a “second of the options above” scenario, regarding us creeping up on more Animated GIF Creation automation ideas we last talked about, with any depth, at Animated GIF Link Image Slide Tutorial.

What prompted the interest, just now, with this? Well, yesterday’s Animated GIF Creation Localhost Text Emoji Slide Tutorial‘s better and non-third-party and independent use of …

  • SVG … to …
  • canvas … via …
  • [canvasElement].toDataURL(‘image/jpeg’, 10) … way to derive a data URI for …
  • textbox … representing an Animated GIF slide content mechanism

… rather than rely on ImageMagick converting from SVG to PNG was a bit of a game changer for us. We thought the extending of its use to other parts of the web application would be a good move. Along this way we also worked out that our Animated GIF dimensioning also needed some tweaking at a new HTML form onsubmit event function intervention point …

<?php echo ”

function dothem() {
for (var iijj=0; iijj<slidecmds.length; iijj++) {
eval(slidecmds[iijj]);
}

if (document.getElementById('selwhs')) {
if (document.getElementById('selwhs').value.indexOf(',') != -1) {
owoh(document.getElementById('selwhs'));
}
}

}

“; ?>

… in our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application used in link below …

https://www.rjmprogramming.com.au/PHP/animegif/tutorial_to_animated_gif.php?irefresh=hTTps://[HtmlWebpageWithSVG].html+++++

… the revisiting of which showed us that the Circle Terminology circle_terminology.html SVG based HTML and Javascript also needed tweaking.


Previous relevant Animated GIF Link Image Slide Tutorial is shown below.

Animated GIF Link Image Slide Tutorial

Animated GIF Link Image Slide Tutorial

Yesterday’s Animated GIF SVG Slide Tutorial had us …

  • taking our animated GIF creator … starting with …
  • SVG user entry functionality … then allow for …
  • other image extraction from HTML user input via + … and today …
  • “a” link to either …
    1. QR Code … via ++ … or …
    2. Webpage Screenshot … via ++++

Do you see the pattern here? If you have a favoured character (ie. “+” here) involved in a user functionality behaviour decision you can give each a …


power of 2 number of characters

… (functionality meaning) and at the Javascript or PHP interpretive end of this arrangement you can know exactly what the user wants (in a way akin to how a bitmap can often be used) … so far this Javascript working (and tailorable into the future with some tweaking) as per …

<?php echo ”

function srchrefit(inbg) {
var outbg=inbg, outbis=[], ibis=0;
var ourblankend=blankend;
if (blankend != '') {
if (eval(eval('' + ourblankend.length) % 2) == 1) { // process img
ourblankend=ourblankend.substring(1);
outbg=outbg.replace(/data\:image\/svg\+xml/g, '!@#$%^&');
outbg=outbg.replace(/data\:image/g, ' SRC=\" data:image');
outbg=outbg.replace(/\!\@\#\$\%\^\&/g, 'data:image/svg+xml');
outbis=outbg.split('<img');
console.log('outbis.length=' + outbis.length + ' and outbg=' + outbg);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' src=\"') != -1) {
outbg=outbg.replace('<img' + outbis[ibis].split('>')[0], '<img' + outbis[ibis].split('>')[0].replace(' src=\"', ' SRC=\" '));
}
}
}
if (eval('' + ourblankend.length) == 4) { // process "a" links to Webpage Screenshot
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
} // ... or ...
} else if (eval('' + ourblankend.length) == 2) { // process "a" links to QR Code
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
}
}
return outbg;
}
return inbg;
}

“; ?>

… in our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application

https://www.rjmprogramming.com.au/PHP/animegif/tutorial_to_animated_gif.php?irefresh=hTTp://[HtmlWebpageWithSVG].html+++

… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a QR Code) …

https://www.rjmprogramming.com.au/PHP/animegif/tutorial_to_animated_gif.php?irefresh=hTTps://[HtmlWebpageWithSVG].html+++++

… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a Webpage Screenshot).


Previous relevant Animated GIF SVG Slide Tutorial is shown below.

Animated GIF SVG Slide Tutorial

Animated GIF SVG Slide Tutorial

The PHP GD library we use to help create animated GIFs (along with a whole lot of other help, it goes without saying) is not into vector graphics which is what …

  • Inkscape … as a vector graphics editor … and …
  • SVG … ie. Scalable Vector Graphics

… are really into … ooooohhh, aaaaahhhh … but luckily for us, the great ImageMagick offers functionality to convert a SVG image file into a PNG image file, via …

Non Windows Windows
convert infile.svg outfile.png magick.exe infile.svg outfile.png

… and we’re using that talent ImageMagick has to offer the user the chance, at any animated GIF slide textbox, the chance to enter encodeURIComponent and window.btoa sensitive entries whose (content) format could match (one of) …

… means by which a user can involve SVG input slides into their animated GIF creations in our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application further to yesterday’s Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial.

Below is a new (PHP writes) Javascript iframe (iois object below) onload event function for recognizing hTTps://[HtmlWebpageWithSVG].html as above, and setting the iframe’s “src” attribute to its value …

<?php echo ”

var mm1='', mm2='', mm3='';
var gdgebimm='', gtval='', onealready='';
var tvals=[], thistval=0, thistdelim='', thistid='';


function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}

function svgmmcallol(iois, tid) {
//alert('TID=' + tid);
var tval='', it=0, dgebimm='';
var tis=document.getElementById(tid);
thistid=tid;
tvals=[];
thistval=0;
thistdelim='';
if (iois != null) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
tval=aconto.body.innerHTML;
//alert('Tval=' + tval);
if (tval.indexOf(encodeURIComponent('data:image/svg+xml')) != -1) {
thistval=1;
tvals=tval.split(encodeURIComponent('data:image/svg+xml'));
thistdelim=encodeURIComponent('data:image/svg+xml');
//alert('thistdeliM=' + thistdelim);


tval='data:image/svg+xml' + decodeURIComponent(tvals[thistval].split(String.fromCharCode(34))[0].split(String.fromCharCode(39))[0].split(')')[0].split('&')[0].split('>')[0]);
//alert('tvAl=' + tval);
//alert('tId=' + tid);

mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf('data:image/svg+xml') != -1) {
thistval=1;
tvals=tval.split('data:image/svg+xml');
thistdelim='data:image/svg+xml';
tval='data:image/svg+xml' + tvals[thistval].split(String.fromCharCode(34))[0].split(String.fromCharCode(39))[0].split(')')[0].split('&')[0].split('>')[0];

mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf(encodeURIComponent('<svg')) != -1 || tval.indexOf(encodeURIComponent('<SVG')) != -1) {
thistval=1;
if (tval.indexOf(encodeURIComponent('<svg')) != -1) {
tvals=tval.split(encodeURIComponent('<svg'));
thistdelim=encodeURIComponent('<svg');
tval='data:image/svg+xml;utf8,<svg' + decodeURIComponent(tvals[thistval].split(encodeURIComponent('</svg>'))[0]) + '</svg>';
} else {
tvals=tval.split(encodeURIComponent('<SVG'));
thistdelim=encodeURIComponent('<SVG');
tval='data:image/svg+xml;utf8,<SVG' + decodeURIComponent(tvals[thistval].split(encodeURIComponent('</SVG>'))[0]) + '</SVG>';
}
mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf(window.btoa('<svg')) != -1 || tval.indexOf(window.btoa('<SVG')) != -1) {
thistval=1;
if (tval.indexOf(window.btoa('<svg')) != -1) {
tvals=tval.split(window.btoa('<svg'));
thistdelim=window.btoa('<svg');
tval='data:image/svg+xml;base64,' + window.btoa('<svg') + tvals[thistval].split(window.btoa('</svg>'))[0] + window.btoa('</svg>');
} else {
tvals=tval.split(window.btoa('<SVG'));
thistdelim=window.btoa('<SVG');
tval='data:image/svg+xml;base64,' + window.btoa('<SVG') + tvals[thistval].split(window.btoa('</SVG>'))[0] + window.btoa('</SVG>');
}
mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.toLowerCase().indexOf('<svg') != -1) {
if (tval.indexOf('<svg') != -1) {
thistdelim='<svg';
tval='data:image/svg+xml;utf8,<svg' + tvals[thistval].split('</svg>')[0] + '</svg>';
} else {
thistdelim='<SVG';
tval='data:image/svg+xml;utf8,<SVG' + tvals[thistval].split('</SVG>')[0] + '</SVG>';
}
//alert('Thistdelim=' + thistdelim);
tvals=tval.split('<svg');
thistval=1;
//alert('1:tval=' + tval);
mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
//alert('2:tval=' + tval);
if (eval('' + dgebimm.length) > 800) {
//alert('0: ' + dgebimm);
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
//alert('1: ' + dgebimm);
document.getElementById('mmcall').innerHTML=dgebimm;
}
//alert('3:tval=' + tval);
//setTimeout(latermm, 9000);
return '';
}
}
}
}
}

“; ?>


Previous relevant Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial is shown below.

Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial

Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial

We wanted, today, to channel the (cruel might say “warped”) thinking behind the recent URL …

  1. interactive entry of absolute URL starting with HtTp means you want a QR Code … and …
  2. interactive entry of absolute URL starting with hTtP means you want (to involve, along the line, creating an animated QR Code scenario) a Webpage Screenshot

… we last talked about at Circular Text Around Media Animated QR Code Tutorial, because we feel this is actually a good inhouse idea to hang on to as a principle. Why?! Glad you asked. It is another way to …

  • end up with an image …
  • from any old absolute (but we have not yet researched ? and & get argument(s) regarding) URL

… really suiting the purpose of today’s work, that being the integration of this idea into our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application we last talked about at PdfImages PDF Output Media Zipping via PHP Tutorial. After all, an animated GIF slide is also an image, and it could be used in this way, to …

  1. create animated GIF of QR Code means by which a smart device user using their Camera might navigate to a series of interesting webpage(s) … or …
  2. create animated GIF of “current snapshot looks” of a series of URLs of interest (with even more currency than Google Earth shows your place!)

It might be you design an animated GIF chapter of slides and always want to follow it up with a “further reading” webpage you could present as a QR Code or Webpage Screenshot.

Anyway, at the “onblur” event Javascript function logic we intervened to end up with an image/png data URI substitute for the HtTp or hTtP URL the user enters to re-enter the normal animated GIF image definition workflow of the animated GIF creator …

<?php echo ”

var mm1='', mm2='', mm3='';


function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}

function maybemore(tval, tid, tis) {
var newi=null, fo=null;
var inmb=0;
if (tval.indexOf('HtTp') == 0) {
mm1=tval;
mm2=tid;
mm3=tis;
document.getElementById('mmcall').innerHTML='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?justcontent=&askfor=' + encodeURIComponent(document.URL.split('//')[0] + '//chart.googleapis.com/chart?chs=300x300&cht=qr&chl=' + encodeURIComponent('http' + encodeURIComponent(tval.substring(4).replace('S:','s:'))) + '&choe=UTF-8') + '\"></iframe>';
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf('hTtP') == 0) {
mm1=tval;
mm2=tid;
mm3=tis;
document.getElementById('mmcall').innerHTML='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=&askyou=' + encodeURIComponent('http' + tval.substring(4).replace('S:','s:')) + '\"></iframe>';
//setTimeout(latermm, 9000);
return '';
}

// rest of maybemore follows ...
}

“; ?>

… to help introduce this new animated GIF slide functionality arrangement.

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


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


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


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


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

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

Animated GIF Creation Automation Tutorial

Animated GIF Creation Automation Tutorial

Animated GIF Creation Automation Tutorial

There are two competing issues going on with software development, of complexity, to challenge the skillset of the programmer …

  • keeping at an issue as it is fresh, and not letting go, as much as anything to keep up with where you are at, as with it being fresh in the mind … versus …
  • useful revisits after a bit of time to review the issue with fresher eyes, can often iron out issues not seen in “the heat of battle”

Today sees us relieved, undertaking a “second of the options above” scenario, regarding us creeping up on more Animated GIF Creation automation ideas we last talked about, with any depth, at Animated GIF Link Image Slide Tutorial.

What prompted the interest, just now, with this? Well, yesterday’s Animated GIF Creation Localhost Text Emoji Slide Tutorial‘s better and non-third-party and independent use of …

  • SVG … to …
  • canvas … via …
  • [canvasElement].toDataURL(‘image/jpeg’, 10) … way to derive a data URI for …
  • textbox … representing an Animated GIF slide content mechanism

… rather than rely on ImageMagick converting from SVG to PNG was a bit of a game changer for us. We thought the extending of its use to other parts of the web application would be a good move. Along this way we also worked out that our Animated GIF dimensioning also needed some tweaking at a new HTML form onsubmit event function intervention point …

<?php echo ”

function dothem() {
for (var iijj=0; iijj<slidecmds.length; iijj++) {
eval(slidecmds[iijj]);
}

if (document.getElementById('selwhs')) {
if (document.getElementById('selwhs').value.indexOf(',') != -1) {
owoh(document.getElementById('selwhs'));
}
}

}

“; ?>

… in our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application used in link below …

https://www.rjmprogramming.com.au/PHP/animegif/tutorial_to_animated_gif.php?irefresh=hTTps://[HtmlWebpageWithSVG].html+++++

… the revisiting of which showed us that the Circle Terminology circle_terminology.html SVG based HTML and Javascript also needed tweaking.


Previous relevant Animated GIF Link Image Slide Tutorial is shown below.

Animated GIF Link Image Slide Tutorial

Animated GIF Link Image Slide Tutorial

Yesterday’s Animated GIF SVG Slide Tutorial had us …

  • taking our animated GIF creator … starting with …
  • SVG user entry functionality … then allow for …
  • other image extraction from HTML user input via + … and today …
  • “a” link to either …
    1. QR Code … via ++ … or …
    2. Webpage Screenshot … via ++++

Do you see the pattern here? If you have a favoured character (ie. “+” here) involved in a user functionality behaviour decision you can give each a …


power of 2 number of characters

… (functionality meaning) and at the Javascript or PHP interpretive end of this arrangement you can know exactly what the user wants (in a way akin to how a bitmap can often be used) … so far this Javascript working (and tailorable into the future with some tweaking) as per …

<?php echo ”

function srchrefit(inbg) {
var outbg=inbg, outbis=[], ibis=0;
var ourblankend=blankend;
if (blankend != '') {
if (eval(eval('' + ourblankend.length) % 2) == 1) { // process img
ourblankend=ourblankend.substring(1);
outbg=outbg.replace(/data\:image\/svg\+xml/g, '!@#$%^&');
outbg=outbg.replace(/data\:image/g, ' SRC=\" data:image');
outbg=outbg.replace(/\!\@\#\$\%\^\&/g, 'data:image/svg+xml');
outbis=outbg.split('<img');
console.log('outbis.length=' + outbis.length + ' and outbg=' + outbg);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' src=\"') != -1) {
outbg=outbg.replace('<img' + outbis[ibis].split('>')[0], '<img' + outbis[ibis].split('>')[0].replace(' src=\"', ' SRC=\" '));
}
}
}
if (eval('' + ourblankend.length) == 4) { // process "a" links to Webpage Screenshot
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
} // ... or ...
} else if (eval('' + ourblankend.length) == 2) { // process "a" links to QR Code
outbis=outbg.split('<a');
console.log('outbis.length=' + outbis.length);
for (ibis=1; ibis<eval('' + outbis.length); ibis++) {
if (outbis[ibis].split('>')[0].indexOf(' href=\"') != -1) {
outbg=outbg.replace('<a' + outbis[ibis].split('>')[0], '<a' + outbis[ibis].split('>')[0].replace(' href=\"', ' SRC=\" '));
}
}
}
return outbg;
}
return inbg;
}

“; ?>

… in our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application

https://www.rjmprogramming.com.au/PHP/animegif/tutorial_to_animated_gif.php?irefresh=hTTp://[HtmlWebpageWithSVG].html+++

… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a QR Code) …

https://www.rjmprogramming.com.au/PHP/animegif/tutorial_to_animated_gif.php?irefresh=hTTps://[HtmlWebpageWithSVG].html+++++

… which fills in the slide data (the link above hooking up to the web application featuring in Circle Terminology in Mathematics Tutorial extracting SVG and hidden non-SVG images and one “a” link presented as a Webpage Screenshot).


Previous relevant Animated GIF SVG Slide Tutorial is shown below.

Animated GIF SVG Slide Tutorial

Animated GIF SVG Slide Tutorial

The PHP GD library we use to help create animated GIFs (along with a whole lot of other help, it goes without saying) is not into vector graphics which is what …

  • Inkscape … as a vector graphics editor … and …
  • SVG … ie. Scalable Vector Graphics

… are really into … ooooohhh, aaaaahhhh … but luckily for us, the great ImageMagick offers functionality to convert a SVG image file into a PNG image file, via …

Non Windows Windows
convert infile.svg outfile.png magick.exe infile.svg outfile.png

… and we’re using that talent ImageMagick has to offer the user the chance, at any animated GIF slide textbox, the chance to enter encodeURIComponent and window.btoa sensitive entries whose (content) format could match (one of) …

… means by which a user can involve SVG input slides into their animated GIF creations in our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application further to yesterday’s Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial.

Below is a new (PHP writes) Javascript iframe (iois object below) onload event function for recognizing hTTps://[HtmlWebpageWithSVG].html as above, and setting the iframe’s “src” attribute to its value …

<?php echo ”

var mm1='', mm2='', mm3='';
var gdgebimm='', gtval='', onealready='';
var tvals=[], thistval=0, thistdelim='', thistid='';


function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}

function svgmmcallol(iois, tid) {
//alert('TID=' + tid);
var tval='', it=0, dgebimm='';
var tis=document.getElementById(tid);
thistid=tid;
tvals=[];
thistval=0;
thistdelim='';
if (iois != null) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
tval=aconto.body.innerHTML;
//alert('Tval=' + tval);
if (tval.indexOf(encodeURIComponent('data:image/svg+xml')) != -1) {
thistval=1;
tvals=tval.split(encodeURIComponent('data:image/svg+xml'));
thistdelim=encodeURIComponent('data:image/svg+xml');
//alert('thistdeliM=' + thistdelim);


tval='data:image/svg+xml' + decodeURIComponent(tvals[thistval].split(String.fromCharCode(34))[0].split(String.fromCharCode(39))[0].split(')')[0].split('&')[0].split('>')[0]);
//alert('tvAl=' + tval);
//alert('tId=' + tid);

mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf('data:image/svg+xml') != -1) {
thistval=1;
tvals=tval.split('data:image/svg+xml');
thistdelim='data:image/svg+xml';
tval='data:image/svg+xml' + tvals[thistval].split(String.fromCharCode(34))[0].split(String.fromCharCode(39))[0].split(')')[0].split('&')[0].split('>')[0];

mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf(encodeURIComponent('<svg')) != -1 || tval.indexOf(encodeURIComponent('<SVG')) != -1) {
thistval=1;
if (tval.indexOf(encodeURIComponent('<svg')) != -1) {
tvals=tval.split(encodeURIComponent('<svg'));
thistdelim=encodeURIComponent('<svg');
tval='data:image/svg+xml;utf8,<svg' + decodeURIComponent(tvals[thistval].split(encodeURIComponent('</svg>'))[0]) + '</svg>';
} else {
tvals=tval.split(encodeURIComponent('<SVG'));
thistdelim=encodeURIComponent('<SVG');
tval='data:image/svg+xml;utf8,<SVG' + decodeURIComponent(tvals[thistval].split(encodeURIComponent('</SVG>'))[0]) + '</SVG>';
}
mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf(window.btoa('<svg')) != -1 || tval.indexOf(window.btoa('<SVG')) != -1) {
thistval=1;
if (tval.indexOf(window.btoa('<svg')) != -1) {
tvals=tval.split(window.btoa('<svg'));
thistdelim=window.btoa('<svg');
tval='data:image/svg+xml;base64,' + window.btoa('<svg') + tvals[thistval].split(window.btoa('</svg>'))[0] + window.btoa('</svg>');
} else {
tvals=tval.split(window.btoa('<SVG'));
thistdelim=window.btoa('<SVG');
tval='data:image/svg+xml;base64,' + window.btoa('<SVG') + tvals[thistval].split(window.btoa('</SVG>'))[0] + window.btoa('</SVG>');
}
mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
if (eval('' + dgebimm.length) > 800) {
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
document.getElementById('mmcall').innerHTML=dgebimm;
}
//setTimeout(latermm, 9000);
return '';
} else if (tval.toLowerCase().indexOf('<svg') != -1) {
if (tval.indexOf('<svg') != -1) {
thistdelim='<svg';
tval='data:image/svg+xml;utf8,<svg' + tvals[thistval].split('</svg>')[0] + '</svg>';
} else {
thistdelim='<SVG';
tval='data:image/svg+xml;utf8,<SVG' + tvals[thistval].split('</SVG>')[0] + '</SVG>';
}
//alert('Thistdelim=' + thistdelim);
tvals=tval.split('<svg');
thistval=1;
//alert('1:tval=' + tval);
mm1=tval;
mm2=tid;
mm3=document.getElementById(tid.replace(/^slideshow1$/g,'slideshow'));
dgebimm='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=' + encodeURIComponent(tval) + '\"></iframe>';
//alert('2:tval=' + tval);
if (eval('' + dgebimm.length) > 800) {
//alert('0: ' + dgebimm);
document.getElementById('myaskfor').value=tval;
document.getElementById('saskfor').click();
} else {
//alert('1: ' + dgebimm);
document.getElementById('mmcall').innerHTML=dgebimm;
}
//alert('3:tval=' + tval);
//setTimeout(latermm, 9000);
return '';
}
}
}
}
}

“; ?>


Previous relevant Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial is shown below.

Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial

Animated GIF Slide QR Code and Webpage Screenshot URL Tutorial

We wanted, today, to channel the (cruel might say “warped”) thinking behind the recent URL …

  1. interactive entry of absolute URL starting with HtTp means you want a QR Code … and …
  2. interactive entry of absolute URL starting with hTtP means you want (to involve, along the line, creating an animated QR Code scenario) a Webpage Screenshot

… we last talked about at Circular Text Around Media Animated QR Code Tutorial, because we feel this is actually a good inhouse idea to hang on to as a principle. Why?! Glad you asked. It is another way to …

  • end up with an image …
  • from any old absolute (but we have not yet researched ? and & get argument(s) regarding) URL

… really suiting the purpose of today’s work, that being the integration of this idea into our changed PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application we last talked about at PdfImages PDF Output Media Zipping via PHP Tutorial. After all, an animated GIF slide is also an image, and it could be used in this way, to …

  1. create animated GIF of QR Code means by which a smart device user using their Camera might navigate to a series of interesting webpage(s) … or …
  2. create animated GIF of “current snapshot looks” of a series of URLs of interest (with even more currency than Google Earth shows your place!)

It might be you design an animated GIF chapter of slides and always want to follow it up with a “further reading” webpage you could present as a QR Code or Webpage Screenshot.

Anyway, at the “onblur” event Javascript function logic we intervened to end up with an image/png data URI substitute for the HtTp or hTtP URL the user enters to re-enter the normal animated GIF image definition workflow of the animated GIF creator …

<?php echo ”

var mm1='', mm2='', mm3='';


function latermm() {
maybemore(mm3.value, mm2, mm3);
mm1='';
mm2='';
mm3='';
}

function maybemore(tval, tid, tis) {
var newi=null, fo=null;
var inmb=0;
if (tval.indexOf('HtTp') == 0) {
mm1=tval;
mm2=tid;
mm3=tis;
document.getElementById('mmcall').innerHTML='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?justcontent=&askfor=' + encodeURIComponent(document.URL.split('//')[0] + '//chart.googleapis.com/chart?chs=300x300&cht=qr&chl=' + encodeURIComponent('http' + encodeURIComponent(tval.substring(4).replace('S:','s:'))) + '&choe=UTF-8') + '\"></iframe>';
//setTimeout(latermm, 9000);
return '';
} else if (tval.indexOf('hTtP') == 0) {
mm1=tval;
mm2=tid;
mm3=tis;
document.getElementById('mmcall').innerHTML='<iframe style=display:none; onload=mmcallol(this); src=\"' + '/PHP/fgc/index.php?askfor=&askyou=' + encodeURIComponent('http' + tval.substring(4).replace('S:','s:')) + '\"></iframe>';
//setTimeout(latermm, 9000);
return '';
}

// rest of maybemore follows ...
}

“; ?>

… to help introduce this new animated GIF slide functionality arrangement.

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


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


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


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

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

Animated GIF Creation Localhost Text Emoji Slide Tutorial

Animated GIF Creation Localhost Text Emoji Slide Tutorial

Animated GIF Creation Localhost Text Emoji Slide Tutorial

A day or so before yesterday’s Animated GIF Creation Slide Annotating Tutorial we intimated with …

… where we have started coding for emojis as well …

… that animated GIF slides could successfully contain unicode emojis. At that stage, unusually for this whole (very long running) Animated Gif Creator project, the functionality …

  • worked in our RJM Programming public domain environment … but …
  • did not work back at our local MAMP Apache/PHP/MySql web server environment

Huh?! Yes, for the public domain usage we were making use of the brilliant Google Pagespeed Insights functionality, thanks, (but) which does not work for localhost URLs, pretty understandably!

We had time to mull over this, and extending yesterday’s Animated GIF Creation Slide Annotating Tutorial‘s use of the Scribble and Annotating Inhouse Helper, which uses an HTML canvas element as its graphics modus operandi, we thought we might be onto a grinner (if you’ll pardon the poor attempt at Clayton‘s Cockney slang). We could get the ball rolling similarly to yesterday, with …

<?php echo ”

var dtval=tval;
if (tval.trim() == '+' || (document.URL.indexOf('http://localhost') == 0 && dtval.replace('>','<').indexOf('<') == -1 && (containsNonLatinCodepoints(dtval) || hasEntities(dtval)))) {
var useyourwords='';
if (canvw == '') {
canvw=document.getElementById('mycanvas').toDataURL('data/jpeg', 10);
}
if (tval.trim() != '+') {
var coldelim=tval.split('`');
if (eval('' + coldelim.length) > 1 && eval('' + coldelim[0].trim().length) > 0 && dtval.split(coldelim[0])[1].indexOf(' ') == -1) {
cfcol=coldelim[1];
if (eval('' + coldelim.length) > 2) {
cbcol=coldelim[2];
}
if (eval('' + coldelim.length) > 3) {
cffam=coldelim[3];
}
if (eval('' + coldelim.length) > 4) {
cfsz=coldelim[4];
}
}
dtval=tval.split('`')[0];
useyourwords='&thewords=' + encodeURIComponent(dtval) + '&cbcol=' + encodeURIComponent(cbcol) + '&cfcol=' + encodeURIComponent(cfcol) + '&cffam=' + encodeURIComponent(cffam) + '&cfsz=' + encodeURIComponent(cfsz);
resetyes();
tval='+';
dtval='+';
}
tval=canvw;
document.getElementById(tid.replace(/^slideshow1$/g,'slideshow')).value=canvw;
var hw=eval(500 - eval(tid.replace('slideshow','')))
canvwo.push(window.open('/HTMLCSS/user_of_signature_signature.htm?slide=' + tid.replace(/^slideshow1$/g,'slideshow') + useyourwords, '_blank', 'top=' + eval(screen.height - hw) + ',left=' + eval(screen.width - hw) + ',width=' + hw + ',height=' + hw));
}

“; ?>

… in our changed animated GIF creator PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application, pulling along with it yesterday’s …

  1. font-color:black;
  2. background-color:white;
  3. font-family:Verdana;
  4. font-size:36px;

… “using ` being able to change as per user requirement” ideas. Then, at the other end one intervention wrapper can have us creating canvas text which is mapped back to an Animated GIF slide data URI content textbox back at the Animated GIF Creator web application …


var wocheck=false, woop=null, lastwoopj='';
var slideis=location.search.split('slide=')[1] ? (location.search.split('slide=')[1].split('&')[0]) : "";
var thewords=location.search.split('thewords=')[1] ? decodeURIComponent(location.search.split('thewords=')[1].split('&')[0]) : "";
var cbcol=location.search.split('cbcol=')[1] ? decodeURIComponent(location.search.split('cbcol=')[1].split('&')[0]) : "";
var cfcol=location.search.split('cfcol=')[1] ? decodeURIComponent(location.search.split('cfcol=')[1].split('&')[0]) : "";
var cffam=location.search.split('cffam=')[1] ? decodeURIComponent(location.search.split('cffam=')[1].split('&')[0]) : "";
var cfsz=location.search.split('cfsz=')[1] ? decodeURIComponent(location.search.split('cfsz=')[1].split('&')[0]) : "";

if (!wocheck) {
wocheck=true;
if (window.opener && slideis != '') {
woop=window.opener;
setTimeout(function() { document.getElementById('topcanvas').title=initialtextmaybe(slideis); setInterval(topcwoop, 5000); }, 3000);
}
}

function placethistext() {
var mycon=document.getElementById('topcanvas').getContext('2d');
mycon.font = cf;
var huhs=thewords.split(String.fromCharCode(92) + 'n'), thisy=eval(8 + eval('' + cfsz));
//if (('' + cbcol) != 'white') {
// mycon.fillStyle='' + cbcol;
// mycon.fillRect(0,0,document.getElementById('topcanvas').width,document.getElementById('topcanvas').height);
//}
for (var ii=0; ii<huhs.length; ii++) {
mycon.font = cf;
mycon.strokeStyle='' + cfcol;
mycon.strokeText(huhs[ii],20,thisy);
thisy+=eval(8 + eval('' + cfsz));
}
}

function ourfillrect() {
document.getElementById('topcanvas').getContext('2d').fillStyle='' + cbcol;
document.getElementById('topcanvas').getContext('2d').fillRect(0,0,document.getElementById('topcanvas').width,document.getElementById('topcanvas').height);
}

function initialtextmaybe(inslidename) {
//useyourwords='&thewords=' + encodeURIComponent(dtval) + '&cbcol=' + encodeURIComponent(cbcol) + '&cfcol=' + encodeURIComponent(cfcol) + '&cffam=' + encodeURIComponent(cffam) + '&cfsz=' + encodeURIComponent(cfsz);
if (thewords.trim() != '') {
cf = "" + cfsz + "px " + cffam;
if (('' + cbcol) != 'white') {
setTimeout(ourfillrect, 4000);
}
setTimeout(placethistext, 5000);
}
return inslidename;
}

… with our changed link’s user_of_signature_signature.htm Scribble and Annotating Helper web application.

You may be wondering why this is worth the effort? Well, we highly recommend using this Animated GIF Creator logic in a local web server (eg. MAMP) environment, in terms of speed, and flexibility involving other Open Source products like ImageMagick and Ffmpeg which can help you out.


Previous relevant Animated GIF Creation Slide Annotating Tutorial is shown below.

Animated GIF Creation Slide Annotating Tutorial

Animated GIF Creation Slide Annotating Tutorial

The main purpose of today’s Animated GIF Creator web application improvements onto yesterday’s Animated GIF Creation Text Slide Styling Tutorial revolve around …

  • interfacing our changed link’s user_of_signature_signature.htm canvas based Scribble and Annotation Tool we last talked about with Shortcuts iOS App Web URL Desktop Icon Tutorial … via slide entries that are just …

    +

    … using a window.open “child” looks back at window.opener “parent” communication conduit paradigm …

    Parent calls Child
    <?php echo ”

    var convwo=[];

    canvwo.push(window.open('/HTMLCSS/user_of_signature_signature.htm?slide=' + tid.replace(/^slideshow1$/g,'slideshow'), '_blank', 'top=' + eval(screen.height - hw) + ',left=' + eval(screen.width - hw) + ',width=' + hw + ',height=' + hw));

    “; ?>
    Child references Parent

    var wocheck=false, woop=null, lastwoopj='';
    var slideis=location.search.split('slide=')[1] ? (location.search.split('slide=')[1].split('&')[0]) : "";

    if (!wocheck) {
    wocheck=true;
    if (window.opener && slideis != '') {
    woop=window.opener;
    setTimeout(function() { document.getElementById('topcanvas').title=slideis; setInterval(topcwoop, 5000); }, 3000);
    }
    }

    function topcwoop() {
    var thiswoopj=document.getElementById('topcanvas').toDataURL('data/jpeg', 10);
    if (thiswoopj != lastwoopj) {
    lastwoopj=thiswoopj;
    document.getElementById('topcanvas').style.cursor='progress';
    woop.document.getElementById(slideis).value=lastwoopj;
    setTimeout(function(){ document.getElementById('topcanvas').style.cursor='pointer'; }, 2000);
    }
    }

    … and …

  • improved the functionality of “text” slides by allowing the user to use \n to indicate they would like to place a line feed in the resultant slide “text” look …

    function bsn(dv) {
    var newdv=dv, twf=25, addon=25;
    var bsnds=dv.split(String.fromCharCode(92) + 'n');
    if (eval('' + bsnds.length) <= 1) { return dv; }
    addon=Math.floor(eval(65 / eval('' + bsnds.length)));
    //alert(dv + ' 00:' + newdv + ' ... ' + addon);
    twf+=addon;
    newdv=bsnds[0] + '</text><text y=' + String.fromCharCode(34) + twf + '%' + String.fromCharCode(34) + '>';
    //alert(dv + ' 0:' + newdv);
    for (var iop=1; iop<eval(-1 + eval('' + bsnds.length)); iop++) {
    twf+=addon;
    newdv+='' + bsnds[iop] + '</text><text y=' + String.fromCharCode(34) + twf + '%' + String.fromCharCode(34) + '>';
    //alert('1:' + newdv);
    }
    newdv+='' + bsnds[eval(-1 + eval('' + bsnds.length))];
    //alert('2:' + newdv);
    return newdv;
    }

… so that, now, the advice goes …

To supplement # delimited comments below you can append to the title # delimited (left,top) or FontColour or Font_name or FontSize_px or AngleDegrees[.Opacity] configurations allowed here … HtTp for QR Code, hTtP for Webpage screenshot, hTTp[+ for other image types too and/or ( ++ for a links to QR Code or ++++ for a links to Webpage Screenshot ) and/or ++++++++ for text SVG based slides ] for SVG HTML or just enter text into slide textboxes to create SVG text based slides (where, in slides below, ` delimitation separates optional SVG text from (all uppercase to keep) font colour [black] and background colour [white] and font family [Verdana] and font size [36] px) … or single + for Canvas Based Annotations to fill slide content. Use \n to place line feeds in text entries.

So, yet again, feel free to try our changed animated GIF creator PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application.


Previous relevant Animated GIF Creation Text Slide Styling Tutorial is shown below.

Animated GIF Creation Text Slide Styling Tutorial

Animated GIF Creation Text Slide Styling Tutorial

We’re revisiting, again, the Animated GIF Creator of Animated GIF Creation Slide Specific Effects Tutorial notoriety. And why might that be the case, for readers who have not read the blog posting title? We thought the previous …

  • text slide … restrictions to …
    1. font-color:black;
    2. background-color:white;
    3. font-family:Verdana;
    4. font-size:36px;

    … were …

  • a tad restrictive … and so we opened slide entries up to some new (optional) rules

    To supplement # delimited comments below you can append to the title # delimited (left,top) or FontColour or Font_name or FontSize_px or AngleDegrees[.Opacity] configurations allowed here … HtTp for QR Code, hTtP for Webpage screenshot, hTTp[+ for other image types too and/or ( ++ for a links to QR Code or ++++ for a links to Webpage Screenshot ) and/or ++++++++ for text SVG based slides ] for SVG HTML or just enter text into slide textboxes to create SVG text based slides (where, in slides below, ` delimitation separates optional SVG text from (all uppercase to keep) font colour [black] and background colour [white] and font family [Verdana] and font size [36] px)

We thank this excellent link for ImageMagick advice regarding background colour ideas when converting SVG to PNG images.

Again, feel free to try our changed animated GIF creator PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application, where we have started coding for emojis as well …


Previous relevant Animated GIF Creation Slide Specific Effects Tutorial is shown below.

Animated GIF Creation Slide Specific Effects Tutorial

Animated GIF Creation Slide Specific Effects Tutorial

With our animated GIF creator, last referenced with Ffmpeg Shelling Peas Tutorial, we wanted to nuance the way the ImageMagick and GD effects could operate …

  • they being only applicable to the entire animated GIF output image … before today’s work which makes it so that …
  • optionally they can be turned on or off for individual animated GIF slides

… thereby allowing more flexibility for the user, we’re hoping.

Feel free to try our changed animated GIF creator PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application which now features the additional “slide blurb additional snippet” …

Please note double click toggles the negation of any GD rotations etcetera for this slide only and will become pale yellow here when in negated status, and that a 4x click on first selection reverses logic to be only 2x click selections from then on for a pale orange slide textbox background.


Previous relevant Ffmpeg Shelling Peas Tutorial is shown below.

Ffmpeg Shelling Peas Tutorial

Ffmpeg Shelling Peas Tutorial

Well, our wish to “shell peas” setting up more ffmpeg media options based on the excellent FFmpeg cheat sheet, thanks, today, had its ups and downs for speed of progress, but, yes, to have a solid “framework” to work within, that you are happy with, barring those tweaks you inevitably discover in projects as they gain complexity, is the best first endeavour you might need to do, to feel more relaxed about the parts of the project requiring that third party expertise, which it is your job to test that you have successfully merged into the project. And so, onto yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial, we have included new

<?php

$vssfi='img%03d.png';
$bn='*';
$bntwo='.*';

foreach (glob('newfolder_*') as $idfilename) {
if (file_exists($idfilename) && $vssfi == 'img%03d.png') {
foreach (glob($idfilename . DIRECTORY_SEPARATOR . '*') as $idifilename) {
if ($vssfi == 'img%03d.png' && strpos($idifilename, '.') !== false) {
$bnis=basename($idifilename);
$bn='';
$bntwo='';
for ($ibn=0; $ibn<strlen(explode('.', $bnis)[0]); $ibn++) {
if (substr(substr($bnis, $ibn),0,1) >= '0' && substr(substr($bnis, $ibn),0,1) <= '9') {
if ($bntwo == '') {
if (substr(substr($bnis, $ibn),0,1) == '0') {
$bntwo='%0' . strlen(substr(explode('.', $bnis)[0], $ibn)) . 'd' . '.' . explode('.', $idifilename)[-1 + sizeof(explode('.', $idifilename))];
} else {
$bntwo='%d' . '.' . explode('.', $idifilename)[-1 + sizeof(explode('.', $idifilename))];
}
}
} else if ($bntwo == '') {
$bn.=substr(substr($bnis, $ibn),0,1);
}
}
if ($bntwo == '') {
$bn='*';
$bntwo='.' . explode('.', $idifilename)[-1 + sizeof(explode('.', $idifilename))];
}
$vssfi=$idfilename . substr(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR,0,1) . $bn . $bntwo;
}
}
}
}

?>
<?php echo ”

var ffstr=' Concat demuxer, Display the frame number on each frame, Trimming, Delay video, Delay audio, Extract a frame per second, Extract the frames from a video, Mute some of the audio, Extract one frame, Create a video slideshow from images,', offstr=null, kffstr=0, affstr=[];

//
// And then ... later ...
//
if (newv == 'Trimming') {


document.getElementById('moreb').innerHTML=firstdivih;

document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML='';
document.getElementById('minusi').innerHTML=' -ss 00:00:00.000 -i ';
document.getElementById('minusi').title='Start time';

document.getElementById('sswitches').innerHTML='-t 60 -c copy ';
document.getElementById('sswitches').title='Duration';

document.getElementById('mysub').value=newv;
} else if (newv == 'Delay video') {

document.getElementById('moreb').innerHTML=firstdivih;
document.getElementById('precmds').innerHTML=' ';

document.getElementById('betweenis').innerHTML='-itsoffset 1.00';
document.getElementById('betweenis').title='Delay in seconds';

document.getElementById('sswitches').innerHTML='-map 1:v -map 0:a <span id=svac contenteditable=false>-vcodec copy -acodec copy </span>';
document.getElementById('sswitches').title='The 1:v 0:a represents video track else use 0:v 1:a for audio track';

document.getElementById('mysub').value=newv;
} else if (newv == 'Delay audio') {

document.getElementById('moreb').innerHTML=firstdivih;
document.getElementById('precmds').innerHTML=' ';

document.getElementById('betweenis').innerHTML='-itsoffset 1.00';
document.getElementById('betweenis').title='Delay in seconds';

document.getElementById('sswitches').innerHTML='-map 0:v -map 1:a <span id=svac contenteditable=false>-vcodec copy -acodec copy </span>';
document.getElementById('sswitches').title='The 0:v 1:a represents audio track else use 1:v 0:a for video track';

document.getElementById('mysub').value=newv;
} else if (newv == 'Extract a frame per second') {

document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' ');
document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML='-filter:v fps=fps=1 -vsync 0';
document.getElementById('secondi').title='The 1 represents 1 per second';
document.getElementById('sswitches').innerHTML=\"<span id=sfolder contenteditable=false>newfolder_" . rand(0,784534) . str_replace("\\","\\\\",$ddn) . "out%d.png\" + '</span>';

document.getElementById('mysub').value=newv;
} else if (newv == 'Extract the frames from a video') {

document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' ');
document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML=\"-vf \" + String.fromCharCode(34) + \"select='between(t,1,5)+between(t,11,15)'\" + String.fromCharCode(34) + \" -vsync 0\";
document.getElementById('secondi').title='To extract all frames from between 1 and 5 seconds, and also between 11 and 15 seconds';
document.getElementById('sswitches').innerHTML=\"<span id=sfolder contenteditable=false>newfolder_" . rand(0,784534) . str_replace("\\","\\\\",$ddn) . "out%d.png\" + '</span>';

document.getElementById('mysub').value=newv;
} else if (newv == 'Mute some of the audio') {

document.getElementById('moreb').innerHTML=firstdivih;
document.getElementById('secondi').innerHTML='';
document.getElementById('precmds').innerHTML=' ';

document.getElementById('sswitches').innerHTML=\"-vcodec copy -af \" + String.fromCharCode(34) + \"volume=enable='between(t,80,90)'<span id=svolume contenteditable=false>:volume=0\" + String.fromCharCode(34) + \" </span>\";
document.getElementById('sswitches').title='To replace all audio between 1:20 and 1:30 with silence';

document.getElementById('mysub').value=newv;
} else if (newv == 'Create a video slideshow from images') {

document.getElementById('moreb').innerHTML=firstdivih;

document.getElementById('minusi').innerHTML='-r 1/5 -i ';
document.getElementById('minusi').title='Parameter -r marks the image framerate (inverse time of each image); -vf fps=25 marks the true framerate of the output';

document.getElementById('secondi').innerHTML='';
document.getElementById('precmds').innerHTML=' ';
document.getElementById('scbi').innerHTML='" . $vssfi . "';

document.getElementById('sswitches').innerHTML=' -c:v libx264 -vf fps=25<span id=shat contenteditable=false> -pix_fmt yuv420p </span>';

document.getElementById('mysub').value=newv;
} else if (newv == 'Extract one frame') {

document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' out.jpg');
document.getElementById('secondi').innerHTML='';
document.getElementById('precmds').innerHTML=' ';

document.getElementById('sswitches').innerHTML='-ss 00:00:10.000<span id=svframes contenteditable=false> -vframes 1 </span>';
document.getElementById('sswitches').title='Extract one frame at 10 second mark';

document.getElementById('mysub').value=newv;
}

“; ?>

ffmpeg media functionality talents for you to try yourself, today, in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial

There were two weakness with the logic in yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial, we reckon, those being …

  1. it is hard to “hover swipe” with no linework to show where one option starts and another ends, in Y (or top) co-ordinates … and …
  2. the user has trouble knowing whether their swipe attempt worked

… for which we supply ideas …

  1. linear-gradient background, in the form of a colourful “underlay” div element under (now transparent backgrounded) select (ie. dropdown) element (and associated “overlay” div) … and …
  2. emoji for swipe left ⬅ (&#11013;) and for swipe right ➡ (&#10145;) shown briefly

… featuring relevant code snippets …

  1. <?php echo ”

    function overlay() {
    origval=document.getElementById('schoices').value;
    var rect=document.getElementById('fcommand').getBoundingClientRect();
    document.getElementById('moreb').style.position='absolute';
    document.getElementById('moreb').style.left='' + rect.left + 'px';
    document.getElementById('moreb').style.top='' + rect.top + 'px';
    document.getElementById('moreb').style.width='96%'; //' + rect.width + 'px';
    document.getElementById('moreb').style.height='' + rect.height + 'px';


    document.getElementById('moreb').style.border='1px solid black';
    document.getElementById('moreb').style.paddingLeft='20px';
    document.getElementById('moreb').style.backgroundColor='#f9f9f9';
    document.getElementById('fcommand').style.opacity='0.0';
    document.getElementById('fcommand').style.cursor='pointer';


    document.getElementById('moreb').innerHTML='<span id=precmds></span><span id=verb>ffmpeg" . $ffmpegsuf . "</span> <span id=prescbi></span><span id=minusi> -i </span><span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&left=y\"></iframe></span> <span id=betweenis></span> <span id=secondi>-i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&right=y\"></iframe></span></span> <span id=sswitches>-c copy -map 0:v:0 -map 1:a:0 -shortest</span> out.mp4 > <a target=_blank title=ffimpdf.bad onclick=getvb(); style=cursor:pointer;text-decoration:underline; data-href=./ffimpdf.bad>ffimpdf.bad</a>';
    if (firstdivih == '') { firstdivih=document.getElementById('moreb').innerHTML; }
    if (firstbutval == '') { firstbutval=document.getElementById('mysub').value; }
    document.getElementById('schoices').style.display='inline-block';


    rect=document.getElementById('schoices').getBoundingClientRect();


    if (eval('' + rect.height) > 100 || 1 == 1) {


    document.getElementById('schoices').style.backgroundColor='transparent';
    document.getElementById('tf').style.position='absolute'; // using new <div id=tf></div>
    document.getElementById('tf').style.left='' + rect.left + 'px';
    document.getElementById('tf').style.top='' + rect.top + 'px';
    document.getElementById('tf').style.width='' + rect.width + 'px';
    document.getElementById('tf').style.height='' + rect.height + 'px';
    // Thanks to https://stackoverflow.com/questions/49660659/css-gradients-inside-gradients
    document.getElementById('tf').style.background='linear-gradient(0deg, #ffffff 10%, rgba(255,255,0,0.6) 20%, rgba(192,192,192,0.6) 31%, rgba(255,215,0,0.6) 42%, rgba(211,211,211,0.6) 53%, rgba(255,165,0,0.6) 63%, rgba(224,255,255,0.6) 74%, rgba(254,254,254,0.6) 85%, #CC7722 100%), linear-gradient( to right, yellow, pink )'; // #fcfafc #f9f6f8 #f8f1f3
    document.getElementById('tf').style.zIndex='-1';


    document.getElementById('doverlay').style.position='absolute';
    document.getElementById('doverlay').style.left='' + rect.left + 'px';
    document.getElementById('doverlay').style.top='' + rect.top + 'px';
    document.getElementById('doverlay').style.width='' + rect.width + 'px';
    if (eval('' + rect.height) < 30) {
    document.getElementById('doverlay').style.height='' + rect.height + 'px';
    } else {
    document.getElementById('doverlay').style.height='' + eval(eval('' + rect.height) / eval('' + document.getElementById('schoices').size)) + 'px';
    }
    document.getElementById('doverlay').style.zIndex='96';
    document.getElementById('doverlay').style.textAlign='center';
    document.getElementById('doverlay').style.display='block';
    document.getElementById('doverlay').title=document.getElementById('mydefopt').title;
    //document.getElementById('mydefopt').style.fontColor='transparent';
    document.getElementById('mydefopt').innerHTML='';


    document.getElementById('doverlaytwo').style.position='absolute';
    document.getElementById('doverlaytwo').style.left='' + rect.left + 'px';
    //document.getElementById('doverlaytwo').style.top='' + eval(eval('' + rect.height) - eval(2 * eval('' + rect.height) / eval('' + document.getElementById('schoices').size))) + 'px';
    document.getElementById('doverlaytwo').style.top='' + eval(eval('' + rect.height) - eval(0.5 * eval('' + rect.height) / eval('' + document.getElementById('schoices').size))) + 'px';
    //document.getElementById('doverlaytwo').style.bottom='' + rect.bottom + 'px';
    document.getElementById('doverlaytwo').style.width='' + rect.width + 'px';
    if (eval('' + rect.height) < 30) {
    if (1 == 2) { document.getElementById('doverlaytwo').style.height='' + rect.height + 'px'; }
    } else {
    document.getElementById('doverlaytwo').style.height='' + eval(eval('' + rect.height) / eval('' + document.getElementById('schoices').size)) + 'px';
    }
    document.getElementById('doverlaytwo').style.zIndex='96';
    document.getElementById('doverlaytwo').style.textAlign='center';
    document.getElementById('doverlaytwo').style.display='block';
    document.getElementById('mydefopttwo').innerHTML='';

    rect=document.getElementById('mysub').getBoundingClientRect();
    document.getElementById('mysub').style.position='absolute';
    document.getElementById('mysub').style.left='' + rect.left + 'px';
    document.getElementById('mysub').style.top='' + rect.top + 'px';

    setInterval(fhoc, 1000);
    }


    }

    “; ?>
    … using a multiple linear-gradient element style background for the first time we can remember
  2. <?php echo ”

    var swipel='', swipelcp='', swiper='', swipercp='';

    var ra='&#10145;', racp=String.fromCodePoint(10145);
    var la='&#11013;', lacp=String.fromCodePoint(11013);


    function isplace(thiso, e) {
    var kkk=0;
    e = e || window.event;
    e.preventDefault();
    if (e.touches) {
    if (e.touches[0].pageX) {
    pos3 = e.touches[0].pageX;
    pos4 = e.touches[0].pageY;
    } else {
    pos3 = e.touches[0].clientX;
    pos4 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos3 = e.clientX;
    pos4 = e.clientY;
    } else {
    pos3 = e.pageX;
    pos4 = e.pageY;
    }
    if (lasto == e.target) {
    if (Math.abs(pos1 - pos3) >= 70) {
    if (pos3 > pos1) { // swipe right
    swiper=ra;
    swipercp=racp;

    if (e.target == opastr) {
    kkk=eval(1 + eval('' + kpastr));
    if (kkk >= eval('' + apastr.length)) {
    kpastr=eval('' + kpastr);
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(1 + eval('' + kpdstr));
    if (kkk >= eval('' + apdstr.length)) {
    kpdstr=eval('' + kpdstr);
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(1 + eval('' + kimstr));
    if (kkk >= eval('' + aimstr.length)) {
    kimstr-=eval('' + kimstr);
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(1 + eval('' + kffstr));
    if (kkk >= eval('' + affstr.length)) {
    kffstr-=eval('' + kffstr);
    } else {
    kffstr=kkk;
    }
    }
    } else { // swipe left
    swipel=la;
    swipelcp=lacp;

    if (e.target == opastr) {
    kkk=eval(-1 + eval('' + kpastr));
    if (kkk < 0) {
    kpastr=eval(-1 + eval('' + apastr.length));
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(-1 + eval('' + kpdstr));
    if (kkk < 0) {
    kpdstr=eval(-1 + eval('' + apdstr.length));
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(-1 + eval('' + kimstr));
    if (kkk < 0) {
    kimstr=eval(-1 + eval('' + aimstr.length));
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(-1 + eval('' + kffstr));
    if (kkk < 0) {
    kffstr=eval(-1 + eval('' + affstr.length));
    } else {
    kffstr=kkk;
    }
    }
    }
    }
    //alert('swipe distance = ' + Math.abs(pos1 - pos3));
    }
    lasto=e.target;
    }

    function betweeneatatjoes() {
    var origt='', origrest='', kkprefix=swipelcp + '...', kksuffix='...' + swipercp;
    var origkkprefix='', origkksuffix='', origkprefix='', origksuffix='';
    if (kprefix == '' && ksuffix == '') {
    kprefix=swipel + '&#128309;..';
    kkprefix=swipelcp + String.fromCodePoint(128309) + '..';
    ksuffix='...' + swiper;
    //document.getElementById('doverlaytwo').style.marginTop='20px';
    } else if (kprefix == swipel + '&#128309;..') {
    kprefix=swipel + '.&#128309;.';
    kkprefix=swipelcp +'.' + String.fromCodePoint(128309) + '.';
    ksuffix='...' + swiper;
    } else if (kprefix == swipel + '.&#128309;.') {
    kprefix=swipel + '..&#128309;';
    kkprefix=swipelcp + '..' + String.fromCodePoint(128309) + '';
    ksuffix='...' + swiper;
    } else if (kprefix == swipel + '..&#128309;') {
    ksuffix='&#128309;..' + swiper;
    kksuffix=String.fromCodePoint(128309) + '..' + swipercp;
    kprefix=swipel + '...' + swiper;
    } else if (ksuffix == '&#128309;..' + swiper) {
    ksuffix='.&#128308;.' + swiper;
    kksuffix='.' + String.fromCodePoint(128308) + '.' + swipercp;
    kprefix=swipel + '...';
    } else if (ksuffix == '.&#128308;.' + swiper) {
    ksuffix='..&#128308;' + swiper;
    kksuffix='..' + String.fromCodePoint(128308) + '' + swipercp;
    kprefix=swipel + '...';
    } else {
    kprefix=swipel + '&#917536;..';
    kkprefix=swipelcp + '..' + String.fromCodePoint(917536) + '..';
    ksuffix='...' + swiper;
    //document.getElementById('doverlaytwo').style.marginTop='0px';
    }


    origkkprefix=kkprefix;
    origkksuffix=kksuffix;
    origkprefix=kprefix;
    origksuffix=ksuffix;



    if (oimstr) {
    origt=oimstr.getAttribute('data-title');
    if (lasto == oimstr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kimstr == 0) {
    oimstr.innerHTML=' ' + kprefix + aimstr[kimstr] + ksuffix;
    origrest=(origt.split('' + aimstr[kimstr])[1] + ',' + origt.split('' + aimstr[kimstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    oimstr.title=kkprefix + aimstr[kimstr] + kksuffix + origrest;
    } else {
    oimstr.innerHTML=' ' + kprefix + aimstr[eval(-1 + kimstr)] + ksuffix;
    origrest=(origt.split('' + aimstr[eval(-1 + kimstr)])[1] + ',' + origt.split('' + aimstr[eval(-1 + kimstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    oimstr.title=kkprefix + aimstr[eval(-1 + kimstr)] + kksuffix + origrest;
    }
    }
    if (opdstr) {
    origt=opdstr.getAttribute('data-title');
    if (lasto == opdstr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kpdstr == 0) {
    opdstr.innerHTML=' ' + kprefix + apdstr[kpdstr] + ksuffix;
    origrest=(origt.split('' + apdstr[kpdstr])[1] + ',' + origt.split('' + apdstr[kpdstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opdstr.title=kkprefix + apdstr[kpdstr] + kksuffix + origrest;
    } else {
    opdstr.innerHTML=' ' + kprefix + apdstr[eval(-1 + kpdstr)] + ksuffix;
    origrest=(origt.split('' + apdstr[eval(-1 + kpdstr)])[1] + ',' + origt.split('' + apdstr[eval(-1 + kpdstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opdstr.title=kkprefix + apdstr[eval(-1 + kpdstr)] + kksuffix + origrest;
    }
    }
    if (opastr) {
    origt=opastr.getAttribute('data-title');
    if (lasto == opastr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kpastr == 0) {
    opastr.innerHTML=' ' + kprefix + apastr[kpastr] + ksuffix;
    origrest=(origt.split('' + apastr[kpastr])[1] + ',' + origt.split('' + apastr[kpastr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opastr.title=kkprefix + apastr[kpastr] + kksuffix + origrest;
    } else {
    opastr.innerHTML=' ' + kprefix + apastr[eval(-1 + kpastr)] + ksuffix;
    origrest=(origt.split('' + apastr[eval(-1 + kpastr)])[1] + ',' + origt.split('' + apastr[eval(-1 + kpastr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opastr.title=kkprefix + apastr[eval(-1 + kpastr)] + kksuffix + origrest;
    }
    }
    if (offstr) {
    origt=offstr.getAttribute('data-title');
    if (lasto == offstr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kffstr == 0) {
    offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
    origrest=(origt.split('' + affstr[kffstr])[1] + ',' + origt.split('' + affstr[kffstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    offstr.title=kkprefix + affstr[kffstr] + kksuffix + origrest;
    } else {
    offstr.innerHTML=' ' + kprefix + affstr[eval(-1 + kffstr)] + ksuffix;
    origrest=(origt.split('' + affstr[eval(-1 + kffstr)])[1] + ',' + origt.split('' + affstr[eval(-1 + kffstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    offstr.title=kkprefix + affstr[eval(-1 + kffstr)] + kksuffix + origrest;
    }
    }
    kcnt++;
    swipel='';
    swipelcp='';
    swiper='';
    swipercp='';

    if (kcnt < 7) { setTimeout(betweeneatatjoes, 1000); }
    }

    “; ?>

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial

Some users are impatient, we grant you. Maybe some don’t want to wait the whole time of an 8 second “Eat at Joes” rotation. Well, we thought about this, and got an idea to extend yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial‘s non-mobile functionality via …

  • dropdown option (with animation) element onmouseover (hover swipe (maybe) in x,y) … call such as oimstr.onmouseover=function(event) { wasplace(oimstr, event); }; … uses …
    <?php echo ”

    var pos1=0, pos2=0, pos3=0, pos4=0, lasto=null;

    function wasplace(thiso, e) {
    e = e || window.event;
    e.preventDefault();
    if (e.touches) {
    if (e.touches[0].pageX) {
    pos1 = e.touches[0].pageX;
    pos2 = e.touches[0].pageY;
    } else {
    pos1 = e.touches[0].clientX;
    pos2 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos1 = e.clientX;
    pos2 = e.clientY;
    } else {
    pos1 = e.pageX;
    pos2 = e.pageY;
    }
    lasto=e.target;
    }

    “; ?>
    …and onmouseout (hover swipe out x,y) events … if deltax >= 70 … call such as oimstr.onmouseout=function(event) { isplace(oimstr, event); }; … uses …
    <?php echo ”

    function isplace(thiso, e) {
    var kkk=0;
    e = e || window.event;
    e.preventDefault();
    if (e.touches) {
    if (e.touches[0].pageX) {
    pos3 = e.touches[0].pageX;
    pos4 = e.touches[0].pageY;
    } else {
    pos3 = e.touches[0].clientX;
    pos4 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos3 = e.clientX;
    pos4 = e.clientY;
    } else {
    pos3 = e.pageX;
    pos4 = e.pageY;
    }
    if (lasto == e.target) {
    if (Math.abs(pos1 - pos3) >= 70) {
    if (pos3 > pos1) { // swipe right
    if (e.target == opastr) {
    kkk=eval(1 + eval('' + kpastr));
    if (kkk >= eval('' + apastr.length)) {
    kpastr=0;
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(1 + eval('' + kpdstr));
    if (kkk >= eval('' + apdstr.length)) {
    kpdstr=0;
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(1 + eval('' + kimstr));
    if (kkk >= eval('' + aimstr.length)) {
    kimstr=0;
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(1 + eval('' + kffstr));
    if (kkk >= eval('' + affstr.length)) {
    kffstr=0;
    } else {
    kffstr=kkk;
    }
    }
    } else { // swipe left
    if (e.target == opastr) {
    kkk=eval(-1 + eval('' + kpastr));
    if (kkk < 0) {
    kpastr=eval(-1 + eval('' + apastr.length));
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(-1 + eval('' + kpdstr));
    if (kkk < 0) {
    kpdstr=eval(-1 + eval('' + apdstr.length));
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(-1 + eval('' + kimstr));
    if (kkk < 0) {
    kimstr=eval(-1 + eval('' + aimstr.length));
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(-1 + eval('' + kffstr));
    if (kkk < 0) {
    kffstr=eval(-1 + eval('' + affstr.length));
    } else {
    kffstr=kkk;
    }
    }
    }
    }
    //alert('swipe distance = ' + Math.abs(pos1 - pos3));
    }
    lasto=e.target;
    }

    “; ?>
  • class a swipe right (if deltax > 0) else swipe left … resulting in …
  • immediately show next option innerText if swipe right and show previous option innerText if swipe left

… for you to try for yourself

Media and document action items … please note you can hover swipe right or left, accurately, and with panache, regarding animated options to speed up transitions between option values

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial

The non-mobile platforms have that useful wooooorrrrllllddd, the “onhover wooooorrrrllllddd” (to be precise) that can be a great partner for Javascript Ajax methodologies. This onhover (actually the “onmouseover”) event is also useful whereby as a user hovers over an HTML element, and that element’s title attribute has a value, then the user can see that value displayed.

And though, with yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial work …

though we’re not going “full marquee Eat at Joes”

… regarding the dropdown option innerText “look”, there is, for non-mobile, this “onhover wooooorrrrllllddd” we can use to try a form of marquee “look” there, as per

<?php echo ”

function betweeneatatjoes() {
var origt='', origrest='', kkprefix='...', kksuffix='...';
if (kprefix == '' && ksuffix == '') {
kprefix='&#128309;..';
kkprefix=String.fromCodePoint(128309) + '..';
ksuffix='...';
//document.getElementById('doverlaytwo').style.marginTop='20px';
} else if (kprefix == '&#128309;..') {
kprefix='.&#128309;.';
kkprefix='.' + String.fromCodePoint(128309) + '.';
ksuffix='...';
} else if (kprefix == '.&#128309;.') {
kprefix='..&#128309;';
kkprefix='..' + String.fromCodePoint(128309) + '';
ksuffix='...';
} else if (kprefix == '..&#128309;') {
ksuffix='&#128309;..';
kksuffix=String.fromCodePoint(128309) + '..';
kprefix='...';
} else if (ksuffix == '&#128309;..') {
ksuffix='.&#128308;.';
kksuffix='.' + String.fromCodePoint(128308) + '.';
kprefix='...';
} else if (ksuffix == '.&#128308;.') {
ksuffix='..&#128308;';
kksuffix='..' + String.fromCodePoint(128308) + '';
kprefix='...';
} else {
kprefix='&#917536;..';
kkprefix='..' + String.fromCodePoint(917536) + '..';
ksuffix='...';
//document.getElementById('doverlaytwo').style.marginTop='0px';
}
if (oimstr) {
origt=oimstr.getAttribute('data-title');
if (kimstr == 0) {
oimstr.innerHTML=' ' + kprefix + aimstr[kimstr] + ksuffix;
origrest=(origt.split('' + aimstr[kimstr])[1] + ',' + origt.split('' + aimstr[kimstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
oimstr.title=kkprefix + aimstr[kimstr] + kksuffix + origrest;

} else {
oimstr.innerHTML=' ' + kprefix + aimstr[eval(-1 + kimstr)] + ksuffix;
origrest=(origt.split('' + aimstr[eval(-1 + kimstr)])[1] + ',' + origt.split('' + aimstr[eval(-1 + kimstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
oimstr.title=kkprefix + aimstr[eval(-1 + kimstr)] + kksuffix + origrest;

}
}
if (opdstr) {
origt=opdstr.getAttribute('data-title');
if (kpdstr == 0) {
opdstr.innerHTML=' ' + kprefix + apdstr[kpdstr] + ksuffix;
origrest=(origt.split('' + apdstr[kpdstr])[1] + ',' + origt.split('' + apdstr[kpdstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opdstr.title=kkprefix + apdstr[kpdstr] + kksuffix + origrest;

} else {
opdstr.innerHTML=' ' + kprefix + apdstr[eval(-1 + kpdstr)] + ksuffix;
origrest=(origt.split('' + apdstr[eval(-1 + kpdstr)])[1] + ',' + origt.split('' + apdstr[eval(-1 + kpdstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opdstr.title=kkprefix + apdstr[eval(-1 + kpdstr)] + kksuffix + origrest;

}
}
if (opastr) {
origt=opastr.getAttribute('data-title');
if (kpastr == 0) {
opastr.innerHTML=' ' + kprefix + apastr[kpastr] + ksuffix;
origrest=(origt.split('' + apastr[kpastr])[1] + ',' + origt.split('' + apastr[kpastr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opastr.title=kkprefix + apastr[kpastr] + kksuffix + origrest;

} else {
opastr.innerHTML=' ' + kprefix + apastr[eval(-1 + kpastr)] + ksuffix;
origrest=(origt.split('' + apastr[eval(-1 + kpastr)])[1] + ',' + origt.split('' + apastr[eval(-1 + kpastr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opastr.title=kkprefix + apastr[eval(-1 + kpastr)] + kksuffix + origrest;

}
}
if (offstr) {
origt=offstr.getAttribute('data-title');
if (kffstr == 0) {
offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
origrest=(origt.split('' + affstr[kffstr])[1] + ',' + origt.split('' + affstr[kffstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
offstr.title=kkprefix + affstr[kffstr] + kksuffix + origrest;

} else {
offstr.innerHTML=' ' + kprefix + affstr[eval(-1 + kffstr)] + ksuffix;
origrest=(origt.split('' + affstr[eval(-1 + kffstr)])[1] + ',' + origt.split('' + affstr[eval(-1 + kffstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
offstr.title=kkprefix + affstr[eval(-1 + kffstr)] + kksuffix + origrest;

}
}
kcnt++;
if (kcnt < 7) { setTimeout(betweeneatatjoes, 1000); }
}

“; ?>

Proof positive that emojis are text, and can help provide a graphic display interest for a webpage. As well, as a CSS means by which we stop “dropdown Y jitteriness”, we introduce the use of an emoji ⚪ (&#9898; or &#x26aa;) for most option element Clayton innerText parts, always …


<style>
option:not(.nonwhite)::before {
content: '\0026aa';
}


#doverlay {
background-color: #FFE7E9;
}


#doverlaytwo {
background-color: #FFE7E9;
}


body {
background-color: #FFFFEF;
}
</style>

“; ?>

… with one more media functionality

<?php

var mlook=false, kcnt=0, kprefix='', ksuffix='';
var imstr=' Images to PDF, Images to GIF,', oimstr=null, kimstr=0, aimstr=[];
var pdstr=' PDF to Images, PDF to HTML, PDF to XML,', opdstr=null, kpdstr=0, apdstr=[];
var pastr=' Text to HTML, Text to Rich Text, Text to Word,', opastr=null, kpastr=0, apastr=[];
var ffstr=' Concat demuxer, Display the frame number on each frame,', offstr=null, kffstr=0, affstr=[];

?>

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial

The “dropdown animations” introduced into yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial were a tad subtle, it only involving …

  • the wording of option elements within the dropdown … and though we’re not going “full marquee Eat at Joes” we are accentuating “midway”, today, by …
  • adding emoji 🔵 (&#128309;) movement to the animation for interest sake, as well as being informative (in that the user can anticipate when the new innerText text will arrive, as the emoji moves from left to right)

… that we team with more instances of multiple animation settings …

<?php echo ”

var mlook=false, kcnt=0, kprefix='', ksuffix='';
var imstr=' Images to PDF, Images to GIF,', oimstr=null, kimstr=0, aimstr=[];
var pdstr=' PDF to Images, PDF to HTML, PDF to XML,', opdstr=null, kpdstr=0, apdstr=[];
var pastr=' Text to HTML, Text to Rich Text, Text to Word,', opastr=null, kpastr=0, apastr=[];
var ffstr=' Concat demuxer, ', offstr=null, kffstr=0, affstr=[];

“; ?>

… and a new “between the 8 second setInterval wording refreshes” Javascript function

<?php echo ”

function betweeneatatjoes() {
if (kprefix == '' && ksuffix == '') {
kprefix='&#128309;..';
ksuffix='...';
document.getElementById('doverlaytwo').style.marginTop='20px';
} else if (kprefix == '&#128309;..') {
kprefix='.&#128309;.';
ksuffix='...';
} else if (kprefix == '.&#128309;.') {
kprefix='..&#128309;';
ksuffix='...';
} else if (kprefix == '..&#128309;') {
ksuffix='&#128309;..';
kprefix='...';
} else if (ksuffix == '&#128309;..') {
ksuffix='.&#128309;.';
kprefix='...';
} else if (ksuffix == '.&#128309;.') {
ksuffix='..&#128309;';
kprefix='...';
} else {
kprefix='...';
ksuffix='...';
document.getElementById('doverlaytwo').style.marginTop='0px';
}
if (oimstr) {
if (kimstr == 0) {
oimstr.innerHTML=' ' + kprefix + aimstr[kimstr] + ksuffix;
} else {
oimstr.innerHTML=' ' + kprefix + aimstr[eval(-1 + kimstr)] + ksuffix;
}
}
if (opdstr) {
if (kpdstr == 0) {
opdstr.innerHTML=' ' + kprefix + apdstr[kpdstr] + ksuffix;
} else {
opdstr.innerHTML=' ' + kprefix + apdstr[eval(-1 + kpdstr)] + ksuffix;
}
}
if (opastr) {
if (kpastr == 0) {
opastr.innerHTML=' ' + kprefix + apastr[kpastr] + ksuffix;
} else {
opastr.innerHTML=' ' + kprefix + apastr[eval(-1 + kpastr)] + ksuffix;
}
}
if (offstr) {
if (kffstr == 0) {
offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
} else {
offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
}
}
kcnt++;
if (kcnt < 7) { setTimeout(betweeneatatjoes, 1000); }
}



function eatatjoes() {
kcnt=0;
kprefix='';
ksuffix='';
document.getElementById('doverlaytwo').style.marginTop='0px';

if (oimstr) {
if (kimstr >= eval('' + aimstr.length)) {
kimstr=0;
oimstr.innerHTML=' ' + aimstr[kimstr];
} else {
oimstr.innerHTML=' ' + aimstr[kimstr];
kimstr++;
}
}
if (opdstr) {
if (kpdstr >= eval('' + apdstr.length)) {
kpdstr=0;
opdstr.innerHTML=' ' + apdstr[kpdstr];
} else {
opdstr.innerHTML=' ' + apdstr[kpdstr];
kpdstr++;
}
}
if (opastr) {
//alert(apastr.length);
if (kpastr >= eval('' + apastr.length)) {
kpastr=0;
opastr.innerHTML=' ' + apastr[kpastr];
} else {
opastr.innerHTML=' ' + apastr[kpastr];
kpastr++;
}
}
if (offstr) {
if (kffstr >= eval('' + affstr.length)) {
kffstr=0;
offstr.innerHTML=' ' + affstr[kffstr];
} else {
offstr.innerHTML=' ' + affstr[kffstr];
kffstr++;
}
}
setTimeout(betweeneatatjoes, 1000);
}


function andthen(iidea) {
var outidea=iidea;
var fndpos=-1;
var optsare=document.getElementsByTagName('option'), ioptsare=0;
var iimstr=(imstr.indexOf(',') == -1 ? -1 : outidea.indexOf(imstr.split(',')[0].trim() + ','));
mlook=false;
if (iimstr != -1) {
if ((imstr.split(',')[0].trim() + ',') != imstr.trim()) {
if (document.getElementById('oimagemagick')) {
oimstr=document.getElementById('oimagemagick');
mlook=true;
aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == imstr.split(',')[0].trim()) {
oimstr=optsare[ioptsare];
mlook=true;
aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(imstr.split(',')[0].trim(), imstr.split(',')[0].trim() + '' + (imstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
var ipdstr=(pdstr.indexOf(',') == -1 ? -1 : outidea.indexOf(pdstr.split(',')[0].trim() + ','));
if (ipdstr != -1) {
if ((pdstr.split(',')[0].trim() + ',') != pdstr.trim()) {
if (document.getElementById('opdfimages')) {
opdstr=document.getElementById('opdfimages');
mlook=true;
apdstr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == pdstr.split(',')[0].trim()) {
opdstr=optsare[ioptsare];
mlook=true;
apdstr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(pdstr.split(',')[0].trim(), pdstr.split(',')[0].trim() + '' + (pdstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
var ipastr=(pastr.indexOf(',') == -1 ? -1 : outidea.indexOf(pastr.split(',')[0].trim() + ','));
if (ipastr != -1) {
if ((pastr.split(',')[0].trim() + ',') != pastr.trim()) {
if (document.getElementById('opandoc')) {
opastr=document.getElementById('opandoc');
mlook=true;
apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == pastr.split(',')[0].trim()) {
opastr=optsare[ioptsare];
mlook=true;
apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(pastr.split(',')[0].trim(), pastr.split(',')[0].trim() + '' + (pastr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
var iffstr=(ffstr.indexOf(',') == -1 ? -1 : outidea.indexOf(ffstr.split(',')[0].trim() + ','));
if (iffstr != -1) {
if ((ffstr.split(',')[0].trim() + ',') != ffstr.trim()) {
if (document.getElementById('offmpeg')) {
offstr=document.getElementById('offmpeg');
mlook=true;
affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == ffstr.split(',')[0].trim()) {
offstr=optsare[ioptsare];
mlook=true;
affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(ffstr.split(',')[0].trim(), ffstr.split(',')[0].trim() + '' + (ffstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
if (mlook) { setInterval(eatatjoes, 8000); }
return outidea;
}

“; ?>

… helped out via the original setInterval Javascript “eatatjoes” function (all kicked off via modified document.body onload logic
document.getElementById(‘mainspan’).title = andthen(document.getElementById(‘schoices’).innerText.replace(/\&nbsp\;/g,’ ‘).replace(/\ \ /g,’, ‘));
), as modified, above.

You can see this in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial

Lemon curry?! Animated dropdown?! What gives? Well, it’s not “shelling peas”, yet!

Yes, there is another “framework” step forward we wanted to implement before the peas. And yes, no surprises there, the “framework” work relates to adding functionality to our main dropdown. We’re adding a layer of functionality we’re going to refer to as “animated dropdown”. It amounts to …

  • dropdown (ie. select element) … for non-mobile …
  • has size attribute equal to the number of option elements it contains
  • logic wise, because our non-nothing option innerTexts have equalled option values (if you Javascript trim() the option innerText, that is), we have the opportunity to start taking more notice of the …
    <?php echo ”

    function process(tv, tvo) {
    var newval='';
    var ourtv=tvo.value;
    if (tv != '') {
    ourtv=tvo.options[tvo.selectedIndex].innerText.trim();
    }

    if (origval == '') { origval=document.getElementById('mydefopt').title; }
    if (tv == '') {
    document.getElementById('mainspan').innerHTML=document.getElementById('mydefopt').title;
    } else {
    document.getElementById('mydefopt').title=ourtv; //tv;
    document.getElementById('mainspan').innerHTML=document.getElementById('mydefopt').title;
    document.getElementById('schoices').value='';
    }
    newval=document.getElementById('mydefopt').title;
    //alert('origval,newval=' + origval + ' ' + newval);
    if (newval != origval) {
    origval=newval;
    wentfrom(origval, newval);
    } else {
    origval=newval;
    }
    }

    “; ?>
    … option innerHTML as above, meaning …
  • we can set up Javascript code facilitating the animated feel of some option innerHTML looks that are taken notice of as selected via …
    Global variables arranged via each “verb” involved … for today’s “proof of concept” we add one extra Pandoc “Text to Rich Text” option, for now, before the flood of peas arrives …
    <?php echo ”

    var mlook=false;
    var imstr=' Images to PDF, ', oimstr=null, kimstr=0, aimstr=[];
    var pdstr=' PDF to Images, ', opdstr=null, kpdstr=0, apdstr=[];
    var pastr=' Text to HTML, Text to Rich Text,', opastr=null, kpastr=0, apastr=[];
    var ffstr=' Concat demuxer, ', offstr=null, kffstr=0, affstr=[];

    “; ?>
    As heading title is determined at document.body onload document.getElementById(‘mainspan’).title=andthen(document.getElementById(‘schoices’).innerText.replace(/\&nbsp\;/g,’ ‘).replace(/\ \ /g,’, ‘));
    <?php echo ”

    function andthen(iidea) {
    var outidea=iidea;
    var fndpos=-1;
    var optsare=document.getElementsByTagName('option'), ioptsare=0;
    var iimstr=(imstr.indexOf(',') == -1 ? -1 : outidea.indexOf(imstr.split(',')[0].trim() + ','));
    mlook=false;
    if (iimstr != -1) {
    if ((imstr.split(',')[0].trim() + ',') != imstr.trim()) {
    if (document.getElementById('oimagemagick')) {
    oimstr=document.getElementById('oimagemagick');
    mlook=true;
    aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == imstr.split(',')[0].trim()) {
    oimstr=optsare[ioptsare];
    mlook=true;
    aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(imstr.split(',')[0].trim(), imstr.split(',')[0].trim() + '' + (imstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    var ipdstr=(pdstr.indexOf(',') == -1 ? -1 : outidea.indexOf(pdstr.split(',')[0].trim() + ','));
    if (ipdstr != -1) {
    if ((pdstr.split(',')[0].trim() + ',') != pdstr.trim()) {
    if (document.getElementById('opdfimages')) {
    opdstr=document.getElementById('opdfimages');
    mlook=true;
    aipdtr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == pdstr.split(',')[0].trim()) {
    opdstr=optsare[ioptsare];
    mlook=true;
    apdstr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(pdstr.split(',')[0].trim(), pdstr.split(',')[0].trim() + '' + (pdstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    var ipastr=(pastr.indexOf(',') == -1 ? -1 : outidea.indexOf(pastr.split(',')[0].trim() + ','));
    if (ipastr != -1) {
    if ((pastr.split(',')[0].trim() + ',') != pastr.trim()) {
    if (document.getElementById('opandoc')) {
    opastr=document.getElementById('opandoc');
    mlook=true;
    apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == pastr.split(',')[0].trim()) {
    opastr=optsare[ioptsare];
    mlook=true;
    apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(pastr.split(',')[0].trim(), pastr.split(',')[0].trim() + '' + (pastr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    var iffstr=(ffstr.indexOf(',') == -1 ? -1 : outidea.indexOf(ffstr.split(',')[0].trim() + ','));
    if (iffstr != -1) {
    if ((ffstr.split(',')[0].trim() + ',') != ffstr.trim()) {
    if (document.getElementById('offmpeg')) {
    offstr=document.getElementById('offmpeg');
    mlook=true;
    affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == ffstr.split(',')[0].trim()) {
    offstr=optsare[ioptsare];
    mlook=true;
    affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(ffstr.split(',')[0].trim(), ffstr.split(',')[0].trim() + '' + (ffstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    if (mlook) { setInterval(eatatjoes, 8000); }
    return outidea;
    }

    “; ?>
    … the appeal of all this being that the dropdown height can be controlled by swapping animation for height extension (and user experience downgrades)
    Animated dropdown setInterval Javascript function (bit like marquee Eat at Joes type of animation (we’ll see if it gets more like it into the future, perhaps?)) …
    <?php echo ”

    function eatatjoes() {
    if (oimstr) {
    if (kimstr >= eval('' + aimstr.length)) {
    kimstr=0;
    oimstr.innerHTML=' ' + aimstr[kimstr];
    } else {
    oimstr.innerHTML=' ' + aimstr[kimstr];
    kimstr++;
    }
    }
    if (opdstr) {
    if (kpdstr >= eval('' + apdstr.length)) {
    kpdstr=0;
    opdstr.innerHTML=' ' + apdstr[kpdstr];
    } else {
    opdstr.innerHTML=' ' + apdstr[kpdstr];
    kpdstr++;
    }
    }
    if (opastr) {
    if (kpastr >= eval('' + apastr.length)) {
    kpastr=0;
    opastr.innerHTML=' ' + apastr[kpastr];
    } else {
    opastr.innerHTML=' ' + apastr[kpastr];
    kpastr++;
    }
    }
    if (offstr) {
    if (kffstr >= eval('' + affstr.length)) {
    kffstr=0;
    offstr.innerHTML=' ' + affstr[kffstr];
    } else {
    offstr.innerHTML=' ' + affstr[kffstr];
    kffstr++;
    }
    }
    }

    “; ?>

… onto yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial

Onto yesterday’s Ffmpeg and ImageMagick and Pdfimages Media Tutorial

  • ffmpeg … two more media manipulation “verb” stars today …
  • ImageMagick (can help us with new “Images to PDF” option)
  • pdfimages (can help us with new “PDF to Images” option) … “verb” collection, today, we wanted to add …
  • pandoc (can help us with new “Text to HTML” option) …

    If you need to convert files from one markup format into another, pandoc is your swiss-army knife.

… to help improve the “one stop shop” aspects, especially regarding “documents”, to our current Intranet feeling web application in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and ImageMagick and Pdfimages Media Tutorial is shown below.

Ffmpeg and ImageMagick and Pdfimages Media Tutorial

Ffmpeg and ImageMagick and Pdfimages Media Tutorial

Yesterday’s Ffmpeg Rotate Video Tutorial left you with …

We now present those four in “an expanded out” (at least on non-mobile) dropdown HTML element. Maybe you can guess why?

… and today we are deploying the framework parts and two new media manipulation options regarding PDF that add to our PHP web application’s functionality.

Operating system commands can be thought of to start with …

  • an action item (to be precise a desktop software file specification) … and, what we often think is, like …
  • the command’s “verb” part (as funny as that is to think of a “noun” sounding desktop software file specification being like a “verb”) … verbs being action items in a sentence … down to being essential in any sentence … to the point a “verb” can be the whole sentence

We want to add functionality by adding to our first “verb” …

  • ffmpeg … two more media manipulation “verb” stars today …
  • ImageMagick (can help us with new “Images to PDF” option)
  • pdfimages (can help us with new “PDF to Images” option)

… and to help the “framework” ahead of “shelling peas” we lean on the experience we got from the Animated GIF Creation on Windows MAMP via PDF Tutorial thread of blog postings to deal with …

  • software paths
  • presenting two new “verb” ideas … and us being so fond of dropdowns, we decided to try, for our first time …
    1. start to use three HTML option CSS text-align style choices being left (for ffmpeg), center (for ImageMagick) and right (for pdfimages) … as in …

      … within …

      Add Voiceover Audio to Video via ffmpeg  pdfimages



      <select size=7 onchange=process(this.value,this); style=display:inline-block;font-size:8px; id=schoices><option style=text-align:center; id=mydefopt title='Add Voiceover Audio to Video' value=''>&#10549; Image&#11015;Magick &#10550;</option><option value='Add Voiceover Audio to Video'> Add Voiceover Audio to Video </option><option style='text-align:center;' value='Images to PDF'> Images to PDF</option><option style='text-align:right;' value='PDF to Images'> PDF to Images</option><option value='Burn subtitles'> Burn subtitles</option><option value='Concat demuxer'> Concat demuxer</option><option value='Rotate a video'> Rotate a video</option></select>

      … and then in order to offer the “center” ImageMagick be a link back to the product we introduce some new overlay code
      <?php echo ”

      function overlay() {
      origval=document.getElementById('schoices').value;
      var rect=document.getElementById('fcommand').getBoundingClientRect();
      document.getElementById('moreb').style.position='absolute';
      document.getElementById('moreb').style.left='' + rect.left + 'px';
      document.getElementById('moreb').style.top='' + rect.top + 'px';
      document.getElementById('moreb').style.width='96%'; //' + rect.width + 'px';
      document.getElementById('moreb').style.height='' + rect.height + 'px';
      document.getElementById('moreb').style.border='1px solid black';
      document.getElementById('moreb').style.paddingLeft='20px';
      document.getElementById('moreb').style.backgroundColor='#f9f9f9';
      document.getElementById('fcommand').style.opacity='0.0';
      document.getElementById('fcommand').style.cursor='pointer';
      document.getElementById('moreb').innerHTML='<span id=precmds></span><span id=verb>ffmpeg" . $ffmpegsuf . "</span> <span id=prescbi></span><span id=minusi> -i </span><span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&left=y\"></iframe></span> <span id=betweenis></span> <span id=secondi>-i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&right=y\"></iframe></span></span> <span id=sswitches>-c copy -map 0:v:0 -map 1:a:0 -shortest</span> out.mp4 > <a target=_blank title=ffimpdf.bad onclick=getvb(); style=cursor:pointer;text-decoration:underline; data-href=./ffimpdf.bad>ffimpdf.bad</a>';
      if (firstdivih == '') { firstdivih=document.getElementById('moreb').innerHTML; }
      if (firstbutval == '') { firstbutval=document.getElementById('mysub').value; }
      document.getElementById('schoices').style.display='inline-block';


      rect=document.getElementById('schoices').getBoundingClientRect();


      if (eval('' + rect.height) > 100 || 1 == 1) {
      document.getElementById('doverlay').style.position='absolute';
      document.getElementById('doverlay').style.left='' + rect.left + 'px';
      document.getElementById('doverlay').style.top='' + rect.top + 'px';
      document.getElementById('doverlay').style.width='' + rect.width + 'px';
      if (eval('' + rect.height) < 30) {
      document.getElementById('doverlay').style.height='' + rect.height + 'px';
      } else {
      document.getElementById('doverlay').style.height='' + eval(eval('' + rect.height) / eval('' + document.getElementById('schoices').size)) + 'px';
      }
      document.getElementById('doverlay').style.zIndex='96';
      document.getElementById('doverlay').style.textAlign='center';
      document.getElementById('doverlay').style.display='block';
      document.getElementById('doverlay').title=document.getElementById('mydefopt').title;
      //document.getElementById('mydefopt').style.fontColor='transparent';
      document.getElementById('mydefopt').innerHTML='';
      setInterval(fhoc, 1000);
      }



      }


      function fhoc() {
      var rectx=document.getElementById('schoices').getBoundingClientRect();
      document.getElementById('doverlay').style.left='' + rectx.left + 'px';
      document.getElementById('doverlay').title=document.getElementById('mydefopt').title;
      if (document.getElementById('scbi')) {
      if (document.getElementById('scbi').innerHTML.indexOf('<') == -1) {
      if (document.getElementById('scbi').innerHTML.trim().indexOf(' ') != -1) {
      if (document.getElementById('scbi').innerHTML.trim().indexOf(String.fromCharCode(34)) == -1) {
      document.getElementById('scbi').innerHTML=String.fromCharCode(34) + document.getElementById('scbi').innerHTML.trim() + String.fromCharCode(34);
      }
      }
      }
      }
      if (document.getElementById('scbix')) {
      if (document.getElementById('scbix').innerHTML.indexOf('<') == -1) {
      if (document.getElementById('scbix').innerHTML.trim().indexOf(' ') != -1) {
      if (document.getElementById('scbix').innerHTML.trim().indexOf(String.fromCharCode(34)) == -1) {
      document.getElementById('scbix').innerHTML=String.fromCharCode(34) + document.getElementById('scbix').innerHTML.trim() + String.fromCharCode(34);
      }
      }
      }
      }
      }


      “; ?>

  • Javascript to set up the HTML div contenteditable=true look for these two new options …
    <?php echo ”

    if (newv == 'PDF to Images') {
    document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' " . $minuspng . "');
    document.getElementById('secondi').innerHTML='';
    document.getElementById('sswitches').innerHTML=\"<span id=sfolder contenteditable=false>newfolder_" . rand(0,784534) . str_replace("\\","\\\\",$ddn) . "\" + '</span>ideas';

    document.getElementById('precmds').innerHTML=' ';
    document.getElementById('verb').innerHTML='" . $pdfimages . $pdfimagessuf . "';
    document.getElementById('scbi').innerHTML=document.getElementById('scbi').innerHTML.replace(/inv\.mp4/g,'inv.pdf ');
    document.getElementById('minusi').innerHTML=' -j ';

    document.getElementById('mysub').value=newv;
    } else if (newv == 'Images to PDF') {
    document.getElementById('moreb').innerHTML=firstdivih.replace('out.mp4','out.pdf');

    document.getElementById('precmds').innerHTML=' ';
    document.getElementById('secondi').innerHTML='';
    document.getElementById('verb').innerHTML='" . $magickverb . $magicksuf . "';
    document.getElementById('sswitches').innerHTML='-auto-orient';
    document.getElementById('sswitches').title='To perform a folder of images (only, we suggest) right click or two finger guesture to left and enter the folder name only';
    document.getElementById('scbi').innerHTML=document.getElementById('scbi').innerHTML.replace(/inv\.mp4/g,'inv.jpg ');
    document.getElementById('minusi').innerHTML='';
    document.getElementById('scbi').setAttribute('contenteditable', true);
    document.getElementById('scbi').onblur=function(event) { if (document.getElementById('mydefopt').title == 'Images to PDF') { if (event.target.innerHTML.replace(/\ \;/g,' ').trim() == '') { event.target.innerHTML='folder' + \"" . str_replace("\\","\\\\",$ddn) . "*\"; } if (event.target.innerHTML.toLowerCase().indexOf('.txt') == -1) { if (event.target.innerHTML.indexOf('.') != -1) { document.getElementById('ifs').innerHTML+='<iframe id=voaskfor' + ifile + ' style=display:none; src=\"./voiceover.php?infilegetsize=' + encodeURIComponent(listtxt + ';' + event.target.innerHTML) + '\"></iframe>'; ifile++; if (document.getElementById('moreb').title.indexOf(\"file '\" + event.target.innerHTML.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\") == -1) { document.getElementById('moreb').title+=String.fromCharCode(10) + \"file '\" + event.target.innerHTML.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\"; } } } event.target.innerHTML=listtxt; if (document.getElementById('minusi')) { document.getElementById('minusi').innerHTML=''; } } };
    document.getElementById('moreb').onblur=function(event) { if (document.getElementById('mydefopt').title == 'Images to PDF') { if (document.getElementById('minusi')) { var thingos=document.getElementById('minusi').innerHTML.replace(/\ \;/g,' ').trim().split('-i '); if (thingos.length > 1) { if (thingos[1].trim() != '' && (thingos[1] + '~').toLowerCase().indexOf('.txt~') == -1) { spanfill(thingos[1]); } } document.getElementById('minusi').innerHTML=''; } if (!document.getElementById('scbi')) { event.target.innerHTML=event.target.innerHTML.replace('<span id=\"between', '<span id=scbi contenteditable=true>' + listtxt + '</span> <span id=\"between'); putbackonblur(); if (event.target.innerHTML.indexOf('> -i </span><span id=\"scbi\"') == -1) { event.target.innerHTML=event.target.innerHTML.replace('</span>' + event.target.innerHTML.split('<span id=\"scbi\"')[0].split('</span>')[-1 + eval(event.target.innerHTML.split('<span id=\"scbi\"')[0].split('</span>').length)],'</span>'); } } } };
    document.getElementById('moreb').oncontextmenu=function(event) { document.getElementById('scbi').innerHTML='folder' + \"" . str_replace("\\","\\\\",$ddn) . "*\"; };


    document.getElementById('mysub').value=newv;
    }

    “; ?>
  • the performing of those two new “verb” ideas …
    <?php

    $pfolder='';
    $ppdf='';

    // ... later ...
    $cmdis=str_replace('+',' ',urldecode($_GET['fcommand']));
    if (PHP_OS =='WINNT' || PHP_OS =='WIN32' || PHP_OS =='Windows') {
    if ($ffmpegpre != '' && strpos($cmdis, 'ffmpeg.') !== false && strpos($cmdis, $ffmpegpre) === false) {
    $cmdis=str_replace('ffmpeg.', $ffmpegpre . 'ffmpeg.', $cmdis);
    }
    if ($magickpre != '' && strpos($cmdis, $magickverb . '.') !== false && strpos($cmdis, $magickpre) === false) {
    $cmdis=str_replace($magickverb . '.', $magickpre . $magickverb . '.', $cmdis);
    }
    if ($pdfimagespre != '' && strpos($cmdis, 'pdfimages.') !== false && strpos($cmdis, $pdfimagespre) === false) {
    $cmdis=str_replace('pdfimages.', $pdfimagespre . 'pdfimages.', $cmdis);
    }
    }

    $precmd=explode('>', $cmdis);
    if (strpos($cmdis, 'pdfimages') !== false && strpos($cmdis, 'newfolder_') !== false) {
    $pfolder='newfolder_' . explode(DIRECTORY_SEPARATOR, explode('newfolder_', $cmdis)[1])[0];
    $beforep=explode($pfolder, $cmdis)[0];
    $afterp=explode($pfolder, $cmdis)[1];
    while (file_exists($pfolder)) {
    $pfolder='newfolder' . '_' . explode('newfolder', $pfolder)[1];
    $cmdis=$beforep . $pfolder . $afterp;
    }
    if (!file_exists($pfolder)) { mkdir($pfolder); }
    }

    // ... later ...
    $outf=$subcmd[1];
    // ... later ...
    if (strpos(strtolower(trim($outf) . '~'), '.pdf~') !== false) {
    $ppdf=trim($outf);
    }

    // ... later ...
    $rs=shell_exec($cmdis);

    // ... later ...
    if ($pfolder != '') {
    $rs.="<br><br>";
    foreach (glob($pfolder . DIRECTORY_SEPARATOR . '*.*') as $ifilename) {
    $rs.='<img title="' . $ifilename . '" src="' . $ifilename . '?rand=' . rand(0,7654532) . '"></img>';
    }
    }
    if ($ppdf != '') {
    $outf='';
    $rs.="<br><br><iframe style='width:98%;height:800px;' src='" . $ppdf . "?rand=" . rand(0,7654532) . "' title='" . $ppdf . "'></iframe>";
    }

    ?>

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg Rotate Video Tutorial is shown below.

Ffmpeg Rotate Video Tutorial

Ffmpeg Rotate Video Tutorial

It’s getting closer to “shelling peas”, are today’s “Rotate a video via ffmpeg” changes, but we are not there yet. Yes, most programmers want to be “shelling peas” adding functionality to web applications, once they have set up a framework in which they are happy to work. Yesterday’s Ffmpeg Concat Demuxer Tutorial “defence talk” is getting us closer to that “shelling peas” “homeostasis feel” (with an “Intranet” pike, no doubt?!) as you can see from a Javascript “Rotate a video” code snippet below …

<?php echo ”

if (newv == 'Rotate a video') {
document.getElementById('moreb').innerHTML=firstdivih;

document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML='';


document.getElementById('sswitches').innerHTML='<span id=notranspose contenteditable=false>-vf \"transpose=</span><span id=transpose contenteditable=true>1</span><span id=nottranspose contenteditable=false>\" </span>';
document.getElementById('sswitches').title='" . str_replace("\n", "' + String.fromCharCode(10) + '",$rotateadvice) . "';
document.getElementById('sswitches').oncontextmenu=function(event) { alert(event.target.title); };

document.getElementById('mysub').value=newv;
}

“; ?>

… effectively straightjacketing the crucial …


-vf "transpose=1"

… ffmpeg switch definition, by the user, to changing that 1 above as per the hover over advice, to help the user, straight from Mux Video and Audio from another Video, thanks, to advise …

<?php

$rotateadvice="Rotate a video

Rotate 90 clockwise:

ffmpeg -i in.mov -vf \"transpose=1\" out.mov
For the transpose parameter you can pass:

0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

Use -vf \"transpose=2,transpose=2\" for 180 degrees.";

?>

Yes, the user can still put a bad entry there, but at least the web application has attempted to point them in the right direction, here.

If you examine the changes the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there), am sure that you will concur

  • Concat demuxer concatenation of videos ffmpeg functionality, onto the “as of yesterday” …
  • Voiceovers … and …
  • Burn subtitles
  • Rotate a video

… was the simplest functionality component, yet, of the four. We now present those four in “an expanded out” (at least on non-mobile) dropdown HTML element. Maybe you can guess why?


Previous relevant Ffmpeg Concat Demuxer Tutorial is shown below.

Ffmpeg Concat Demuxer Tutorial

Ffmpeg Concat Demuxer Tutorial

Onto yesterday’s Ffmpeg Burn Subtitles Tutorial work we’re still not up to “shelling any peas” adding in …

  • Concat demuxer concatenation of videos ffmpeg functionality, onto the “as of yesterday” …
  • Voiceovers … and …
  • Burn subtitles

… progress.

What’s different this time? Well, ffmpeg works the command, we again thank Mux Video and Audio from another Video for (regarding “the plan”), using an interim file …

Concat demuxer

First, make a text file.

file ‘in1.mp4’
file ‘in2.mp4’
file ‘in3.mp4’
file ‘in4.mp4’

Then, run ffmpeg :

ffmpeg -f concat -i list.txt -c copy out.mp4

… and for File API browsing (with our, once again, tweaked inhouse client_browsing.htm) there will be a delay, deriving the file path in “second call PHP”. We handle this by writing two new Javascript functions …

<?php echo ”

var ifile=0, ibfile=0;

function takeoffone() {
ibfile--;
if (ibfile <= 0) {
document.getElementById('mysub').style.cursor='pointer';
} else {
document.getElementById('mysub').style.cursor='progress';
}
}

function organizefilenamesize(fn, fs) {
document.getElementById('ifs').innerHTML+='<iframe id=voaskfor' + ifile + ' style=display:none; src=\"./voiceover.php?concat=' + encodeURIComponent('list.txt') + '&filename=' + encodeURIComponent(fn) + '&haveasleep=' + eval(3 * eval('' + ifile)) + '&filesize=' + fs + '\"></iframe>';
if (ibfile == 0) {
document.getElementById('mysub').style.cursor='progress';
}
ifile++;
ibfile++;
if (document.getElementById('moreb').title.indexOf(\"file '\" + fn.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\") == -1) {
document.getElementById('moreb').title+=String.fromCharCode(10) + \"file '\" + fn.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\";
}
}

“; ?>

… available to call from child iframes via parent.takeoneoff(); (from voiceover.php second PHP call) and parent.organizefilenamesize(files[ij].name, files[ij].size); (from client_browsing.htm) respectively, to facilitate a progress cursor on the submit button to remind the user we’d like more time. Along the way, too, we found


ffmpeg -f concat -safe 0 -i list.txt -c copy out.mp4

… thanks to the excellent advice we found at this webpage.

You can see this work in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).

Did you know?

Just like the use of …

… are the SpongeBob, Patrick, and Squidward of the online woooorrrrllllddd, in an “offence” line of “piecing together an operating system command” thinking, thinking “defence” regarding this we added one (we were pleasantly surprised to discover worked, so as) to have …

  • div contenteditable=true
  • spanizing within that div
  • innerText
  • mask off parts the programmer wants left untouched via span contenteditable=false

… being like the Hall and Oates meets Everything But the Girl (on a yacht, of course) step back into the ’80s!

Take a look at some tweaks


if (newv == 'Burn subtitles') {
document.getElementById('moreb').innerHTML=firstdivih;
//document.getElementById('precmds').innerHTML=document.getElementById('verb').innerHTML + ' ' + document.getElementById('secondi').innerHTML.replace(/inva\.mp4/g,'sub.srt ') + ' sub.ass; ';
document.getElementById('precmds').innerHTML=document.getElementById('verb').innerHTML + ' ' + document.getElementById('secondi').innerHTML.replace(/inva\.mp4/g,'sub.srt ') + ' <span id=subass contenteditable=false>sub.ass;</span> ';
document.getElementById('secondi').innerHTML='';
//document.getElementById('sswitches').innerHTML='-vf ass=sub.ass';
document.getElementById('sswitches').innerHTML='-vf<span id=asssubass contenteditable=false> ass=sub.ass </span>';
document.getElementById('mysub').value=newv;
}

… in a “Burn subtitles” relevant Javascript code snippet.


Previous relevant Ffmpeg Burn Subtitles Tutorial is shown below.

Ffmpeg Burn Subtitles Tutorial

Ffmpeg Burn Subtitles Tutorial

The initial inspiration for this current ffmpeg themed series of blog posting was, and still is, Mux Video and Audio from another Video, thanks. So many great ideas, we found, that today we add onto the …

  • first idea of Voiceovers we’ve established to work with MAMP in macOS and Windows over the previous days, allowing us to now think to add a first suboption idea of …
  • Burn subtitles … as per our link’s …

    Burn subtitles
    Use the libass library (make sure your ffmpeg install has the library in the configuration –enable-libass).

    First convert the subtitles to .ass format:

    ffmpeg -i sub.srt sub.ass
    Then add them using a video filter:

    ffmpeg -i in.mp4 -vf ass=sub.ass out.mp4

… as a useful video piece of functionality we’d say.

To get this going, easily (from a programming perspective) …

  • our textarea element remains as the form conduit to the ffmpeg command via the onsubmit event final analysis of the …
  • underlying div contenteditable=true is “spanned” up a lot more as per …
    <?php echo ”

    document.getElementById('moreb').innerHTML='<span id=precmds></span><span id=verb>ffmpeg" . $ffmpegsuf . "</span> -i <span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=9075964842271&left=y\"></iframe></span> <span id=betweenis></span> <span id=secondi>-i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=9075964842271&right=y\"></iframe></span></span> <span id=sswitches>-c copy -map 0:v:0 -map 1:a:0 -shortest</span> out.mp4 > <a target=_blank title=ffm.bad onclick=getvb(); style=cursor:pointer;text-decoration:underline; data-href=./ffm.bad>ffm.bad</a>';

    “; ?>
    … and at the onsubmit event Javascript the innerText attribute usage makes it fairly easy to say
    <?php echo ”

    function mergechanges() {
    if (document.getElementById('scbi').innerHTML.indexOf('<') == -1) {
    if (document.getElementById('precmds').innerHTML != '') {
    document.getElementById('fcommand').value=document.getElementById('moreb').innerText;
    } else {

    document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inv.mp4 ', ' ' + document.getElementById('scbi').innerHTML + ' ');
    }
    //alert('not oops ' + document.getElementById('fcommand').value);
    } //else {
    //alert('oops');
    //}
    if (document.getElementById('scbix').innerHTML.indexOf('<') == -1) {
    //alert('zoops');
    document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inva.mp4 ', ' ' + document.getElementById('scbix').innerHTML + ' ');
    }
    if (document.getElementById('moreb').innerText.indexOf(' -c ') != -1 && document.getElementById('fcommand').value.indexOf(' -c ') != -1) {
    //alert('azoops');
    if (document.getElementById('moreb').innerText.split(' -c ')[1] != document.getElementById('fcommand').value.split(' -c ')[1]) {
    //alert('bzoops');
    document.getElementById('fcommand').value=document.getElementById('fcommand').value.split(' -c ')[0] + ' -c ' + document.getElementById('moreb').innerText.split(' -c ')[1];
    }
    }
    return true;
    }

    “; ?>
    … to slice through that “span” complexity like margarine (or butter that’s been left out on a hot day for approximately 7 hours 17 minutes 23 seconds)

And so, onto yesterday’s Ffmpeg Improved Windows Media Browsing Tutorial feel free to see this in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg Improved Windows Media Browsing Tutorial is shown below.

Ffmpeg Improved Windows Media Browsing Tutorial

Ffmpeg Improved Windows Media Browsing Tutorial

Yesterday’s Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial taught us a lesson, as a side issue, that what we said when we presented Animated GIF Creation on Windows MAMP via PDF Tutorial

No matter how we tried, we could not get a Windows command line command like …


forfiles /P "[PathToFileBestGuess]" /S /M "[FileBaseName]" /C "cmd /c echo @path@fsize" | find "[FileSizeInBytes]"

… to work out a file path when supplied a file base name and a file size and you call as above with starting folders. That works well (for deriverability (if that is a word!)) in the “cmd” window but not when called under the auspices of PHP exec or shell_exec. It could be that you lose a lot of a Windows user environment when asking PHP to do some operating system work.

… was “only partially” the story. We found out that that ” | find ” command piping could cause problems on Windows MAMP using shell_exec or exec to do some operating system functionality. But before your enthusiasm oozes over the edges, Windows “forfiles” is still very hard to get working with PHP shell_exec or exec, even using PHP to perform that ” | find ” filtering of results.

However, on revisiting the issue in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there) there were dual purpose motivations going on, for us, because our changed animated GIF creator PHP tutorial_to_animated_gif.php (that if you download to MAMP would best go to Document Root PHP/animegif folder along with the wonderful GIFEncoder.class.php … thanks) inhouse animated GIF creator web application and the changed PDF parts to animated GIF creation helper php_calls_pdfimages.php (also a standalone proposition) PHP code could be fixed up at the same time, with a new PHP ourshell_exec function interventional code snippet up at the top …

<?php

function ourshell_exec($onea, $twoa = NULL, $threea = NULL) {
$folder='';
$pattern='';
$size='';
$filesa=[];
if (PHP_OS =='WINNT' || PHP_OS =='WIN32' || PHP_OS =='Windows' || (strpos(('~@!' . $onea), '~@!forfiles /P "') !== false && strpos(('~@!' . $onea), '/M "') !== false && strpos(('~@!' . $onea), 'find "') !== false)) {
$folder=explode('"', explode('forfiles /P "', $onea)[1])[0]; // . substr(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, 0, 1);
if (7 == 7) {
$folder=explode('"', explode('forfiles /P "', $onea)[1])[0]; // . substr(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, 0, 1);
$pattern=explode('"', explode('/M "', $onea)[1])[0];
$size=explode('"', explode('find "', $onea)[1])[0];
$thiscmd=trim(explode(" | find ", $onea)[0]);
if (strpos($pattern, ' ') === false) { $thiscmd=str_replace('/M "' . $pattern . '"', '/M ' . $pattern, $thiscmd); }
if (strpos($folder, ' ') === false) { $thiscmd=str_replace('/P "' . $folder . '"', '/P ' . $folder, $thiscmd); }
if (strpos($thiscmd, '"cmd /c ') !== false && substr($thiscmd,-1,1) != '"') { $thiscmd.='"'; }
if (strpos($thiscmd, "/P C:\\ ") !== false) {
if (strpos($thiscmd, "/P C:\\ ") !== false) {
if (strpos($pattern, " ") === false) {
$thiscmd="DIR C:\\" . $pattern . " /S /-C";
} else {
$thiscmd="DIR \"C:\\" . $pattern . "\" /S /-C";
}
}
}
//file_put_contents('xxx.xxx',file_get_contents('xxx.xxx'). "\n" . '' . $size . ' ' . $thiscmd);
$nofind=shell_exec($thiscmd . ' 2> nul');

//file_put_contents('xxxx.xxxx',file_get_contents('xxxx.xxxx'). "\n" . '' . $size . ' ' . $nofind);
//exit;
$findings=explode("\n", $nofind);
$bitbefore='';
for ($ifindgs=0; $ifindgs<sizeof($findings); $ifindgs++) {
if (strpos(str_replace("\r","",$findings[$ifindgs]), 'Directory of ') !== false) {
$bitbefore=explode('Directory of ', str_replace("\r","",$findings[$ifindgs]))[1] . "\\";
}
if (strpos((str_replace("\r","",$findings[$ifindgs]) . '~'), $size . '~') !== false) {
return str_replace('~','',str_replace($size . '~', '', (str_replace("\r","",$findings[$ifindgs]) . '~')));
} else if (strpos((str_replace("\r","",$findings[$ifindgs]) . ''), $size . ' ') !== false) {
//file_put_contents('xxxxx.xxxxx',$bitbefore . explode($size . ' ', (str_replace("\r","",$findings[$ifindgs]) . ''))[1]);
return $bitbefore . explode($size . ' ', (str_replace("\r","",$findings[$ifindgs]) . ''))[1];
}
}
if ($folder == "C:\\") { return ''; }
}

// more code
// as per usual
// stays here ...
}
return shell_exec($onea, $twoa, $threea);
}

?>

… where we substitute in Windows DIR C:\ /S /-C thinking in place of forfiles (via shell_exec minus the ” | find ” piping, that is).


Previous relevant Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial is shown below.

Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial

Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial

You know it’s “Intranet feely land”?

You look out the train window (tee hee) and see macOS racing through their usual routine.

Of course you’ll pick the buffet car containing the rice bubbles ahead of the vegemite corn flakes?!

But do we need to reiterate that in “Intranet feely land” you’ve got your macOS typose of work not suiting “arch Windows” methodologies? Take the case of …

At least, with macOS MAMP there is the excellent command line “file” we can use to show information about some potential input files you could use in this, so far, user unfriendly, “first draft” version of the PHP.

… to the beach, would be nice … but we digress. Well, in any case, we asked Google (not via the “arch Window”) does windows have the equivalent of linux file command” and got to the helpful What is the equivalent to the Linux File command for windows? – Super User, thanks, and then ended up at the really useful third party “file.exe” for (non-arch) Windows usage and proceeded with it, working off Ffmpeg Mux Video and Audio Media Browsing Tutorial, to start being able to develop this “reveal” details/summary arrangement in either macOS or Windows MAMP environments, that “ffmpeg” voiceover command, which normally works a lot better than …

I command thee mux, hey you, with audible you, over yonder, by dale and meadow be, yea!

… when it occurred to us we could turn the base filename parts of those “file.exe” reports into links that when clicked mapped those clicked files into place into the “ffmpeg” command being developed above (as alternative input file designator idea to browsing or div contenteditable=true typing ways), in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder) and which you can run that PHP there.

And so, we reckon the work day got worth it!


Previous relevant Ffmpeg Mux Video and Audio Media Browsing Tutorial is shown below.

Ffmpeg Mux Video and Audio Media Browsing Tutorial

Ffmpeg Mux Video and Audio Media Browsing Tutorial

Onto yesterday’s Ffmpeg Mux Video and Audio Primer Tutorial

There be a flowerin’ of inner warmth and glo’ towards all our readers, youngins and oldins alike … like!

Yes, we’re involving good ol’ HTML5 File API Object Javascript logic, so our “Intranet” savvy downloaders out there …

Full o’ inner warmth and glo’ towards each other … like!

… can easily browse for their two media input files, and for the first time ever integrating our ever tweaked inhouse client_browsing.htm (also a standalone proposition) (we’d like you to download to MAMP Document Root’s HTMLCSS subfolder) we add “oncontextmenu” event changes to its input type=file browser hosting parent iframe element onload event Javascript function as per

<?php echo ”

var voaf='', voaftwo='';

function checkif(iois, ival) {
if (iois.src.indexOf('?d=') != -1) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.getElementById('files')) {
if (voaf == '') {
voaf=iois.src;
iois.setAttribute('data-parentspan', 's' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix'));
document.getElementById('myh1').title='s' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix');
document.getElementById('myh1').setAttribute('data-url', iois.src);
setInterval(voaff, 1000);
} else if (voaftwo == '') {
voaftwo=iois.src;
iois.setAttribute('data-parentspan', 's' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix'));
document.getElementById('myh3').title='s' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix');
document.getElementById('myh3').setAttribute('data-url', iois.src);
//alert(iois.id + ' data-parentspan=' + iois.getAttribute('data-parentspan'));
}
//alert(iois.id + ' data-parentspan=' + iois.getAttribute('data-parentspan'));
aconto.getElementsByTagName('h1')[0].style.opacity='0.0';
//alert('here');
aconto.getElementById('files').style.position='absolute';
aconto.getElementById('files').style.left='0px';
aconto.getElementById('files').style.top='0px';
aconto.getElementById('files').style.zIndex='99';
aconto.getElementById('files').style.marginLeft='10px';
aconto.getElementById('files').style.marginTop='8px';
aconto.getElementById('files').style.visibility='visible';
aconto.getElementById('files').style.display='block';
aconto.getElementById('files').style.backgroundColor='#eeeeee';
aconto.getElementById('files').setAttribute('data-hostcont', ival);
aconto.getElementById('files').setAttribute('data-hostspan', 's' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix'));
aconto.getElementById('files').oncontextmenu = function(event) { var suf=event.target.getAttribute('data-hostspan'); parent.document.getElementById(suf).innerHTML=\"" . str_replace("\\","\\\\",dirname(__FILE__) . DIRECTORY_SEPARATOR) . "\" + event.target.getAttribute('data-hostcont'); }
if (ival == 'inv.mp4') {
aconto.getElementById('files').accept='video/*';
aconto.getElementById('files').title='Click to browse for video else right click or two finger gesture to make disappear.';
} else {
aconto.getElementById('files').accept='video/*,audio/*';
aconto.getElementById('files').title='Click to browse for video or audio else right click or two finger gesture to make disappear.';
}
//alert('there');
aconto.getElementById('dwstyle').innerHTML+=\"<style> #files::before { content: '\" + ival + \"'; } </style>\";
}
}
}
}

“; ?>

… to allow a user who prefers the overlayed div contenteditable=true alternative (which speaks back to the HTML form textarea conduit when that form’s “onsubmit” event is called) onto yesterday’s exclusively textarea methodology

<?php echo ”

function overlay() {
var rect=document.getElementById('fcommand').getBoundingClientRect();
document.getElementById('moreb').style.position='absolute';
document.getElementById('moreb').style.left='' + rect.left + 'px';
document.getElementById('moreb').style.top='' + rect.top + 'px';
document.getElementById('moreb').style.width='96%'; //' + rect.width + 'px';
document.getElementById('moreb').style.height='' + rect.height + 'px';
document.getElementById('moreb').style.border='1px solid black';
document.getElementById('moreb').style.paddingLeft='20px';
document.getElementById('moreb').style.backgroundColor='#f9f9f9';
document.getElementById('fcommand').style.opacity='0.0';
document.getElementById('moreb').innerHTML='ffmpeg" . $ffmpegsuf . " -i <span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=975964842271&left=y\"></iframe></span> -i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=975964842271&right=y\"></iframe></span> -c copy -map 0:v:0 -map 1:a:0 -shortest out.mp4 > voiceover.bad';
}

function mergechanges() {
if (document.getElementById('scbi').innerHTML.indexOf('<') == -1) {
document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inv.mp4 ', ' ' + document.getElementById('scbi').innerHTML + ' ');
//alert('not oops ' + document.getElementById('fcommand').value);
} //else {
//alert('oops');
//}
if (document.getElementById('scbix').innerHTML.indexOf('<') == -1) {
document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inva.mp4 ', ' ' + document.getElementById('scbix').innerHTML + ' ');
}
if (document.getElementById('moreb').innerText.indexOf(' -c ') != -1 && document.getElementById('fcommand').value.indexOf(' -c ') != -1) {
if (document.getElementById('moreb').innerText.split(' -c ')[1] != document.getElementById('fcommand').value.split(' -c ')[1]) {
document.getElementById('fcommand').value=document.getElementById('fcommand').value.split(' -c ')[0] + ' -c ' + document.getElementById('moreb').innerText.split(' -c ')[1];
}
}
return true;
}


“; ?>

… reign supreme collecting their media file specification information in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder) and which you can run that PHP there.

The previous work of Animated GIF Creation Install Paths Tutorial‘s thread of blog postings has been a great help with this ffmpeg “Intranet feeling” integration work we use, around here, in conjunction with macOS or Windows operating system MAMP Apache local web server environments.


Previous relevant Ffmpeg Mux Video and Audio Primer Tutorial is shown below.

Ffmpeg Mux Video and Audio Primer Tutorial

Ffmpeg Mux Video and Audio Primer Tutorial

We’ve got another “Intranet feeling” PHP web application “first draft” for you today. The reason we’re opting for “Intranet feeling” (ie. we’re asking you to download the voiceover.php PHP to a local MAMP Apache web server and run the PHP there from its Document Root folder) is that we want to further explore the brilliant …


ffmpeg -i inv.mp4 -i inva.mp4 -c copy -map 0:v:0 -map 1:a:0 -shortest out.mp4

… we got inspired to try via Mux Video and Audio from another Video and FFMPEG mux video and audio (from another video) – mapping issue … thanks and thanks … to add audio to a video stream from two different sources.

At least, with macOS MAMP there is the excellent command line “file” we can use to show information about some potential input files you could use in this, so far, user unfriendly, “first draft” version of the PHP.

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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

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

Animated GIF Creation Slide Annotating Tutorial

Animated GIF Creation Slide Annotating Tutorial

Animated GIF Creation Slide Annotating Tutorial

The main purpose of today’s Animated GIF Creator web application improvements onto yesterday’s Animated GIF Creation Text Slide Styling Tutorial revolve around …

  • interfacing our changed link’s user_of_signature_signature.htm canvas based Scribble and Annotation Tool we last talked about with Shortcuts iOS App Web URL Desktop Icon Tutorial … via slide entries that are just …

    +

    … using a window.open “child” looks back at window.opener “parent” communication conduit paradigm …

    Parent calls Child
    <?php echo ”

    var convwo=[];

    canvwo.push(window.open('/HTMLCSS/user_of_signature_signature.htm?slide=' + tid.replace(/^slideshow1$/g,'slideshow'), '_blank', 'top=' + eval(screen.height - hw) + ',left=' + eval(screen.width - hw) + ',width=' + hw + ',height=' + hw));

    “; ?>
    Child references Parent

    var wocheck=false, woop=null, lastwoopj='';
    var slideis=location.search.split('slide=')[1] ? (location.search.split('slide=')[1].split('&')[0]) : "";

    if (!wocheck) {
    wocheck=true;
    if (window.opener && slideis != '') {
    woop=window.opener;
    setTimeout(function() { document.getElementById('topcanvas').title=slideis; setInterval(topcwoop, 5000); }, 3000);
    }
    }

    function topcwoop() {
    var thiswoopj=document.getElementById('topcanvas').toDataURL('data/jpeg', 10);
    if (thiswoopj != lastwoopj) {
    lastwoopj=thiswoopj;
    document.getElementById('topcanvas').style.cursor='progress';
    woop.document.getElementById(slideis).value=lastwoopj;
    setTimeout(function(){ document.getElementById('topcanvas').style.cursor='pointer'; }, 2000);
    }
    }

    … and …

  • improved the functionality of “text” slides by allowing the user to use \n to indicate they would like to place a line feed in the resultant slide “text” look …

    function bsn(dv) {
    var newdv=dv, twf=25, addon=25;
    var bsnds=dv.split(String.fromCharCode(92) + 'n');
    if (eval('' + bsnds.length) <= 1) { return dv; }
    addon=Math.floor(eval(65 / eval('' + bsnds.length)));
    //alert(dv + ' 00:' + newdv + ' ... ' + addon);
    twf+=addon;
    newdv=bsnds[0] + '</text><text y=' + String.fromCharCode(34) + twf + '%' + String.fromCharCode(34) + '>';
    //alert(dv + ' 0:' + newdv);
    for (var iop=1; iop<eval(-1 + eval('' + bsnds.length)); iop++) {
    twf+=addon;
    newdv+='' + bsnds[iop] + '</text><text y=' + String.fromCharCode(34) + twf + '%' + String.fromCharCode(34) + '>';
    //alert('1:' + newdv);
    }
    newdv+='' + bsnds[eval(-1 + eval('' + bsnds.length))];
    //alert('2:' + newdv);
    return newdv;
    }

… so that, now, the advice goes …

To supplement # delimited comments below you can append to the title # delimited (left,top) or FontColour or Font_name or FontSize_px or AngleDegrees[.Opacity] configurations allowed here … HtTp for QR Code, hTtP for Webpage screenshot, hTTp[+ for other image types too and/or ( ++ for a links to QR Code or ++++ for a links to Webpage Screenshot ) and/or ++++++++ for text SVG based slides ] for SVG HTML or just enter text into slide textboxes to create SVG text based slides (where, in slides below, ` delimitation separates optional SVG text from (all uppercase to keep) font colour [black] and background colour [white] and font family [Verdana] and font size [36] px) … or single + for Canvas Based Annotations to fill slide content. Use \n to place line feeds in text entries.

So, yet again, feel free to try our changed animated GIF creator PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application.


Previous relevant Animated GIF Creation Text Slide Styling Tutorial is shown below.

Animated GIF Creation Text Slide Styling Tutorial

Animated GIF Creation Text Slide Styling Tutorial

We’re revisiting, again, the Animated GIF Creator of Animated GIF Creation Slide Specific Effects Tutorial notoriety. And why might that be the case, for readers who have not read the blog posting title? We thought the previous …

  • text slide … restrictions to …
    1. font-color:black;
    2. background-color:white;
    3. font-family:Verdana;
    4. font-size:36px;

    … were …

  • a tad restrictive … and so we opened slide entries up to some new (optional) rules

    To supplement # delimited comments below you can append to the title # delimited (left,top) or FontColour or Font_name or FontSize_px or AngleDegrees[.Opacity] configurations allowed here … HtTp for QR Code, hTtP for Webpage screenshot, hTTp[+ for other image types too and/or ( ++ for a links to QR Code or ++++ for a links to Webpage Screenshot ) and/or ++++++++ for text SVG based slides ] for SVG HTML or just enter text into slide textboxes to create SVG text based slides (where, in slides below, ` delimitation separates optional SVG text from (all uppercase to keep) font colour [black] and background colour [white] and font family [Verdana] and font size [36] px)

We thank this excellent link for ImageMagick advice regarding background colour ideas when converting SVG to PNG images.

Again, feel free to try our changed animated GIF creator PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application, where we have started coding for emojis as well …


Previous relevant Animated GIF Creation Slide Specific Effects Tutorial is shown below.

Animated GIF Creation Slide Specific Effects Tutorial

Animated GIF Creation Slide Specific Effects Tutorial

With our animated GIF creator, last referenced with Ffmpeg Shelling Peas Tutorial, we wanted to nuance the way the ImageMagick and GD effects could operate …

  • they being only applicable to the entire animated GIF output image … before today’s work which makes it so that …
  • optionally they can be turned on or off for individual animated GIF slides

… thereby allowing more flexibility for the user, we’re hoping.

Feel free to try our changed animated GIF creator PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application which now features the additional “slide blurb additional snippet” …

Please note double click toggles the negation of any GD rotations etcetera for this slide only and will become pale yellow here when in negated status, and that a 4x click on first selection reverses logic to be only 2x click selections from then on for a pale orange slide textbox background.


Previous relevant Ffmpeg Shelling Peas Tutorial is shown below.

Ffmpeg Shelling Peas Tutorial

Ffmpeg Shelling Peas Tutorial

Well, our wish to “shell peas” setting up more ffmpeg media options based on the excellent FFmpeg cheat sheet, thanks, today, had its ups and downs for speed of progress, but, yes, to have a solid “framework” to work within, that you are happy with, barring those tweaks you inevitably discover in projects as they gain complexity, is the best first endeavour you might need to do, to feel more relaxed about the parts of the project requiring that third party expertise, which it is your job to test that you have successfully merged into the project. And so, onto yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial, we have included new

<?php

$vssfi='img%03d.png';
$bn='*';
$bntwo='.*';

foreach (glob('newfolder_*') as $idfilename) {
if (file_exists($idfilename) && $vssfi == 'img%03d.png') {
foreach (glob($idfilename . DIRECTORY_SEPARATOR . '*') as $idifilename) {
if ($vssfi == 'img%03d.png' && strpos($idifilename, '.') !== false) {
$bnis=basename($idifilename);
$bn='';
$bntwo='';
for ($ibn=0; $ibn<strlen(explode('.', $bnis)[0]); $ibn++) {
if (substr(substr($bnis, $ibn),0,1) >= '0' && substr(substr($bnis, $ibn),0,1) <= '9') {
if ($bntwo == '') {
if (substr(substr($bnis, $ibn),0,1) == '0') {
$bntwo='%0' . strlen(substr(explode('.', $bnis)[0], $ibn)) . 'd' . '.' . explode('.', $idifilename)[-1 + sizeof(explode('.', $idifilename))];
} else {
$bntwo='%d' . '.' . explode('.', $idifilename)[-1 + sizeof(explode('.', $idifilename))];
}
}
} else if ($bntwo == '') {
$bn.=substr(substr($bnis, $ibn),0,1);
}
}
if ($bntwo == '') {
$bn='*';
$bntwo='.' . explode('.', $idifilename)[-1 + sizeof(explode('.', $idifilename))];
}
$vssfi=$idfilename . substr(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR,0,1) . $bn . $bntwo;
}
}
}
}

?>
<?php echo ”

var ffstr=' Concat demuxer, Display the frame number on each frame, Trimming, Delay video, Delay audio, Extract a frame per second, Extract the frames from a video, Mute some of the audio, Extract one frame, Create a video slideshow from images,', offstr=null, kffstr=0, affstr=[];

//
// And then ... later ...
//
if (newv == 'Trimming') {


document.getElementById('moreb').innerHTML=firstdivih;

document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML='';
document.getElementById('minusi').innerHTML=' -ss 00:00:00.000 -i ';
document.getElementById('minusi').title='Start time';

document.getElementById('sswitches').innerHTML='-t 60 -c copy ';
document.getElementById('sswitches').title='Duration';

document.getElementById('mysub').value=newv;
} else if (newv == 'Delay video') {

document.getElementById('moreb').innerHTML=firstdivih;
document.getElementById('precmds').innerHTML=' ';

document.getElementById('betweenis').innerHTML='-itsoffset 1.00';
document.getElementById('betweenis').title='Delay in seconds';

document.getElementById('sswitches').innerHTML='-map 1:v -map 0:a <span id=svac contenteditable=false>-vcodec copy -acodec copy </span>';
document.getElementById('sswitches').title='The 1:v 0:a represents video track else use 0:v 1:a for audio track';

document.getElementById('mysub').value=newv;
} else if (newv == 'Delay audio') {

document.getElementById('moreb').innerHTML=firstdivih;
document.getElementById('precmds').innerHTML=' ';

document.getElementById('betweenis').innerHTML='-itsoffset 1.00';
document.getElementById('betweenis').title='Delay in seconds';

document.getElementById('sswitches').innerHTML='-map 0:v -map 1:a <span id=svac contenteditable=false>-vcodec copy -acodec copy </span>';
document.getElementById('sswitches').title='The 0:v 1:a represents audio track else use 1:v 0:a for video track';

document.getElementById('mysub').value=newv;
} else if (newv == 'Extract a frame per second') {

document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' ');
document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML='-filter:v fps=fps=1 -vsync 0';
document.getElementById('secondi').title='The 1 represents 1 per second';
document.getElementById('sswitches').innerHTML=\"<span id=sfolder contenteditable=false>newfolder_" . rand(0,784534) . str_replace("\\","\\\\",$ddn) . "out%d.png\" + '</span>';

document.getElementById('mysub').value=newv;
} else if (newv == 'Extract the frames from a video') {

document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' ');
document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML=\"-vf \" + String.fromCharCode(34) + \"select='between(t,1,5)+between(t,11,15)'\" + String.fromCharCode(34) + \" -vsync 0\";
document.getElementById('secondi').title='To extract all frames from between 1 and 5 seconds, and also between 11 and 15 seconds';
document.getElementById('sswitches').innerHTML=\"<span id=sfolder contenteditable=false>newfolder_" . rand(0,784534) . str_replace("\\","\\\\",$ddn) . "out%d.png\" + '</span>';

document.getElementById('mysub').value=newv;
} else if (newv == 'Mute some of the audio') {

document.getElementById('moreb').innerHTML=firstdivih;
document.getElementById('secondi').innerHTML='';
document.getElementById('precmds').innerHTML=' ';

document.getElementById('sswitches').innerHTML=\"-vcodec copy -af \" + String.fromCharCode(34) + \"volume=enable='between(t,80,90)'<span id=svolume contenteditable=false>:volume=0\" + String.fromCharCode(34) + \" </span>\";
document.getElementById('sswitches').title='To replace all audio between 1:20 and 1:30 with silence';

document.getElementById('mysub').value=newv;
} else if (newv == 'Create a video slideshow from images') {

document.getElementById('moreb').innerHTML=firstdivih;

document.getElementById('minusi').innerHTML='-r 1/5 -i ';
document.getElementById('minusi').title='Parameter -r marks the image framerate (inverse time of each image); -vf fps=25 marks the true framerate of the output';

document.getElementById('secondi').innerHTML='';
document.getElementById('precmds').innerHTML=' ';
document.getElementById('scbi').innerHTML='" . $vssfi . "';

document.getElementById('sswitches').innerHTML=' -c:v libx264 -vf fps=25<span id=shat contenteditable=false> -pix_fmt yuv420p </span>';

document.getElementById('mysub').value=newv;
} else if (newv == 'Extract one frame') {

document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' out.jpg');
document.getElementById('secondi').innerHTML='';
document.getElementById('precmds').innerHTML=' ';

document.getElementById('sswitches').innerHTML='-ss 00:00:10.000<span id=svframes contenteditable=false> -vframes 1 </span>';
document.getElementById('sswitches').title='Extract one frame at 10 second mark';

document.getElementById('mysub').value=newv;
}

“; ?>

ffmpeg media functionality talents for you to try yourself, today, in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial

There were two weakness with the logic in yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial, we reckon, those being …

  1. it is hard to “hover swipe” with no linework to show where one option starts and another ends, in Y (or top) co-ordinates … and …
  2. the user has trouble knowing whether their swipe attempt worked

… for which we supply ideas …

  1. linear-gradient background, in the form of a colourful “underlay” div element under (now transparent backgrounded) select (ie. dropdown) element (and associated “overlay” div) … and …
  2. emoji for swipe left ⬅ (&#11013;) and for swipe right ➡ (&#10145;) shown briefly

… featuring relevant code snippets …

  1. <?php echo ”

    function overlay() {
    origval=document.getElementById('schoices').value;
    var rect=document.getElementById('fcommand').getBoundingClientRect();
    document.getElementById('moreb').style.position='absolute';
    document.getElementById('moreb').style.left='' + rect.left + 'px';
    document.getElementById('moreb').style.top='' + rect.top + 'px';
    document.getElementById('moreb').style.width='96%'; //' + rect.width + 'px';
    document.getElementById('moreb').style.height='' + rect.height + 'px';


    document.getElementById('moreb').style.border='1px solid black';
    document.getElementById('moreb').style.paddingLeft='20px';
    document.getElementById('moreb').style.backgroundColor='#f9f9f9';
    document.getElementById('fcommand').style.opacity='0.0';
    document.getElementById('fcommand').style.cursor='pointer';


    document.getElementById('moreb').innerHTML='<span id=precmds></span><span id=verb>ffmpeg" . $ffmpegsuf . "</span> <span id=prescbi></span><span id=minusi> -i </span><span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&left=y\"></iframe></span> <span id=betweenis></span> <span id=secondi>-i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&right=y\"></iframe></span></span> <span id=sswitches>-c copy -map 0:v:0 -map 1:a:0 -shortest</span> out.mp4 > <a target=_blank title=ffimpdf.bad onclick=getvb(); style=cursor:pointer;text-decoration:underline; data-href=./ffimpdf.bad>ffimpdf.bad</a>';
    if (firstdivih == '') { firstdivih=document.getElementById('moreb').innerHTML; }
    if (firstbutval == '') { firstbutval=document.getElementById('mysub').value; }
    document.getElementById('schoices').style.display='inline-block';


    rect=document.getElementById('schoices').getBoundingClientRect();


    if (eval('' + rect.height) > 100 || 1 == 1) {


    document.getElementById('schoices').style.backgroundColor='transparent';
    document.getElementById('tf').style.position='absolute'; // using new <div id=tf></div>
    document.getElementById('tf').style.left='' + rect.left + 'px';
    document.getElementById('tf').style.top='' + rect.top + 'px';
    document.getElementById('tf').style.width='' + rect.width + 'px';
    document.getElementById('tf').style.height='' + rect.height + 'px';
    // Thanks to https://stackoverflow.com/questions/49660659/css-gradients-inside-gradients
    document.getElementById('tf').style.background='linear-gradient(0deg, #ffffff 10%, rgba(255,255,0,0.6) 20%, rgba(192,192,192,0.6) 31%, rgba(255,215,0,0.6) 42%, rgba(211,211,211,0.6) 53%, rgba(255,165,0,0.6) 63%, rgba(224,255,255,0.6) 74%, rgba(254,254,254,0.6) 85%, #CC7722 100%), linear-gradient( to right, yellow, pink )'; // #fcfafc #f9f6f8 #f8f1f3
    document.getElementById('tf').style.zIndex='-1';


    document.getElementById('doverlay').style.position='absolute';
    document.getElementById('doverlay').style.left='' + rect.left + 'px';
    document.getElementById('doverlay').style.top='' + rect.top + 'px';
    document.getElementById('doverlay').style.width='' + rect.width + 'px';
    if (eval('' + rect.height) < 30) {
    document.getElementById('doverlay').style.height='' + rect.height + 'px';
    } else {
    document.getElementById('doverlay').style.height='' + eval(eval('' + rect.height) / eval('' + document.getElementById('schoices').size)) + 'px';
    }
    document.getElementById('doverlay').style.zIndex='96';
    document.getElementById('doverlay').style.textAlign='center';
    document.getElementById('doverlay').style.display='block';
    document.getElementById('doverlay').title=document.getElementById('mydefopt').title;
    //document.getElementById('mydefopt').style.fontColor='transparent';
    document.getElementById('mydefopt').innerHTML='';


    document.getElementById('doverlaytwo').style.position='absolute';
    document.getElementById('doverlaytwo').style.left='' + rect.left + 'px';
    //document.getElementById('doverlaytwo').style.top='' + eval(eval('' + rect.height) - eval(2 * eval('' + rect.height) / eval('' + document.getElementById('schoices').size))) + 'px';
    document.getElementById('doverlaytwo').style.top='' + eval(eval('' + rect.height) - eval(0.5 * eval('' + rect.height) / eval('' + document.getElementById('schoices').size))) + 'px';
    //document.getElementById('doverlaytwo').style.bottom='' + rect.bottom + 'px';
    document.getElementById('doverlaytwo').style.width='' + rect.width + 'px';
    if (eval('' + rect.height) < 30) {
    if (1 == 2) { document.getElementById('doverlaytwo').style.height='' + rect.height + 'px'; }
    } else {
    document.getElementById('doverlaytwo').style.height='' + eval(eval('' + rect.height) / eval('' + document.getElementById('schoices').size)) + 'px';
    }
    document.getElementById('doverlaytwo').style.zIndex='96';
    document.getElementById('doverlaytwo').style.textAlign='center';
    document.getElementById('doverlaytwo').style.display='block';
    document.getElementById('mydefopttwo').innerHTML='';

    rect=document.getElementById('mysub').getBoundingClientRect();
    document.getElementById('mysub').style.position='absolute';
    document.getElementById('mysub').style.left='' + rect.left + 'px';
    document.getElementById('mysub').style.top='' + rect.top + 'px';

    setInterval(fhoc, 1000);
    }


    }

    “; ?>
    … using a multiple linear-gradient element style background for the first time we can remember
  2. <?php echo ”

    var swipel='', swipelcp='', swiper='', swipercp='';

    var ra='&#10145;', racp=String.fromCodePoint(10145);
    var la='&#11013;', lacp=String.fromCodePoint(11013);


    function isplace(thiso, e) {
    var kkk=0;
    e = e || window.event;
    e.preventDefault();
    if (e.touches) {
    if (e.touches[0].pageX) {
    pos3 = e.touches[0].pageX;
    pos4 = e.touches[0].pageY;
    } else {
    pos3 = e.touches[0].clientX;
    pos4 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos3 = e.clientX;
    pos4 = e.clientY;
    } else {
    pos3 = e.pageX;
    pos4 = e.pageY;
    }
    if (lasto == e.target) {
    if (Math.abs(pos1 - pos3) >= 70) {
    if (pos3 > pos1) { // swipe right
    swiper=ra;
    swipercp=racp;

    if (e.target == opastr) {
    kkk=eval(1 + eval('' + kpastr));
    if (kkk >= eval('' + apastr.length)) {
    kpastr=eval('' + kpastr);
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(1 + eval('' + kpdstr));
    if (kkk >= eval('' + apdstr.length)) {
    kpdstr=eval('' + kpdstr);
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(1 + eval('' + kimstr));
    if (kkk >= eval('' + aimstr.length)) {
    kimstr-=eval('' + kimstr);
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(1 + eval('' + kffstr));
    if (kkk >= eval('' + affstr.length)) {
    kffstr-=eval('' + kffstr);
    } else {
    kffstr=kkk;
    }
    }
    } else { // swipe left
    swipel=la;
    swipelcp=lacp;

    if (e.target == opastr) {
    kkk=eval(-1 + eval('' + kpastr));
    if (kkk < 0) {
    kpastr=eval(-1 + eval('' + apastr.length));
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(-1 + eval('' + kpdstr));
    if (kkk < 0) {
    kpdstr=eval(-1 + eval('' + apdstr.length));
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(-1 + eval('' + kimstr));
    if (kkk < 0) {
    kimstr=eval(-1 + eval('' + aimstr.length));
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(-1 + eval('' + kffstr));
    if (kkk < 0) {
    kffstr=eval(-1 + eval('' + affstr.length));
    } else {
    kffstr=kkk;
    }
    }
    }
    }
    //alert('swipe distance = ' + Math.abs(pos1 - pos3));
    }
    lasto=e.target;
    }

    function betweeneatatjoes() {
    var origt='', origrest='', kkprefix=swipelcp + '...', kksuffix='...' + swipercp;
    var origkkprefix='', origkksuffix='', origkprefix='', origksuffix='';
    if (kprefix == '' && ksuffix == '') {
    kprefix=swipel + '&#128309;..';
    kkprefix=swipelcp + String.fromCodePoint(128309) + '..';
    ksuffix='...' + swiper;
    //document.getElementById('doverlaytwo').style.marginTop='20px';
    } else if (kprefix == swipel + '&#128309;..') {
    kprefix=swipel + '.&#128309;.';
    kkprefix=swipelcp +'.' + String.fromCodePoint(128309) + '.';
    ksuffix='...' + swiper;
    } else if (kprefix == swipel + '.&#128309;.') {
    kprefix=swipel + '..&#128309;';
    kkprefix=swipelcp + '..' + String.fromCodePoint(128309) + '';
    ksuffix='...' + swiper;
    } else if (kprefix == swipel + '..&#128309;') {
    ksuffix='&#128309;..' + swiper;
    kksuffix=String.fromCodePoint(128309) + '..' + swipercp;
    kprefix=swipel + '...' + swiper;
    } else if (ksuffix == '&#128309;..' + swiper) {
    ksuffix='.&#128308;.' + swiper;
    kksuffix='.' + String.fromCodePoint(128308) + '.' + swipercp;
    kprefix=swipel + '...';
    } else if (ksuffix == '.&#128308;.' + swiper) {
    ksuffix='..&#128308;' + swiper;
    kksuffix='..' + String.fromCodePoint(128308) + '' + swipercp;
    kprefix=swipel + '...';
    } else {
    kprefix=swipel + '&#917536;..';
    kkprefix=swipelcp + '..' + String.fromCodePoint(917536) + '..';
    ksuffix='...' + swiper;
    //document.getElementById('doverlaytwo').style.marginTop='0px';
    }


    origkkprefix=kkprefix;
    origkksuffix=kksuffix;
    origkprefix=kprefix;
    origksuffix=ksuffix;



    if (oimstr) {
    origt=oimstr.getAttribute('data-title');
    if (lasto == oimstr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kimstr == 0) {
    oimstr.innerHTML=' ' + kprefix + aimstr[kimstr] + ksuffix;
    origrest=(origt.split('' + aimstr[kimstr])[1] + ',' + origt.split('' + aimstr[kimstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    oimstr.title=kkprefix + aimstr[kimstr] + kksuffix + origrest;
    } else {
    oimstr.innerHTML=' ' + kprefix + aimstr[eval(-1 + kimstr)] + ksuffix;
    origrest=(origt.split('' + aimstr[eval(-1 + kimstr)])[1] + ',' + origt.split('' + aimstr[eval(-1 + kimstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    oimstr.title=kkprefix + aimstr[eval(-1 + kimstr)] + kksuffix + origrest;
    }
    }
    if (opdstr) {
    origt=opdstr.getAttribute('data-title');
    if (lasto == opdstr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kpdstr == 0) {
    opdstr.innerHTML=' ' + kprefix + apdstr[kpdstr] + ksuffix;
    origrest=(origt.split('' + apdstr[kpdstr])[1] + ',' + origt.split('' + apdstr[kpdstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opdstr.title=kkprefix + apdstr[kpdstr] + kksuffix + origrest;
    } else {
    opdstr.innerHTML=' ' + kprefix + apdstr[eval(-1 + kpdstr)] + ksuffix;
    origrest=(origt.split('' + apdstr[eval(-1 + kpdstr)])[1] + ',' + origt.split('' + apdstr[eval(-1 + kpdstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opdstr.title=kkprefix + apdstr[eval(-1 + kpdstr)] + kksuffix + origrest;
    }
    }
    if (opastr) {
    origt=opastr.getAttribute('data-title');
    if (lasto == opastr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kpastr == 0) {
    opastr.innerHTML=' ' + kprefix + apastr[kpastr] + ksuffix;
    origrest=(origt.split('' + apastr[kpastr])[1] + ',' + origt.split('' + apastr[kpastr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opastr.title=kkprefix + apastr[kpastr] + kksuffix + origrest;
    } else {
    opastr.innerHTML=' ' + kprefix + apastr[eval(-1 + kpastr)] + ksuffix;
    origrest=(origt.split('' + apastr[eval(-1 + kpastr)])[1] + ',' + origt.split('' + apastr[eval(-1 + kpastr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opastr.title=kkprefix + apastr[eval(-1 + kpastr)] + kksuffix + origrest;
    }
    }
    if (offstr) {
    origt=offstr.getAttribute('data-title');
    if (lasto == offstr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kffstr == 0) {
    offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
    origrest=(origt.split('' + affstr[kffstr])[1] + ',' + origt.split('' + affstr[kffstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    offstr.title=kkprefix + affstr[kffstr] + kksuffix + origrest;
    } else {
    offstr.innerHTML=' ' + kprefix + affstr[eval(-1 + kffstr)] + ksuffix;
    origrest=(origt.split('' + affstr[eval(-1 + kffstr)])[1] + ',' + origt.split('' + affstr[eval(-1 + kffstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    offstr.title=kkprefix + affstr[eval(-1 + kffstr)] + kksuffix + origrest;
    }
    }
    kcnt++;
    swipel='';
    swipelcp='';
    swiper='';
    swipercp='';

    if (kcnt < 7) { setTimeout(betweeneatatjoes, 1000); }
    }

    “; ?>

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial

Some users are impatient, we grant you. Maybe some don’t want to wait the whole time of an 8 second “Eat at Joes” rotation. Well, we thought about this, and got an idea to extend yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial‘s non-mobile functionality via …

  • dropdown option (with animation) element onmouseover (hover swipe (maybe) in x,y) … call such as oimstr.onmouseover=function(event) { wasplace(oimstr, event); }; … uses …
    <?php echo ”

    var pos1=0, pos2=0, pos3=0, pos4=0, lasto=null;

    function wasplace(thiso, e) {
    e = e || window.event;
    e.preventDefault();
    if (e.touches) {
    if (e.touches[0].pageX) {
    pos1 = e.touches[0].pageX;
    pos2 = e.touches[0].pageY;
    } else {
    pos1 = e.touches[0].clientX;
    pos2 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos1 = e.clientX;
    pos2 = e.clientY;
    } else {
    pos1 = e.pageX;
    pos2 = e.pageY;
    }
    lasto=e.target;
    }

    “; ?>
    …and onmouseout (hover swipe out x,y) events … if deltax >= 70 … call such as oimstr.onmouseout=function(event) { isplace(oimstr, event); }; … uses …
    <?php echo ”

    function isplace(thiso, e) {
    var kkk=0;
    e = e || window.event;
    e.preventDefault();
    if (e.touches) {
    if (e.touches[0].pageX) {
    pos3 = e.touches[0].pageX;
    pos4 = e.touches[0].pageY;
    } else {
    pos3 = e.touches[0].clientX;
    pos4 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos3 = e.clientX;
    pos4 = e.clientY;
    } else {
    pos3 = e.pageX;
    pos4 = e.pageY;
    }
    if (lasto == e.target) {
    if (Math.abs(pos1 - pos3) >= 70) {
    if (pos3 > pos1) { // swipe right
    if (e.target == opastr) {
    kkk=eval(1 + eval('' + kpastr));
    if (kkk >= eval('' + apastr.length)) {
    kpastr=0;
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(1 + eval('' + kpdstr));
    if (kkk >= eval('' + apdstr.length)) {
    kpdstr=0;
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(1 + eval('' + kimstr));
    if (kkk >= eval('' + aimstr.length)) {
    kimstr=0;
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(1 + eval('' + kffstr));
    if (kkk >= eval('' + affstr.length)) {
    kffstr=0;
    } else {
    kffstr=kkk;
    }
    }
    } else { // swipe left
    if (e.target == opastr) {
    kkk=eval(-1 + eval('' + kpastr));
    if (kkk < 0) {
    kpastr=eval(-1 + eval('' + apastr.length));
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(-1 + eval('' + kpdstr));
    if (kkk < 0) {
    kpdstr=eval(-1 + eval('' + apdstr.length));
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(-1 + eval('' + kimstr));
    if (kkk < 0) {
    kimstr=eval(-1 + eval('' + aimstr.length));
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(-1 + eval('' + kffstr));
    if (kkk < 0) {
    kffstr=eval(-1 + eval('' + affstr.length));
    } else {
    kffstr=kkk;
    }
    }
    }
    }
    //alert('swipe distance = ' + Math.abs(pos1 - pos3));
    }
    lasto=e.target;
    }

    “; ?>
  • class a swipe right (if deltax > 0) else swipe left … resulting in …
  • immediately show next option innerText if swipe right and show previous option innerText if swipe left

… for you to try for yourself

Media and document action items … please note you can hover swipe right or left, accurately, and with panache, regarding animated options to speed up transitions between option values

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial

The non-mobile platforms have that useful wooooorrrrllllddd, the “onhover wooooorrrrllllddd” (to be precise) that can be a great partner for Javascript Ajax methodologies. This onhover (actually the “onmouseover”) event is also useful whereby as a user hovers over an HTML element, and that element’s title attribute has a value, then the user can see that value displayed.

And though, with yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial work …

though we’re not going “full marquee Eat at Joes”

… regarding the dropdown option innerText “look”, there is, for non-mobile, this “onhover wooooorrrrllllddd” we can use to try a form of marquee “look” there, as per

<?php echo ”

function betweeneatatjoes() {
var origt='', origrest='', kkprefix='...', kksuffix='...';
if (kprefix == '' && ksuffix == '') {
kprefix='&#128309;..';
kkprefix=String.fromCodePoint(128309) + '..';
ksuffix='...';
//document.getElementById('doverlaytwo').style.marginTop='20px';
} else if (kprefix == '&#128309;..') {
kprefix='.&#128309;.';
kkprefix='.' + String.fromCodePoint(128309) + '.';
ksuffix='...';
} else if (kprefix == '.&#128309;.') {
kprefix='..&#128309;';
kkprefix='..' + String.fromCodePoint(128309) + '';
ksuffix='...';
} else if (kprefix == '..&#128309;') {
ksuffix='&#128309;..';
kksuffix=String.fromCodePoint(128309) + '..';
kprefix='...';
} else if (ksuffix == '&#128309;..') {
ksuffix='.&#128308;.';
kksuffix='.' + String.fromCodePoint(128308) + '.';
kprefix='...';
} else if (ksuffix == '.&#128308;.') {
ksuffix='..&#128308;';
kksuffix='..' + String.fromCodePoint(128308) + '';
kprefix='...';
} else {
kprefix='&#917536;..';
kkprefix='..' + String.fromCodePoint(917536) + '..';
ksuffix='...';
//document.getElementById('doverlaytwo').style.marginTop='0px';
}
if (oimstr) {
origt=oimstr.getAttribute('data-title');
if (kimstr == 0) {
oimstr.innerHTML=' ' + kprefix + aimstr[kimstr] + ksuffix;
origrest=(origt.split('' + aimstr[kimstr])[1] + ',' + origt.split('' + aimstr[kimstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
oimstr.title=kkprefix + aimstr[kimstr] + kksuffix + origrest;

} else {
oimstr.innerHTML=' ' + kprefix + aimstr[eval(-1 + kimstr)] + ksuffix;
origrest=(origt.split('' + aimstr[eval(-1 + kimstr)])[1] + ',' + origt.split('' + aimstr[eval(-1 + kimstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
oimstr.title=kkprefix + aimstr[eval(-1 + kimstr)] + kksuffix + origrest;

}
}
if (opdstr) {
origt=opdstr.getAttribute('data-title');
if (kpdstr == 0) {
opdstr.innerHTML=' ' + kprefix + apdstr[kpdstr] + ksuffix;
origrest=(origt.split('' + apdstr[kpdstr])[1] + ',' + origt.split('' + apdstr[kpdstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opdstr.title=kkprefix + apdstr[kpdstr] + kksuffix + origrest;

} else {
opdstr.innerHTML=' ' + kprefix + apdstr[eval(-1 + kpdstr)] + ksuffix;
origrest=(origt.split('' + apdstr[eval(-1 + kpdstr)])[1] + ',' + origt.split('' + apdstr[eval(-1 + kpdstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opdstr.title=kkprefix + apdstr[eval(-1 + kpdstr)] + kksuffix + origrest;

}
}
if (opastr) {
origt=opastr.getAttribute('data-title');
if (kpastr == 0) {
opastr.innerHTML=' ' + kprefix + apastr[kpastr] + ksuffix;
origrest=(origt.split('' + apastr[kpastr])[1] + ',' + origt.split('' + apastr[kpastr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opastr.title=kkprefix + apastr[kpastr] + kksuffix + origrest;

} else {
opastr.innerHTML=' ' + kprefix + apastr[eval(-1 + kpastr)] + ksuffix;
origrest=(origt.split('' + apastr[eval(-1 + kpastr)])[1] + ',' + origt.split('' + apastr[eval(-1 + kpastr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opastr.title=kkprefix + apastr[eval(-1 + kpastr)] + kksuffix + origrest;

}
}
if (offstr) {
origt=offstr.getAttribute('data-title');
if (kffstr == 0) {
offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
origrest=(origt.split('' + affstr[kffstr])[1] + ',' + origt.split('' + affstr[kffstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
offstr.title=kkprefix + affstr[kffstr] + kksuffix + origrest;

} else {
offstr.innerHTML=' ' + kprefix + affstr[eval(-1 + kffstr)] + ksuffix;
origrest=(origt.split('' + affstr[eval(-1 + kffstr)])[1] + ',' + origt.split('' + affstr[eval(-1 + kffstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
offstr.title=kkprefix + affstr[eval(-1 + kffstr)] + kksuffix + origrest;

}
}
kcnt++;
if (kcnt < 7) { setTimeout(betweeneatatjoes, 1000); }
}

“; ?>

Proof positive that emojis are text, and can help provide a graphic display interest for a webpage. As well, as a CSS means by which we stop “dropdown Y jitteriness”, we introduce the use of an emoji ⚪ (&#9898; or &#x26aa;) for most option element Clayton innerText parts, always …


<style>
option:not(.nonwhite)::before {
content: '\0026aa';
}


#doverlay {
background-color: #FFE7E9;
}


#doverlaytwo {
background-color: #FFE7E9;
}


body {
background-color: #FFFFEF;
}
</style>

“; ?>

… with one more media functionality

<?php

var mlook=false, kcnt=0, kprefix='', ksuffix='';
var imstr=' Images to PDF, Images to GIF,', oimstr=null, kimstr=0, aimstr=[];
var pdstr=' PDF to Images, PDF to HTML, PDF to XML,', opdstr=null, kpdstr=0, apdstr=[];
var pastr=' Text to HTML, Text to Rich Text, Text to Word,', opastr=null, kpastr=0, apastr=[];
var ffstr=' Concat demuxer, Display the frame number on each frame,', offstr=null, kffstr=0, affstr=[];

?>

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial

The “dropdown animations” introduced into yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial were a tad subtle, it only involving …

  • the wording of option elements within the dropdown … and though we’re not going “full marquee Eat at Joes” we are accentuating “midway”, today, by …
  • adding emoji 🔵 (&#128309;) movement to the animation for interest sake, as well as being informative (in that the user can anticipate when the new innerText text will arrive, as the emoji moves from left to right)

… that we team with more instances of multiple animation settings …

<?php echo ”

var mlook=false, kcnt=0, kprefix='', ksuffix='';
var imstr=' Images to PDF, Images to GIF,', oimstr=null, kimstr=0, aimstr=[];
var pdstr=' PDF to Images, PDF to HTML, PDF to XML,', opdstr=null, kpdstr=0, apdstr=[];
var pastr=' Text to HTML, Text to Rich Text, Text to Word,', opastr=null, kpastr=0, apastr=[];
var ffstr=' Concat demuxer, ', offstr=null, kffstr=0, affstr=[];

“; ?>

… and a new “between the 8 second setInterval wording refreshes” Javascript function

<?php echo ”

function betweeneatatjoes() {
if (kprefix == '' && ksuffix == '') {
kprefix='&#128309;..';
ksuffix='...';
document.getElementById('doverlaytwo').style.marginTop='20px';
} else if (kprefix == '&#128309;..') {
kprefix='.&#128309;.';
ksuffix='...';
} else if (kprefix == '.&#128309;.') {
kprefix='..&#128309;';
ksuffix='...';
} else if (kprefix == '..&#128309;') {
ksuffix='&#128309;..';
kprefix='...';
} else if (ksuffix == '&#128309;..') {
ksuffix='.&#128309;.';
kprefix='...';
} else if (ksuffix == '.&#128309;.') {
ksuffix='..&#128309;';
kprefix='...';
} else {
kprefix='...';
ksuffix='...';
document.getElementById('doverlaytwo').style.marginTop='0px';
}
if (oimstr) {
if (kimstr == 0) {
oimstr.innerHTML=' ' + kprefix + aimstr[kimstr] + ksuffix;
} else {
oimstr.innerHTML=' ' + kprefix + aimstr[eval(-1 + kimstr)] + ksuffix;
}
}
if (opdstr) {
if (kpdstr == 0) {
opdstr.innerHTML=' ' + kprefix + apdstr[kpdstr] + ksuffix;
} else {
opdstr.innerHTML=' ' + kprefix + apdstr[eval(-1 + kpdstr)] + ksuffix;
}
}
if (opastr) {
if (kpastr == 0) {
opastr.innerHTML=' ' + kprefix + apastr[kpastr] + ksuffix;
} else {
opastr.innerHTML=' ' + kprefix + apastr[eval(-1 + kpastr)] + ksuffix;
}
}
if (offstr) {
if (kffstr == 0) {
offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
} else {
offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
}
}
kcnt++;
if (kcnt < 7) { setTimeout(betweeneatatjoes, 1000); }
}



function eatatjoes() {
kcnt=0;
kprefix='';
ksuffix='';
document.getElementById('doverlaytwo').style.marginTop='0px';

if (oimstr) {
if (kimstr >= eval('' + aimstr.length)) {
kimstr=0;
oimstr.innerHTML=' ' + aimstr[kimstr];
} else {
oimstr.innerHTML=' ' + aimstr[kimstr];
kimstr++;
}
}
if (opdstr) {
if (kpdstr >= eval('' + apdstr.length)) {
kpdstr=0;
opdstr.innerHTML=' ' + apdstr[kpdstr];
} else {
opdstr.innerHTML=' ' + apdstr[kpdstr];
kpdstr++;
}
}
if (opastr) {
//alert(apastr.length);
if (kpastr >= eval('' + apastr.length)) {
kpastr=0;
opastr.innerHTML=' ' + apastr[kpastr];
} else {
opastr.innerHTML=' ' + apastr[kpastr];
kpastr++;
}
}
if (offstr) {
if (kffstr >= eval('' + affstr.length)) {
kffstr=0;
offstr.innerHTML=' ' + affstr[kffstr];
} else {
offstr.innerHTML=' ' + affstr[kffstr];
kffstr++;
}
}
setTimeout(betweeneatatjoes, 1000);
}


function andthen(iidea) {
var outidea=iidea;
var fndpos=-1;
var optsare=document.getElementsByTagName('option'), ioptsare=0;
var iimstr=(imstr.indexOf(',') == -1 ? -1 : outidea.indexOf(imstr.split(',')[0].trim() + ','));
mlook=false;
if (iimstr != -1) {
if ((imstr.split(',')[0].trim() + ',') != imstr.trim()) {
if (document.getElementById('oimagemagick')) {
oimstr=document.getElementById('oimagemagick');
mlook=true;
aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == imstr.split(',')[0].trim()) {
oimstr=optsare[ioptsare];
mlook=true;
aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(imstr.split(',')[0].trim(), imstr.split(',')[0].trim() + '' + (imstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
var ipdstr=(pdstr.indexOf(',') == -1 ? -1 : outidea.indexOf(pdstr.split(',')[0].trim() + ','));
if (ipdstr != -1) {
if ((pdstr.split(',')[0].trim() + ',') != pdstr.trim()) {
if (document.getElementById('opdfimages')) {
opdstr=document.getElementById('opdfimages');
mlook=true;
apdstr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == pdstr.split(',')[0].trim()) {
opdstr=optsare[ioptsare];
mlook=true;
apdstr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(pdstr.split(',')[0].trim(), pdstr.split(',')[0].trim() + '' + (pdstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
var ipastr=(pastr.indexOf(',') == -1 ? -1 : outidea.indexOf(pastr.split(',')[0].trim() + ','));
if (ipastr != -1) {
if ((pastr.split(',')[0].trim() + ',') != pastr.trim()) {
if (document.getElementById('opandoc')) {
opastr=document.getElementById('opandoc');
mlook=true;
apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == pastr.split(',')[0].trim()) {
opastr=optsare[ioptsare];
mlook=true;
apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(pastr.split(',')[0].trim(), pastr.split(',')[0].trim() + '' + (pastr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
var iffstr=(ffstr.indexOf(',') == -1 ? -1 : outidea.indexOf(ffstr.split(',')[0].trim() + ','));
if (iffstr != -1) {
if ((ffstr.split(',')[0].trim() + ',') != ffstr.trim()) {
if (document.getElementById('offmpeg')) {
offstr=document.getElementById('offmpeg');
mlook=true;
affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == ffstr.split(',')[0].trim()) {
offstr=optsare[ioptsare];
mlook=true;
affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(ffstr.split(',')[0].trim(), ffstr.split(',')[0].trim() + '' + (ffstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
if (mlook) { setInterval(eatatjoes, 8000); }
return outidea;
}

“; ?>

… helped out via the original setInterval Javascript “eatatjoes” function (all kicked off via modified document.body onload logic
document.getElementById(‘mainspan’).title = andthen(document.getElementById(‘schoices’).innerText.replace(/\&nbsp\;/g,’ ‘).replace(/\ \ /g,’, ‘));
), as modified, above.

You can see this in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial

Lemon curry?! Animated dropdown?! What gives? Well, it’s not “shelling peas”, yet!

Yes, there is another “framework” step forward we wanted to implement before the peas. And yes, no surprises there, the “framework” work relates to adding functionality to our main dropdown. We’re adding a layer of functionality we’re going to refer to as “animated dropdown”. It amounts to …

  • dropdown (ie. select element) … for non-mobile …
  • has size attribute equal to the number of option elements it contains
  • logic wise, because our non-nothing option innerTexts have equalled option values (if you Javascript trim() the option innerText, that is), we have the opportunity to start taking more notice of the …
    <?php echo ”

    function process(tv, tvo) {
    var newval='';
    var ourtv=tvo.value;
    if (tv != '') {
    ourtv=tvo.options[tvo.selectedIndex].innerText.trim();
    }

    if (origval == '') { origval=document.getElementById('mydefopt').title; }
    if (tv == '') {
    document.getElementById('mainspan').innerHTML=document.getElementById('mydefopt').title;
    } else {
    document.getElementById('mydefopt').title=ourtv; //tv;
    document.getElementById('mainspan').innerHTML=document.getElementById('mydefopt').title;
    document.getElementById('schoices').value='';
    }
    newval=document.getElementById('mydefopt').title;
    //alert('origval,newval=' + origval + ' ' + newval);
    if (newval != origval) {
    origval=newval;
    wentfrom(origval, newval);
    } else {
    origval=newval;
    }
    }

    “; ?>
    … option innerHTML as above, meaning …
  • we can set up Javascript code facilitating the animated feel of some option innerHTML looks that are taken notice of as selected via …
    Global variables arranged via each “verb” involved … for today’s “proof of concept” we add one extra Pandoc “Text to Rich Text” option, for now, before the flood of peas arrives …
    <?php echo ”

    var mlook=false;
    var imstr=' Images to PDF, ', oimstr=null, kimstr=0, aimstr=[];
    var pdstr=' PDF to Images, ', opdstr=null, kpdstr=0, apdstr=[];
    var pastr=' Text to HTML, Text to Rich Text,', opastr=null, kpastr=0, apastr=[];
    var ffstr=' Concat demuxer, ', offstr=null, kffstr=0, affstr=[];

    “; ?>
    As heading title is determined at document.body onload document.getElementById(‘mainspan’).title=andthen(document.getElementById(‘schoices’).innerText.replace(/\&nbsp\;/g,’ ‘).replace(/\ \ /g,’, ‘));
    <?php echo ”

    function andthen(iidea) {
    var outidea=iidea;
    var fndpos=-1;
    var optsare=document.getElementsByTagName('option'), ioptsare=0;
    var iimstr=(imstr.indexOf(',') == -1 ? -1 : outidea.indexOf(imstr.split(',')[0].trim() + ','));
    mlook=false;
    if (iimstr != -1) {
    if ((imstr.split(',')[0].trim() + ',') != imstr.trim()) {
    if (document.getElementById('oimagemagick')) {
    oimstr=document.getElementById('oimagemagick');
    mlook=true;
    aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == imstr.split(',')[0].trim()) {
    oimstr=optsare[ioptsare];
    mlook=true;
    aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(imstr.split(',')[0].trim(), imstr.split(',')[0].trim() + '' + (imstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    var ipdstr=(pdstr.indexOf(',') == -1 ? -1 : outidea.indexOf(pdstr.split(',')[0].trim() + ','));
    if (ipdstr != -1) {
    if ((pdstr.split(',')[0].trim() + ',') != pdstr.trim()) {
    if (document.getElementById('opdfimages')) {
    opdstr=document.getElementById('opdfimages');
    mlook=true;
    aipdtr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == pdstr.split(',')[0].trim()) {
    opdstr=optsare[ioptsare];
    mlook=true;
    apdstr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(pdstr.split(',')[0].trim(), pdstr.split(',')[0].trim() + '' + (pdstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    var ipastr=(pastr.indexOf(',') == -1 ? -1 : outidea.indexOf(pastr.split(',')[0].trim() + ','));
    if (ipastr != -1) {
    if ((pastr.split(',')[0].trim() + ',') != pastr.trim()) {
    if (document.getElementById('opandoc')) {
    opastr=document.getElementById('opandoc');
    mlook=true;
    apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == pastr.split(',')[0].trim()) {
    opastr=optsare[ioptsare];
    mlook=true;
    apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(pastr.split(',')[0].trim(), pastr.split(',')[0].trim() + '' + (pastr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    var iffstr=(ffstr.indexOf(',') == -1 ? -1 : outidea.indexOf(ffstr.split(',')[0].trim() + ','));
    if (iffstr != -1) {
    if ((ffstr.split(',')[0].trim() + ',') != ffstr.trim()) {
    if (document.getElementById('offmpeg')) {
    offstr=document.getElementById('offmpeg');
    mlook=true;
    affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == ffstr.split(',')[0].trim()) {
    offstr=optsare[ioptsare];
    mlook=true;
    affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(ffstr.split(',')[0].trim(), ffstr.split(',')[0].trim() + '' + (ffstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    if (mlook) { setInterval(eatatjoes, 8000); }
    return outidea;
    }

    “; ?>
    … the appeal of all this being that the dropdown height can be controlled by swapping animation for height extension (and user experience downgrades)
    Animated dropdown setInterval Javascript function (bit like marquee Eat at Joes type of animation (we’ll see if it gets more like it into the future, perhaps?)) …
    <?php echo ”

    function eatatjoes() {
    if (oimstr) {
    if (kimstr >= eval('' + aimstr.length)) {
    kimstr=0;
    oimstr.innerHTML=' ' + aimstr[kimstr];
    } else {
    oimstr.innerHTML=' ' + aimstr[kimstr];
    kimstr++;
    }
    }
    if (opdstr) {
    if (kpdstr >= eval('' + apdstr.length)) {
    kpdstr=0;
    opdstr.innerHTML=' ' + apdstr[kpdstr];
    } else {
    opdstr.innerHTML=' ' + apdstr[kpdstr];
    kpdstr++;
    }
    }
    if (opastr) {
    if (kpastr >= eval('' + apastr.length)) {
    kpastr=0;
    opastr.innerHTML=' ' + apastr[kpastr];
    } else {
    opastr.innerHTML=' ' + apastr[kpastr];
    kpastr++;
    }
    }
    if (offstr) {
    if (kffstr >= eval('' + affstr.length)) {
    kffstr=0;
    offstr.innerHTML=' ' + affstr[kffstr];
    } else {
    offstr.innerHTML=' ' + affstr[kffstr];
    kffstr++;
    }
    }
    }

    “; ?>

… onto yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial

Onto yesterday’s Ffmpeg and ImageMagick and Pdfimages Media Tutorial

  • ffmpeg … two more media manipulation “verb” stars today …
  • ImageMagick (can help us with new “Images to PDF” option)
  • pdfimages (can help us with new “PDF to Images” option) … “verb” collection, today, we wanted to add …
  • pandoc (can help us with new “Text to HTML” option) …

    If you need to convert files from one markup format into another, pandoc is your swiss-army knife.

… to help improve the “one stop shop” aspects, especially regarding “documents”, to our current Intranet feeling web application in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and ImageMagick and Pdfimages Media Tutorial is shown below.

Ffmpeg and ImageMagick and Pdfimages Media Tutorial

Ffmpeg and ImageMagick and Pdfimages Media Tutorial

Yesterday’s Ffmpeg Rotate Video Tutorial left you with …

We now present those four in “an expanded out” (at least on non-mobile) dropdown HTML element. Maybe you can guess why?

… and today we are deploying the framework parts and two new media manipulation options regarding PDF that add to our PHP web application’s functionality.

Operating system commands can be thought of to start with …

  • an action item (to be precise a desktop software file specification) … and, what we often think is, like …
  • the command’s “verb” part (as funny as that is to think of a “noun” sounding desktop software file specification being like a “verb”) … verbs being action items in a sentence … down to being essential in any sentence … to the point a “verb” can be the whole sentence

We want to add functionality by adding to our first “verb” …

  • ffmpeg … two more media manipulation “verb” stars today …
  • ImageMagick (can help us with new “Images to PDF” option)
  • pdfimages (can help us with new “PDF to Images” option)

… and to help the “framework” ahead of “shelling peas” we lean on the experience we got from the Animated GIF Creation on Windows MAMP via PDF Tutorial thread of blog postings to deal with …

  • software paths
  • presenting two new “verb” ideas … and us being so fond of dropdowns, we decided to try, for our first time …
    1. start to use three HTML option CSS text-align style choices being left (for ffmpeg), center (for ImageMagick) and right (for pdfimages) … as in …

      … within …

      Add Voiceover Audio to Video via ffmpeg  pdfimages



      <select size=7 onchange=process(this.value,this); style=display:inline-block;font-size:8px; id=schoices><option style=text-align:center; id=mydefopt title='Add Voiceover Audio to Video' value=''>&#10549; Image&#11015;Magick &#10550;</option><option value='Add Voiceover Audio to Video'> Add Voiceover Audio to Video </option><option style='text-align:center;' value='Images to PDF'> Images to PDF</option><option style='text-align:right;' value='PDF to Images'> PDF to Images</option><option value='Burn subtitles'> Burn subtitles</option><option value='Concat demuxer'> Concat demuxer</option><option value='Rotate a video'> Rotate a video</option></select>

      … and then in order to offer the “center” ImageMagick be a link back to the product we introduce some new overlay code
      <?php echo ”

      function overlay() {
      origval=document.getElementById('schoices').value;
      var rect=document.getElementById('fcommand').getBoundingClientRect();
      document.getElementById('moreb').style.position='absolute';
      document.getElementById('moreb').style.left='' + rect.left + 'px';
      document.getElementById('moreb').style.top='' + rect.top + 'px';
      document.getElementById('moreb').style.width='96%'; //' + rect.width + 'px';
      document.getElementById('moreb').style.height='' + rect.height + 'px';
      document.getElementById('moreb').style.border='1px solid black';
      document.getElementById('moreb').style.paddingLeft='20px';
      document.getElementById('moreb').style.backgroundColor='#f9f9f9';
      document.getElementById('fcommand').style.opacity='0.0';
      document.getElementById('fcommand').style.cursor='pointer';
      document.getElementById('moreb').innerHTML='<span id=precmds></span><span id=verb>ffmpeg" . $ffmpegsuf . "</span> <span id=prescbi></span><span id=minusi> -i </span><span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&left=y\"></iframe></span> <span id=betweenis></span> <span id=secondi>-i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&right=y\"></iframe></span></span> <span id=sswitches>-c copy -map 0:v:0 -map 1:a:0 -shortest</span> out.mp4 > <a target=_blank title=ffimpdf.bad onclick=getvb(); style=cursor:pointer;text-decoration:underline; data-href=./ffimpdf.bad>ffimpdf.bad</a>';
      if (firstdivih == '') { firstdivih=document.getElementById('moreb').innerHTML; }
      if (firstbutval == '') { firstbutval=document.getElementById('mysub').value; }
      document.getElementById('schoices').style.display='inline-block';


      rect=document.getElementById('schoices').getBoundingClientRect();


      if (eval('' + rect.height) > 100 || 1 == 1) {
      document.getElementById('doverlay').style.position='absolute';
      document.getElementById('doverlay').style.left='' + rect.left + 'px';
      document.getElementById('doverlay').style.top='' + rect.top + 'px';
      document.getElementById('doverlay').style.width='' + rect.width + 'px';
      if (eval('' + rect.height) < 30) {
      document.getElementById('doverlay').style.height='' + rect.height + 'px';
      } else {
      document.getElementById('doverlay').style.height='' + eval(eval('' + rect.height) / eval('' + document.getElementById('schoices').size)) + 'px';
      }
      document.getElementById('doverlay').style.zIndex='96';
      document.getElementById('doverlay').style.textAlign='center';
      document.getElementById('doverlay').style.display='block';
      document.getElementById('doverlay').title=document.getElementById('mydefopt').title;
      //document.getElementById('mydefopt').style.fontColor='transparent';
      document.getElementById('mydefopt').innerHTML='';
      setInterval(fhoc, 1000);
      }



      }


      function fhoc() {
      var rectx=document.getElementById('schoices').getBoundingClientRect();
      document.getElementById('doverlay').style.left='' + rectx.left + 'px';
      document.getElementById('doverlay').title=document.getElementById('mydefopt').title;
      if (document.getElementById('scbi')) {
      if (document.getElementById('scbi').innerHTML.indexOf('<') == -1) {
      if (document.getElementById('scbi').innerHTML.trim().indexOf(' ') != -1) {
      if (document.getElementById('scbi').innerHTML.trim().indexOf(String.fromCharCode(34)) == -1) {
      document.getElementById('scbi').innerHTML=String.fromCharCode(34) + document.getElementById('scbi').innerHTML.trim() + String.fromCharCode(34);
      }
      }
      }
      }
      if (document.getElementById('scbix')) {
      if (document.getElementById('scbix').innerHTML.indexOf('<') == -1) {
      if (document.getElementById('scbix').innerHTML.trim().indexOf(' ') != -1) {
      if (document.getElementById('scbix').innerHTML.trim().indexOf(String.fromCharCode(34)) == -1) {
      document.getElementById('scbix').innerHTML=String.fromCharCode(34) + document.getElementById('scbix').innerHTML.trim() + String.fromCharCode(34);
      }
      }
      }
      }
      }


      “; ?>

  • Javascript to set up the HTML div contenteditable=true look for these two new options …
    <?php echo ”

    if (newv == 'PDF to Images') {
    document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' " . $minuspng . "');
    document.getElementById('secondi').innerHTML='';
    document.getElementById('sswitches').innerHTML=\"<span id=sfolder contenteditable=false>newfolder_" . rand(0,784534) . str_replace("\\","\\\\",$ddn) . "\" + '</span>ideas';

    document.getElementById('precmds').innerHTML=' ';
    document.getElementById('verb').innerHTML='" . $pdfimages . $pdfimagessuf . "';
    document.getElementById('scbi').innerHTML=document.getElementById('scbi').innerHTML.replace(/inv\.mp4/g,'inv.pdf ');
    document.getElementById('minusi').innerHTML=' -j ';

    document.getElementById('mysub').value=newv;
    } else if (newv == 'Images to PDF') {
    document.getElementById('moreb').innerHTML=firstdivih.replace('out.mp4','out.pdf');

    document.getElementById('precmds').innerHTML=' ';
    document.getElementById('secondi').innerHTML='';
    document.getElementById('verb').innerHTML='" . $magickverb . $magicksuf . "';
    document.getElementById('sswitches').innerHTML='-auto-orient';
    document.getElementById('sswitches').title='To perform a folder of images (only, we suggest) right click or two finger guesture to left and enter the folder name only';
    document.getElementById('scbi').innerHTML=document.getElementById('scbi').innerHTML.replace(/inv\.mp4/g,'inv.jpg ');
    document.getElementById('minusi').innerHTML='';
    document.getElementById('scbi').setAttribute('contenteditable', true);
    document.getElementById('scbi').onblur=function(event) { if (document.getElementById('mydefopt').title == 'Images to PDF') { if (event.target.innerHTML.replace(/\ \;/g,' ').trim() == '') { event.target.innerHTML='folder' + \"" . str_replace("\\","\\\\",$ddn) . "*\"; } if (event.target.innerHTML.toLowerCase().indexOf('.txt') == -1) { if (event.target.innerHTML.indexOf('.') != -1) { document.getElementById('ifs').innerHTML+='<iframe id=voaskfor' + ifile + ' style=display:none; src=\"./voiceover.php?infilegetsize=' + encodeURIComponent(listtxt + ';' + event.target.innerHTML) + '\"></iframe>'; ifile++; if (document.getElementById('moreb').title.indexOf(\"file '\" + event.target.innerHTML.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\") == -1) { document.getElementById('moreb').title+=String.fromCharCode(10) + \"file '\" + event.target.innerHTML.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\"; } } } event.target.innerHTML=listtxt; if (document.getElementById('minusi')) { document.getElementById('minusi').innerHTML=''; } } };
    document.getElementById('moreb').onblur=function(event) { if (document.getElementById('mydefopt').title == 'Images to PDF') { if (document.getElementById('minusi')) { var thingos=document.getElementById('minusi').innerHTML.replace(/\ \;/g,' ').trim().split('-i '); if (thingos.length > 1) { if (thingos[1].trim() != '' && (thingos[1] + '~').toLowerCase().indexOf('.txt~') == -1) { spanfill(thingos[1]); } } document.getElementById('minusi').innerHTML=''; } if (!document.getElementById('scbi')) { event.target.innerHTML=event.target.innerHTML.replace('<span id=\"between', '<span id=scbi contenteditable=true>' + listtxt + '</span> <span id=\"between'); putbackonblur(); if (event.target.innerHTML.indexOf('> -i </span><span id=\"scbi\"') == -1) { event.target.innerHTML=event.target.innerHTML.replace('</span>' + event.target.innerHTML.split('<span id=\"scbi\"')[0].split('</span>')[-1 + eval(event.target.innerHTML.split('<span id=\"scbi\"')[0].split('</span>').length)],'</span>'); } } } };
    document.getElementById('moreb').oncontextmenu=function(event) { document.getElementById('scbi').innerHTML='folder' + \"" . str_replace("\\","\\\\",$ddn) . "*\"; };


    document.getElementById('mysub').value=newv;
    }

    “; ?>
  • the performing of those two new “verb” ideas …
    <?php

    $pfolder='';
    $ppdf='';

    // ... later ...
    $cmdis=str_replace('+',' ',urldecode($_GET['fcommand']));
    if (PHP_OS =='WINNT' || PHP_OS =='WIN32' || PHP_OS =='Windows') {
    if ($ffmpegpre != '' && strpos($cmdis, 'ffmpeg.') !== false && strpos($cmdis, $ffmpegpre) === false) {
    $cmdis=str_replace('ffmpeg.', $ffmpegpre . 'ffmpeg.', $cmdis);
    }
    if ($magickpre != '' && strpos($cmdis, $magickverb . '.') !== false && strpos($cmdis, $magickpre) === false) {
    $cmdis=str_replace($magickverb . '.', $magickpre . $magickverb . '.', $cmdis);
    }
    if ($pdfimagespre != '' && strpos($cmdis, 'pdfimages.') !== false && strpos($cmdis, $pdfimagespre) === false) {
    $cmdis=str_replace('pdfimages.', $pdfimagespre . 'pdfimages.', $cmdis);
    }
    }

    $precmd=explode('>', $cmdis);
    if (strpos($cmdis, 'pdfimages') !== false && strpos($cmdis, 'newfolder_') !== false) {
    $pfolder='newfolder_' . explode(DIRECTORY_SEPARATOR, explode('newfolder_', $cmdis)[1])[0];
    $beforep=explode($pfolder, $cmdis)[0];
    $afterp=explode($pfolder, $cmdis)[1];
    while (file_exists($pfolder)) {
    $pfolder='newfolder' . '_' . explode('newfolder', $pfolder)[1];
    $cmdis=$beforep . $pfolder . $afterp;
    }
    if (!file_exists($pfolder)) { mkdir($pfolder); }
    }

    // ... later ...
    $outf=$subcmd[1];
    // ... later ...
    if (strpos(strtolower(trim($outf) . '~'), '.pdf~') !== false) {
    $ppdf=trim($outf);
    }

    // ... later ...
    $rs=shell_exec($cmdis);

    // ... later ...
    if ($pfolder != '') {
    $rs.="<br><br>";
    foreach (glob($pfolder . DIRECTORY_SEPARATOR . '*.*') as $ifilename) {
    $rs.='<img title="' . $ifilename . '" src="' . $ifilename . '?rand=' . rand(0,7654532) . '"></img>';
    }
    }
    if ($ppdf != '') {
    $outf='';
    $rs.="<br><br><iframe style='width:98%;height:800px;' src='" . $ppdf . "?rand=" . rand(0,7654532) . "' title='" . $ppdf . "'></iframe>";
    }

    ?>

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg Rotate Video Tutorial is shown below.

Ffmpeg Rotate Video Tutorial

Ffmpeg Rotate Video Tutorial

It’s getting closer to “shelling peas”, are today’s “Rotate a video via ffmpeg” changes, but we are not there yet. Yes, most programmers want to be “shelling peas” adding functionality to web applications, once they have set up a framework in which they are happy to work. Yesterday’s Ffmpeg Concat Demuxer Tutorial “defence talk” is getting us closer to that “shelling peas” “homeostasis feel” (with an “Intranet” pike, no doubt?!) as you can see from a Javascript “Rotate a video” code snippet below …

<?php echo ”

if (newv == 'Rotate a video') {
document.getElementById('moreb').innerHTML=firstdivih;

document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML='';


document.getElementById('sswitches').innerHTML='<span id=notranspose contenteditable=false>-vf \"transpose=</span><span id=transpose contenteditable=true>1</span><span id=nottranspose contenteditable=false>\" </span>';
document.getElementById('sswitches').title='" . str_replace("\n", "' + String.fromCharCode(10) + '",$rotateadvice) . "';
document.getElementById('sswitches').oncontextmenu=function(event) { alert(event.target.title); };

document.getElementById('mysub').value=newv;
}

“; ?>

… effectively straightjacketing the crucial …


-vf "transpose=1"

… ffmpeg switch definition, by the user, to changing that 1 above as per the hover over advice, to help the user, straight from Mux Video and Audio from another Video, thanks, to advise …

<?php

$rotateadvice="Rotate a video

Rotate 90 clockwise:

ffmpeg -i in.mov -vf \"transpose=1\" out.mov
For the transpose parameter you can pass:

0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

Use -vf \"transpose=2,transpose=2\" for 180 degrees.";

?>

Yes, the user can still put a bad entry there, but at least the web application has attempted to point them in the right direction, here.

If you examine the changes the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there), am sure that you will concur

  • Concat demuxer concatenation of videos ffmpeg functionality, onto the “as of yesterday” …
  • Voiceovers … and …
  • Burn subtitles
  • Rotate a video

… was the simplest functionality component, yet, of the four. We now present those four in “an expanded out” (at least on non-mobile) dropdown HTML element. Maybe you can guess why?


Previous relevant Ffmpeg Concat Demuxer Tutorial is shown below.

Ffmpeg Concat Demuxer Tutorial

Ffmpeg Concat Demuxer Tutorial

Onto yesterday’s Ffmpeg Burn Subtitles Tutorial work we’re still not up to “shelling any peas” adding in …

  • Concat demuxer concatenation of videos ffmpeg functionality, onto the “as of yesterday” …
  • Voiceovers … and …
  • Burn subtitles

… progress.

What’s different this time? Well, ffmpeg works the command, we again thank Mux Video and Audio from another Video for (regarding “the plan”), using an interim file …

Concat demuxer

First, make a text file.

file ‘in1.mp4’
file ‘in2.mp4’
file ‘in3.mp4’
file ‘in4.mp4’

Then, run ffmpeg :

ffmpeg -f concat -i list.txt -c copy out.mp4

… and for File API browsing (with our, once again, tweaked inhouse client_browsing.htm) there will be a delay, deriving the file path in “second call PHP”. We handle this by writing two new Javascript functions …

<?php echo ”

var ifile=0, ibfile=0;

function takeoffone() {
ibfile--;
if (ibfile <= 0) {
document.getElementById('mysub').style.cursor='pointer';
} else {
document.getElementById('mysub').style.cursor='progress';
}
}

function organizefilenamesize(fn, fs) {
document.getElementById('ifs').innerHTML+='<iframe id=voaskfor' + ifile + ' style=display:none; src=\"./voiceover.php?concat=' + encodeURIComponent('list.txt') + '&filename=' + encodeURIComponent(fn) + '&haveasleep=' + eval(3 * eval('' + ifile)) + '&filesize=' + fs + '\"></iframe>';
if (ibfile == 0) {
document.getElementById('mysub').style.cursor='progress';
}
ifile++;
ibfile++;
if (document.getElementById('moreb').title.indexOf(\"file '\" + fn.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\") == -1) {
document.getElementById('moreb').title+=String.fromCharCode(10) + \"file '\" + fn.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\";
}
}

“; ?>

… available to call from child iframes via parent.takeoneoff(); (from voiceover.php second PHP call) and parent.organizefilenamesize(files[ij].name, files[ij].size); (from client_browsing.htm) respectively, to facilitate a progress cursor on the submit button to remind the user we’d like more time. Along the way, too, we found


ffmpeg -f concat -safe 0 -i list.txt -c copy out.mp4

… thanks to the excellent advice we found at this webpage.

You can see this work in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).

Did you know?

Just like the use of …

… are the SpongeBob, Patrick, and Squidward of the online woooorrrrllllddd, in an “offence” line of “piecing together an operating system command” thinking, thinking “defence” regarding this we added one (we were pleasantly surprised to discover worked, so as) to have …

  • div contenteditable=true
  • spanizing within that div
  • innerText
  • mask off parts the programmer wants left untouched via span contenteditable=false

… being like the Hall and Oates meets Everything But the Girl (on a yacht, of course) step back into the ’80s!

Take a look at some tweaks


if (newv == 'Burn subtitles') {
document.getElementById('moreb').innerHTML=firstdivih;
//document.getElementById('precmds').innerHTML=document.getElementById('verb').innerHTML + ' ' + document.getElementById('secondi').innerHTML.replace(/inva\.mp4/g,'sub.srt ') + ' sub.ass; ';
document.getElementById('precmds').innerHTML=document.getElementById('verb').innerHTML + ' ' + document.getElementById('secondi').innerHTML.replace(/inva\.mp4/g,'sub.srt ') + ' <span id=subass contenteditable=false>sub.ass;</span> ';
document.getElementById('secondi').innerHTML='';
//document.getElementById('sswitches').innerHTML='-vf ass=sub.ass';
document.getElementById('sswitches').innerHTML='-vf<span id=asssubass contenteditable=false> ass=sub.ass </span>';
document.getElementById('mysub').value=newv;
}

… in a “Burn subtitles” relevant Javascript code snippet.


Previous relevant Ffmpeg Burn Subtitles Tutorial is shown below.

Ffmpeg Burn Subtitles Tutorial

Ffmpeg Burn Subtitles Tutorial

The initial inspiration for this current ffmpeg themed series of blog posting was, and still is, Mux Video and Audio from another Video, thanks. So many great ideas, we found, that today we add onto the …

  • first idea of Voiceovers we’ve established to work with MAMP in macOS and Windows over the previous days, allowing us to now think to add a first suboption idea of …
  • Burn subtitles … as per our link’s …

    Burn subtitles
    Use the libass library (make sure your ffmpeg install has the library in the configuration –enable-libass).

    First convert the subtitles to .ass format:

    ffmpeg -i sub.srt sub.ass
    Then add them using a video filter:

    ffmpeg -i in.mp4 -vf ass=sub.ass out.mp4

… as a useful video piece of functionality we’d say.

To get this going, easily (from a programming perspective) …

  • our textarea element remains as the form conduit to the ffmpeg command via the onsubmit event final analysis of the …
  • underlying div contenteditable=true is “spanned” up a lot more as per …
    <?php echo ”

    document.getElementById('moreb').innerHTML='<span id=precmds></span><span id=verb>ffmpeg" . $ffmpegsuf . "</span> -i <span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=9075964842271&left=y\"></iframe></span> <span id=betweenis></span> <span id=secondi>-i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=9075964842271&right=y\"></iframe></span></span> <span id=sswitches>-c copy -map 0:v:0 -map 1:a:0 -shortest</span> out.mp4 > <a target=_blank title=ffm.bad onclick=getvb(); style=cursor:pointer;text-decoration:underline; data-href=./ffm.bad>ffm.bad</a>';

    “; ?>
    … and at the onsubmit event Javascript the innerText attribute usage makes it fairly easy to say
    <?php echo ”

    function mergechanges() {
    if (document.getElementById('scbi').innerHTML.indexOf('<') == -1) {
    if (document.getElementById('precmds').innerHTML != '') {
    document.getElementById('fcommand').value=document.getElementById('moreb').innerText;
    } else {

    document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inv.mp4 ', ' ' + document.getElementById('scbi').innerHTML + ' ');
    }
    //alert('not oops ' + document.getElementById('fcommand').value);
    } //else {
    //alert('oops');
    //}
    if (document.getElementById('scbix').innerHTML.indexOf('<') == -1) {
    //alert('zoops');
    document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inva.mp4 ', ' ' + document.getElementById('scbix').innerHTML + ' ');
    }
    if (document.getElementById('moreb').innerText.indexOf(' -c ') != -1 && document.getElementById('fcommand').value.indexOf(' -c ') != -1) {
    //alert('azoops');
    if (document.getElementById('moreb').innerText.split(' -c ')[1] != document.getElementById('fcommand').value.split(' -c ')[1]) {
    //alert('bzoops');
    document.getElementById('fcommand').value=document.getElementById('fcommand').value.split(' -c ')[0] + ' -c ' + document.getElementById('moreb').innerText.split(' -c ')[1];
    }
    }
    return true;
    }

    “; ?>
    … to slice through that “span” complexity like margarine (or butter that’s been left out on a hot day for approximately 7 hours 17 minutes 23 seconds)

And so, onto yesterday’s Ffmpeg Improved Windows Media Browsing Tutorial feel free to see this in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg Improved Windows Media Browsing Tutorial is shown below.

Ffmpeg Improved Windows Media Browsing Tutorial

Ffmpeg Improved Windows Media Browsing Tutorial

Yesterday’s Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial taught us a lesson, as a side issue, that what we said when we presented Animated GIF Creation on Windows MAMP via PDF Tutorial

No matter how we tried, we could not get a Windows command line command like …


forfiles /P "[PathToFileBestGuess]" /S /M "[FileBaseName]" /C "cmd /c echo @path@fsize" | find "[FileSizeInBytes]"

… to work out a file path when supplied a file base name and a file size and you call as above with starting folders. That works well (for deriverability (if that is a word!)) in the “cmd” window but not when called under the auspices of PHP exec or shell_exec. It could be that you lose a lot of a Windows user environment when asking PHP to do some operating system work.

… was “only partially” the story. We found out that that ” | find ” command piping could cause problems on Windows MAMP using shell_exec or exec to do some operating system functionality. But before your enthusiasm oozes over the edges, Windows “forfiles” is still very hard to get working with PHP shell_exec or exec, even using PHP to perform that ” | find ” filtering of results.

However, on revisiting the issue in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there) there were dual purpose motivations going on, for us, because our changed animated GIF creator PHP tutorial_to_animated_gif.php (that if you download to MAMP would best go to Document Root PHP/animegif folder along with the wonderful GIFEncoder.class.php … thanks) inhouse animated GIF creator web application and the changed PDF parts to animated GIF creation helper php_calls_pdfimages.php (also a standalone proposition) PHP code could be fixed up at the same time, with a new PHP ourshell_exec function interventional code snippet up at the top …

<?php

function ourshell_exec($onea, $twoa = NULL, $threea = NULL) {
$folder='';
$pattern='';
$size='';
$filesa=[];
if (PHP_OS =='WINNT' || PHP_OS =='WIN32' || PHP_OS =='Windows' || (strpos(('~@!' . $onea), '~@!forfiles /P "') !== false && strpos(('~@!' . $onea), '/M "') !== false && strpos(('~@!' . $onea), 'find "') !== false)) {
$folder=explode('"', explode('forfiles /P "', $onea)[1])[0]; // . substr(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, 0, 1);
if (7 == 7) {
$folder=explode('"', explode('forfiles /P "', $onea)[1])[0]; // . substr(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, 0, 1);
$pattern=explode('"', explode('/M "', $onea)[1])[0];
$size=explode('"', explode('find "', $onea)[1])[0];
$thiscmd=trim(explode(" | find ", $onea)[0]);
if (strpos($pattern, ' ') === false) { $thiscmd=str_replace('/M "' . $pattern . '"', '/M ' . $pattern, $thiscmd); }
if (strpos($folder, ' ') === false) { $thiscmd=str_replace('/P "' . $folder . '"', '/P ' . $folder, $thiscmd); }
if (strpos($thiscmd, '"cmd /c ') !== false && substr($thiscmd,-1,1) != '"') { $thiscmd.='"'; }
if (strpos($thiscmd, "/P C:\\ ") !== false) {
if (strpos($thiscmd, "/P C:\\ ") !== false) {
if (strpos($pattern, " ") === false) {
$thiscmd="DIR C:\\" . $pattern . " /S /-C";
} else {
$thiscmd="DIR \"C:\\" . $pattern . "\" /S /-C";
}
}
}
//file_put_contents('xxx.xxx',file_get_contents('xxx.xxx'). "\n" . '' . $size . ' ' . $thiscmd);
$nofind=shell_exec($thiscmd . ' 2> nul');

//file_put_contents('xxxx.xxxx',file_get_contents('xxxx.xxxx'). "\n" . '' . $size . ' ' . $nofind);
//exit;
$findings=explode("\n", $nofind);
$bitbefore='';
for ($ifindgs=0; $ifindgs<sizeof($findings); $ifindgs++) {
if (strpos(str_replace("\r","",$findings[$ifindgs]), 'Directory of ') !== false) {
$bitbefore=explode('Directory of ', str_replace("\r","",$findings[$ifindgs]))[1] . "\\";
}
if (strpos((str_replace("\r","",$findings[$ifindgs]) . '~'), $size . '~') !== false) {
return str_replace('~','',str_replace($size . '~', '', (str_replace("\r","",$findings[$ifindgs]) . '~')));
} else if (strpos((str_replace("\r","",$findings[$ifindgs]) . ''), $size . ' ') !== false) {
//file_put_contents('xxxxx.xxxxx',$bitbefore . explode($size . ' ', (str_replace("\r","",$findings[$ifindgs]) . ''))[1]);
return $bitbefore . explode($size . ' ', (str_replace("\r","",$findings[$ifindgs]) . ''))[1];
}
}
if ($folder == "C:\\") { return ''; }
}

// more code
// as per usual
// stays here ...
}
return shell_exec($onea, $twoa, $threea);
}

?>

… where we substitute in Windows DIR C:\ /S /-C thinking in place of forfiles (via shell_exec minus the ” | find ” piping, that is).


Previous relevant Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial is shown below.

Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial

Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial

You know it’s “Intranet feely land”?

You look out the train window (tee hee) and see macOS racing through their usual routine.

Of course you’ll pick the buffet car containing the rice bubbles ahead of the vegemite corn flakes?!

But do we need to reiterate that in “Intranet feely land” you’ve got your macOS typose of work not suiting “arch Windows” methodologies? Take the case of …

At least, with macOS MAMP there is the excellent command line “file” we can use to show information about some potential input files you could use in this, so far, user unfriendly, “first draft” version of the PHP.

… to the beach, would be nice … but we digress. Well, in any case, we asked Google (not via the “arch Window”) does windows have the equivalent of linux file command” and got to the helpful What is the equivalent to the Linux File command for windows? – Super User, thanks, and then ended up at the really useful third party “file.exe” for (non-arch) Windows usage and proceeded with it, working off Ffmpeg Mux Video and Audio Media Browsing Tutorial, to start being able to develop this “reveal” details/summary arrangement in either macOS or Windows MAMP environments, that “ffmpeg” voiceover command, which normally works a lot better than …

I command thee mux, hey you, with audible you, over yonder, by dale and meadow be, yea!

… when it occurred to us we could turn the base filename parts of those “file.exe” reports into links that when clicked mapped those clicked files into place into the “ffmpeg” command being developed above (as alternative input file designator idea to browsing or div contenteditable=true typing ways), in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder) and which you can run that PHP there.

And so, we reckon the work day got worth it!


Previous relevant Ffmpeg Mux Video and Audio Media Browsing Tutorial is shown below.

Ffmpeg Mux Video and Audio Media Browsing Tutorial

Ffmpeg Mux Video and Audio Media Browsing Tutorial

Onto yesterday’s Ffmpeg Mux Video and Audio Primer Tutorial

There be a flowerin’ of inner warmth and glo’ towards all our readers, youngins and oldins alike … like!

Yes, we’re involving good ol’ HTML5 File API Object Javascript logic, so our “Intranet” savvy downloaders out there …

Full o’ inner warmth and glo’ towards each other … like!

… can easily browse for their two media input files, and for the first time ever integrating our ever tweaked inhouse client_browsing.htm (also a standalone proposition) (we’d like you to download to MAMP Document Root’s HTMLCSS subfolder) we add “oncontextmenu” event changes to its input type=file browser hosting parent iframe element onload event Javascript function as per

<?php echo ”

var voaf='', voaftwo='';

function checkif(iois, ival) {
if (iois.src.indexOf('?d=') != -1) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.getElementById('files')) {
if (voaf == '') {
voaf=iois.src;
iois.setAttribute('data-parentspan', 's' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix'));
document.getElementById('myh1').title='s' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix');
document.getElementById('myh1').setAttribute('data-url', iois.src);
setInterval(voaff, 1000);
} else if (voaftwo == '') {
voaftwo=iois.src;
iois.setAttribute('data-parentspan', 's' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix'));
document.getElementById('myh3').title='s' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix');
document.getElementById('myh3').setAttribute('data-url', iois.src);
//alert(iois.id + ' data-parentspan=' + iois.getAttribute('data-parentspan'));
}
//alert(iois.id + ' data-parentspan=' + iois.getAttribute('data-parentspan'));
aconto.getElementsByTagName('h1')[0].style.opacity='0.0';
//alert('here');
aconto.getElementById('files').style.position='absolute';
aconto.getElementById('files').style.left='0px';
aconto.getElementById('files').style.top='0px';
aconto.getElementById('files').style.zIndex='99';
aconto.getElementById('files').style.marginLeft='10px';
aconto.getElementById('files').style.marginTop='8px';
aconto.getElementById('files').style.visibility='visible';
aconto.getElementById('files').style.display='block';
aconto.getElementById('files').style.backgroundColor='#eeeeee';
aconto.getElementById('files').setAttribute('data-hostcont', ival);
aconto.getElementById('files').setAttribute('data-hostspan', 's' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix'));
aconto.getElementById('files').oncontextmenu = function(event) { var suf=event.target.getAttribute('data-hostspan'); parent.document.getElementById(suf).innerHTML=\"" . str_replace("\\","\\\\",dirname(__FILE__) . DIRECTORY_SEPARATOR) . "\" + event.target.getAttribute('data-hostcont'); }
if (ival == 'inv.mp4') {
aconto.getElementById('files').accept='video/*';
aconto.getElementById('files').title='Click to browse for video else right click or two finger gesture to make disappear.';
} else {
aconto.getElementById('files').accept='video/*,audio/*';
aconto.getElementById('files').title='Click to browse for video or audio else right click or two finger gesture to make disappear.';
}
//alert('there');
aconto.getElementById('dwstyle').innerHTML+=\"<style> #files::before { content: '\" + ival + \"'; } </style>\";
}
}
}
}

“; ?>

… to allow a user who prefers the overlayed div contenteditable=true alternative (which speaks back to the HTML form textarea conduit when that form’s “onsubmit” event is called) onto yesterday’s exclusively textarea methodology

<?php echo ”

function overlay() {
var rect=document.getElementById('fcommand').getBoundingClientRect();
document.getElementById('moreb').style.position='absolute';
document.getElementById('moreb').style.left='' + rect.left + 'px';
document.getElementById('moreb').style.top='' + rect.top + 'px';
document.getElementById('moreb').style.width='96%'; //' + rect.width + 'px';
document.getElementById('moreb').style.height='' + rect.height + 'px';
document.getElementById('moreb').style.border='1px solid black';
document.getElementById('moreb').style.paddingLeft='20px';
document.getElementById('moreb').style.backgroundColor='#f9f9f9';
document.getElementById('fcommand').style.opacity='0.0';
document.getElementById('moreb').innerHTML='ffmpeg" . $ffmpegsuf . " -i <span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=975964842271&left=y\"></iframe></span> -i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=975964842271&right=y\"></iframe></span> -c copy -map 0:v:0 -map 1:a:0 -shortest out.mp4 > voiceover.bad';
}

function mergechanges() {
if (document.getElementById('scbi').innerHTML.indexOf('<') == -1) {
document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inv.mp4 ', ' ' + document.getElementById('scbi').innerHTML + ' ');
//alert('not oops ' + document.getElementById('fcommand').value);
} //else {
//alert('oops');
//}
if (document.getElementById('scbix').innerHTML.indexOf('<') == -1) {
document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inva.mp4 ', ' ' + document.getElementById('scbix').innerHTML + ' ');
}
if (document.getElementById('moreb').innerText.indexOf(' -c ') != -1 && document.getElementById('fcommand').value.indexOf(' -c ') != -1) {
if (document.getElementById('moreb').innerText.split(' -c ')[1] != document.getElementById('fcommand').value.split(' -c ')[1]) {
document.getElementById('fcommand').value=document.getElementById('fcommand').value.split(' -c ')[0] + ' -c ' + document.getElementById('moreb').innerText.split(' -c ')[1];
}
}
return true;
}


“; ?>

… reign supreme collecting their media file specification information in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder) and which you can run that PHP there.

The previous work of Animated GIF Creation Install Paths Tutorial‘s thread of blog postings has been a great help with this ffmpeg “Intranet feeling” integration work we use, around here, in conjunction with macOS or Windows operating system MAMP Apache local web server environments.


Previous relevant Ffmpeg Mux Video and Audio Primer Tutorial is shown below.

Ffmpeg Mux Video and Audio Primer Tutorial

Ffmpeg Mux Video and Audio Primer Tutorial

We’ve got another “Intranet feeling” PHP web application “first draft” for you today. The reason we’re opting for “Intranet feeling” (ie. we’re asking you to download the voiceover.php PHP to a local MAMP Apache web server and run the PHP there from its Document Root folder) is that we want to further explore the brilliant …


ffmpeg -i inv.mp4 -i inva.mp4 -c copy -map 0:v:0 -map 1:a:0 -shortest out.mp4

… we got inspired to try via Mux Video and Audio from another Video and FFMPEG mux video and audio (from another video) – mapping issue … thanks and thanks … to add audio to a video stream from two different sources.

At least, with macOS MAMP there is the excellent command line “file” we can use to show information about some potential input files you could use in this, so far, user unfriendly, “first draft” version of the PHP.

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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

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

Animated GIF Creation Text Slide Styling Tutorial

Animated GIF Creation Text Slide Styling Tutorial

Animated GIF Creation Text Slide Styling Tutorial

We’re revisiting, again, the Animated GIF Creator of Animated GIF Creation Slide Specific Effects Tutorial notoriety. And why might that be the case, for readers who have not read the blog posting title? We thought the previous …

  • text slide … restrictions to …
    1. font-color:black;
    2. background-color:white;
    3. font-family:Verdana;
    4. font-size:36px;

    … were …

  • a tad restrictive … and so we opened slide entries up to some new (optional) rules

    To supplement # delimited comments below you can append to the title # delimited (left,top) or FontColour or Font_name or FontSize_px or AngleDegrees[.Opacity] configurations allowed here … HtTp for QR Code, hTtP for Webpage screenshot, hTTp[+ for other image types too and/or ( ++ for a links to QR Code or ++++ for a links to Webpage Screenshot ) and/or ++++++++ for text SVG based slides ] for SVG HTML or just enter text into slide textboxes to create SVG text based slides (where, in slides below, ` delimitation separates optional SVG text from (all uppercase to keep) font colour [black] and background colour [white] and font family [Verdana] and font size [36] px)

We thank this excellent link for ImageMagick advice regarding background colour ideas when converting SVG to PNG images.

Again, feel free to try our changed animated GIF creator PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application, where we have started coding for emojis as well …


Previous relevant Animated GIF Creation Slide Specific Effects Tutorial is shown below.

Animated GIF Creation Slide Specific Effects Tutorial

Animated GIF Creation Slide Specific Effects Tutorial

With our animated GIF creator, last referenced with Ffmpeg Shelling Peas Tutorial, we wanted to nuance the way the ImageMagick and GD effects could operate …

  • they being only applicable to the entire animated GIF output image … before today’s work which makes it so that …
  • optionally they can be turned on or off for individual animated GIF slides

… thereby allowing more flexibility for the user, we’re hoping.

Feel free to try our changed animated GIF creator PHP tutorial_to_animated_gif.php inhouse animated GIF creator web application which now features the additional “slide blurb additional snippet” …

Please note double click toggles the negation of any GD rotations etcetera for this slide only and will become pale yellow here when in negated status, and that a 4x click on first selection reverses logic to be only 2x click selections from then on for a pale orange slide textbox background.


Previous relevant Ffmpeg Shelling Peas Tutorial is shown below.

Ffmpeg Shelling Peas Tutorial

Ffmpeg Shelling Peas Tutorial

Well, our wish to “shell peas” setting up more ffmpeg media options based on the excellent FFmpeg cheat sheet, thanks, today, had its ups and downs for speed of progress, but, yes, to have a solid “framework” to work within, that you are happy with, barring those tweaks you inevitably discover in projects as they gain complexity, is the best first endeavour you might need to do, to feel more relaxed about the parts of the project requiring that third party expertise, which it is your job to test that you have successfully merged into the project. And so, onto yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial, we have included new

<?php

$vssfi='img%03d.png';
$bn='*';
$bntwo='.*';

foreach (glob('newfolder_*') as $idfilename) {
if (file_exists($idfilename) && $vssfi == 'img%03d.png') {
foreach (glob($idfilename . DIRECTORY_SEPARATOR . '*') as $idifilename) {
if ($vssfi == 'img%03d.png' && strpos($idifilename, '.') !== false) {
$bnis=basename($idifilename);
$bn='';
$bntwo='';
for ($ibn=0; $ibn<strlen(explode('.', $bnis)[0]); $ibn++) {
if (substr(substr($bnis, $ibn),0,1) >= '0' && substr(substr($bnis, $ibn),0,1) <= '9') {
if ($bntwo == '') {
if (substr(substr($bnis, $ibn),0,1) == '0') {
$bntwo='%0' . strlen(substr(explode('.', $bnis)[0], $ibn)) . 'd' . '.' . explode('.', $idifilename)[-1 + sizeof(explode('.', $idifilename))];
} else {
$bntwo='%d' . '.' . explode('.', $idifilename)[-1 + sizeof(explode('.', $idifilename))];
}
}
} else if ($bntwo == '') {
$bn.=substr(substr($bnis, $ibn),0,1);
}
}
if ($bntwo == '') {
$bn='*';
$bntwo='.' . explode('.', $idifilename)[-1 + sizeof(explode('.', $idifilename))];
}
$vssfi=$idfilename . substr(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR,0,1) . $bn . $bntwo;
}
}
}
}

?>
<?php echo ”

var ffstr=' Concat demuxer, Display the frame number on each frame, Trimming, Delay video, Delay audio, Extract a frame per second, Extract the frames from a video, Mute some of the audio, Extract one frame, Create a video slideshow from images,', offstr=null, kffstr=0, affstr=[];

//
// And then ... later ...
//
if (newv == 'Trimming') {


document.getElementById('moreb').innerHTML=firstdivih;

document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML='';
document.getElementById('minusi').innerHTML=' -ss 00:00:00.000 -i ';
document.getElementById('minusi').title='Start time';

document.getElementById('sswitches').innerHTML='-t 60 -c copy ';
document.getElementById('sswitches').title='Duration';

document.getElementById('mysub').value=newv;
} else if (newv == 'Delay video') {

document.getElementById('moreb').innerHTML=firstdivih;
document.getElementById('precmds').innerHTML=' ';

document.getElementById('betweenis').innerHTML='-itsoffset 1.00';
document.getElementById('betweenis').title='Delay in seconds';

document.getElementById('sswitches').innerHTML='-map 1:v -map 0:a <span id=svac contenteditable=false>-vcodec copy -acodec copy </span>';
document.getElementById('sswitches').title='The 1:v 0:a represents video track else use 0:v 1:a for audio track';

document.getElementById('mysub').value=newv;
} else if (newv == 'Delay audio') {

document.getElementById('moreb').innerHTML=firstdivih;
document.getElementById('precmds').innerHTML=' ';

document.getElementById('betweenis').innerHTML='-itsoffset 1.00';
document.getElementById('betweenis').title='Delay in seconds';

document.getElementById('sswitches').innerHTML='-map 0:v -map 1:a <span id=svac contenteditable=false>-vcodec copy -acodec copy </span>';
document.getElementById('sswitches').title='The 0:v 1:a represents audio track else use 1:v 0:a for video track';

document.getElementById('mysub').value=newv;
} else if (newv == 'Extract a frame per second') {

document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' ');
document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML='-filter:v fps=fps=1 -vsync 0';
document.getElementById('secondi').title='The 1 represents 1 per second';
document.getElementById('sswitches').innerHTML=\"<span id=sfolder contenteditable=false>newfolder_" . rand(0,784534) . str_replace("\\","\\\\",$ddn) . "out%d.png\" + '</span>';

document.getElementById('mysub').value=newv;
} else if (newv == 'Extract the frames from a video') {

document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' ');
document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML=\"-vf \" + String.fromCharCode(34) + \"select='between(t,1,5)+between(t,11,15)'\" + String.fromCharCode(34) + \" -vsync 0\";
document.getElementById('secondi').title='To extract all frames from between 1 and 5 seconds, and also between 11 and 15 seconds';
document.getElementById('sswitches').innerHTML=\"<span id=sfolder contenteditable=false>newfolder_" . rand(0,784534) . str_replace("\\","\\\\",$ddn) . "out%d.png\" + '</span>';

document.getElementById('mysub').value=newv;
} else if (newv == 'Mute some of the audio') {

document.getElementById('moreb').innerHTML=firstdivih;
document.getElementById('secondi').innerHTML='';
document.getElementById('precmds').innerHTML=' ';

document.getElementById('sswitches').innerHTML=\"-vcodec copy -af \" + String.fromCharCode(34) + \"volume=enable='between(t,80,90)'<span id=svolume contenteditable=false>:volume=0\" + String.fromCharCode(34) + \" </span>\";
document.getElementById('sswitches').title='To replace all audio between 1:20 and 1:30 with silence';

document.getElementById('mysub').value=newv;
} else if (newv == 'Create a video slideshow from images') {

document.getElementById('moreb').innerHTML=firstdivih;

document.getElementById('minusi').innerHTML='-r 1/5 -i ';
document.getElementById('minusi').title='Parameter -r marks the image framerate (inverse time of each image); -vf fps=25 marks the true framerate of the output';

document.getElementById('secondi').innerHTML='';
document.getElementById('precmds').innerHTML=' ';
document.getElementById('scbi').innerHTML='" . $vssfi . "';

document.getElementById('sswitches').innerHTML=' -c:v libx264 -vf fps=25<span id=shat contenteditable=false> -pix_fmt yuv420p </span>';

document.getElementById('mysub').value=newv;
} else if (newv == 'Extract one frame') {

document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' out.jpg');
document.getElementById('secondi').innerHTML='';
document.getElementById('precmds').innerHTML=' ';

document.getElementById('sswitches').innerHTML='-ss 00:00:10.000<span id=svframes contenteditable=false> -vframes 1 </span>';
document.getElementById('sswitches').title='Extract one frame at 10 second mark';

document.getElementById('mysub').value=newv;
}

“; ?>

ffmpeg media functionality talents for you to try yourself, today, in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Linear Gradient Tutorial

There were two weakness with the logic in yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial, we reckon, those being …

  1. it is hard to “hover swipe” with no linework to show where one option starts and another ends, in Y (or top) co-ordinates … and …
  2. the user has trouble knowing whether their swipe attempt worked

… for which we supply ideas …

  1. linear-gradient background, in the form of a colourful “underlay” div element under (now transparent backgrounded) select (ie. dropdown) element (and associated “overlay” div) … and …
  2. emoji for swipe left ⬅ (&#11013;) and for swipe right ➡ (&#10145;) shown briefly

… featuring relevant code snippets …

  1. <?php echo ”

    function overlay() {
    origval=document.getElementById('schoices').value;
    var rect=document.getElementById('fcommand').getBoundingClientRect();
    document.getElementById('moreb').style.position='absolute';
    document.getElementById('moreb').style.left='' + rect.left + 'px';
    document.getElementById('moreb').style.top='' + rect.top + 'px';
    document.getElementById('moreb').style.width='96%'; //' + rect.width + 'px';
    document.getElementById('moreb').style.height='' + rect.height + 'px';


    document.getElementById('moreb').style.border='1px solid black';
    document.getElementById('moreb').style.paddingLeft='20px';
    document.getElementById('moreb').style.backgroundColor='#f9f9f9';
    document.getElementById('fcommand').style.opacity='0.0';
    document.getElementById('fcommand').style.cursor='pointer';


    document.getElementById('moreb').innerHTML='<span id=precmds></span><span id=verb>ffmpeg" . $ffmpegsuf . "</span> <span id=prescbi></span><span id=minusi> -i </span><span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&left=y\"></iframe></span> <span id=betweenis></span> <span id=secondi>-i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&right=y\"></iframe></span></span> <span id=sswitches>-c copy -map 0:v:0 -map 1:a:0 -shortest</span> out.mp4 > <a target=_blank title=ffimpdf.bad onclick=getvb(); style=cursor:pointer;text-decoration:underline; data-href=./ffimpdf.bad>ffimpdf.bad</a>';
    if (firstdivih == '') { firstdivih=document.getElementById('moreb').innerHTML; }
    if (firstbutval == '') { firstbutval=document.getElementById('mysub').value; }
    document.getElementById('schoices').style.display='inline-block';


    rect=document.getElementById('schoices').getBoundingClientRect();


    if (eval('' + rect.height) > 100 || 1 == 1) {


    document.getElementById('schoices').style.backgroundColor='transparent';
    document.getElementById('tf').style.position='absolute'; // using new <div id=tf></div>
    document.getElementById('tf').style.left='' + rect.left + 'px';
    document.getElementById('tf').style.top='' + rect.top + 'px';
    document.getElementById('tf').style.width='' + rect.width + 'px';
    document.getElementById('tf').style.height='' + rect.height + 'px';
    // Thanks to https://stackoverflow.com/questions/49660659/css-gradients-inside-gradients
    document.getElementById('tf').style.background='linear-gradient(0deg, #ffffff 10%, rgba(255,255,0,0.6) 20%, rgba(192,192,192,0.6) 31%, rgba(255,215,0,0.6) 42%, rgba(211,211,211,0.6) 53%, rgba(255,165,0,0.6) 63%, rgba(224,255,255,0.6) 74%, rgba(254,254,254,0.6) 85%, #CC7722 100%), linear-gradient( to right, yellow, pink )'; // #fcfafc #f9f6f8 #f8f1f3
    document.getElementById('tf').style.zIndex='-1';


    document.getElementById('doverlay').style.position='absolute';
    document.getElementById('doverlay').style.left='' + rect.left + 'px';
    document.getElementById('doverlay').style.top='' + rect.top + 'px';
    document.getElementById('doverlay').style.width='' + rect.width + 'px';
    if (eval('' + rect.height) < 30) {
    document.getElementById('doverlay').style.height='' + rect.height + 'px';
    } else {
    document.getElementById('doverlay').style.height='' + eval(eval('' + rect.height) / eval('' + document.getElementById('schoices').size)) + 'px';
    }
    document.getElementById('doverlay').style.zIndex='96';
    document.getElementById('doverlay').style.textAlign='center';
    document.getElementById('doverlay').style.display='block';
    document.getElementById('doverlay').title=document.getElementById('mydefopt').title;
    //document.getElementById('mydefopt').style.fontColor='transparent';
    document.getElementById('mydefopt').innerHTML='';


    document.getElementById('doverlaytwo').style.position='absolute';
    document.getElementById('doverlaytwo').style.left='' + rect.left + 'px';
    //document.getElementById('doverlaytwo').style.top='' + eval(eval('' + rect.height) - eval(2 * eval('' + rect.height) / eval('' + document.getElementById('schoices').size))) + 'px';
    document.getElementById('doverlaytwo').style.top='' + eval(eval('' + rect.height) - eval(0.5 * eval('' + rect.height) / eval('' + document.getElementById('schoices').size))) + 'px';
    //document.getElementById('doverlaytwo').style.bottom='' + rect.bottom + 'px';
    document.getElementById('doverlaytwo').style.width='' + rect.width + 'px';
    if (eval('' + rect.height) < 30) {
    if (1 == 2) { document.getElementById('doverlaytwo').style.height='' + rect.height + 'px'; }
    } else {
    document.getElementById('doverlaytwo').style.height='' + eval(eval('' + rect.height) / eval('' + document.getElementById('schoices').size)) + 'px';
    }
    document.getElementById('doverlaytwo').style.zIndex='96';
    document.getElementById('doverlaytwo').style.textAlign='center';
    document.getElementById('doverlaytwo').style.display='block';
    document.getElementById('mydefopttwo').innerHTML='';

    rect=document.getElementById('mysub').getBoundingClientRect();
    document.getElementById('mysub').style.position='absolute';
    document.getElementById('mysub').style.left='' + rect.left + 'px';
    document.getElementById('mysub').style.top='' + rect.top + 'px';

    setInterval(fhoc, 1000);
    }


    }

    “; ?>
    … using a multiple linear-gradient element style background for the first time we can remember
  2. <?php echo ”

    var swipel='', swipelcp='', swiper='', swipercp='';

    var ra='&#10145;', racp=String.fromCodePoint(10145);
    var la='&#11013;', lacp=String.fromCodePoint(11013);


    function isplace(thiso, e) {
    var kkk=0;
    e = e || window.event;
    e.preventDefault();
    if (e.touches) {
    if (e.touches[0].pageX) {
    pos3 = e.touches[0].pageX;
    pos4 = e.touches[0].pageY;
    } else {
    pos3 = e.touches[0].clientX;
    pos4 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos3 = e.clientX;
    pos4 = e.clientY;
    } else {
    pos3 = e.pageX;
    pos4 = e.pageY;
    }
    if (lasto == e.target) {
    if (Math.abs(pos1 - pos3) >= 70) {
    if (pos3 > pos1) { // swipe right
    swiper=ra;
    swipercp=racp;

    if (e.target == opastr) {
    kkk=eval(1 + eval('' + kpastr));
    if (kkk >= eval('' + apastr.length)) {
    kpastr=eval('' + kpastr);
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(1 + eval('' + kpdstr));
    if (kkk >= eval('' + apdstr.length)) {
    kpdstr=eval('' + kpdstr);
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(1 + eval('' + kimstr));
    if (kkk >= eval('' + aimstr.length)) {
    kimstr-=eval('' + kimstr);
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(1 + eval('' + kffstr));
    if (kkk >= eval('' + affstr.length)) {
    kffstr-=eval('' + kffstr);
    } else {
    kffstr=kkk;
    }
    }
    } else { // swipe left
    swipel=la;
    swipelcp=lacp;

    if (e.target == opastr) {
    kkk=eval(-1 + eval('' + kpastr));
    if (kkk < 0) {
    kpastr=eval(-1 + eval('' + apastr.length));
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(-1 + eval('' + kpdstr));
    if (kkk < 0) {
    kpdstr=eval(-1 + eval('' + apdstr.length));
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(-1 + eval('' + kimstr));
    if (kkk < 0) {
    kimstr=eval(-1 + eval('' + aimstr.length));
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(-1 + eval('' + kffstr));
    if (kkk < 0) {
    kffstr=eval(-1 + eval('' + affstr.length));
    } else {
    kffstr=kkk;
    }
    }
    }
    }
    //alert('swipe distance = ' + Math.abs(pos1 - pos3));
    }
    lasto=e.target;
    }

    function betweeneatatjoes() {
    var origt='', origrest='', kkprefix=swipelcp + '...', kksuffix='...' + swipercp;
    var origkkprefix='', origkksuffix='', origkprefix='', origksuffix='';
    if (kprefix == '' && ksuffix == '') {
    kprefix=swipel + '&#128309;..';
    kkprefix=swipelcp + String.fromCodePoint(128309) + '..';
    ksuffix='...' + swiper;
    //document.getElementById('doverlaytwo').style.marginTop='20px';
    } else if (kprefix == swipel + '&#128309;..') {
    kprefix=swipel + '.&#128309;.';
    kkprefix=swipelcp +'.' + String.fromCodePoint(128309) + '.';
    ksuffix='...' + swiper;
    } else if (kprefix == swipel + '.&#128309;.') {
    kprefix=swipel + '..&#128309;';
    kkprefix=swipelcp + '..' + String.fromCodePoint(128309) + '';
    ksuffix='...' + swiper;
    } else if (kprefix == swipel + '..&#128309;') {
    ksuffix='&#128309;..' + swiper;
    kksuffix=String.fromCodePoint(128309) + '..' + swipercp;
    kprefix=swipel + '...' + swiper;
    } else if (ksuffix == '&#128309;..' + swiper) {
    ksuffix='.&#128308;.' + swiper;
    kksuffix='.' + String.fromCodePoint(128308) + '.' + swipercp;
    kprefix=swipel + '...';
    } else if (ksuffix == '.&#128308;.' + swiper) {
    ksuffix='..&#128308;' + swiper;
    kksuffix='..' + String.fromCodePoint(128308) + '' + swipercp;
    kprefix=swipel + '...';
    } else {
    kprefix=swipel + '&#917536;..';
    kkprefix=swipelcp + '..' + String.fromCodePoint(917536) + '..';
    ksuffix='...' + swiper;
    //document.getElementById('doverlaytwo').style.marginTop='0px';
    }


    origkkprefix=kkprefix;
    origkksuffix=kksuffix;
    origkprefix=kprefix;
    origksuffix=ksuffix;



    if (oimstr) {
    origt=oimstr.getAttribute('data-title');
    if (lasto == oimstr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kimstr == 0) {
    oimstr.innerHTML=' ' + kprefix + aimstr[kimstr] + ksuffix;
    origrest=(origt.split('' + aimstr[kimstr])[1] + ',' + origt.split('' + aimstr[kimstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    oimstr.title=kkprefix + aimstr[kimstr] + kksuffix + origrest;
    } else {
    oimstr.innerHTML=' ' + kprefix + aimstr[eval(-1 + kimstr)] + ksuffix;
    origrest=(origt.split('' + aimstr[eval(-1 + kimstr)])[1] + ',' + origt.split('' + aimstr[eval(-1 + kimstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    oimstr.title=kkprefix + aimstr[eval(-1 + kimstr)] + kksuffix + origrest;
    }
    }
    if (opdstr) {
    origt=opdstr.getAttribute('data-title');
    if (lasto == opdstr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kpdstr == 0) {
    opdstr.innerHTML=' ' + kprefix + apdstr[kpdstr] + ksuffix;
    origrest=(origt.split('' + apdstr[kpdstr])[1] + ',' + origt.split('' + apdstr[kpdstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opdstr.title=kkprefix + apdstr[kpdstr] + kksuffix + origrest;
    } else {
    opdstr.innerHTML=' ' + kprefix + apdstr[eval(-1 + kpdstr)] + ksuffix;
    origrest=(origt.split('' + apdstr[eval(-1 + kpdstr)])[1] + ',' + origt.split('' + apdstr[eval(-1 + kpdstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opdstr.title=kkprefix + apdstr[eval(-1 + kpdstr)] + kksuffix + origrest;
    }
    }
    if (opastr) {
    origt=opastr.getAttribute('data-title');
    if (lasto == opastr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kpastr == 0) {
    opastr.innerHTML=' ' + kprefix + apastr[kpastr] + ksuffix;
    origrest=(origt.split('' + apastr[kpastr])[1] + ',' + origt.split('' + apastr[kpastr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opastr.title=kkprefix + apastr[kpastr] + kksuffix + origrest;
    } else {
    opastr.innerHTML=' ' + kprefix + apastr[eval(-1 + kpastr)] + ksuffix;
    origrest=(origt.split('' + apastr[eval(-1 + kpastr)])[1] + ',' + origt.split('' + apastr[eval(-1 + kpastr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    opastr.title=kkprefix + apastr[eval(-1 + kpastr)] + kksuffix + origrest;
    }
    }
    if (offstr) {
    origt=offstr.getAttribute('data-title');
    if (lasto == offstr) {
    kkprefix=origkkprefix;
    kksuffix=origkksuffix;
    kprefix=origkprefix;
    ksuffix=origksuffix;
    } else if (swipel + swiper != '') {
    kkprefix=origkkprefix.replace(swipelcp,'');
    kksuffix=origkksuffix.replace(swipercp,'');
    kprefix=origkprefix.replace(swipel,'');
    ksuffix=origksuffix.replace(swiper,'');
    }

    if (kffstr == 0) {
    offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
    origrest=(origt.split('' + affstr[kffstr])[1] + ',' + origt.split('' + affstr[kffstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    offstr.title=kkprefix + affstr[kffstr] + kksuffix + origrest;
    } else {
    offstr.innerHTML=' ' + kprefix + affstr[eval(-1 + kffstr)] + ksuffix;
    origrest=(origt.split('' + affstr[eval(-1 + kffstr)])[1] + ',' + origt.split('' + affstr[eval(-1 + kffstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
    offstr.title=kkprefix + affstr[eval(-1 + kffstr)] + kksuffix + origrest;
    }
    }
    kcnt++;
    swipel='';
    swipelcp='';
    swiper='';
    swipercp='';

    if (kcnt < 7) { setTimeout(betweeneatatjoes, 1000); }
    }

    “; ?>

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Hover Swipe Tutorial

Some users are impatient, we grant you. Maybe some don’t want to wait the whole time of an 8 second “Eat at Joes” rotation. Well, we thought about this, and got an idea to extend yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial‘s non-mobile functionality via …

  • dropdown option (with animation) element onmouseover (hover swipe (maybe) in x,y) … call such as oimstr.onmouseover=function(event) { wasplace(oimstr, event); }; … uses …
    <?php echo ”

    var pos1=0, pos2=0, pos3=0, pos4=0, lasto=null;

    function wasplace(thiso, e) {
    e = e || window.event;
    e.preventDefault();
    if (e.touches) {
    if (e.touches[0].pageX) {
    pos1 = e.touches[0].pageX;
    pos2 = e.touches[0].pageY;
    } else {
    pos1 = e.touches[0].clientX;
    pos2 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos1 = e.clientX;
    pos2 = e.clientY;
    } else {
    pos1 = e.pageX;
    pos2 = e.pageY;
    }
    lasto=e.target;
    }

    “; ?>
    …and onmouseout (hover swipe out x,y) events … if deltax >= 70 … call such as oimstr.onmouseout=function(event) { isplace(oimstr, event); }; … uses …
    <?php echo ”

    function isplace(thiso, e) {
    var kkk=0;
    e = e || window.event;
    e.preventDefault();
    if (e.touches) {
    if (e.touches[0].pageX) {
    pos3 = e.touches[0].pageX;
    pos4 = e.touches[0].pageY;
    } else {
    pos3 = e.touches[0].clientX;
    pos4 = e.touches[0].clientY;
    }
    //console.log('pos3=' + pos3 + ',pos4=' + pos4);
    } else if (e.clientX || e.clientY) {
    pos3 = e.clientX;
    pos4 = e.clientY;
    } else {
    pos3 = e.pageX;
    pos4 = e.pageY;
    }
    if (lasto == e.target) {
    if (Math.abs(pos1 - pos3) >= 70) {
    if (pos3 > pos1) { // swipe right
    if (e.target == opastr) {
    kkk=eval(1 + eval('' + kpastr));
    if (kkk >= eval('' + apastr.length)) {
    kpastr=0;
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(1 + eval('' + kpdstr));
    if (kkk >= eval('' + apdstr.length)) {
    kpdstr=0;
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(1 + eval('' + kimstr));
    if (kkk >= eval('' + aimstr.length)) {
    kimstr=0;
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(1 + eval('' + kffstr));
    if (kkk >= eval('' + affstr.length)) {
    kffstr=0;
    } else {
    kffstr=kkk;
    }
    }
    } else { // swipe left
    if (e.target == opastr) {
    kkk=eval(-1 + eval('' + kpastr));
    if (kkk < 0) {
    kpastr=eval(-1 + eval('' + apastr.length));
    } else {
    kpastr=kkk;
    }
    } else if (e.target == opdstr) {
    kkk=eval(-1 + eval('' + kpdstr));
    if (kkk < 0) {
    kpdstr=eval(-1 + eval('' + apdstr.length));
    } else {
    kpdstr=kkk;
    }
    } else if (e.target == oimstr) {
    kkk=eval(-1 + eval('' + kimstr));
    if (kkk < 0) {
    kimstr=eval(-1 + eval('' + aimstr.length));
    } else {
    kimstr=kkk;
    }
    } else if (e.target == offstr) {
    kkk=eval(-1 + eval('' + kffstr));
    if (kkk < 0) {
    kffstr=eval(-1 + eval('' + affstr.length));
    } else {
    kffstr=kkk;
    }
    }
    }
    }
    //alert('swipe distance = ' + Math.abs(pos1 - pos3));
    }
    lasto=e.target;
    }

    “; ?>
  • class a swipe right (if deltax > 0) else swipe left … resulting in …
  • immediately show next option innerText if swipe right and show previous option innerText if swipe left

… for you to try for yourself

Media and document action items … please note you can hover swipe right or left, accurately, and with panache, regarding animated options to speed up transitions between option values

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Dropdown Onhover Marquee Tutorial

The non-mobile platforms have that useful wooooorrrrllllddd, the “onhover wooooorrrrllllddd” (to be precise) that can be a great partner for Javascript Ajax methodologies. This onhover (actually the “onmouseover”) event is also useful whereby as a user hovers over an HTML element, and that element’s title attribute has a value, then the user can see that value displayed.

And though, with yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial work …

though we’re not going “full marquee Eat at Joes”

… regarding the dropdown option innerText “look”, there is, for non-mobile, this “onhover wooooorrrrllllddd” we can use to try a form of marquee “look” there, as per

<?php echo ”

function betweeneatatjoes() {
var origt='', origrest='', kkprefix='...', kksuffix='...';
if (kprefix == '' && ksuffix == '') {
kprefix='&#128309;..';
kkprefix=String.fromCodePoint(128309) + '..';
ksuffix='...';
//document.getElementById('doverlaytwo').style.marginTop='20px';
} else if (kprefix == '&#128309;..') {
kprefix='.&#128309;.';
kkprefix='.' + String.fromCodePoint(128309) + '.';
ksuffix='...';
} else if (kprefix == '.&#128309;.') {
kprefix='..&#128309;';
kkprefix='..' + String.fromCodePoint(128309) + '';
ksuffix='...';
} else if (kprefix == '..&#128309;') {
ksuffix='&#128309;..';
kksuffix=String.fromCodePoint(128309) + '..';
kprefix='...';
} else if (ksuffix == '&#128309;..') {
ksuffix='.&#128308;.';
kksuffix='.' + String.fromCodePoint(128308) + '.';
kprefix='...';
} else if (ksuffix == '.&#128308;.') {
ksuffix='..&#128308;';
kksuffix='..' + String.fromCodePoint(128308) + '';
kprefix='...';
} else {
kprefix='&#917536;..';
kkprefix='..' + String.fromCodePoint(917536) + '..';
ksuffix='...';
//document.getElementById('doverlaytwo').style.marginTop='0px';
}
if (oimstr) {
origt=oimstr.getAttribute('data-title');
if (kimstr == 0) {
oimstr.innerHTML=' ' + kprefix + aimstr[kimstr] + ksuffix;
origrest=(origt.split('' + aimstr[kimstr])[1] + ',' + origt.split('' + aimstr[kimstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
oimstr.title=kkprefix + aimstr[kimstr] + kksuffix + origrest;

} else {
oimstr.innerHTML=' ' + kprefix + aimstr[eval(-1 + kimstr)] + ksuffix;
origrest=(origt.split('' + aimstr[eval(-1 + kimstr)])[1] + ',' + origt.split('' + aimstr[eval(-1 + kimstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
oimstr.title=kkprefix + aimstr[eval(-1 + kimstr)] + kksuffix + origrest;

}
}
if (opdstr) {
origt=opdstr.getAttribute('data-title');
if (kpdstr == 0) {
opdstr.innerHTML=' ' + kprefix + apdstr[kpdstr] + ksuffix;
origrest=(origt.split('' + apdstr[kpdstr])[1] + ',' + origt.split('' + apdstr[kpdstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opdstr.title=kkprefix + apdstr[kpdstr] + kksuffix + origrest;

} else {
opdstr.innerHTML=' ' + kprefix + apdstr[eval(-1 + kpdstr)] + ksuffix;
origrest=(origt.split('' + apdstr[eval(-1 + kpdstr)])[1] + ',' + origt.split('' + apdstr[eval(-1 + kpdstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opdstr.title=kkprefix + apdstr[eval(-1 + kpdstr)] + kksuffix + origrest;

}
}
if (opastr) {
origt=opastr.getAttribute('data-title');
if (kpastr == 0) {
opastr.innerHTML=' ' + kprefix + apastr[kpastr] + ksuffix;
origrest=(origt.split('' + apastr[kpastr])[1] + ',' + origt.split('' + apastr[kpastr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opastr.title=kkprefix + apastr[kpastr] + kksuffix + origrest;

} else {
opastr.innerHTML=' ' + kprefix + apastr[eval(-1 + kpastr)] + ksuffix;
origrest=(origt.split('' + apastr[eval(-1 + kpastr)])[1] + ',' + origt.split('' + apastr[eval(-1 + kpastr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
opastr.title=kkprefix + apastr[eval(-1 + kpastr)] + kksuffix + origrest;

}
}
if (offstr) {
origt=offstr.getAttribute('data-title');
if (kffstr == 0) {
offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
origrest=(origt.split('' + affstr[kffstr])[1] + ',' + origt.split('' + affstr[kffstr])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
offstr.title=kkprefix + affstr[kffstr] + kksuffix + origrest;

} else {
offstr.innerHTML=' ' + kprefix + affstr[eval(-1 + kffstr)] + ksuffix;
origrest=(origt.split('' + affstr[eval(-1 + kffstr)])[1] + ',' + origt.split('' + affstr[eval(-1 + kffstr)])[0]).trim().replace(/\,\,/g,'').replace('undefined','');
offstr.title=kkprefix + affstr[eval(-1 + kffstr)] + kksuffix + origrest;

}
}
kcnt++;
if (kcnt < 7) { setTimeout(betweeneatatjoes, 1000); }
}

“; ?>

Proof positive that emojis are text, and can help provide a graphic display interest for a webpage. As well, as a CSS means by which we stop “dropdown Y jitteriness”, we introduce the use of an emoji ⚪ (&#9898; or &#x26aa;) for most option element Clayton innerText parts, always …


<style>
option:not(.nonwhite)::before {
content: '\0026aa';
}


#doverlay {
background-color: #FFE7E9;
}


#doverlaytwo {
background-color: #FFE7E9;
}


body {
background-color: #FFFFEF;
}
</style>

“; ?>

… with one more media functionality

<?php

var mlook=false, kcnt=0, kprefix='', ksuffix='';
var imstr=' Images to PDF, Images to GIF,', oimstr=null, kimstr=0, aimstr=[];
var pdstr=' PDF to Images, PDF to HTML, PDF to XML,', opdstr=null, kpdstr=0, apdstr=[];
var pastr=' Text to HTML, Text to Rich Text, Text to Word,', opastr=null, kpastr=0, apastr=[];
var ffstr=' Concat demuxer, Display the frame number on each frame,', offstr=null, kffstr=0, affstr=[];

?>

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Emoji Tutorial

The “dropdown animations” introduced into yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial were a tad subtle, it only involving …

  • the wording of option elements within the dropdown … and though we’re not going “full marquee Eat at Joes” we are accentuating “midway”, today, by …
  • adding emoji 🔵 (&#128309;) movement to the animation for interest sake, as well as being informative (in that the user can anticipate when the new innerText text will arrive, as the emoji moves from left to right)

… that we team with more instances of multiple animation settings …

<?php echo ”

var mlook=false, kcnt=0, kprefix='', ksuffix='';
var imstr=' Images to PDF, Images to GIF,', oimstr=null, kimstr=0, aimstr=[];
var pdstr=' PDF to Images, PDF to HTML, PDF to XML,', opdstr=null, kpdstr=0, apdstr=[];
var pastr=' Text to HTML, Text to Rich Text, Text to Word,', opastr=null, kpastr=0, apastr=[];
var ffstr=' Concat demuxer, ', offstr=null, kffstr=0, affstr=[];

“; ?>

… and a new “between the 8 second setInterval wording refreshes” Javascript function

<?php echo ”

function betweeneatatjoes() {
if (kprefix == '' && ksuffix == '') {
kprefix='&#128309;..';
ksuffix='...';
document.getElementById('doverlaytwo').style.marginTop='20px';
} else if (kprefix == '&#128309;..') {
kprefix='.&#128309;.';
ksuffix='...';
} else if (kprefix == '.&#128309;.') {
kprefix='..&#128309;';
ksuffix='...';
} else if (kprefix == '..&#128309;') {
ksuffix='&#128309;..';
kprefix='...';
} else if (ksuffix == '&#128309;..') {
ksuffix='.&#128309;.';
kprefix='...';
} else if (ksuffix == '.&#128309;.') {
ksuffix='..&#128309;';
kprefix='...';
} else {
kprefix='...';
ksuffix='...';
document.getElementById('doverlaytwo').style.marginTop='0px';
}
if (oimstr) {
if (kimstr == 0) {
oimstr.innerHTML=' ' + kprefix + aimstr[kimstr] + ksuffix;
} else {
oimstr.innerHTML=' ' + kprefix + aimstr[eval(-1 + kimstr)] + ksuffix;
}
}
if (opdstr) {
if (kpdstr == 0) {
opdstr.innerHTML=' ' + kprefix + apdstr[kpdstr] + ksuffix;
} else {
opdstr.innerHTML=' ' + kprefix + apdstr[eval(-1 + kpdstr)] + ksuffix;
}
}
if (opastr) {
if (kpastr == 0) {
opastr.innerHTML=' ' + kprefix + apastr[kpastr] + ksuffix;
} else {
opastr.innerHTML=' ' + kprefix + apastr[eval(-1 + kpastr)] + ksuffix;
}
}
if (offstr) {
if (kffstr == 0) {
offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
} else {
offstr.innerHTML=' ' + kprefix + affstr[kffstr] + ksuffix;
}
}
kcnt++;
if (kcnt < 7) { setTimeout(betweeneatatjoes, 1000); }
}



function eatatjoes() {
kcnt=0;
kprefix='';
ksuffix='';
document.getElementById('doverlaytwo').style.marginTop='0px';

if (oimstr) {
if (kimstr >= eval('' + aimstr.length)) {
kimstr=0;
oimstr.innerHTML=' ' + aimstr[kimstr];
} else {
oimstr.innerHTML=' ' + aimstr[kimstr];
kimstr++;
}
}
if (opdstr) {
if (kpdstr >= eval('' + apdstr.length)) {
kpdstr=0;
opdstr.innerHTML=' ' + apdstr[kpdstr];
} else {
opdstr.innerHTML=' ' + apdstr[kpdstr];
kpdstr++;
}
}
if (opastr) {
//alert(apastr.length);
if (kpastr >= eval('' + apastr.length)) {
kpastr=0;
opastr.innerHTML=' ' + apastr[kpastr];
} else {
opastr.innerHTML=' ' + apastr[kpastr];
kpastr++;
}
}
if (offstr) {
if (kffstr >= eval('' + affstr.length)) {
kffstr=0;
offstr.innerHTML=' ' + affstr[kffstr];
} else {
offstr.innerHTML=' ' + affstr[kffstr];
kffstr++;
}
}
setTimeout(betweeneatatjoes, 1000);
}


function andthen(iidea) {
var outidea=iidea;
var fndpos=-1;
var optsare=document.getElementsByTagName('option'), ioptsare=0;
var iimstr=(imstr.indexOf(',') == -1 ? -1 : outidea.indexOf(imstr.split(',')[0].trim() + ','));
mlook=false;
if (iimstr != -1) {
if ((imstr.split(',')[0].trim() + ',') != imstr.trim()) {
if (document.getElementById('oimagemagick')) {
oimstr=document.getElementById('oimagemagick');
mlook=true;
aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == imstr.split(',')[0].trim()) {
oimstr=optsare[ioptsare];
mlook=true;
aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(imstr.split(',')[0].trim(), imstr.split(',')[0].trim() + '' + (imstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
var ipdstr=(pdstr.indexOf(',') == -1 ? -1 : outidea.indexOf(pdstr.split(',')[0].trim() + ','));
if (ipdstr != -1) {
if ((pdstr.split(',')[0].trim() + ',') != pdstr.trim()) {
if (document.getElementById('opdfimages')) {
opdstr=document.getElementById('opdfimages');
mlook=true;
apdstr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == pdstr.split(',')[0].trim()) {
opdstr=optsare[ioptsare];
mlook=true;
apdstr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(pdstr.split(',')[0].trim(), pdstr.split(',')[0].trim() + '' + (pdstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
var ipastr=(pastr.indexOf(',') == -1 ? -1 : outidea.indexOf(pastr.split(',')[0].trim() + ','));
if (ipastr != -1) {
if ((pastr.split(',')[0].trim() + ',') != pastr.trim()) {
if (document.getElementById('opandoc')) {
opastr=document.getElementById('opandoc');
mlook=true;
apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == pastr.split(',')[0].trim()) {
opastr=optsare[ioptsare];
mlook=true;
apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(pastr.split(',')[0].trim(), pastr.split(',')[0].trim() + '' + (pastr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
var iffstr=(ffstr.indexOf(',') == -1 ? -1 : outidea.indexOf(ffstr.split(',')[0].trim() + ','));
if (iffstr != -1) {
if ((ffstr.split(',')[0].trim() + ',') != ffstr.trim()) {
if (document.getElementById('offmpeg')) {
offstr=document.getElementById('offmpeg');
mlook=true;
affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
} else {
for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
if (optsare[ioptsare].value == ffstr.split(',')[0].trim()) {
offstr=optsare[ioptsare];
mlook=true;
affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
}
}
}
outidea=outidea.replace(ffstr.split(',')[0].trim(), ffstr.split(',')[0].trim() + '' + (ffstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
}
}
if (mlook) { setInterval(eatatjoes, 8000); }
return outidea;
}

“; ?>

… helped out via the original setInterval Javascript “eatatjoes” function (all kicked off via modified document.body onload logic
document.getElementById(‘mainspan’).title = andthen(document.getElementById(‘schoices’).innerText.replace(/\&nbsp\;/g,’ ‘).replace(/\ \ /g,’, ‘));
), as modified, above.

You can see this in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Animated Dropdown Tutorial

Lemon curry?! Animated dropdown?! What gives? Well, it’s not “shelling peas”, yet!

Yes, there is another “framework” step forward we wanted to implement before the peas. And yes, no surprises there, the “framework” work relates to adding functionality to our main dropdown. We’re adding a layer of functionality we’re going to refer to as “animated dropdown”. It amounts to …

  • dropdown (ie. select element) … for non-mobile …
  • has size attribute equal to the number of option elements it contains
  • logic wise, because our non-nothing option innerTexts have equalled option values (if you Javascript trim() the option innerText, that is), we have the opportunity to start taking more notice of the …
    <?php echo ”

    function process(tv, tvo) {
    var newval='';
    var ourtv=tvo.value;
    if (tv != '') {
    ourtv=tvo.options[tvo.selectedIndex].innerText.trim();
    }

    if (origval == '') { origval=document.getElementById('mydefopt').title; }
    if (tv == '') {
    document.getElementById('mainspan').innerHTML=document.getElementById('mydefopt').title;
    } else {
    document.getElementById('mydefopt').title=ourtv; //tv;
    document.getElementById('mainspan').innerHTML=document.getElementById('mydefopt').title;
    document.getElementById('schoices').value='';
    }
    newval=document.getElementById('mydefopt').title;
    //alert('origval,newval=' + origval + ' ' + newval);
    if (newval != origval) {
    origval=newval;
    wentfrom(origval, newval);
    } else {
    origval=newval;
    }
    }

    “; ?>
    … option innerHTML as above, meaning …
  • we can set up Javascript code facilitating the animated feel of some option innerHTML looks that are taken notice of as selected via …
    Global variables arranged via each “verb” involved … for today’s “proof of concept” we add one extra Pandoc “Text to Rich Text” option, for now, before the flood of peas arrives …
    <?php echo ”

    var mlook=false;
    var imstr=' Images to PDF, ', oimstr=null, kimstr=0, aimstr=[];
    var pdstr=' PDF to Images, ', opdstr=null, kpdstr=0, apdstr=[];
    var pastr=' Text to HTML, Text to Rich Text,', opastr=null, kpastr=0, apastr=[];
    var ffstr=' Concat demuxer, ', offstr=null, kffstr=0, affstr=[];

    “; ?>
    As heading title is determined at document.body onload document.getElementById(‘mainspan’).title=andthen(document.getElementById(‘schoices’).innerText.replace(/\&nbsp\;/g,’ ‘).replace(/\ \ /g,’, ‘));
    <?php echo ”

    function andthen(iidea) {
    var outidea=iidea;
    var fndpos=-1;
    var optsare=document.getElementsByTagName('option'), ioptsare=0;
    var iimstr=(imstr.indexOf(',') == -1 ? -1 : outidea.indexOf(imstr.split(',')[0].trim() + ','));
    mlook=false;
    if (iimstr != -1) {
    if ((imstr.split(',')[0].trim() + ',') != imstr.trim()) {
    if (document.getElementById('oimagemagick')) {
    oimstr=document.getElementById('oimagemagick');
    mlook=true;
    aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == imstr.split(',')[0].trim()) {
    oimstr=optsare[ioptsare];
    mlook=true;
    aimstr=imstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(imstr.split(',')[0].trim(), imstr.split(',')[0].trim() + '' + (imstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    var ipdstr=(pdstr.indexOf(',') == -1 ? -1 : outidea.indexOf(pdstr.split(',')[0].trim() + ','));
    if (ipdstr != -1) {
    if ((pdstr.split(',')[0].trim() + ',') != pdstr.trim()) {
    if (document.getElementById('opdfimages')) {
    opdstr=document.getElementById('opdfimages');
    mlook=true;
    aipdtr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == pdstr.split(',')[0].trim()) {
    opdstr=optsare[ioptsare];
    mlook=true;
    apdstr=pdstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(pdstr.split(',')[0].trim(), pdstr.split(',')[0].trim() + '' + (pdstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    var ipastr=(pastr.indexOf(',') == -1 ? -1 : outidea.indexOf(pastr.split(',')[0].trim() + ','));
    if (ipastr != -1) {
    if ((pastr.split(',')[0].trim() + ',') != pastr.trim()) {
    if (document.getElementById('opandoc')) {
    opastr=document.getElementById('opandoc');
    mlook=true;
    apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == pastr.split(',')[0].trim()) {
    opastr=optsare[ioptsare];
    mlook=true;
    apastr=pastr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(pastr.split(',')[0].trim(), pastr.split(',')[0].trim() + '' + (pastr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    var iffstr=(ffstr.indexOf(',') == -1 ? -1 : outidea.indexOf(ffstr.split(',')[0].trim() + ','));
    if (iffstr != -1) {
    if ((ffstr.split(',')[0].trim() + ',') != ffstr.trim()) {
    if (document.getElementById('offmpeg')) {
    offstr=document.getElementById('offmpeg');
    mlook=true;
    affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    } else {
    for (ioptsare=0; ioptsare<optsare.length; ioptsare++) {
    if (optsare[ioptsare].value == ffstr.split(',')[0].trim()) {
    offstr=optsare[ioptsare];
    mlook=true;
    affstr=ffstr.trim().replace(/\,\ \ /g,',').replace(/\,\ /g,',').replace(/\,$/g,'').split(',');
    }
    }
    }
    outidea=outidea.replace(ffstr.split(',')[0].trim(), ffstr.split(',')[0].trim() + '' + (ffstr.replace(imstr.split(',')[0],'').trim() + ',').replace(',,',',').replace(/\,$/g,''));
    }
    }
    if (mlook) { setInterval(eatatjoes, 8000); }
    return outidea;
    }

    “; ?>
    … the appeal of all this being that the dropdown height can be controlled by swapping animation for height extension (and user experience downgrades)
    Animated dropdown setInterval Javascript function (bit like marquee Eat at Joes type of animation (we’ll see if it gets more like it into the future, perhaps?)) …
    <?php echo ”

    function eatatjoes() {
    if (oimstr) {
    if (kimstr >= eval('' + aimstr.length)) {
    kimstr=0;
    oimstr.innerHTML=' ' + aimstr[kimstr];
    } else {
    oimstr.innerHTML=' ' + aimstr[kimstr];
    kimstr++;
    }
    }
    if (opdstr) {
    if (kpdstr >= eval('' + apdstr.length)) {
    kpdstr=0;
    opdstr.innerHTML=' ' + apdstr[kpdstr];
    } else {
    opdstr.innerHTML=' ' + apdstr[kpdstr];
    kpdstr++;
    }
    }
    if (opastr) {
    if (kpastr >= eval('' + apastr.length)) {
    kpastr=0;
    opastr.innerHTML=' ' + apastr[kpastr];
    } else {
    opastr.innerHTML=' ' + apastr[kpastr];
    kpastr++;
    }
    }
    if (offstr) {
    if (kffstr >= eval('' + affstr.length)) {
    kffstr=0;
    offstr.innerHTML=' ' + affstr[kffstr];
    } else {
    offstr.innerHTML=' ' + affstr[kffstr];
    kffstr++;
    }
    }
    }

    “; ?>

… onto yesterday’s Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial is shown below.

Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial

Ffmpeg and Pandoc and ImageMagick and Pdfimages Media Tutorial

Onto yesterday’s Ffmpeg and ImageMagick and Pdfimages Media Tutorial

  • ffmpeg … two more media manipulation “verb” stars today …
  • ImageMagick (can help us with new “Images to PDF” option)
  • pdfimages (can help us with new “PDF to Images” option) … “verb” collection, today, we wanted to add …
  • pandoc (can help us with new “Text to HTML” option) …

    If you need to convert files from one markup format into another, pandoc is your swiss-army knife.

… to help improve the “one stop shop” aspects, especially regarding “documents”, to our current Intranet feeling web application in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg and ImageMagick and Pdfimages Media Tutorial is shown below.

Ffmpeg and ImageMagick and Pdfimages Media Tutorial

Ffmpeg and ImageMagick and Pdfimages Media Tutorial

Yesterday’s Ffmpeg Rotate Video Tutorial left you with …

We now present those four in “an expanded out” (at least on non-mobile) dropdown HTML element. Maybe you can guess why?

… and today we are deploying the framework parts and two new media manipulation options regarding PDF that add to our PHP web application’s functionality.

Operating system commands can be thought of to start with …

  • an action item (to be precise a desktop software file specification) … and, what we often think is, like …
  • the command’s “verb” part (as funny as that is to think of a “noun” sounding desktop software file specification being like a “verb”) … verbs being action items in a sentence … down to being essential in any sentence … to the point a “verb” can be the whole sentence

We want to add functionality by adding to our first “verb” …

  • ffmpeg … two more media manipulation “verb” stars today …
  • ImageMagick (can help us with new “Images to PDF” option)
  • pdfimages (can help us with new “PDF to Images” option)

… and to help the “framework” ahead of “shelling peas” we lean on the experience we got from the Animated GIF Creation on Windows MAMP via PDF Tutorial thread of blog postings to deal with …

  • software paths
  • presenting two new “verb” ideas … and us being so fond of dropdowns, we decided to try, for our first time …
    1. start to use three HTML option CSS text-align style choices being left (for ffmpeg), center (for ImageMagick) and right (for pdfimages) … as in …

      … within …

      Add Voiceover Audio to Video via ffmpeg  pdfimages



      <select size=7 onchange=process(this.value,this); style=display:inline-block;font-size:8px; id=schoices><option style=text-align:center; id=mydefopt title='Add Voiceover Audio to Video' value=''>&#10549; Image&#11015;Magick &#10550;</option><option value='Add Voiceover Audio to Video'> Add Voiceover Audio to Video </option><option style='text-align:center;' value='Images to PDF'> Images to PDF</option><option style='text-align:right;' value='PDF to Images'> PDF to Images</option><option value='Burn subtitles'> Burn subtitles</option><option value='Concat demuxer'> Concat demuxer</option><option value='Rotate a video'> Rotate a video</option></select>

      … and then in order to offer the “center” ImageMagick be a link back to the product we introduce some new overlay code
      <?php echo ”

      function overlay() {
      origval=document.getElementById('schoices').value;
      var rect=document.getElementById('fcommand').getBoundingClientRect();
      document.getElementById('moreb').style.position='absolute';
      document.getElementById('moreb').style.left='' + rect.left + 'px';
      document.getElementById('moreb').style.top='' + rect.top + 'px';
      document.getElementById('moreb').style.width='96%'; //' + rect.width + 'px';
      document.getElementById('moreb').style.height='' + rect.height + 'px';
      document.getElementById('moreb').style.border='1px solid black';
      document.getElementById('moreb').style.paddingLeft='20px';
      document.getElementById('moreb').style.backgroundColor='#f9f9f9';
      document.getElementById('fcommand').style.opacity='0.0';
      document.getElementById('fcommand').style.cursor='pointer';
      document.getElementById('moreb').innerHTML='<span id=precmds></span><span id=verb>ffmpeg" . $ffmpegsuf . "</span> <span id=prescbi></span><span id=minusi> -i </span><span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&left=y\"></iframe></span> <span id=betweenis></span> <span id=secondi>-i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=69075964842271&right=y\"></iframe></span></span> <span id=sswitches>-c copy -map 0:v:0 -map 1:a:0 -shortest</span> out.mp4 > <a target=_blank title=ffimpdf.bad onclick=getvb(); style=cursor:pointer;text-decoration:underline; data-href=./ffimpdf.bad>ffimpdf.bad</a>';
      if (firstdivih == '') { firstdivih=document.getElementById('moreb').innerHTML; }
      if (firstbutval == '') { firstbutval=document.getElementById('mysub').value; }
      document.getElementById('schoices').style.display='inline-block';


      rect=document.getElementById('schoices').getBoundingClientRect();


      if (eval('' + rect.height) > 100 || 1 == 1) {
      document.getElementById('doverlay').style.position='absolute';
      document.getElementById('doverlay').style.left='' + rect.left + 'px';
      document.getElementById('doverlay').style.top='' + rect.top + 'px';
      document.getElementById('doverlay').style.width='' + rect.width + 'px';
      if (eval('' + rect.height) < 30) {
      document.getElementById('doverlay').style.height='' + rect.height + 'px';
      } else {
      document.getElementById('doverlay').style.height='' + eval(eval('' + rect.height) / eval('' + document.getElementById('schoices').size)) + 'px';
      }
      document.getElementById('doverlay').style.zIndex='96';
      document.getElementById('doverlay').style.textAlign='center';
      document.getElementById('doverlay').style.display='block';
      document.getElementById('doverlay').title=document.getElementById('mydefopt').title;
      //document.getElementById('mydefopt').style.fontColor='transparent';
      document.getElementById('mydefopt').innerHTML='';
      setInterval(fhoc, 1000);
      }



      }


      function fhoc() {
      var rectx=document.getElementById('schoices').getBoundingClientRect();
      document.getElementById('doverlay').style.left='' + rectx.left + 'px';
      document.getElementById('doverlay').title=document.getElementById('mydefopt').title;
      if (document.getElementById('scbi')) {
      if (document.getElementById('scbi').innerHTML.indexOf('<') == -1) {
      if (document.getElementById('scbi').innerHTML.trim().indexOf(' ') != -1) {
      if (document.getElementById('scbi').innerHTML.trim().indexOf(String.fromCharCode(34)) == -1) {
      document.getElementById('scbi').innerHTML=String.fromCharCode(34) + document.getElementById('scbi').innerHTML.trim() + String.fromCharCode(34);
      }
      }
      }
      }
      if (document.getElementById('scbix')) {
      if (document.getElementById('scbix').innerHTML.indexOf('<') == -1) {
      if (document.getElementById('scbix').innerHTML.trim().indexOf(' ') != -1) {
      if (document.getElementById('scbix').innerHTML.trim().indexOf(String.fromCharCode(34)) == -1) {
      document.getElementById('scbix').innerHTML=String.fromCharCode(34) + document.getElementById('scbix').innerHTML.trim() + String.fromCharCode(34);
      }
      }
      }
      }
      }


      “; ?>

  • Javascript to set up the HTML div contenteditable=true look for these two new options …
    <?php echo ”

    if (newv == 'PDF to Images') {
    document.getElementById('moreb').innerHTML=firstdivih.replace(' out.mp4',' " . $minuspng . "');
    document.getElementById('secondi').innerHTML='';
    document.getElementById('sswitches').innerHTML=\"<span id=sfolder contenteditable=false>newfolder_" . rand(0,784534) . str_replace("\\","\\\\",$ddn) . "\" + '</span>ideas';

    document.getElementById('precmds').innerHTML=' ';
    document.getElementById('verb').innerHTML='" . $pdfimages . $pdfimagessuf . "';
    document.getElementById('scbi').innerHTML=document.getElementById('scbi').innerHTML.replace(/inv\.mp4/g,'inv.pdf ');
    document.getElementById('minusi').innerHTML=' -j ';

    document.getElementById('mysub').value=newv;
    } else if (newv == 'Images to PDF') {
    document.getElementById('moreb').innerHTML=firstdivih.replace('out.mp4','out.pdf');

    document.getElementById('precmds').innerHTML=' ';
    document.getElementById('secondi').innerHTML='';
    document.getElementById('verb').innerHTML='" . $magickverb . $magicksuf . "';
    document.getElementById('sswitches').innerHTML='-auto-orient';
    document.getElementById('sswitches').title='To perform a folder of images (only, we suggest) right click or two finger guesture to left and enter the folder name only';
    document.getElementById('scbi').innerHTML=document.getElementById('scbi').innerHTML.replace(/inv\.mp4/g,'inv.jpg ');
    document.getElementById('minusi').innerHTML='';
    document.getElementById('scbi').setAttribute('contenteditable', true);
    document.getElementById('scbi').onblur=function(event) { if (document.getElementById('mydefopt').title == 'Images to PDF') { if (event.target.innerHTML.replace(/\ \;/g,' ').trim() == '') { event.target.innerHTML='folder' + \"" . str_replace("\\","\\\\",$ddn) . "*\"; } if (event.target.innerHTML.toLowerCase().indexOf('.txt') == -1) { if (event.target.innerHTML.indexOf('.') != -1) { document.getElementById('ifs').innerHTML+='<iframe id=voaskfor' + ifile + ' style=display:none; src=\"./voiceover.php?infilegetsize=' + encodeURIComponent(listtxt + ';' + event.target.innerHTML) + '\"></iframe>'; ifile++; if (document.getElementById('moreb').title.indexOf(\"file '\" + event.target.innerHTML.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\") == -1) { document.getElementById('moreb').title+=String.fromCharCode(10) + \"file '\" + event.target.innerHTML.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\"; } } } event.target.innerHTML=listtxt; if (document.getElementById('minusi')) { document.getElementById('minusi').innerHTML=''; } } };
    document.getElementById('moreb').onblur=function(event) { if (document.getElementById('mydefopt').title == 'Images to PDF') { if (document.getElementById('minusi')) { var thingos=document.getElementById('minusi').innerHTML.replace(/\ \;/g,' ').trim().split('-i '); if (thingos.length > 1) { if (thingos[1].trim() != '' && (thingos[1] + '~').toLowerCase().indexOf('.txt~') == -1) { spanfill(thingos[1]); } } document.getElementById('minusi').innerHTML=''; } if (!document.getElementById('scbi')) { event.target.innerHTML=event.target.innerHTML.replace('<span id=\"between', '<span id=scbi contenteditable=true>' + listtxt + '</span> <span id=\"between'); putbackonblur(); if (event.target.innerHTML.indexOf('> -i </span><span id=\"scbi\"') == -1) { event.target.innerHTML=event.target.innerHTML.replace('</span>' + event.target.innerHTML.split('<span id=\"scbi\"')[0].split('</span>')[-1 + eval(event.target.innerHTML.split('<span id=\"scbi\"')[0].split('</span>').length)],'</span>'); } } } };
    document.getElementById('moreb').oncontextmenu=function(event) { document.getElementById('scbi').innerHTML='folder' + \"" . str_replace("\\","\\\\",$ddn) . "*\"; };


    document.getElementById('mysub').value=newv;
    }

    “; ?>
  • the performing of those two new “verb” ideas …
    <?php

    $pfolder='';
    $ppdf='';

    // ... later ...
    $cmdis=str_replace('+',' ',urldecode($_GET['fcommand']));
    if (PHP_OS =='WINNT' || PHP_OS =='WIN32' || PHP_OS =='Windows') {
    if ($ffmpegpre != '' && strpos($cmdis, 'ffmpeg.') !== false && strpos($cmdis, $ffmpegpre) === false) {
    $cmdis=str_replace('ffmpeg.', $ffmpegpre . 'ffmpeg.', $cmdis);
    }
    if ($magickpre != '' && strpos($cmdis, $magickverb . '.') !== false && strpos($cmdis, $magickpre) === false) {
    $cmdis=str_replace($magickverb . '.', $magickpre . $magickverb . '.', $cmdis);
    }
    if ($pdfimagespre != '' && strpos($cmdis, 'pdfimages.') !== false && strpos($cmdis, $pdfimagespre) === false) {
    $cmdis=str_replace('pdfimages.', $pdfimagespre . 'pdfimages.', $cmdis);
    }
    }

    $precmd=explode('>', $cmdis);
    if (strpos($cmdis, 'pdfimages') !== false && strpos($cmdis, 'newfolder_') !== false) {
    $pfolder='newfolder_' . explode(DIRECTORY_SEPARATOR, explode('newfolder_', $cmdis)[1])[0];
    $beforep=explode($pfolder, $cmdis)[0];
    $afterp=explode($pfolder, $cmdis)[1];
    while (file_exists($pfolder)) {
    $pfolder='newfolder' . '_' . explode('newfolder', $pfolder)[1];
    $cmdis=$beforep . $pfolder . $afterp;
    }
    if (!file_exists($pfolder)) { mkdir($pfolder); }
    }

    // ... later ...
    $outf=$subcmd[1];
    // ... later ...
    if (strpos(strtolower(trim($outf) . '~'), '.pdf~') !== false) {
    $ppdf=trim($outf);
    }

    // ... later ...
    $rs=shell_exec($cmdis);

    // ... later ...
    if ($pfolder != '') {
    $rs.="<br><br>";
    foreach (glob($pfolder . DIRECTORY_SEPARATOR . '*.*') as $ifilename) {
    $rs.='<img title="' . $ifilename . '" src="' . $ifilename . '?rand=' . rand(0,7654532) . '"></img>';
    }
    }
    if ($ppdf != '') {
    $outf='';
    $rs.="<br><br><iframe style='width:98%;height:800px;' src='" . $ppdf . "?rand=" . rand(0,7654532) . "' title='" . $ppdf . "'></iframe>";
    }

    ?>

… in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg Rotate Video Tutorial is shown below.

Ffmpeg Rotate Video Tutorial

Ffmpeg Rotate Video Tutorial

It’s getting closer to “shelling peas”, are today’s “Rotate a video via ffmpeg” changes, but we are not there yet. Yes, most programmers want to be “shelling peas” adding functionality to web applications, once they have set up a framework in which they are happy to work. Yesterday’s Ffmpeg Concat Demuxer Tutorial “defence talk” is getting us closer to that “shelling peas” “homeostasis feel” (with an “Intranet” pike, no doubt?!) as you can see from a Javascript “Rotate a video” code snippet below …

<?php echo ”

if (newv == 'Rotate a video') {
document.getElementById('moreb').innerHTML=firstdivih;

document.getElementById('precmds').innerHTML=' ';
document.getElementById('secondi').innerHTML='';


document.getElementById('sswitches').innerHTML='<span id=notranspose contenteditable=false>-vf \"transpose=</span><span id=transpose contenteditable=true>1</span><span id=nottranspose contenteditable=false>\" </span>';
document.getElementById('sswitches').title='" . str_replace("\n", "' + String.fromCharCode(10) + '",$rotateadvice) . "';
document.getElementById('sswitches').oncontextmenu=function(event) { alert(event.target.title); };

document.getElementById('mysub').value=newv;
}

“; ?>

… effectively straightjacketing the crucial …


-vf "transpose=1"

… ffmpeg switch definition, by the user, to changing that 1 above as per the hover over advice, to help the user, straight from Mux Video and Audio from another Video, thanks, to advise …

<?php

$rotateadvice="Rotate a video

Rotate 90 clockwise:

ffmpeg -i in.mov -vf \"transpose=1\" out.mov
For the transpose parameter you can pass:

0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

Use -vf \"transpose=2,transpose=2\" for 180 degrees.";

?>

Yes, the user can still put a bad entry there, but at least the web application has attempted to point them in the right direction, here.

If you examine the changes the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there), am sure that you will concur

  • Concat demuxer concatenation of videos ffmpeg functionality, onto the “as of yesterday” …
  • Voiceovers … and …
  • Burn subtitles
  • Rotate a video

… was the simplest functionality component, yet, of the four. We now present those four in “an expanded out” (at least on non-mobile) dropdown HTML element. Maybe you can guess why?


Previous relevant Ffmpeg Concat Demuxer Tutorial is shown below.

Ffmpeg Concat Demuxer Tutorial

Ffmpeg Concat Demuxer Tutorial

Onto yesterday’s Ffmpeg Burn Subtitles Tutorial work we’re still not up to “shelling any peas” adding in …

  • Concat demuxer concatenation of videos ffmpeg functionality, onto the “as of yesterday” …
  • Voiceovers … and …
  • Burn subtitles

… progress.

What’s different this time? Well, ffmpeg works the command, we again thank Mux Video and Audio from another Video for (regarding “the plan”), using an interim file …

Concat demuxer

First, make a text file.

file ‘in1.mp4’
file ‘in2.mp4’
file ‘in3.mp4’
file ‘in4.mp4’

Then, run ffmpeg :

ffmpeg -f concat -i list.txt -c copy out.mp4

… and for File API browsing (with our, once again, tweaked inhouse client_browsing.htm) there will be a delay, deriving the file path in “second call PHP”. We handle this by writing two new Javascript functions …

<?php echo ”

var ifile=0, ibfile=0;

function takeoffone() {
ibfile--;
if (ibfile <= 0) {
document.getElementById('mysub').style.cursor='pointer';
} else {
document.getElementById('mysub').style.cursor='progress';
}
}

function organizefilenamesize(fn, fs) {
document.getElementById('ifs').innerHTML+='<iframe id=voaskfor' + ifile + ' style=display:none; src=\"./voiceover.php?concat=' + encodeURIComponent('list.txt') + '&filename=' + encodeURIComponent(fn) + '&haveasleep=' + eval(3 * eval('' + ifile)) + '&filesize=' + fs + '\"></iframe>';
if (ibfile == 0) {
document.getElementById('mysub').style.cursor='progress';
}
ifile++;
ibfile++;
if (document.getElementById('moreb').title.indexOf(\"file '\" + fn.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\") == -1) {
document.getElementById('moreb').title+=String.fromCharCode(10) + \"file '\" + fn.replace(String.fromCharCode(34),'').replace(String.fromCharCode(34),'') + \"'\";
}
}

“; ?>

… available to call from child iframes via parent.takeoneoff(); (from voiceover.php second PHP call) and parent.organizefilenamesize(files[ij].name, files[ij].size); (from client_browsing.htm) respectively, to facilitate a progress cursor on the submit button to remind the user we’d like more time. Along the way, too, we found


ffmpeg -f concat -safe 0 -i list.txt -c copy out.mp4

… thanks to the excellent advice we found at this webpage.

You can see this work in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).

Did you know?

Just like the use of …

… are the SpongeBob, Patrick, and Squidward of the online woooorrrrllllddd, in an “offence” line of “piecing together an operating system command” thinking, thinking “defence” regarding this we added one (we were pleasantly surprised to discover worked, so as) to have …

  • div contenteditable=true
  • spanizing within that div
  • innerText
  • mask off parts the programmer wants left untouched via span contenteditable=false

… being like the Hall and Oates meets Everything But the Girl (on a yacht, of course) step back into the ’80s!

Take a look at some tweaks


if (newv == 'Burn subtitles') {
document.getElementById('moreb').innerHTML=firstdivih;
//document.getElementById('precmds').innerHTML=document.getElementById('verb').innerHTML + ' ' + document.getElementById('secondi').innerHTML.replace(/inva\.mp4/g,'sub.srt ') + ' sub.ass; ';
document.getElementById('precmds').innerHTML=document.getElementById('verb').innerHTML + ' ' + document.getElementById('secondi').innerHTML.replace(/inva\.mp4/g,'sub.srt ') + ' <span id=subass contenteditable=false>sub.ass;</span> ';
document.getElementById('secondi').innerHTML='';
//document.getElementById('sswitches').innerHTML='-vf ass=sub.ass';
document.getElementById('sswitches').innerHTML='-vf<span id=asssubass contenteditable=false> ass=sub.ass </span>';
document.getElementById('mysub').value=newv;
}

… in a “Burn subtitles” relevant Javascript code snippet.


Previous relevant Ffmpeg Burn Subtitles Tutorial is shown below.

Ffmpeg Burn Subtitles Tutorial

Ffmpeg Burn Subtitles Tutorial

The initial inspiration for this current ffmpeg themed series of blog posting was, and still is, Mux Video and Audio from another Video, thanks. So many great ideas, we found, that today we add onto the …

  • first idea of Voiceovers we’ve established to work with MAMP in macOS and Windows over the previous days, allowing us to now think to add a first suboption idea of …
  • Burn subtitles … as per our link’s …

    Burn subtitles
    Use the libass library (make sure your ffmpeg install has the library in the configuration –enable-libass).

    First convert the subtitles to .ass format:

    ffmpeg -i sub.srt sub.ass
    Then add them using a video filter:

    ffmpeg -i in.mp4 -vf ass=sub.ass out.mp4

… as a useful video piece of functionality we’d say.

To get this going, easily (from a programming perspective) …

  • our textarea element remains as the form conduit to the ffmpeg command via the onsubmit event final analysis of the …
  • underlying div contenteditable=true is “spanned” up a lot more as per …
    <?php echo ”

    document.getElementById('moreb').innerHTML='<span id=precmds></span><span id=verb>ffmpeg" . $ffmpegsuf . "</span> -i <span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=9075964842271&left=y\"></iframe></span> <span id=betweenis></span> <span id=secondi>-i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=9075964842271&right=y\"></iframe></span></span> <span id=sswitches>-c copy -map 0:v:0 -map 1:a:0 -shortest</span> out.mp4 > <a target=_blank title=ffm.bad onclick=getvb(); style=cursor:pointer;text-decoration:underline; data-href=./ffm.bad>ffm.bad</a>';

    “; ?>
    … and at the onsubmit event Javascript the innerText attribute usage makes it fairly easy to say
    <?php echo ”

    function mergechanges() {
    if (document.getElementById('scbi').innerHTML.indexOf('<') == -1) {
    if (document.getElementById('precmds').innerHTML != '') {
    document.getElementById('fcommand').value=document.getElementById('moreb').innerText;
    } else {

    document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inv.mp4 ', ' ' + document.getElementById('scbi').innerHTML + ' ');
    }
    //alert('not oops ' + document.getElementById('fcommand').value);
    } //else {
    //alert('oops');
    //}
    if (document.getElementById('scbix').innerHTML.indexOf('<') == -1) {
    //alert('zoops');
    document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inva.mp4 ', ' ' + document.getElementById('scbix').innerHTML + ' ');
    }
    if (document.getElementById('moreb').innerText.indexOf(' -c ') != -1 && document.getElementById('fcommand').value.indexOf(' -c ') != -1) {
    //alert('azoops');
    if (document.getElementById('moreb').innerText.split(' -c ')[1] != document.getElementById('fcommand').value.split(' -c ')[1]) {
    //alert('bzoops');
    document.getElementById('fcommand').value=document.getElementById('fcommand').value.split(' -c ')[0] + ' -c ' + document.getElementById('moreb').innerText.split(' -c ')[1];
    }
    }
    return true;
    }

    “; ?>
    … to slice through that “span” complexity like margarine (or butter that’s been left out on a hot day for approximately 7 hours 17 minutes 23 seconds)

And so, onto yesterday’s Ffmpeg Improved Windows Media Browsing Tutorial feel free to see this in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there).


Previous relevant Ffmpeg Improved Windows Media Browsing Tutorial is shown below.

Ffmpeg Improved Windows Media Browsing Tutorial

Ffmpeg Improved Windows Media Browsing Tutorial

Yesterday’s Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial taught us a lesson, as a side issue, that what we said when we presented Animated GIF Creation on Windows MAMP via PDF Tutorial

No matter how we tried, we could not get a Windows command line command like …


forfiles /P "[PathToFileBestGuess]" /S /M "[FileBaseName]" /C "cmd /c echo @path@fsize" | find "[FileSizeInBytes]"

… to work out a file path when supplied a file base name and a file size and you call as above with starting folders. That works well (for deriverability (if that is a word!)) in the “cmd” window but not when called under the auspices of PHP exec or shell_exec. It could be that you lose a lot of a Windows user environment when asking PHP to do some operating system work.

… was “only partially” the story. We found out that that ” | find ” command piping could cause problems on Windows MAMP using shell_exec or exec to do some operating system functionality. But before your enthusiasm oozes over the edges, Windows “forfiles” is still very hard to get working with PHP shell_exec or exec, even using PHP to perform that ” | find ” filtering of results.

However, on revisiting the issue in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder and which you can run that PHP there) there were dual purpose motivations going on, for us, because our changed animated GIF creator PHP tutorial_to_animated_gif.php (that if you download to MAMP would best go to Document Root PHP/animegif folder along with the wonderful GIFEncoder.class.php … thanks) inhouse animated GIF creator web application and the changed PDF parts to animated GIF creation helper php_calls_pdfimages.php (also a standalone proposition) PHP code could be fixed up at the same time, with a new PHP ourshell_exec function interventional code snippet up at the top …

<?php

function ourshell_exec($onea, $twoa = NULL, $threea = NULL) {
$folder='';
$pattern='';
$size='';
$filesa=[];
if (PHP_OS =='WINNT' || PHP_OS =='WIN32' || PHP_OS =='Windows' || (strpos(('~@!' . $onea), '~@!forfiles /P "') !== false && strpos(('~@!' . $onea), '/M "') !== false && strpos(('~@!' . $onea), 'find "') !== false)) {
$folder=explode('"', explode('forfiles /P "', $onea)[1])[0]; // . substr(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, 0, 1);
if (7 == 7) {
$folder=explode('"', explode('forfiles /P "', $onea)[1])[0]; // . substr(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, 0, 1);
$pattern=explode('"', explode('/M "', $onea)[1])[0];
$size=explode('"', explode('find "', $onea)[1])[0];
$thiscmd=trim(explode(" | find ", $onea)[0]);
if (strpos($pattern, ' ') === false) { $thiscmd=str_replace('/M "' . $pattern . '"', '/M ' . $pattern, $thiscmd); }
if (strpos($folder, ' ') === false) { $thiscmd=str_replace('/P "' . $folder . '"', '/P ' . $folder, $thiscmd); }
if (strpos($thiscmd, '"cmd /c ') !== false && substr($thiscmd,-1,1) != '"') { $thiscmd.='"'; }
if (strpos($thiscmd, "/P C:\\ ") !== false) {
if (strpos($thiscmd, "/P C:\\ ") !== false) {
if (strpos($pattern, " ") === false) {
$thiscmd="DIR C:\\" . $pattern . " /S /-C";
} else {
$thiscmd="DIR \"C:\\" . $pattern . "\" /S /-C";
}
}
}
//file_put_contents('xxx.xxx',file_get_contents('xxx.xxx'). "\n" . '' . $size . ' ' . $thiscmd);
$nofind=shell_exec($thiscmd . ' 2> nul');

//file_put_contents('xxxx.xxxx',file_get_contents('xxxx.xxxx'). "\n" . '' . $size . ' ' . $nofind);
//exit;
$findings=explode("\n", $nofind);
$bitbefore='';
for ($ifindgs=0; $ifindgs<sizeof($findings); $ifindgs++) {
if (strpos(str_replace("\r","",$findings[$ifindgs]), 'Directory of ') !== false) {
$bitbefore=explode('Directory of ', str_replace("\r","",$findings[$ifindgs]))[1] . "\\";
}
if (strpos((str_replace("\r","",$findings[$ifindgs]) . '~'), $size . '~') !== false) {
return str_replace('~','',str_replace($size . '~', '', (str_replace("\r","",$findings[$ifindgs]) . '~')));
} else if (strpos((str_replace("\r","",$findings[$ifindgs]) . ''), $size . ' ') !== false) {
//file_put_contents('xxxxx.xxxxx',$bitbefore . explode($size . ' ', (str_replace("\r","",$findings[$ifindgs]) . ''))[1]);
return $bitbefore . explode($size . ' ', (str_replace("\r","",$findings[$ifindgs]) . ''))[1];
}
}
if ($folder == "C:\\") { return ''; }
}

// more code
// as per usual
// stays here ...
}
return shell_exec($onea, $twoa, $threea);
}

?>

… where we substitute in Windows DIR C:\ /S /-C thinking in place of forfiles (via shell_exec minus the ” | find ” piping, that is).


Previous relevant Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial is shown below.

Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial

Ffmpeg Mux Video and Audio Windows Media Browsing Tutorial

You know it’s “Intranet feely land”?

You look out the train window (tee hee) and see macOS racing through their usual routine.

Of course you’ll pick the buffet car containing the rice bubbles ahead of the vegemite corn flakes?!

But do we need to reiterate that in “Intranet feely land” you’ve got your macOS typose of work not suiting “arch Windows” methodologies? Take the case of …

At least, with macOS MAMP there is the excellent command line “file” we can use to show information about some potential input files you could use in this, so far, user unfriendly, “first draft” version of the PHP.

… to the beach, would be nice … but we digress. Well, in any case, we asked Google (not via the “arch Window”) does windows have the equivalent of linux file command” and got to the helpful What is the equivalent to the Linux File command for windows? – Super User, thanks, and then ended up at the really useful third party “file.exe” for (non-arch) Windows usage and proceeded with it, working off Ffmpeg Mux Video and Audio Media Browsing Tutorial, to start being able to develop this “reveal” details/summary arrangement in either macOS or Windows MAMP environments, that “ffmpeg” voiceover command, which normally works a lot better than …

I command thee mux, hey you, with audible you, over yonder, by dale and meadow be, yea!

… when it occurred to us we could turn the base filename parts of those “file.exe” reports into links that when clicked mapped those clicked files into place into the “ffmpeg” command being developed above (as alternative input file designator idea to browsing or div contenteditable=true typing ways), in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder) and which you can run that PHP there.

And so, we reckon the work day got worth it!


Previous relevant Ffmpeg Mux Video and Audio Media Browsing Tutorial is shown below.

Ffmpeg Mux Video and Audio Media Browsing Tutorial

Ffmpeg Mux Video and Audio Media Browsing Tutorial

Onto yesterday’s Ffmpeg Mux Video and Audio Primer Tutorial

There be a flowerin’ of inner warmth and glo’ towards all our readers, youngins and oldins alike … like!

Yes, we’re involving good ol’ HTML5 File API Object Javascript logic, so our “Intranet” savvy downloaders out there …

Full o’ inner warmth and glo’ towards each other … like!

… can easily browse for their two media input files, and for the first time ever integrating our ever tweaked inhouse client_browsing.htm (also a standalone proposition) (we’d like you to download to MAMP Document Root’s HTMLCSS subfolder) we add “oncontextmenu” event changes to its input type=file browser hosting parent iframe element onload event Javascript function as per

<?php echo ”

var voaf='', voaftwo='';

function checkif(iois, ival) {
if (iois.src.indexOf('?d=') != -1) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.getElementById('files')) {
if (voaf == '') {
voaf=iois.src;
iois.setAttribute('data-parentspan', 's' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix'));
document.getElementById('myh1').title='s' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix');
document.getElementById('myh1').setAttribute('data-url', iois.src);
setInterval(voaff, 1000);
} else if (voaftwo == '') {
voaftwo=iois.src;
iois.setAttribute('data-parentspan', 's' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix'));
document.getElementById('myh3').title='s' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix');
document.getElementById('myh3').setAttribute('data-url', iois.src);
//alert(iois.id + ' data-parentspan=' + iois.getAttribute('data-parentspan'));
}
//alert(iois.id + ' data-parentspan=' + iois.getAttribute('data-parentspan'));
aconto.getElementsByTagName('h1')[0].style.opacity='0.0';
//alert('here');
aconto.getElementById('files').style.position='absolute';
aconto.getElementById('files').style.left='0px';
aconto.getElementById('files').style.top='0px';
aconto.getElementById('files').style.zIndex='99';
aconto.getElementById('files').style.marginLeft='10px';
aconto.getElementById('files').style.marginTop='8px';
aconto.getElementById('files').style.visibility='visible';
aconto.getElementById('files').style.display='block';
aconto.getElementById('files').style.backgroundColor='#eeeeee';
aconto.getElementById('files').setAttribute('data-hostcont', ival);
aconto.getElementById('files').setAttribute('data-hostspan', 's' + ival.replace('inv.mp4','cbi').replace('inva.mp4','cbix'));
aconto.getElementById('files').oncontextmenu = function(event) { var suf=event.target.getAttribute('data-hostspan'); parent.document.getElementById(suf).innerHTML=\"" . str_replace("\\","\\\\",dirname(__FILE__) . DIRECTORY_SEPARATOR) . "\" + event.target.getAttribute('data-hostcont'); }
if (ival == 'inv.mp4') {
aconto.getElementById('files').accept='video/*';
aconto.getElementById('files').title='Click to browse for video else right click or two finger gesture to make disappear.';
} else {
aconto.getElementById('files').accept='video/*,audio/*';
aconto.getElementById('files').title='Click to browse for video or audio else right click or two finger gesture to make disappear.';
}
//alert('there');
aconto.getElementById('dwstyle').innerHTML+=\"<style> #files::before { content: '\" + ival + \"'; } </style>\";
}
}
}
}

“; ?>

… to allow a user who prefers the overlayed div contenteditable=true alternative (which speaks back to the HTML form textarea conduit when that form’s “onsubmit” event is called) onto yesterday’s exclusively textarea methodology

<?php echo ”

function overlay() {
var rect=document.getElementById('fcommand').getBoundingClientRect();
document.getElementById('moreb').style.position='absolute';
document.getElementById('moreb').style.left='' + rect.left + 'px';
document.getElementById('moreb').style.top='' + rect.top + 'px';
document.getElementById('moreb').style.width='96%'; //' + rect.width + 'px';
document.getElementById('moreb').style.height='' + rect.height + 'px';
document.getElementById('moreb').style.border='1px solid black';
document.getElementById('moreb').style.paddingLeft='20px';
document.getElementById('moreb').style.backgroundColor='#f9f9f9';
document.getElementById('fcommand').style.opacity='0.0';
document.getElementById('moreb').innerHTML='ffmpeg" . $ffmpegsuf . " -i <span id=scbi><iframe onload=checkif(this,\"inv.mp4\"); scrolling=no frameborder=0 id=cbi data-type=file data-value=inv.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:92px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=975964842271&left=y\"></iframe></span> -i <span id=scbix><iframe onload=checkiftwo(this,\"inva.mp4\"); scrolling=no frameborder=0 id=cbix data-type=file data-value=inva.mp4 data-accept=\"video/*\" style=\"display:inline-block;height:40px;width:106px;vertical-align:middle;\" src=\"/HTMLCSS/client_browsing.htm?d=975964842271&right=y\"></iframe></span> -c copy -map 0:v:0 -map 1:a:0 -shortest out.mp4 > voiceover.bad';
}

function mergechanges() {
if (document.getElementById('scbi').innerHTML.indexOf('<') == -1) {
document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inv.mp4 ', ' ' + document.getElementById('scbi').innerHTML + ' ');
//alert('not oops ' + document.getElementById('fcommand').value);
} //else {
//alert('oops');
//}
if (document.getElementById('scbix').innerHTML.indexOf('<') == -1) {
document.getElementById('fcommand').value=document.getElementById('fcommand').value.replace(' inva.mp4 ', ' ' + document.getElementById('scbix').innerHTML + ' ');
}
if (document.getElementById('moreb').innerText.indexOf(' -c ') != -1 && document.getElementById('fcommand').value.indexOf(' -c ') != -1) {
if (document.getElementById('moreb').innerText.split(' -c ')[1] != document.getElementById('fcommand').value.split(' -c ')[1]) {
document.getElementById('fcommand').value=document.getElementById('fcommand').value.split(' -c ')[0] + ' -c ' + document.getElementById('moreb').innerText.split(' -c ')[1];
}
}
return true;
}


“; ?>

… reign supreme collecting their media file specification information in the changed voiceover.php PHP (we’d want you to download to a local MAMP Apache web server’s Document Root folder) and which you can run that PHP there.

The previous work of Animated GIF Creation Install Paths Tutorial‘s thread of blog postings has been a great help with this ffmpeg “Intranet feeling” integration work we use, around here, in conjunction with macOS or Windows operating system MAMP Apache local web server environments.


Previous relevant Ffmpeg Mux Video and Audio Primer Tutorial is shown below.

Ffmpeg Mux Video and Audio Primer Tutorial

Ffmpeg Mux Video and Audio Primer Tutorial

We’ve got another “Intranet feeling” PHP web application “first draft” for you today. The reason we’re opting for “Intranet feeling” (ie. we’re asking you to download the voiceover.php PHP to a local MAMP Apache web server and run the PHP there from its Document Root folder) is that we want to further explore the brilliant …


ffmpeg -i inv.mp4 -i inva.mp4 -c copy -map 0:v:0 -map 1:a:0 -shortest out.mp4

… we got inspired to try via Mux Video and Audio from another Video and FFMPEG mux video and audio (from another video) – mapping issue … thanks and thanks … to add audio to a video stream from two different sources.

At least, with macOS MAMP there is the excellent command line “file” we can use to show information about some potential input files you could use in this, so far, user unfriendly, “first draft” version of the PHP.

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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

Posted in Animation, eLearning, Operating System, Tutorials | Tagged , , , , , , , , , , , , , , , , , , | Leave a comment

Landing Page Web Inspector CSS Styling Tutorial

Landing Page Web Inspector CSS Styling Tutorial

Landing Page Web Inspector CSS Styling Tutorial

Are you a member of the IBORT? If not, would you like to become a member? Anyone, anyone? Hang on, Isaac, can you please “use your words” in front of the class, please …

What does IBORT stand for?

Okay, class … over to you

Well, okay Sandra, yes, we understand “World Peace” might work … but anyone else?

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

You all give up?!

International Board of Registered Tweakers
(no Registered Tweakers were harmed in the making of this infomercial)

Yes, you can tweak webpages in the morning or afternoon, and for simple styling changes we recommend …

  1. getting the relevant webpage showing in your favoured web browser on a non-mobile platform …
  2. inspect that webpage via that web browser’s Web Inspector … for Google Chrome on macOS we went …

    View -> Developer -> Developer Tools -> "Elements" tab

  3. the “before your eyes, dynamically” approach being to zero in on web element style=”[CSS styling]” parts and, “tweak away” …
  4. the results immediate and further tweakable, until you are happy … then …
  5. think what can be done to directly, or indirectly (eg. “client pre-emptive iframe” action) to simulate this change back at the relevant code (in our RJM Programming Landing Page case some PHP in our Apache web server’s Document Root folder called “index.php”) to simulate what you were happy with back at your Web Inspector session (ie. until this, your changes are “Ephemeral”) …
  6. you upload into place to turn a “tweak” into some “tweak realia”

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

Posted in eLearning, Tutorials | Tagged , , , , , , , , , , , , , , , | Leave a comment

CSS3 Grid Primer Tutorial

CSS3 Grid Primer Tutorial

CSS3 Grid Primer Tutorial

Continuing on with some of the styling themes from CSS3 Multi Columns Primer Tutorial, today, we present a tutorial aboout CSS Grid Styling, primarily, thanking W3school’s excellent https://www.w3schools.com/css/tryit.asp?filename=trycss_grid for ideas.

The lesson is that HTML table element designs do not have to be the go, to display tabular datasets. And there is the responsive design consideration where HTML table element arrangements sometimes fall down. As you might expect, there are a myriad of CSS properties that come into play, and perhaps it is best for us to let you explore some possibilities playing around with today’s “proof of concept” grid_bb_nine.html Playing Around with Grids web application also available, below …


Previous relevant CSS3 Multi Columns Primer Tutorial is shown below.

CSS3 Multi Columns Primer Tutorial

CSS3 Multi Columns Primer Tutorial

Today’s “catch up” with CSS3 styling of web applications, adding onto yesterday’s CSS3 Border Image Primer Tutorial, involves Multi Columns (thanks, TutorialsPoint) styling that does not require any work with the HTML table element. Typically, what we are talking about here, is styling as you would find in a newspaper or magazine, set out in columns.

To do the research on this we took and added Javascript DOM thoughts to the code at the Tutorial Points webpage above to end up with (a proof of concept) live run‘s HTML and CSS3 and Javascript DOM “make it dynamic” newspaper.html source code.

We are going to illustrate this dynamism below as well to show you a Javascript DOM approach to changing the styling properties (randomly) …

  • column-count: 4;
  • column-gap: 40px;
  • column-rule-style: solid;
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer commodo nibh et aliquet molestie. Phasellus vehicula arcu ut convallis facilisis. Etiam interdum mollis massa, dapibus sollicitudin sem condimentum a. Aliquam viverra enim eget faucibus vulputate. Suspendisse cursus magna a ultricies finibus. Phasellus at eros aliquam, iaculis sem at, pharetra dui. Praesent scelerisque tellus leo, ac consequat ante convallis sit amet. In libero tellus, luctus sit amet velit quis, laoreet mollis urna. Aliquam aliquet tristique pharetra. Praesent quis cursus mauris. Etiam a ipsum euismod, rutrum erat vel, tincidunt enim. Sed a lorem magna. Sed odio libero, ultricies in nibh a, rutrum venenatis nisi. Pellentesque aliquet nibh augue, eget congue ante rhoncus sed. Maecenas ut ante nec erat scelerisque rutrum. Curabitur at lacinia velit, non ultricies ante.

Nam tortor nisi, porttitor eget tincidunt eu, faucibus in libero. Maecenas sed nulla non sapien facilisis porta semper eu neque. Aliquam imperdiet purus consectetur bibendum vehicula. Nam risus ex, iaculis eget lorem in, fermentum tempor augue. Aliquam semper viverra neque, nec finibus arcu porta sit amet. Proin sollicitudin risus et magna condimentum, ut vestibulum lacus euismod. Nulla eu mattis enim. Praesent ultrices faucibus tortor, eget scelerisque ante faucibus vel. Proin ullamcorper nulla ut tellus cursus blandit. Duis mattis vestibulum sem. Fusce laoreet enim quis nunc egestas, ultricies finibus orci cursus. Nam auctor eros faucibus orci scelerisque viverra. Quisque at diam fermentum mauris venenatis elementum. Integer lobortis dolor sed rutrum varius. Duis non odio massa.

Aliquam erat volutpat. Nunc ante turpis, vehicula et scelerisque sed, tincidunt eu metus. Aliquam ut augue tincidunt, lobortis lectus commodo, sagittis nunc. Fusce mattis elit maximus, ullamcorper justo quis, varius nisi. Donec risus orci, fringilla non posuere at, laoreet ac ligula. Phasellus molestie, tortor in porttitor euismod, tellus lacus convallis lacus, nec condimentum sapien nisl quis sapien. Duis iaculis dolor turpis, et feugiat dui commodo quis. Proin vehicula accumsan sapien vitae facilisis. Morbi et dignissim odio, volutpat posuere sem. Vestibulum interdum feugiat enim vel molestie.

Proin sit amet dolor quis mi maximus eleifend at et enim. Cras nec augue massa. Mauris nec nisi quis arcu ullamcorper commodo. Donec molestie leo varius mi dignissim pretium. Integer eu metus quis sapien dignissim ultrices. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi tristique dui ac pretium vestibulum. Duis maximus, tortor et sodales sagittis, ante nulla mattis felis, sit amet sollicitudin orci nisi a eros. Curabitur ac nibh condimentum risus euismod vulputate sed non felis. Vivamus eget purus interdum, euismod nisi sed, maximus ante. Nam magna erat, condimentum id posuere vel, suscipit vel ante. Praesent vel faucibus tortor. Cras sit amet nulla tempus, ultricies velit tristique, interdum tellus. Mauris in commodo orci. Pellentesque sapien libero, tempus in tincidunt nec, accumsan id sem.

Food for thought, we hope?!


Previous relevant CSS3 Border Image Primer Tutorial is shown below.

CSS3 Border Image Primer Tutorial

CSS3 Border Image Primer Tutorial

Adding to our recent CSS3 Filters Primer Tutorial, today, we’d like to delve further into the great things CSS3 brought to the client side “aesthetics” of web application work. Today’s “proof of concept” web application’s topic is border images. How often when developing a webpage or blog post via HTML, if you are into that kind of thangthing, have you wanted to enhance something and make it stand out, but were satisfied enough with its content? Lots, I’d imagine, and perhaps you put a normal border around it from the CSS days. That can be impactive, and there are lots of styling choices here. But what if you wanted to “theme” the content via the “look” of its border? You can pattern a normal border via dashed and dotted styles, and other methods, but unless the content is about Morse Code, or some such content, it is unlikely there, that you have “themed” your content to align with the “look” of your border. That is where CSS3’s border images can come to the fore. Today, we don’t “theme” and match with the “look”, as we just try to make things “stand out”, and this can be good with these border image styling approaches too.

Researching this topic, we lobbed onto the great resource that TutorialsPoint provides and based our HTML and CSS3 and Javascript live run‘s border_image.html source code off their example code, so thanks.

You’ll see the border image CSS3 parts to this proof of concept code below …


<style>
#borderimg1 {
border: 10px solid transparent;
padding: 15px;
border-image-source: url(body_systems.jpg);
border-image-repeat: round;
border-image-slice: 30;
border-image-width: 10px;

height:150px;
background-color: yellow;
text-align: center;
}
#borderimg2 {
border: 10px solid transparent;
padding: 15px;
border-image-source: url(body_systems.jpg);
border-image-repeat: round;
border-image-slice: 30;
border-image-width: 20px;

height:150px;
background-color: yellow;
text-align: center;
}
#borderimg3 {
border: 10px solid transparent;
padding: 15px;
border-image-source: url(body_systems.jpg);
border-image-repeat: round;
border-image-slice: 30;
border-image-width: 30px;

height:150px;
background-color: yellow;
text-align: center;
}
</style>

… which sets up the “static” first up scenario, but to add some randomness into the web application workings, we use some Javascript DOM (kicked off via a document.body onload event call and then perpetuated by good ol’ setTimeout method calls) as below to make the web application more dynamic, using images used with our “one image webpage” Ephemeral


function randomize() {
var choice=Math.floor(Math.random() * border_images.length);
document.getElementById('borderimg1').style.borderImageSource="url(" + border_images[choice] + ")";
choice=Math.floor(Math.random() * 100);
document.getElementById('borderimg1').style.borderImageWidth='' + choice + 'px';
choice=Math.floor(Math.random() * 100);
document.getElementById('borderimg1').style.borderImageSlice='' + choice;
document.getElementById('borderimg1').style.backgroundColor='rgba(' + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," + eval(Math.floor(Math.random() * 10) / 10) + ")";
choice=Math.floor(Math.random() * border_images.length);
document.getElementById('borderimg2').style.borderImageSource="url(" + border_images[choice] + ")";
choice=Math.floor(Math.random() * 100);
document.getElementById('borderimg2').style.borderImageWidth='' + choice + 'px';
choice=Math.floor(Math.random() * 100);
document.getElementById('borderimg2').style.borderImageSlice='' + choice;
document.getElementById('borderimg2').style.backgroundColor='rgba(' + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," + eval(Math.floor(Math.random() * 10) / 10) + ")";
choice=Math.floor(Math.random() * border_images.length);
document.getElementById('borderimg3').style.borderImageSource="url(" + border_images[choice] + ")";
choice=Math.floor(Math.random() * 100);
document.getElementById('borderimg3').style.borderImageWidth='' + choice + 'px';
choice=Math.floor(Math.random() * 100);
document.getElementById('borderimg3').style.borderImageSlice='' + choice;
document.getElementById('borderimg3').style.backgroundColor='rgba(' + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," + eval(Math.floor(Math.random() * 10) / 10) + ")";
setTimeout(randomize, 5000);
}

We hope this “aesthetic” is something you might be interested in applying, on occasions, to your blog postings or webpages yourself.

You can also see this play out at WordPress 4.1.1’s CSS3 Border Image Primer Tutorial.


Previous relevant CSS3 Filters Primer Tutorial is shown below.

CSS3 Filters Primer Tutorial

CSS3 Filters Primer Tutorial

It’s not just the image editor Gimp that has “filters” as tools to create effects with image data (files), as you might see with tutorials like Gimp Decor Filters Revisit Tutorial. These days, with CSS, and with CSS3 these days, there are some great “filters” to play around with, that modify an image there and then with CSS and/or Javascript DOM (as per the HTML select “dropdown” element onchange event logic …


function selchange(selo) {
var bs="";
if (selo == null) {
if (document.getElementById("sh-shadow").value != "" && document.getElementById("sv-shadow").value != "") {
if (document.getElementById("xblur").value != "") bs+=document.getElementById("xblur").value + document.getElementById("xblur").title + " ";
if (document.getElementById("sspread").value != "") bs+=document.getElementById("sspread").value + document.getElementById("sspread").title + " ";
//alert("drop-shadow(" + document.getElementById("sh-shadow").value + document.getElementById("sh-shadow").title + " " + document.getElementById("sv-shadow").value + document.getElementById("sv-shadow").title + " " + bs + document.getElementById("mycolour").value + ")");
document.getElementById("myimage").style.filter = "drop-shadow(" + document.getElementById("sh-shadow").value + document.getElementById("sh-shadow").title + " " + document.getElementById("sv-shadow").value + document.getElementById("sv-shadow").title + " " + bs + document.getElementById("mycolour").value + ")";
document.getElementById("myimage").style.WebkitFilter = "drop-shadow(" + document.getElementById("sh-shadow").value + document.getElementById("sh-shadow").title + " " + document.getElementById("sv-shadow").value + document.getElementById("sv-shadow").title + " " + bs + document.getElementById("mycolour").value + ")";
}
} else if (selo.id.substring(1) == 'h-shadow') {
if (document.getElementById("sv-shadow").value != "") {
if (document.getElementById("xblur").value != "") bs+=document.getElementById("xblur").value + document.getElementById("xblur").title + " ";
if (document.getElementById("sspread").value != "") bs+=document.getElementById("sspread").value + document.getElementById("sspread").title + " ";
document.getElementById("myimage").style.filter = "drop-shadow(" + selo.value + selo.title + " " + document.getElementById("sv-shadow").value + document.getElementById("sv-shadow").title + " " + bs + document.getElementById("mycolour").value + ")";
document.getElementById("myimage").style.WebkitFilter = "drop-shadow(" + selo.value + selo.title + " " + document.getElementById("sv-shadow").value + document.getElementById("sv-shadow").title + " " + bs + document.getElementById("mycolour").value + ")";
}
} else if (selo.id.substring(1) == 'v-shadow') {
if (document.getElementById("sh-shadow").value != "") {
if (document.getElementById("xblur").value != "") bs+=document.getElementById("xblur").value + document.getElementById("xblur").title + " ";
if (document.getElementById("sspread").value != "") bs+=document.getElementById("sspread").value + document.getElementById("sspread").title + " ";
//alert("drop-shadow(" + document.getElementById("sh-shadow").value + document.getElementById("sh-shadow").title + " " + selo.value + selo.title + " " + bs + document.getElementById("mycolour").value + ")");
document.getElementById("myimage").style.filter = "drop-shadow(" + document.getElementById("sh-shadow").value + document.getElementById("sh-shadow").title + " " + selo.value + selo.title + " " + bs + document.getElementById("mycolour").value + ")";
document.getElementById("myimage").style.WebkitFilter = "drop-shadow(" + document.getElementById("sh-shadow").value + document.getElementById("sh-shadow").title + " " + selo.value + selo.title + " " + bs + document.getElementById("mycolour").value + ")";
}
} else if (selo.id == 'xblur') {
if (document.getElementById("sh-shadow").value != "" && document.getElementById("sv-shadow").value != "") {
if (document.getElementById("xblur").value != "") bs+=document.getElementById("xblur").value + document.getElementById("xblur").title + " ";
if (document.getElementById("sspread").value != "") bs+=document.getElementById("sspread").value + document.getElementById("sspread").title + " ";
document.getElementById("myimage").style.filter = "drop-shadow(" + document.getElementById("sh-shadow").value + document.getElementById("sh-shadow").title + " " + document.getElementById("sv-shadow").value + document.getElementById("sv-shadow").title + " " + bs + document.getElementById("mycolour").value + ")";
document.getElementById("myimage").style.WebkitFilter = "drop-shadow(" + document.getElementById("sh-shadow").value + document.getElementById("sh-shadow").title + " " + document.getElementById("sv-shadow").value + document.getElementById("sv-shadow").title + " " + bs + document.getElementById("mycolour").value + ")";
}
} else if (selo.id.substring(1) == 'spread') {
if (document.getElementById("sh-shadow").value != "" && document.getElementById("sv-shadow").value != "") {
if (document.getElementById("xblur").value != "") bs+=document.getElementById("xblur").value + document.getElementById("xblur").title + " ";
if (document.getElementById("sspread").value != "") bs+=document.getElementById("sspread").value + document.getElementById("sspread").title + " ";
document.getElementById("myimage").style.filter = "drop-shadow(" + document.getElementById("sh-shadow").value + document.getElementById("sh-shadow").title + " " + document.getElementById("sv-shadow").value + document.getElementById("sv-shadow").title + " " + bs + document.getElementById("mycolour").value + ")";
document.getElementById("myimage").style.WebkitFilter = "drop-shadow(" + document.getElementById("sh-shadow").value + document.getElementById("sh-shadow").title + " " + document.getElementById("sv-shadow").value + document.getElementById("sv-shadow").title + " " + bs + document.getElementById("mycolour").value + ")";
}
} else {
document.getElementById("myimage").style.filter = selo.id.substring(1) + "(" + selo.value + selo.title + ")";
document.getElementById("myimage").style.WebkitFilter = selo.id.substring(1) + "(" + selo.value + selo.title + ")";
}
}

) … or jQuery means by which to make this happen with a lot of the modern web browsers. If you see “CSS3” mentioned, then don’t expect everything to work on super-old web browsers, but expect that anything you implement could be aesthetically interesting or pleasing, as it would not have taken until CSS3 to come along if it was a dead set simple thing to have implemented in the early days of the internet.

Today’s simple (really) proof of concept web application owes a debt of gratitude to this very useful link, which gave us the parameters by which we could construct today’s live run with its pretty simple HTML and CSS (via CSS3) and Javascript DOM css_filters.html source code for you to peruse, and make of what you will. So what (CSS3) filters are we talking about here?

  • blur(px)
  • brightness(%)
  • contrast(%)
  • drop-shadow(h-shadow v-shadow blur spread color)
  • grayscale(%)
  • hue-rotate(deg)
  • invert(%)
  • opacity(%)
  • saturate(%)
  • sepia(%)

… which are mostly self explanatory we hope. Let’s just say you’re me … “You’re me.” … ta … please explain “drop shadow” … oh … you mean … me?

In graphic design, a drop shadow is a visual effect consisting of a drawing element which looks like the shadow of an object, giving the impression that the object is raised above the objects behind it.

… thanks, Wikipedia.

As you can imagine, this opening up of this functionality to the client-side web developer opens up lots of opportunities to make your webpages stand out.


Previous relevant Gimp Decor Filters Revisit Tutorial is shown below.

Gimp Decor Filters Revisit Tutorial

Gimp Decor Filters Revisit Tutorial

Today we return to the wonderful, marvellous and stupendous Gimp image editor and examine some more of its filters, following up on concepts last discussed with Gimp Decor Border Filters Primer Tutorial in the “Decor” category, namely …

  • Fuzzy Border
  • Coffee Stain
  • Old Photo … in the tutorial picture … plus below …
  • Add Bevel
  • Add Border
  • Slide
  • Rounded Corners

… which create quite good effects we feel, especially the Fuzzy Border filter, as it is quite difficult, otherwise to create a “smudged” border effect, perhaps for vignetting purposes, without this filter. We imagine an old map photo could be glamourized using “Coffee Stain” (for the accident prone) or “Old Photo”.

These “Decor” filters are available off Gimp’s Filter menu as a submenu containing these and some other effects. They use “Script-Fu” based on the Scheme interpretive language. These “Script-Fu” filters are not only powerful and useful for what they are, but also for how you can introduce predictability with your effects, in that you can record settings you use, make them public, as necessary, to help create a unified creative but predictable set of effects in the photographs you are applying filters to.

So we’ll leave you with a photo of our house …

… with …

  • Fuzzy Border …
  • Coffee Stain (“Darken only” unchecked) … probably not so apt for this image’s subject matter …
  • Old Photo (“Defocus”, “Sepia”, “Mottle” all checked) …
  • Add Bevel (30, “Keep bump layer” checked) …
  • Add Border (37 x and 37 y width, 85 delta value on default blue colour) …
  • Slide (62) …
  • Rounded Corners (Edge radius 30, Shadow x offset 15, y 15, Blur radius 25) …

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


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


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


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


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

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