|
@@ -0,0 +1,91 @@
|
|
|
+import * as THREE from "three";
|
|
|
+
|
|
|
+export function screenshotObject(obj, camera, renderer) {
|
|
|
+ this.obj = obj;
|
|
|
+ this.camera = camera;
|
|
|
+ this.renderer = renderer;
|
|
|
+ this.box = new THREE.Box3().setFromObject(obj);
|
|
|
+ this.size = { w: 0, h: 0 };
|
|
|
+ this.pos = { x: 0, y: 0 };
|
|
|
+
|
|
|
+ var distance = this.distance();
|
|
|
+ this.size = this.getSizeInPixel(distance);
|
|
|
+ this.pos = this.getPositionInPixel();
|
|
|
+ this.getImage(this.size.w, this.size.h, this.pos.x, this.pos.y);
|
|
|
+}
|
|
|
+
|
|
|
+screenshotObject.prototype.distance = function () {
|
|
|
+ var self = this;
|
|
|
+ var size = new THREE.Vector3();
|
|
|
+ self.box.getSize(size);
|
|
|
+ var z = self.camera.position.z - self.obj.position.z - size.z / 2;
|
|
|
+ // or use self.camera.position.distanceTo( self.obj.position );
|
|
|
+ return z;
|
|
|
+};
|
|
|
+screenshotObject.prototype.getSizeInPixel = function (distance) {
|
|
|
+ var self = this;
|
|
|
+ var size = new THREE.Vector3();
|
|
|
+ self.box.getSize(size);
|
|
|
+
|
|
|
+ // Calc visible height and width
|
|
|
+ var vFOV = THREE.Math.degToRad(self.camera.fov); // convert vertical fov to radians
|
|
|
+ var height = 2 * Math.tan(vFOV / 2) * Math.abs(distance); // visible height
|
|
|
+ var width =
|
|
|
+ height * (self.renderer.domElement.width / self.renderer.domElement.height); // visible width
|
|
|
+ // Calc ratio between pixel and visible z-unit of threejs
|
|
|
+ var ratio = self.renderer.domElement.height / height;
|
|
|
+
|
|
|
+ var width = size.x * ratio;
|
|
|
+ var height = size.y * ratio;
|
|
|
+ return { w: width, h: height };
|
|
|
+};
|
|
|
+screenshotObject.prototype.getPositionInPixel = function () {
|
|
|
+ var self = this;
|
|
|
+ var vector = new THREE.Vector3();
|
|
|
+ var viewProjectionMatrix = new THREE.Matrix4();
|
|
|
+ var viewMatrix = new THREE.Matrix4();
|
|
|
+ viewMatrix.copy(self.camera.matrixWorldInverse);
|
|
|
+ viewProjectionMatrix.multiplyMatrices(
|
|
|
+ self.camera.projectionMatrix,
|
|
|
+ viewMatrix
|
|
|
+ );
|
|
|
+ var widthHalf = 0.5 * self.renderer.domElement.width;
|
|
|
+ var heightHalf = 0.5 * self.renderer.domElement.height;
|
|
|
+ self.obj.updateMatrixWorld();
|
|
|
+ vector.setFromMatrixPosition(self.obj.matrixWorld);
|
|
|
+ //vector.project(camera);
|
|
|
+ vector.applyMatrix4(viewProjectionMatrix);
|
|
|
+
|
|
|
+ vector.x = vector.x * widthHalf + widthHalf;
|
|
|
+ vector.y = -(vector.y * heightHalf) + heightHalf;
|
|
|
+
|
|
|
+ var x = vector.x - self.size.w / 2;
|
|
|
+ var y = vector.y - self.size.h / 2;
|
|
|
+ return { x: x, y: y };
|
|
|
+};
|
|
|
+screenshotObject.prototype.getImage = function (w, h, x, y) {
|
|
|
+ var self = this;
|
|
|
+ var oldCanvas = self.renderer.domElement;
|
|
|
+ var newCanvas = document.createElement("canvas");
|
|
|
+ newCanvas.width = w;
|
|
|
+ newCanvas.height = h;
|
|
|
+ var newContext = newCanvas.getContext("2d");
|
|
|
+ newContext.drawImage(oldCanvas, x, y, w, h, 0, 0, w, h);
|
|
|
+
|
|
|
+ var fileName = "test.png";
|
|
|
+ var strMime = "image/png";
|
|
|
+ var strDownloadMime = "image/octet-stream";
|
|
|
+ var imgData = newCanvas.toDataURL(strMime);
|
|
|
+ var base64str = imgData.replace(strMime, strDownloadMime);
|
|
|
+
|
|
|
+ var link = document.createElement("a");
|
|
|
+ if (typeof link.download === "string") {
|
|
|
+ document.body.appendChild(link); //Firefox requires the link to be in the body
|
|
|
+ link.download = fileName;
|
|
|
+ link.href = base64str;
|
|
|
+ link.click();
|
|
|
+ document.body.removeChild(link); //remove the link when done
|
|
|
+ } else {
|
|
|
+ window.location.replace(uri);
|
|
|
+ }
|
|
|
+};
|