132 lines
4 KiB
JavaScript
132 lines
4 KiB
JavaScript
/** @namespace */
|
|
var THREEx = THREEx || {};
|
|
|
|
// TODO http://29a.ch/2011/9/11/uploading-from-html5-canvas-to-imgur-data-uri
|
|
// able to upload your screenshot without running servers
|
|
|
|
// forced closure
|
|
(function(){
|
|
|
|
/**
|
|
* Take a screenshot of a renderer
|
|
* - require WebGLRenderer to have "preserveDrawingBuffer: true" to be set
|
|
* - TODO is it possible to check if this variable is set ? if so check it
|
|
* and make advice in the console.log
|
|
* - maybe with direct access to the gl context...
|
|
*
|
|
* @param {Object} renderer to use
|
|
* @param {String} mimetype of the output image. default to "image/png"
|
|
* @param {String} dataUrl of the image
|
|
*/
|
|
var toDataURL = function(renderer, mimetype)
|
|
{
|
|
mimetype = mimetype || "image/png";
|
|
var dataUrl = renderer.domElement.toDataURL(mimetype);
|
|
return dataUrl;
|
|
}
|
|
|
|
/**
|
|
* resize an image to another resolution while preserving aspect
|
|
*
|
|
* @param {String} srcUrl the url of the image to resize
|
|
* @param {Number} dstWidth the destination width of the image
|
|
* @param {Number} dstHeight the destination height of the image
|
|
* @param {Number} callback the callback to notify once completed with callback(newImageUrl)
|
|
*/
|
|
var _aspectResize = function(srcUrl, dstW, dstH, callback){
|
|
// to compute the width/height while keeping aspect
|
|
var cpuScaleAspect = function(maxW, maxH, curW, curH){
|
|
var ratio = curH / curW;
|
|
if( curW >= maxW && ratio <= 1 ){
|
|
curW = maxW;
|
|
curH = maxW * ratio;
|
|
}else if(curH >= maxH){
|
|
curH = maxH;
|
|
curW = maxH / ratio;
|
|
}
|
|
return { width: curW, height: curH };
|
|
}
|
|
// callback once the image is loaded
|
|
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
|
var onLoad = __bind(function(){
|
|
// init the canvas
|
|
var canvas = document.createElement('canvas');
|
|
canvas.width = dstW; canvas.height = dstH;
|
|
var ctx = canvas.getContext('2d');
|
|
|
|
// TODO is this needed
|
|
ctx.fillStyle = "black";
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
|
// scale the image while preserving the aspect
|
|
var scaled = cpuScaleAspect(canvas.width, canvas.height, image.width, image.height);
|
|
|
|
// actually draw the image on canvas
|
|
var offsetX = (canvas.width - scaled.width )/2;
|
|
var offsetY = (canvas.height - scaled.height)/2;
|
|
ctx.drawImage(image, offsetX, offsetY, scaled.width, scaled.height);
|
|
|
|
// dump the canvas to an URL
|
|
var mimetype = "image/png";
|
|
var newDataUrl = canvas.toDataURL(mimetype);
|
|
// notify the url to the caller
|
|
callback && callback(newDataUrl)
|
|
}, this);
|
|
|
|
// Create new Image object
|
|
var image = new Image();
|
|
image.onload = onLoad;
|
|
image.src = srcUrl;
|
|
}
|
|
|
|
|
|
// Super cooked function: THREEx.Screenshot.bindKey(renderer)
|
|
// and you are done to get screenshot on your demo
|
|
|
|
/**
|
|
* Bind a key to renderer screenshot
|
|
*/
|
|
var bindKey = function(renderer, opts){
|
|
// handle parameters
|
|
opts = opts || {};
|
|
var charCode = opts.charCode || 'p'.charCodeAt(0);
|
|
var width = opts.width;
|
|
var height = opts.height;
|
|
var callback = opts.callback || function(url){
|
|
window.open(url, "name-"+Math.random());
|
|
};
|
|
|
|
// callback to handle keypress
|
|
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
|
var onKeyPress = __bind(function(event){
|
|
// return now if the KeyPress isnt for the proper charCode
|
|
if( event.which !== charCode ) return;
|
|
// get the renderer output
|
|
var dataUrl = this.toDataURL(renderer);
|
|
|
|
if( width === undefined && height === undefined ){
|
|
callback( dataUrl )
|
|
}else{
|
|
// resize it and notify the callback
|
|
// * resize == async so if callback is a window open, it triggers the pop blocker
|
|
_aspectResize(dataUrl, width, height, callback);
|
|
}
|
|
}, this);
|
|
|
|
// listen to keypress
|
|
// NOTE: for firefox it seems mandatory to listen to document directly
|
|
document.addEventListener('keypress', onKeyPress, false);
|
|
|
|
return {
|
|
unbind : function(){
|
|
document.removeEventListener('keypress', onKeyPress, false);
|
|
}
|
|
};
|
|
}
|
|
|
|
// export it
|
|
THREEx.Screenshot = {
|
|
toDataURL : toDataURL,
|
|
bindKey : bindKey
|
|
};
|
|
})();
|