define([ '/bower_components/tweetnacl/nacl-fast.min.js', ], function () { var Nacl = window.nacl; var Thumb = { dimension: 100, }; var supportedTypes = [ 'image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'video/', 'application/pdf' ]; Thumb.isSupportedType = function (type) { return supportedTypes.some(function (t) { return type.indexOf(t) !== -1; }); }; // create thumbnail image from metadata // return an img tag, or undefined if anything goes wrong Thumb.fromMetadata = function (metadata) { if (!metadata || typeof(metadata) !== 'object' || !metadata.thumbnail) { return; } try { var u8 = Nacl.util.decodeBase64(metadata.thumbnail); var blob = new Blob([u8], { type: 'image/png' }); var url = URL.createObjectURL(blob); var img = new Image(); img.src = url; img.width = Thumb.dimension; img.height = Thumb.dimension; return img; } catch (e) { console.error(e); return; } }; var getResizedDimensions = function (img, type) { var h = type === 'video' ? img.videoHeight : img.height; var w = type === 'video' ? img.videoWidth : img.width; var dim = Thumb.dimension; // if the image is too small, don't bother making a thumbnail if (h <= dim && w <= dim) { return null; } // the image is taller than it is wide, so scale to that. var r = dim / (h > w? h: w); // ratio var d; if (h > w) { var newW = Math.floor(w*r); d = Math.floor((dim - newW) / 2); return { x: d, w: newW, y: 0, h: dim, }; } else { var newH = Math.floor(h*r); d = Math.floor((dim - newH) / 2); return { x: 0, w: dim, y: d, h: newH }; } }; // assumes that your canvas is square // nodeback returning blob Thumb.fromCanvas = Thumb.fromImage = function (canvas, D, cb) { var c2 = document.createElement('canvas'); if (!D) { return void cb('TOO_SMALL'); } c2.width = Thumb.dimension; c2.height = Thumb.dimension; var ctx = c2.getContext('2d'); ctx.drawImage(canvas, D.x, D.y, D.w, D.h); c2.toBlob(function (blob) { cb(void 0, blob); }); }; Thumb.fromImageBlob = function (blob, cb) { var url = URL.createObjectURL(blob); var img = new Image(); img.onload = function () { var D = getResizedDimensions(img, 'image'); Thumb.fromImage(img, D, function (err, t) { if (err === 'TOO_SMALL') { return void cb(void 0, blob); } cb(err, t); }); }; img.onerror = function () { cb('ERROR'); }; img.src = url; }; Thumb.fromVideoBlob = function (blob, cb) { var url = URL.createObjectURL(blob); var video = document.createElement("VIDEO"); video.src = url; video.addEventListener('loadedmetadata', function() { video.currentTime = Number(Math.floor(Math.min(video.duration/10, 5))); video.addEventListener('loadeddata', function() { var D = getResizedDimensions(video, 'video'); Thumb.fromCanvas(video, D, cb); }); }); video.addEventListener('error', function (e) { console.error(e); cb('ERROR'); }); }; Thumb.fromPdfBlob = function (blob, cb) { require.config({paths: {'pdfjs-dist': '/common/pdfjs'}}); require(['pdfjs-dist/build/pdf'], function (PDFJS) { var url = URL.createObjectURL(blob); var makeThumb = function (page) { var vp = page.getViewport(1); var canvas = document.createElement("canvas"); canvas.width = canvas.height = Thumb.dimension; var scale = Math.min(canvas.width / vp.width, canvas.height / vp.height); canvas.width = Math.floor(vp.width * scale); canvas.height = Math.floor(vp.height * scale); return page.render({ canvasContext: canvas.getContext("2d"), viewport: page.getViewport(scale) }).promise.then(function () { return canvas; }); }; PDFJS.getDocument(url).promise .then(function (doc) { return doc.getPage(1).then(makeThumb).then(function (canvas) { canvas.toBlob(function (blob) { cb(void 0, blob); }); }); }).catch(function () { cb('ERROR'); }); }); }; Thumb.fromBlob = function (blob, cb) { if (blob.type.indexOf('video/') !== -1) { return void Thumb.fromVideoBlob(blob, cb); } if (blob.type.indexOf('application/pdf') !== -1) { return void Thumb.fromPdfBlob(blob, cb); } Thumb.fromImageBlob(blob, cb); }; Thumb.fromVideo = function (video, cb) { cb = cb; // WIP }; return Thumb; });