1
0

Scene.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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. loadLight = () => {
  126. const light = new THREE.AmbientLight(0xffffff, 1.5); // 柔和的白光
  127. this.scene.add(light);
  128. };
  129. setCamera = () => {};
  130. toHorizontal = () => {};
  131. toVertical = () => {};
  132. lockView(open) {
  133. if (open) {
  134. this.player.floorplanControls.enablePan = true;
  135. } else {
  136. this.player.floorplanControls.enablePan = false;
  137. }
  138. }
  139. setMode(mode) {
  140. this.player.setMode(mode);
  141. }
  142. onResize = (width, height) => {
  143. this.width = width !== undefined ? width : this.domElement.clientWidth;
  144. this.height = height !== undefined ? height : this.domElement.clientHeight;
  145. console.log("resize", this.width, this.height);
  146. (this.orthCamera.left = -this.width / 2),
  147. (this.orthCamera.right = this.width / 2),
  148. (this.orthCamera.bottom = -this.height / 2),
  149. (this.orthCamera.top = this.height / 2),
  150. this.orthCamera.updateProjectionMatrix();
  151. this.renderer.setSize(this.width, this.height);
  152. };
  153. render = () => {
  154. if (this.player) {
  155. this.player.update();
  156. this.renderer.render(this.scene, this.orthCamera);
  157. }
  158. };
  159. animate = () => {
  160. stats.begin();
  161. this.render();
  162. stats.end();
  163. requestAnimationFrame(this.animate);
  164. };
  165. resetCameraView() {
  166. this.orthCamera.zoom = this.defaultZoom;
  167. this.orthCamera.position.copy(this.initCamPView);
  168. this.orthCamera.rotation.copy(this.initCamRView);
  169. // this.orthCamera.updateMatrixWorld();
  170. }
  171. editing(item) {
  172. this.player.editing(item);
  173. }
  174. screenshot(x, index) {
  175. var imgData, imgNode;
  176. const times = 4;
  177. this.orthCamera.zoom = this.defaultZoom;
  178. this.scene.position.x = x || 0;
  179. this.renderer.setSize(this.width * times, this.height * times);
  180. this.orthCamera.aspect = this.width / this.height;
  181. // this.player.floorplanControls.minZoom = 1;
  182. // this.orthCamera.zoom = 50;
  183. this.orthCamera.updateProjectionMatrix();
  184. this.renderer.render(this.scene, this.orthCamera, null, false);
  185. const dataURL = this.renderer.domElement.toDataURL("image/jpeg");
  186. saveFile(dataURL, `${index}.jpg`);
  187. this.onResize(this.width, this.height);
  188. }
  189. test() {
  190. this.orthCamera.zoom = this.defaultZoom;
  191. const object = this.boxManager.model;
  192. let total;
  193. if (this.sceneType === 2) {
  194. total = this.boxManager.imgList.length;
  195. } else {
  196. total = this.boxManager.imgList.length / 2;
  197. }
  198. object.updateMatrixWorld();
  199. this.orthCamera.updateProjectionMatrix();
  200. const boundingBox = new THREE.Box3().setFromObject(object);
  201. // 计算宽度、高度和深度
  202. const width = boundingBox.max.x - boundingBox.min.x;
  203. const one = width / total;
  204. let slides = Math.floor(total / 3);
  205. console.log("slides", slides);
  206. if (slides > 1) {
  207. for (var i = 0; i <= slides; i++) {
  208. (function (index, that) {
  209. setTimeout(function () {
  210. const offset = -(one * 3 * index);
  211. console.log("Iteration:", offset);
  212. that.screenshot(offset, index);
  213. console.log(`Width: ${offset}`);
  214. }, index * 1000);
  215. })(i, this); // 传递当前迭代的索引i给setTimeout的回调函数
  216. }
  217. }
  218. }
  219. test1() {
  220. const object = this.boxManager.model;
  221. for (var i = 0; i <= object.children.length; i++) {
  222. console.log(object.children[i]);
  223. this.scene.lookAt(this.boxManager.model);
  224. }
  225. }
  226. onBindEvent = () => {
  227. //window.addEventListener('resize', this.onResize)
  228. };
  229. }