We’re adding some new functionality onto the recent HTML Canvas Video Display Primer Tutorial, that being …
- turn the “Video” hardcoded text, on the webpage … into an “a” link …
<a style="cursor:pointer;text-decoration:underline;" onclick="askv();">Video</a>
… calling on the Javascript function …
function askv() {
var vurl=prompt("Enter a video URL (if you click OK to blank entry we'll open a local file browse window).", "");
if (vurl != null) {
if (vurl == "") {
document.getElementById('cvideo').click(); // browse for video file on local device
found=false;
lookfor();
} else {
location.href=document.URL.split('#')[0].split('?')[0] + '?vurl=' + encodeURIComponent(vurl); // reload with video URL
}
}
}
- to allow for a “reload with video URL” …
<script type='text/javascript'>
var types = ["video/mp4","image/svg","audio/wav","audio/x-wav","audio/x-pn-realaudio","audio/x-mpegurl","audio/x-aiff","audio/mpeg","audio/mid",
"audio/basic","audio/ogg","video/x-sgi-movie","video/x-msvideo","video/quicktime","audio/mp3","video/mp4","video/mpeg",
"video/x-la-asf","video/ogg","video/webm","audio/mp4", "image/jpeg", "image/jpeg", "image/png", "image/gif", "image/bmp", "image/tif",
"text/html", "text/html", "text/html", "text/javascript", "text/css", "text/plain", "text/xml", "text/csv",
"application/vnd.ms-word", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/x-php", "application/pdf",
"application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.ms-powerpoint",
"application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"];
var exts = [".mp4",".svg",".wav",".wav",".ram",".m3u",".aiff",".mp3",".rmi",
".snd",".ogg",".movie",".avi",".mov",".mp3",".m4v",".mpeg",
".lsx",".ogv",".webm",".m4a", ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tif",
".htm", ".html", ".htmls", ".js", ".css", ".txt", ".xml", ".csv",
".doc", ".docx", ".php", ".pdf",
".pptx", ".ppt",
".xls", ".xlsx"];
var ourmimetype="";
var vnameis=location.search.split('vurl=')[1] ? decodeURIComponent(location.search.split('vurl=')[1].split('&')[0]) : 'ants_reversed.mp4';
for (var ji=0; ji<exts.length; ji++) {
if (("." + vnameis.split('.')[eval(-1 + vnameis.split('.').length)]).toLowerCase() == exts[ji].toLowerCase()) {
ourmimetype=types[ji];
}
}
</script>
… dovetailing with the new …
<script type='text/javascript'>
document.write("<video id=vvideo data-style=display:none; controls><source id=vsource src=" + vnameis + " type=" + ourmimetype + "></video>");
</script>
- to allow for a “browse for video file on local device” …
function lookfor() {
if (!found) {
if (document.getElementById('cvideo').value != "") {
document.getElementById('vbut').click();
} else {
setTimeout(lookfor, 1000);
}
}
}
…
<input style="display:none;" type="file" name="video" id="cvideo" accept="video/*"></input><span class=readVBytesButtons><button style=display:none; data-startbyte=0 data-endbyte=4>1-5</button><button style=display:none; data-startbyte=5 data-endbyte=14>6-15</button><button style=display:none; data-startbyte=6 data-endbyte=7>7-8</button><button id=vbut style=background-color:pink;display:none;>Video Process</button></span>
…
document.querySelector('.readVBytesButtons').addEventListener('click', function(evt) {
if (evt.target.tagName.toLowerCase() == 'button') {
var startByte = evt.target.getAttribute('data-startbyte');
var endByte = evt.target.getAttribute('data-endbyte');
readVBlob(startByte, endByte);
}
}, false);
…
var mfil=null;
function readVBlob(opt_startByte, opt_stopByte) {
var file = document.getElementById('cvideo').files[0];
mfile = file;
document.getElementById('vsource').type=mfile.type;
var start = parseInt(opt_startByte) || 0;
var stop = parseInt(opt_stopByte) || mfile.size - 1;
var reader = new FileReader();
// If we use onloadend, we need to check the readyState.
reader.onloadend = function(e) {
if (e.target.readyState == FileReader.DONE) { // DONE == 2
document.getElementById('dvideo').innerHTML='<video id=vvideo data-style=display:none; controls><source id=vsource type=' + document.getElementById('vsource').type + ' src="' + e.target.result + '"></source></video>';
initCanvas();
}
};
var blob = mfile.slice(start, stop + 1);
reader.readAsDataURL(mfile); //blob);
}
- to allow for some changed …
HTML
<select onchange="qangle='-0.0'; dorotate=false; inversev=false; grayscalev=false; doflip=false; doflop=false; rep=scratchit(this.value);"><option value='repeat'>Repeat</option><option value='no-repeat'>No Repeat</option><option value='Repeat'>Grayscale Repeat</option><option value='No-repeat'>Grayscale No Repeat</option><option value='rEpeat'>Inverse Repeat</option><option value='nO-repeat'>Inverse No Repeat</option><option value='repEat'>Flip Repeat</option><option value='no-Repeat'>Flip No Repeat</option><option value='repeAt'>Flop Repeat</option><option value='no-rEpeat'>Flop No Repeat</option><option value='repeaT'>Rotate Repeat</option><option value='no-rePeat'>Rotate No Repeat</option></select>
Javascript initializations ...
var inversev=false, grayscalev=false;
var doflip=false, doflop=false;
var qangle='-0.0', dorotate=false;
Javascript changed function ...
function scratchit(inr) {
if (('' + inr).toLowerCase().indexOf('no-') == 0) {
scratch.width = eval('' + iwis);
scratch.height = eval('' + ihis);
}
if (('' + inr + ' ').substring(0,1) == ('' + inr + ' ').substring(0,1).toUpperCase()) {
grayscalev=true;
} else if (('' + inr + ' ').substring(1).substring(0,1) == ('' + inr + ' ').substring(1).substring(0,1).toUpperCase()) {
inversev=true;
} else if (('' + inr + ' ').substring(3).substring(0,1) == ('' + inr + ' ').substring(3).substring(0,1).toUpperCase()) {
doflip=true;
} else if (('' + inr + ' ').substring(4).substring(0,1) == ('' + inr + ' ').substring(4).substring(0,1).toUpperCase()) {
doflop=true;
} else if (('' + inr + ' ').substring(5).substring(0,1) == ('' + inr + ' ').substring(5).substring(0,1).toUpperCase()) {
if (qangle == '-0.0') { qangle=prompt('How many degrees rotation do you want?', ''); if (qangle == null) { qanghle='-0.0'; } }
if (qangle.replace('-0.0','').trim() != '') { dorotate=true; } else { dorotate=false; }
}
return inr;
}
… canvas data Filtering …- Grayscale (in similar way to Feedback Annotation Canvas Image Filter Tutorial)
- Inverse (in similar way to Feedback Annotation Canvas Image Filter Tutorial)
- Flip (in similar way to Feedback Annotation Canvas Image Filter Tutorial)
- Flop (in similar way to Feedback Annotation Canvas Image Filter Tutorial)
- Rotated Canvas …
function crotate(ioo, ione, itwo, ithree, ifour, ifive, isix, iseven, ieight) { // thanks to https://www.w3schools.com/tags/canvas_getimagedata.asp
var qcos=Math.cos(qangle * Math.PI / 180);
var qsin=Math.sin(qangle * Math.PI / 180);
sctxt.transform(qcos, qsin, -qsin, qcos, 0, 0);
context.transform(qcos, qsin, -qsin, qcos, 0, 0);
}
You can retry for yourself at the changed canvas_createpattern_video.html‘s live run link.
Previous relevant HTML Canvas Video Display Primer Tutorial is shown below.
In doing the research for yesterday’s HTML Canvas Pros and Cons Inline HTML Email Tutorial‘s heavy use of the stupendous HTML(5) canvas element we came upon a very interesting discovery, at least for us, that being the HTML canvas createPattern() Method. Have you read this webpage yet? Did you notice …
Definition and Usage
The createPattern() method repeats the specified element in the specified direction.
The element can be an image, video, or another <canvas> element.
The repeated element can be used to draw/fill rectangles, circles, lines etc.
? So modestly put, in a list like that, but the implications so big, would you not say … eh wot, guv’?!
No examples followed, alas, but a scouring of the “net” arrived at The Definitive Guide to HTML5 Video (ISBN: 978-1-4302-3091-5) mention on a Google search, thanks everyone!
This gave us great scope for a proof of concept web application we got going so long as we clicked (and so the video becomes visible) on the controls of a video element (to play it), as is now the go with a lot of platforms, when it comes to working with (and amongst) media forms. A video plays, and the canvas createPattern helps project “repeat” or “no-repeat” (controllable to user, a concept similar to how background images can work) onto the right hand table cell’s canvas via a hidden smaller canvas conduit, the widths and heights controllable to the user as well (all the way to, perhaps, having the canvas be bigger than the video, and so zoom into it (and maybe zoom out the screen) as you can see with today’s animated GIF tutorial picture). In that tutorial picture, also take a quick skeg at macOS two finger gesture’s video “Picture in Picture” functionality, too.
Pretty interesting start to a journey we think there’ll be more to talk about into the future. You can try for yourself at the “proof of concept” canvas_createpattern_video.html‘s live run link.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.