Scene.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. import * as THREE from "three";
  2. import Stats from "three/examples/jsm/libs/stats.module.js";
  3. import Player from "./player/Player.js";
  4. import BoxManager from "./box/BoxManager.js";
  5. import { Mitt } from "./mitt.js";
  6. import testData from "./save.json";
  7. const stats = new Stats();
  8. function sleep(ms) {
  9. return new Promise((resolve) => setTimeout(resolve, ms));
  10. }
  11. const saveFile = function (strData, filename) {
  12. var link = document.createElement("a");
  13. if (typeof link.download === "string") {
  14. document.body.appendChild(link); //Firefox requires the link to be in the body
  15. link.download = filename;
  16. link.href = strData;
  17. link.click();
  18. document.body.removeChild(link); //remove the link when done
  19. } else {
  20. location.replace(uri);
  21. }
  22. };
  23. export default class Scene extends Mitt {
  24. constructor(domElement) {
  25. super();
  26. this.domElement = domElement;
  27. this.scene = null;
  28. this.renderer = null;
  29. this.orthCamera = null;
  30. this.player = null;
  31. this.sceneType = 1;
  32. this.width = 0;
  33. this.height = 0;
  34. this.defaultZoom = 250;
  35. this.initCamPView = new THREE.Vector3();
  36. this.initCamRView = new THREE.Vector3();
  37. this.inited = false;
  38. this.init = () => {
  39. this.scene = new THREE.Scene();
  40. this.scene.background = new THREE.Color(0xf0f2f5);
  41. this.renderer = new THREE.WebGLRenderer({
  42. canvas: this.domElement,
  43. antialias: true,
  44. autoClear: true,
  45. preserveDrawingBuffer: true,
  46. });
  47. this.width = this.domElement.clientWidth;
  48. this.height = this.domElement.clientHeight;
  49. this.renderRes = window.devicePixelRatio;
  50. this.renderer.setSize(this.width, this.height);
  51. this.renderer.setPixelRatio(this.renderRes);
  52. console.log(this.width, this.height, this.renderRes);
  53. this.orthCamera = new THREE.OrthographicCamera(
  54. -this.width / 2,
  55. this.width / 2,
  56. this.height / 2,
  57. -this.height / 2,
  58. 0.1,
  59. 1000
  60. );
  61. this.orthCamera.zoom = this.defaultZoom;
  62. this.orthCamera.position.set(0, 10, 0);
  63. this.orthCamera.lookAt(0, 0, 0);
  64. // this.orthCamera.setViewOffset(this.width, this.height, 0, 0);
  65. this.orthCamera.updateProjectionMatrix();
  66. //player
  67. this.player = new Player(this);
  68. //stats
  69. domElement.parentNode.appendChild(stats.dom);
  70. stats.dom.style.pointerEvents = "none";
  71. stats.dom.style.left = "15%";
  72. stats.dom.style.display = "none";
  73. this.onBindEvent();
  74. this.inited = true;
  75. this.load();
  76. this.animate();
  77. };
  78. }
  79. load = (list, type, data) => {
  80. if (!list) return;
  81. // console.log("scene: ", list, type, data);
  82. //axesHeloer
  83. this.clearScene();
  84. this.sceneType = type;
  85. // const axesHelper = new THREE.AxesHelper(1);
  86. // this.scene.add(axesHelper);
  87. this.boxManager = new BoxManager(this);
  88. this.boxManager.load(list, type);
  89. //light
  90. this.loadLight();
  91. this.player.load(type, data || []);
  92. this.initCamPView.copy(this.orthCamera.position);
  93. this.initCamRView.copy(this.orthCamera.rotation);
  94. };
  95. clearScene() {
  96. for (var i = this.scene.children.length - 1; i >= 0; i--) {
  97. let obj = this.scene.children[i];
  98. this.scene.remove(obj);
  99. }
  100. }
  101. clearDrawScene() {
  102. for (var i = this.scene.children.length - 1; i >= 0; i--) {
  103. let obj = this.scene.children[i];
  104. if (
  105. String(obj.name).includes("marker_") ||
  106. String(obj.name).includes("line_") ||
  107. String(obj.name).includes("line_point_") ||
  108. String(obj.name).includes("circle_") ||
  109. String(obj.name).includes("pureText_")
  110. ) {
  111. this.scene.remove(obj);
  112. }
  113. }
  114. }
  115. deleteItemById(uuid, type) {
  116. for (var i = this.scene.children.length - 1; i >= 0; i--) {
  117. let obj = this.scene.children[i];
  118. if (obj.uuid === uuid) {
  119. console.log("deleteItemById-userData", obj.userData);
  120. this.player.deleteItemByType(type, obj.userData);
  121. this.scene.remove(obj);
  122. }
  123. }
  124. }
  125. deleteImageDataByIds(ids) {
  126. this.player.deleteImageDataByIds(ids);
  127. }
  128. loadLight = () => {
  129. const light = new THREE.AmbientLight(0xffffff, 1.5); // 柔和的白光
  130. this.scene.add(light);
  131. };
  132. setCamera = () => {};
  133. toHorizontal = () => {};
  134. toVertical = () => {};
  135. lockView(open) {
  136. if (open) {
  137. this.player.floorplanControls.enablePan = true;
  138. } else {
  139. this.player.floorplanControls.enablePan = false;
  140. }
  141. }
  142. setMode(mode) {
  143. this.player.setMode(mode);
  144. }
  145. onResize = (width, height) => {
  146. this.width = width !== undefined ? width : this.domElement.clientWidth;
  147. this.height = height !== undefined ? height : this.domElement.clientHeight;
  148. console.log("resize", this.width, this.height);
  149. (this.orthCamera.left = -this.width / 2),
  150. (this.orthCamera.right = this.width / 2),
  151. (this.orthCamera.bottom = -this.height / 2),
  152. (this.orthCamera.top = this.height / 2),
  153. this.orthCamera.updateProjectionMatrix();
  154. this.renderer.setSize(this.width, this.height);
  155. };
  156. render = () => {
  157. if (this.player) {
  158. this.player.update();
  159. this.renderer.render(this.scene, this.orthCamera);
  160. }
  161. };
  162. animate = () => {
  163. stats.begin();
  164. this.render();
  165. stats.end();
  166. requestAnimationFrame(this.animate);
  167. };
  168. resetCameraView() {
  169. this.orthCamera.zoom = this.defaultZoom;
  170. // this.orthCamera.position.set(0, 0, 0);
  171. // this.orthCamera.rotation.set(0, 10, 0);
  172. // this.orthCamera.updateMatrixWorld();
  173. }
  174. editing(item) {
  175. this.player.editing(item);
  176. }
  177. screenshot(x, index) {
  178. var imgData, imgNode;
  179. const times = 4;
  180. this.orthCamera.zoom = this.defaultZoom;
  181. this.scene.position.x = x || 0;
  182. this.renderer.setSize(this.width * times, this.height * times);
  183. this.orthCamera.aspect = this.width / this.height;
  184. // this.player.floorplanControls.minZoom = 1;
  185. // this.orthCamera.zoom = 50;
  186. this.orthCamera.updateProjectionMatrix();
  187. this.renderer.render(this.scene, this.orthCamera, null, false);
  188. const dataURL = this.renderer.domElement.toDataURL("image/jpeg");
  189. saveFile(dataURL, `${index}.jpg`);
  190. this.onResize(this.width, this.height);
  191. }
  192. test() {
  193. this.orthCamera.zoom = this.defaultZoom;
  194. const object = this.boxManager.model;
  195. let total;
  196. if (this.sceneType === 2) {
  197. total = this.boxManager.imgList.length;
  198. } else {
  199. total = this.boxManager.imgList.length / 2;
  200. }
  201. object.updateMatrixWorld();
  202. this.orthCamera.updateProjectionMatrix();
  203. const boundingBox = new THREE.Box3().setFromObject(object);
  204. // 计算宽度、高度和深度
  205. const width = boundingBox.max.x - boundingBox.min.x;
  206. const one = width / total;
  207. let slides = Math.floor(total / 3);
  208. console.log("slides", slides);
  209. if (slides > 1) {
  210. for (var i = 0; i <= slides; i++) {
  211. (function (index, that) {
  212. setTimeout(function () {
  213. const offset = -(one * 3 * index);
  214. console.log("Iteration:", offset);
  215. that.screenshot(offset, index);
  216. console.log(`Width: ${offset}`);
  217. }, index * 1000);
  218. })(i, this); // 传递当前迭代的索引i给setTimeout的回调函数
  219. }
  220. }
  221. }
  222. test1() {
  223. const object = this.boxManager.model;
  224. for (var i = 0; i <= object.children.length; i++) {
  225. console.log(object.children[i]);
  226. this.scene.lookAt(this.boxManager.model);
  227. }
  228. }
  229. onBindEvent = () => {
  230. window.addEventListener("resize", this.onResize);
  231. };
  232. }