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); } };