cap.js 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import * as THREE from "three";
  2. export function screenshotObject(obj, camera, renderer) {
  3. this.obj = obj;
  4. this.camera = camera;
  5. this.renderer = renderer;
  6. this.box = new THREE.Box3().setFromObject(obj);
  7. this.size = { w: 0, h: 0 };
  8. this.pos = { x: 0, y: 0 };
  9. var distance = this.distance();
  10. this.size = this.getSizeInPixel(distance);
  11. this.pos = this.getPositionInPixel();
  12. this.getImage(this.size.w, this.size.h, this.pos.x, this.pos.y);
  13. }
  14. screenshotObject.prototype.distance = function () {
  15. var self = this;
  16. var size = new THREE.Vector3();
  17. self.box.getSize(size);
  18. var z = self.camera.position.z - self.obj.position.z - size.z / 2;
  19. // or use self.camera.position.distanceTo( self.obj.position );
  20. return z;
  21. };
  22. screenshotObject.prototype.getSizeInPixel = function (distance) {
  23. var self = this;
  24. var size = new THREE.Vector3();
  25. self.box.getSize(size);
  26. // Calc visible height and width
  27. var vFOV = THREE.Math.degToRad(self.camera.fov); // convert vertical fov to radians
  28. var height = 2 * Math.tan(vFOV / 2) * Math.abs(distance); // visible height
  29. var width =
  30. height * (self.renderer.domElement.width / self.renderer.domElement.height); // visible width
  31. // Calc ratio between pixel and visible z-unit of threejs
  32. var ratio = self.renderer.domElement.height / height;
  33. var width = size.x * ratio;
  34. var height = size.y * ratio;
  35. return { w: width, h: height };
  36. };
  37. screenshotObject.prototype.getPositionInPixel = function () {
  38. var self = this;
  39. var vector = new THREE.Vector3();
  40. var viewProjectionMatrix = new THREE.Matrix4();
  41. var viewMatrix = new THREE.Matrix4();
  42. viewMatrix.copy(self.camera.matrixWorldInverse);
  43. viewProjectionMatrix.multiplyMatrices(
  44. self.camera.projectionMatrix,
  45. viewMatrix
  46. );
  47. var widthHalf = 0.5 * self.renderer.domElement.width;
  48. var heightHalf = 0.5 * self.renderer.domElement.height;
  49. self.obj.updateMatrixWorld();
  50. vector.setFromMatrixPosition(self.obj.matrixWorld);
  51. //vector.project(camera);
  52. vector.applyMatrix4(viewProjectionMatrix);
  53. vector.x = vector.x * widthHalf + widthHalf;
  54. vector.y = -(vector.y * heightHalf) + heightHalf;
  55. var x = vector.x - self.size.w / 2;
  56. var y = vector.y - self.size.h / 2;
  57. return { x: x, y: y };
  58. };
  59. screenshotObject.prototype.getImage = function (w, h, x, y) {
  60. var self = this;
  61. var oldCanvas = self.renderer.domElement;
  62. var newCanvas = document.createElement("canvas");
  63. newCanvas.width = w;
  64. newCanvas.height = h;
  65. var newContext = newCanvas.getContext("2d");
  66. newContext.drawImage(oldCanvas, x, y, w, h, 0, 0, w, h);
  67. var fileName = "test.png";
  68. var strMime = "image/png";
  69. var strDownloadMime = "image/octet-stream";
  70. var imgData = newCanvas.toDataURL(strMime);
  71. var base64str = imgData.replace(strMime, strDownloadMime);
  72. var link = document.createElement("a");
  73. if (typeof link.download === "string") {
  74. document.body.appendChild(link); //Firefox requires the link to be in the body
  75. link.download = fileName;
  76. link.href = base64str;
  77. link.click();
  78. document.body.removeChild(link); //remove the link when done
  79. } else {
  80. window.location.replace(uri);
  81. }
  82. };