PageSourceSearch

https://toplivo-expert.ru/assets/js/main.js

js toplivo-expert.ru collected 2026-10-09 23:09:41 UTC 11,414 bytes, 333 lines download raw bytes

1import {
2    AmbientLight,
3    AxesHelper,
4    Box3,
5    Cache,
6    Color,
7    DirectionalLight,
8    HemisphereLight,
9    LoadingManager,
10    PMREMGenerator,
11    PerspectiveCamera,
12    Scene,
13    Vector3,
14    WebGLRenderer,
15    LinearToneMapping,
16  } from "three";
17  import Stats from "three/addons/libs/stats.module.js";
18  import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
19  import { OrbitControls } from "three/addons/controls/OrbitControls.js";
20  import { EXRLoader } from "three/addons/loaders/EXRLoader.js";
21  import { RoomEnvironment } from "three/addons/environments/RoomEnvironment.js";
22  
23  document.addEventListener("DOMContentLoaded", () => {
24    window.VIEWER = {};
25  
26    const DEFAULT_CAMERA = "[default]";
27    const MANAGER = new LoadingManager();
28    const Preset = { ASSET_GENERATOR: "assetgenerator" };
29  
30    Cache.enabled = true;
31  
32    class Viewer {
33      constructor(el, options) {
34        this.el = el;
35        this.options = {};
36  
37        this.lights = [];
38        this.content = null;
39        this.mixer = null;
40        this.clips = [];
41  
42        this.state = {
43          environment: "Neutral",
44          background: false,
45          playbackSpeed: 1.0,
46          actionStates: {},
47          camera: DEFAULT_CAMERA,
48          wireframe: false,
49          skeleton: false,
50          grid: false,
51          autoRotate: false,
52  
53          // Lights
54          punctualLights: true,
55          exposure: 0.0,
56          toneMapping: LinearToneMapping,
57          ambientIntensity: 0.3,
58          ambientColor: "#FFFFFF",
59          directIntensity: 0.8 * Math.PI,
60          directColor: "#FFFFFF",
61          bgColor: "#B8B8B8",
62          pointSize: 1.0,
63        };
64  
65        this.prevTime = 0;
66        this.stats = new Stats();
67        this.stats.dom.height = "48px";
68        this.backgroundColor = new Color(this.state.bgColor);
69        this.scene = new Scene();
70        this.scene.background = this.backgroundColor;
71        const fov = options.preset === Preset.ASSET_GENERATOR ? (0.8 * 180) / Math.PI : 60;
72        const aspect = el.clientWidth / el.clientHeight;
73        this.defaultCamera = new PerspectiveCamera(fov, aspect, 0.01, 1000);
74        this.activeCamera = this.defaultCamera;
75        this.scene.add(this.defaultCamera);
76        this.renderer = window.renderer = new WebGLRenderer({ antialias: true });
77        this.renderer.setClearColor(0xcccccc);
78        this.renderer.setPixelRatio(window.devicePixelRatio);
79        this.renderer.setSize(el.clientWidth, el.clientHeight);
80        this.pmremGenerator = new PMREMGenerator(this.renderer);
81        this.pmremGenerator.compileEquirectangularShader();
82        this.neutralEnvironment = this.pmremGenerator.fromScene(new RoomEnvironment()).texture;
83        this.controls = new OrbitControls(this.defaultCamera, this.renderer.domElement);
84        this.controls.screenSpacePanning = true;
85        this.el.appendChild(this.renderer.domElement);
86        this.cameraCtrl = null;
87        this.cameraFolder = null;
88        this.animFolder = null;
89        this.animCtrls = [];
90        this.morphFolder = null;
91        this.morphCtrls = [];
92        this.skeletonHelpers = [];
93        this.gridHelper = null;
94        this.axesHelper = null;
95        this.addAxesHelper();
96        this.animate = this.animate.bind(this);
97        requestAnimationFrame(this.animate);
98        window.addEventListener("resize", this.resize.bind(this), false);
99      }
100  
101      animate(time) {
102        requestAnimationFrame(this.animate);
103        const dt = (time - this.prevTime) / 1000;
104        this.controls.update();
105        this.stats.update();
106        this.mixer && this.mixer.update(dt);
107        this.render();
108        this.prevTime = time;
109      }
110  
111      render() {
112        this.renderer.render(this.scene, this.activeCamera);
113        if (this.state.grid) {
114          this.axesCamera.position.copy(this.defaultCamera.position);
115          this.axesCamera.lookAt(this.axesScene.position);
116          this.axesRenderer.render(this.axesScene, this.axesCamera);
117        }
118      }
119  
120      resize() {
121        const { clientHeight, clientWidth } = this.el.parentElement;
122  
123        this.defaultCamera.aspect = clientWidth / clientHeight;
124        this.defaultCamera.updateProjectionMatrix();
125        this.renderer.setSize(clientWidth, clientHeight);
126  
127        this.axesCamera.aspect = this.axesDiv.clientWidth / this.axesDiv.clientHeight;
128        this.axesCamera.updateProjectionMatrix();
129        this.axesRenderer.setSize(this.axesDiv.clientWidth, this.axesDiv.clientHeight);
130      }
131  
132      load(url) {
133        return new Promise((resolve, reject) => {
134          const loader = new GLTFLoader(MANAGER);
135  
136          loader.load(
137            url,
138            (gltf) => {
139              window.VIEWER.json = gltf;
140              const scene = gltf.scene || gltf.scenes[0];
141              const clips = gltf.animations || [];
142              this.setContent(scene, clips);
143              resolve(gltf);
144            },
145            undefined,
146            reject
147          );
148        });
149      }
150      setContent(object) {
151        object.updateMatrixWorld();
152        const box = new Box3().setFromObject(object);
153        const size = box.getSize(new Vector3()).length();
154        const center = box.getCenter(new Vector3());
155  
156        this.controls.reset();
157        object.position.x -= center.x;
158        object.position.y -= center.y;
159        object.position.z -= center.z;
160        this.controls.maxDistance = size * 10;
161        this.defaultCamera.near = size / 100;
162        this.defaultCamera.far = size * 100;
163        this.defaultCamera.updateProjectionMatrix();
164  
165        if (this.options.cameraPosition) {
166          this.defaultCamera.position.fromArray(this.options.cameraPosition);
167          this.defaultCamera.lookAt(new Vector3());
168        } else {
169          this.defaultCamera.position.copy(center);
170          this.defaultCamera.position.x += size / 2.0;
171          this.defaultCamera.position.y += size / 15.0;
172          this.defaultCamera.position.z += size / 2.0;
173          this.defaultCamera.lookAt(center);
174        }
175  
176        this.axesCamera.position.copy(this.defaultCamera.position);
177        this.axesCamera.lookAt(this.axesScene.position);
178        this.axesCamera.near = size / 100;
179        this.axesCamera.far = size * 100;
180        this.axesCamera.updateProjectionMatrix();
181        this.axesCorner.scale.set(size, size, size);
182        this.scene.add(object);
183        this.content = object;
184        this.state.punctualLights = true;
185        this.content.traverse((node) => {
186          if (node.isLight) {
187            this.state.punctualLights = false;
188          }
189        });
190        this.updateLights();
191        this.updateEnvironment();
192      }
193  
194      updateLights() {
195        const state = this.state;
196        const lights = this.lights;
197  
198        if (state.punctualLights && !lights.length) {
199          this.addLights();
200        }
201  
202        this.renderer.toneMapping = Number(state.toneMapping);
203        this.renderer.toneMappingExposure = Math.pow(2, state.exposure);
204  
205        if (lights.length === 2) {
206          lights[0].intensity = state.ambientIntensity;
207          lights[0].color.set(state.ambientColor);
208          lights[1].intensity = state.directIntensity;
209          lights[1].color.set(state.directColor);
210        }
211      }
212  
213      addLights() {
214        const state = this.state;
215  
216        if (this.options.preset === Preset.ASSET_GENERATOR) {
217          const hemiLight = new HemisphereLight();
218          hemiLight.name = "hemi_light";
219          this.scene.add(hemiLight);
220          this.lights.push(hemiLight);
221          return;
222        }
223  
224        const light1 = new AmbientLight(state.ambientColor, state.ambientIntensity);
225        light1.name = "ambient_light";
226        this.defaultCamera.add(light1);
227  
228        const light2 = new DirectionalLight(state.directColor, state.directIntensity);
229        light2.position.set(0.5, 0, 0.866); // ~60º
230        light2.name = "main_light";
231        this.defaultCamera.add(light2);
232  
233        this.lights.push(light1, light2);
234      }
235  
236      updateEnvironment() {
237        const environment = {
238          id: "neutral",
239          name: "Neutral",
240          path: null,
241        };
242  
243        this.getCubeMapTexture(environment).then(({ envMap }) => {
244          this.scene.environment = envMap;
245          this.scene.background = this.state.background ? envMap : this.backgroundColor;
246        });
247      }
248  
249      getCubeMapTexture(environment) {
250        const { id, path } = environment;
251        if (id === "neutral") {
252          return Promise.resolve({ envMap: this.neutralEnvironment });
253        }
254  
255        // none
256        if (id === "") {
257          return Promise.resolve({ envMap: null });
258        }
259  
260        return new Promise((resolve, reject) => {
261          new EXRLoader().load(
262            path,
263            (texture) => {
264              const envMap = this.pmremGenerator.fromEquirectangular(texture).texture;
265              this.pmremGenerator.dispose();
266  
267              resolve({ envMap });
268            },
269            undefined,
270            reject
271          );
272        });
273      }
274      addAxesHelper() {
275        this.axesDiv = document.createElement("div");
276        this.el.appendChild(this.axesDiv);
277        this.axesDiv.classList.add("axes");
278  
279        const { clientWidth, clientHeight } = this.axesDiv;
280  
281        this.axesScene = new Scene();
282        this.axesCamera = new PerspectiveCamera(50, clientWidth / clientHeight, 0.1, 10);
283        this.axesScene.add(this.axesCamera);
284  
285        this.axesRenderer = new WebGLRenderer({ alpha: true });
286        this.axesRenderer.setPixelRatio(window.devicePixelRatio);
287        this.axesRenderer.setSize(this.axesDiv.clientWidth, this.axesDiv.clientHeight);
288  
289        this.axesCamera.up = this.defaultCamera.up;
290  
291        this.axesCorner = new AxesHelper(5);
292        this.axesScene.add(this.axesCorner);
293        this.axesDiv.appendChild(this.axesRenderer.domElement);
294      }
295    }
296  
297    class App {
298      constructor(el, file) {
299        this.options = {};
300        this.el = el;
301        this.viewer = null;
302        this.viewerEl = null;
303        this.dropEl = el.querySelector(".dropzone");
304        this.view(file);
305      }
306  
307      createViewer() {
308        this.viewerEl = document.createElement("div");
309        this.viewerEl.classList.add("viewer");
310        this.dropEl.appendChild(this.viewerEl);
311        this.viewer = new Viewer(this.viewerEl, this.options);
312        return this.viewer;
313      }
314  
315      view(rootFile) {
316        const viewer = this.createViewer();
317        viewer.load(rootFile);
318      }
319    }
320  
321    // const file1 = "/assets/img/closed _type_small.glb";
322    // const file2 = "/assets/img/container_type_big.glb";
323    // const file3 = "/assets/img/open_type_small.glb";
324
325    const file1 = "/assets/img/closed.glb";
326    const file2 = "/assets/img/container.glb";
327    const file3 = "/assets/img/open.glb";
328  
329    // new App(document.body, file1);
330  //   const app = new App(document.body, file2);
331    const app = new App(document.body, file3);
332  });
333  

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.