<!doctype html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Canvas createPattern Video Proof of Concept - c ... thanks to https://books.google.com.au/books?id=IxhnNqaaW_IC&pg=PA183&dq=canvas+createPattern+video+example&hl=en&sa=X&ved=0ahUKEwjIkvP5hKjpAhUXzjgGHWmgA7cQ6AEIKDAA#v=onepage&q=canvas%20createPattern%20video%20example&f=false</title>
<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>
</head>
<body>
<h1>Canvas createPattern Video Proof of Concept</h1>
<h3>Canvas createPattern Video Proof of Concept</h3>
<h4>Thanks to <a target=_blank title='The Definitive Guide to HTML5 Video' href='//books.google.com.au/books?id=IxhnNqaaW_IC&pg=PA183&dq=canvas+createPattern+video+example&hl=en&sa=X&ved=0ahUKEwjIkvP5hKjpAhUXzjgGHWmgA7cQ6AEIKDAA#v=onepage&q=canvas%20createPattern%20video%20example&f=false'>The Definitive Guide to HTML5 Video</a></h4>
<table style=width:100%;>
<tr><th style='text-align:left;border:1px solid green;background-color:yellow;'><a style="cursor:pointer;text-decoration:underline;" onclick="askv();">Video</a> <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><font size=1>... <a style='cursor:pointer;text-decoration:underline;' onclick='video.click();'>click video below to see it played in Canvas</a> ...</font></th><th style='text-align:left;border:1px solid green;background-color:pink;'>Canvas <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> W <input style='width:40px;' type=number onblur='iwis=eval(this.value); scratch.width=iwis; if (iwis > wis) { wis=iwis; canvas.width=wis; }' onchange='iwis=eval(this.value); scratch.width=iwis; if (iwis > wis) { wis=iwis; canvas.width=wis; }' value='108' min=0 step=1></input> x H <input style='width:40px;' type=number onblur='ihis=eval(this.value); scratch.height=ihis; if (ihis > his) { his=ihis; canvas.height=his; }' onchange='ihis=eval(this.value); scratch.height=ihis; if (ihis > his) { his=ihis; canvas.height=his; }' value='192' min=0 step=1></input></th></tr>
<tr><td style='background-color:#f0f0f0;vertical-align:top;'>
<div id=dvideo>
<script type='text/javascript'>
document.write("<video id=vvideo data-style=display:none; controls><source id=vsource src=" + vnameis + " type=" + ourmimetype + "></video>");
</script>
</div>
</td><td style='vertical-align:top;background-color:#f7f7f7;'>
<canvas width=540 height=960 style="border:1px solid transparent;float:top;"></canvas>
<canvas id=scratch width=108 height=192 style="display:none;border:1px solid black;float:top;"></canvas>
</td></tr>
</table>
<script type='text/javascript'>
var wis=540, his=960; // 1080 x 1920
var iwis=108, ihis=192;
var rep='repeat';
var inversev=false, grayscalev=false;
var doflip=false, doflop=false;
var qangle='-0.0', dorotate=false;
var cfile=null, mfile=null;
window.onload = function() {
initCanvas();
}
var context, sctxt, video;
var found=false;
function lookfor() {
if (!found) {
if (document.getElementById('cvideo').value != "") {
document.getElementById('vbut').click();
} else {
setTimeout(lookfor, 1000);
}
}
}
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();
found=false;
lookfor();
} else {
location.href=document.URL.split('#')[0].split('?')[0] + '?vurl=' + encodeURIComponent(vurl);
}
}
}
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;
}
function initCanvas() {
video = document.getElementsByTagName("video")[0];
canvas = document.getElementsByTagName("canvas")[0];
context = canvas.getContext("2d");
scratch = document.getElementById("scratch");
sctxt = scratch.getContext("2d");
video.addEventListener("play", paintFrame, false);
if (video.readyState >= video.HAVE_METADATA) {
startPlay();
} else {
video.addEventListener("loadmetadata", startPlay, false);
}
}
function startPlay() {
video.play();
}
function inverse(ioo, ione, itwo, ithree, ifour, ifive, isix, iseven, ieight) { // thanks to https://www.w3schools.com/tags/canvas_getimagedata.asp
var i;
var imgData;
if (typeof ieight !== 'undefined') {
imgData=sctxt.getImageData(ione, itwo, ithree, ifour);
} else if (typeof isix !== 'undefined') {
imgData=sctxt.getImageData(ione, itwo, ithree, ifour);
} else {
imgData=sctxt.getImageData(ione, itwo, ithree, ifour);
}
var data = imgData.data;
for (i=0;i<data.length;i+=4) {
data[i]=eval(255 - data[i]);
data[i+1]=eval(255 - data[i+1]);
data[i+2]=eval(255 - data[i+2]);
//data[i+3]=eval(15); //255); // - data[i+3]);
}
sctxt.putImageData(imgData,ione, itwo);
}
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);
}
function grayscale(ioo, ione, itwo, ithree, ifour, ifive, isix, iseven, ieight) { // thanks to https://www.w3schools.com/tags/canvas_getimagedata.asp
var i;
var imgData;
if (typeof ieight !== 'undefined') {
imgData=sctxt.getImageData(ione, itwo, ithree, ifour);
} else if (typeof isix !== 'undefined') {
imgData=sctxt.getImageData(ione, itwo, ithree, ifour);
} else {
imgData=sctxt.getImageData(ione, itwo, ithree, ifour);
}
var data = imgData.data;
for (i = 0; i < data.length; i += 4) {
var bright = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
data[i] = bright;
data[i + 1] = bright;
data[i + 2] = bright;
}
sctxt.putImageData(imgData,ione, itwo);
}
function readVBlob(opt_startByte, opt_stopByte) {
//alert(1);
var file = document.getElementById('cvideo').files[0];
//alert(2);
mfile = file;
//alert(3);
//var filen = mfile.name;
//alert('4 ' + file.type);
document.getElementById('vsource').type=mfile.type;
//alert(5);
var start = parseInt(opt_startByte) || 0;
//alert(6);
var stop = parseInt(opt_stopByte) || mfile.size - 1;
//alert(7);
var reader = new FileReader();
//alert(8);
// If we use onloadend, we need to check the readyState.
reader.onloadend = function(e) {
if (e.target.readyState == FileReader.DONE) { // DONE == 2
//alert('9 ' + e.target.result.substring(0,150));
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>';
//alert('10 ' + document.getElementById('vvideo').innerHTML.substring(0,250));
initCanvas();
}
};
var blob = mfile.slice(start, stop + 1);
reader.readAsDataURL(mfile); //blob);
}
function paintFrame() {
sctxt.drawImage(video, 0, 0, scratch.width, scratch.height);
if (inversev) {
inverse(video, 0, 0, scratch.width, scratch.height);
}
if (grayscalev) {
grayscale(video, 0, 0, scratch.width, scratch.height);
}
if (doflip) {
sctxt.setTransform(-1,0,0,1,scratch.width,0); // thanks to https://stackoverflow.com/questions/42844470/how-to-rotate-and-mirror-canvas-element
} else if (doflop) {
sctxt.setTransform(1,0,0,-1,0,scratch.height); // thanks to https://stackoverflow.com/questions/42844470/how-to-rotate-and-mirror-canvas-element
}
if (dorotate) {
crotate(video, 0, 0, scratch.width, scratch.height);
}
pattern = context.createPattern(scratch, rep.toLowerCase());
context.fillStyle = pattern;
context.fillRect(0, 0, wis, his);
if (video.paused || video.ended) {
return;
}
setTimeout(function () {
paintFrame();
}, 10);
}
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);
</script>
</body>
</html>