forked from jeromeetienne/threex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
THREEx.screenshot.js
130 lines (113 loc) · 3.86 KB
/
THREEx.screenshot.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/** @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 onLoad = 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)
}.bind(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 onKeyPress = 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);
}
}.bind(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
};
})();