浏览代码

feat: icon save

gemercheung 1 年之前
父节点
当前提交
8fb1ee05fd
共有 2 个文件被更改,包括 102 次插入0 次删除
  1. 11 0
      src/core/Scene.js
  2. 91 0
      src/core/utils/cap.js

+ 11 - 0
src/core/Scene.js

@@ -5,6 +5,7 @@ import BoxManager from "./box/BoxManager.js";
 import { Mitt } from "./mitt.js";
 import testData from "./save.json";
 import { dataURItoBlob, saveFile } from "./utils/utils.js";
+import { screenshotObject } from "./utils/cap.js";
 
 const stats = new Stats();
 
@@ -293,6 +294,16 @@ export default class Scene extends Mitt {
       }
     }
   }
+  test() {
+    const object = this.boxManager.model;
+    const box = new THREE.Box3().setFromObject(object);
+    let size = new THREE.Vector3();
+    box.getSize(size);
+    const distance = this.orthCamera.position.distanceTo(object.position);
+    console.log("size", size);
+    console.log("distance", distance);
+    new screenshotObject(object, this.orthCamera, this.renderer);
+  }
 
   onBindEvent = () => {
     window.addEventListener("resize", this.onResize, false);

+ 91 - 0
src/core/utils/cap.js

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