【发布时间】:2017-07-24 15:24:36
【问题描述】:
我正在尝试将三个 STL 查看器演示转换为 ES6 类,然后使用 webpack 2 进行编译,但我希望它从 URL 而不是从实际文件输入打开文件,我设法加载了三个组件和大部分课程都在工作,但我认为我在一些组件的范围内遇到了问题,我遇到了一个问题,我在尝试使用 FileReader 然后打开场景和对象时似乎无法解决。 TypeError: Cannot read property 'remove' of undefined
threeDimensionalModels.js
// jshint esversion:6
import {
Scene, PerspectiveCamera, WebGLRenderer, Geometry, Mesh,
AmbientLight, DirectionalLight, MeshPhongMaterial, Vector3, Face3,
} from 'three';
var thisClass = null;
class threeDimensionalModels {
constructor(height,width,selector){
this.w = height;
this.h = width;
this.selector = selector;
this.renderer = new WebGLRenderer();
this.view = document.getElementById(this.selector);
this.camera = new PerspectiveCamera(45, this.w / this.h, 1, 1000);
this.scene = new Scene();
this.light1 = new DirectionalLight(0xffffff);
this.light2 = new DirectionalLight(0xffffff);
this.mat = new MeshPhongMaterial({ color: 0x339900, specular: 0x030303 });
this.obj = new Mesh(new Geometry(), this.mat);
this.renderer.setSize(this.w, this.h);
this.view.appendChild(this.renderer.domElement);
this.camera.position.set(0, 0, 50);
this.scene.add(new AmbientLight(0x666666));
this.light1.position.set(0, 100, 100);
this.scene.add(this.light1);
this.light2.position.set(0, -100, -100);
this.scene.add(this.light2);
this.scene.add(this.obj);
}
static binaryVector3(view, offset) {
var v = new Vector3();
v.x = view.getFloat32(offset + 0, true);
v.y = view.getFloat32(offset + 4, true);
v.z = view.getFloat32(offset + 8, true);
return v;
}
static loadBinaryStl(buffer) {
// binary STL
var view = new DataView(buffer);
var size = view.getUint32(80, true);
var geom = new Geometry();
var offset = 84;
for (var i = 0; i < size; i++) {
var normal = threeDimensionalModels.binaryVector3(view, offset);
geom.vertices.push(threeDimensionalModels.binaryVector3(view, offset + 12));
geom.vertices.push(threeDimensionalModels.binaryVector3(view, offset + 24));
geom.vertices.push(threeDimensionalModels.binaryVector3(view, offset + 36));
geom.faces.push(
new Face3(i * 3, i * 3 + 1, i * 3 + 2, normal));
offset += 4 * 3 * 4 + 2;
}
return geom;
}
static m2vec3(match) {
var v = new Vector3();
v.x = parseFloat(match[1]);
v.y = parseFloat(match[2]);
v.z = parseFloat(match[3]);
return v;
}
static toLines(array) {
var lines = [];
var h = 0;
for (var i = 0; i < array.length; i++) {
if (array[i] === 10) {
var line = String.fromCharCode.apply(
null, array.subarray(h, i));
lines.push(line);
h = i + 1;
}
}
lines.push(String.fromCharCode.apply(null, array.subarray(h)));
return lines;
}
static loadTextStl(buffer) {
var lines = threeDimensionalModels.toLines(new Uint8Array(buffer));
var index = 0;
var scan = function (regexp) {
while (lines[index].match(/^\s*$/)) index++;
var r = lines[index].match(regexp);
return r;
};
var scanOk = function (regexp) {
var r = scan(regexp);
if (!r) throw new Error(
"not text stl: " + regexp.toString() +
"=> (line " + (index - 1) + ")" +
"[" + lines[index-1] + "]");
index++;
return r;
};
var facetReg = /^\s*facet\s+normal\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)/;
var vertexReg = /^\s*vertex\s+([^s]+)\s+([^\s]+)\s+([^\s]+)/;
var geom = new Geometry();
scanOk(/^\s*solid\s(.*)/);
while (!scan(/^\s*endsolid/)) {
var normal = scanOk(facetReg);
scanOk(/^\s*outer\s+loop/);
var v1 = scanOk(vertexReg);
var v2 = scanOk(vertexReg);
var v3 = scanOk(vertexReg);
scanOk(/\s*endloop/);
scanOk(/\s*endfacet/);
var base = geom.vertices.length;
geom.vertices.push(threeDimensionalModels.m2vec3(v1));
geom.vertices.push(threeDimensionalModels.m2vec3(v2));
geom.vertices.push(threeDimensionalModels.m2vec3(v3));
geom.faces.push(
new Face3(base, base + 1, base + 2, threeDimensionalModels.m2vec3(normal)));
}
return geom;
}
static loadStlModel(buffer) {
try {
return threeDimensionalModels.loadTextStl(buffer);
} catch (ex) {
return threeDimensionalModels.loadBinaryStl(buffer);
}
}
openStl(url) {
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "blob";//force the HTTP response, response-type header to be blob
xhr.onload = function() {
blob = xhr.response;
thisClass = this;
var reader = new FileReader();
reader.addEventListener("load", function (ev) {
var buffer = ev.target.result;
var geom = threeDimensionalModels.loadStlModel(buffer);
threeDimensionalModels.scene.remove(thisClass.obj);
threeDimensionalModels.obj = new Mesh(geom, threeDimensionalModels.mat);
threeDimensionalModels.scene.add(threeDimensionalModels.obj);
}, false);
reader.readAsArrayBuffer(blob);
};
xhr.send();
}
}
export default threeDimensionalModels;
HTML
<div id="threedm-view"></div>
<script type="text/javascript">
window.addEventListener("load", function () {
"use strict";
var threedm = new threeDimensionalModels(800,800,'threedm-view');
var loop = function loop() {
requestAnimationFrame(loop);
threedm.obj.rotation.z += 0.05;
threedm.renderer.clear();
threedm.renderer.render(threedm.scene, threedm.camera);
};
loop();
threedm.openStl("/app/uploads/2017/07/Stator.stl");
});
</script>
【问题讨论】:
-
你没有移植
static remove,也用大写开始类以避免将来出现这种混乱。另外,请隔离您的示例。 -
我很困惑,可能不是一个好的开始,
threeDimensionalModels.scene.remove(thisClass.obj);的意思是THREE.Scene()被导入到类中,然后在构造函数中调用this.scene = new Scene(); -
对,所以
this.scene... -
如果我尝试以某种方式调用它,它不会在事件内部的范围内结束,所以我可以通过创建一个全局变量并将其应用于全局变量然后调用全局变量来应用它eventListener,但我认为这也不完全正确,甚至对于这个用例也不太适用。与另一个班级合作,但不是这个班级
-
我可能已经发现问题
thisClass = this;在 XHR 函数内部,我认为这不在那个范围内,是的,示例现在正在运行
标签: javascript ecmascript-6 es6-class