Pārlūkot izejas kodu

feat: 文字增加换行

gemercheung 1 gadu atpakaļ
vecāks
revīzija
9093512f42

+ 33 - 0
src/core/Scene.js

@@ -6,6 +6,19 @@ import { Mitt } from "./mitt.js";
 import testData from "./save.json";
 const stats = new Stats();
 
+const saveFile = function (strData, filename) {
+  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 = strData;
+    link.click();
+    document.body.removeChild(link); //remove the link when done
+  } else {
+    location.replace(uri);
+  }
+};
+
 export default class Scene extends Mitt {
   constructor(domElement) {
     super();
@@ -26,6 +39,7 @@ export default class Scene extends Mitt {
         canvas: this.domElement,
         antialias: true,
         autoClear: true,
+        preserveDrawingBuffer: true,
       });
 
       this.width = this.domElement.clientWidth;
@@ -163,6 +177,25 @@ export default class Scene extends Mitt {
   editing(item) {
     this.player.editing(item);
   }
+
+  screenshot() {
+    var imgData, imgNode;
+    const times = 4;
+    this.orthCamera.zoom = 230;
+
+    this.renderer.setSize(this.width * times, this.height * times);
+    this.orthCamera.aspect = this.width / this.height;
+
+    // this.player.floorplanControls.minZoom = 1;
+    // this.orthCamera.zoom = 50;
+    this.orthCamera.updateProjectionMatrix();
+    this.renderer.render(this.scene, this.orthCamera, null, false);
+
+    const dataURL = this.renderer.domElement.toDataURL("image/jpeg");
+
+    saveFile(dataURL, "test.jpg");
+    this.onResize(this.width, this.height);
+  }
   onBindEvent = () => {
     //window.addEventListener('resize', this.onResize)
   };

+ 54 - 0
src/core/box/object/PureTextLabel copy.js

@@ -0,0 +1,54 @@
+import * as THREE from "three";
+
+export default class PureTextLabel extends THREE.Mesh {
+  constructor(text, point, fontsize = 12, color = "#000000", id) {
+    let res = 2;
+    const width = 168 * res;
+    const height = 50 * res;
+    var canvas = document.createElement("canvas");
+    canvas.width = width;
+    canvas.height = height;
+
+    let fontFamily = "Arial";
+    let fs = fontsize * res;
+    var context = canvas.getContext("2d");
+    context.fillStyle = "transparent";
+    context.rect(0, 0, width, height);
+    context.fill();
+    let fontStyle = "normal " + fs + "px " + fontFamily;
+    // console.log("fontStyle", fontStyle);
+    context.font = fontStyle;
+    context.fillStyle = color;
+    context.textAlign = "center";
+    context.textBaseline = "middle";
+    context.fillText(text, width / 2, height / 2);
+    const canvas_map = new THREE.Texture(canvas);
+    canvas_map.colorSpace = THREE.SRGBColorSpace;
+    canvas_map.needsUpdate = true;
+    canvas_map.anisotropy = 4;
+
+    const g = new THREE.PlaneGeometry(1.5, 0.44);
+    g.rotateX(-Math.PI / 2);
+
+    // const texture = new THREE.CanvasTexture(canvas_map);
+
+    const m = new THREE.MeshBasicMaterial({
+      map: canvas_map,
+      transparent: true, // 允许材质透明
+    });
+    super(g, m);
+    if (id) {
+      this.uuid = id;
+    }
+    const p = new THREE.Vector3().copy(point);
+    this.userData = {
+      id: this.uuid,
+      text: text,
+      color: color,
+      pos: p.toArray(),
+      fontsize: fontsize,
+    };
+    this.position.copy(p);
+    this.name = "pureText_" + text;
+  }
+}

+ 25 - 6
src/core/box/object/PureTextLabel.js

@@ -1,19 +1,31 @@
 import * as THREE from "three";
+import { getWrapText } from "../../utils/text";
 
 export default class PureTextLabel extends THREE.Mesh {
   constructor(text, point, fontsize = 12, color = "#000000", id) {
+    const radio = fontsize / 12;
+
+    let containerWidth = 1.5 * radio;
+    let containerHeight = 0.12 * radio;
+    const containerRadio = containerWidth / containerHeight;
     let res = 2;
-    const width = 168 * res;
-    const height = 50 * res;
+    const width = 168 * res * radio;
+    const height = width / containerRadio;
     var canvas = document.createElement("canvas");
     canvas.width = width;
     canvas.height = height;
 
     let fontFamily = "Arial";
-    let fs = fontsize * res;
+    let fs = 12 * res * radio;
     var context = canvas.getContext("2d");
+
+    const lines = getWrapText(context, text, 158);
+    console.log("lines", lines);
+    containerHeight = containerHeight * lines.length;
+    canvas.height = height * lines.length;
     context.fillStyle = "transparent";
-    context.rect(0, 0, width, height);
+    // context.fillStyle = "rgba(255,255,255,0.5)";
+    context.rect(0, 0, width, height * lines.length);
     context.fill();
     let fontStyle = "normal " + fs + "px " + fontFamily;
     // console.log("fontStyle", fontStyle);
@@ -21,13 +33,17 @@ export default class PureTextLabel extends THREE.Mesh {
     context.fillStyle = color;
     context.textAlign = "center";
     context.textBaseline = "middle";
-    context.fillText(text, width / 2, height / 2);
+    // context.fillText(text, width / 2, height / 2);
+    lines.forEach((txt, index) => {
+      context.fillText(txt, width / 2, height / 2 + height * index);
+    });
     const canvas_map = new THREE.Texture(canvas);
     canvas_map.colorSpace = THREE.SRGBColorSpace;
     canvas_map.needsUpdate = true;
     canvas_map.anisotropy = 4;
 
-    const g = new THREE.PlaneGeometry(1.5, 0.44);
+    const g = new THREE.PlaneGeometry(containerWidth, containerHeight);
+
     g.rotateX(-Math.PI / 2);
 
     // const texture = new THREE.CanvasTexture(canvas_map);
@@ -36,7 +52,9 @@ export default class PureTextLabel extends THREE.Mesh {
       map: canvas_map,
       transparent: true, // 允许材质透明
     });
+
     super(g, m);
+
     if (id) {
       this.uuid = id;
     }
@@ -49,6 +67,7 @@ export default class PureTextLabel extends THREE.Mesh {
       fontsize: fontsize,
     };
     this.position.copy(p);
+
     this.name = "pureText_" + text;
   }
 }

+ 14 - 0
src/core/utils/text.js

@@ -0,0 +1,14 @@
+export const getWrapText = (ctx, text = "", maxWidth = 200) => {
+  let txtList = [];
+  let str = "";
+  for (let i = 0, len = text.length; i < len; i++) {
+    str += text.charAt(i);
+    if (ctx.measureText(str).width > maxWidth) {
+      txtList.push(str.substring(0, str.length - 1));
+      str = "";
+      i--;
+    }
+  }
+  txtList.push(str);
+  return txtList;
+};

+ 2 - 2
vite.config.ts

@@ -10,8 +10,8 @@ if (process.argv.length > 3) {
 }
 
 const dev = true;
-// const devUrl = "https://xj-mix3d.4dkankan.com"
-const devUrl = "https://192.168.0.25"
+const devUrl = "https://xj-mix3d.4dkankan.com"
+// const devUrl = "https://192.168.0.25"
 export default defineConfig({
   define: {
     VITE_APP_APP: JSON.stringify(app),