【发布时间】:2018-01-24 00:01:47
【问题描述】:
我在访问属性时遇到了麻烦,即使它们存在于对象中,但 typescript 告诉我它们不存在。我创建了一个粒子对象,其中包含形状的几何形状和一种材质。我需要能够访问粒子的几何顶点,但是当我尝试时打字稿会抛出一个合适的。例如,this.particles.geometry.vertices.length 应该返回我的顶点的长度,但 typescript 说顶点在实际存在的几何中并不存在。
我的问题是在加载图像、创建顶点之后出现的,然后我需要将它们移动到目标索引,但它说 this.particles.geometry.vertices 不存在。
这是我的粒子对象,其中包含几何,几何内部是一个属性,它是包含我所有顶点的顶点,但我无法按照我显示的方式访问它们。
这是我的完整源代码。 drawImage 方法将正确绘制所有顶点,并将顶点对象推入我的几何对象中。然后一旦完成,我将几何图形添加到粒子中,它工作得很好,我将它添加到场景中并显示我的所有顶点。问题是我无法访问我的顶点来操作它们。所以我的粒子对象、drawImage 和包含我的 for 循环的渲染方法就是所有这些发生的地方。在我的渲染方法中,它只是说(TS)属性“顶点”不存在于类型“几何 |缓冲几何'。它确实存在,我用图像表明我的粒子对象是一个点对象,它包含我的几何图形,并且几何图形内部有一个属性,它包含我所有的顶点,称为顶点。
import { Component, AfterViewInit, ElementRef, Input, ViewChild, HostListener} from '@angular/core';
import { TweenLite } from 'gsap';
import * as THREE from 'three';
declare const require: (moduleId: string) => any;
var OrbitControls = require('three-orbit-controls')(THREE);
@Component({
selector: 'shared-background-scene',
templateUrl: './backgroundScene.component.html',
styleUrls: ['./backgroundScene.component.scss']
})
export class BackgroundSceneComponent {
public scene: THREE.Scene;
private renderer: THREE.WebGLRenderer;
private camera: THREE.PerspectiveCamera;
private cameraTarget: THREE.Vector3;
public controls: THREE.OrbitControls;
public fieldOfView: number = 60;
public nearClippingPane: number = 1;
public farClippingPane: number = 1100;
@ViewChild('canvas')
private canvasRef: ElementRef;
public particles: THREE.Points;
public imageData: any;
public geometry = new THREE.Geometry();
public material = new THREE.PointsMaterial({
size: 3,
color: 0x313742,
sizeAttenuation: false
});
public loadImage() {
//load texture, which is the image, and then get the imagedata, and draw image.
var texture = new THREE.TextureLoader().load("assets/img/example-clouds.png", () => { console.log(texture); this.imageData = this.getImageData(texture.image); this.drawImage(); this.startRendering(); })
}
public getImageData(image: any) {
console.log(image);
// Create canvas for the image
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.width;
// Make sure context is 2d
let context = canvas.getContext("2d");
context!.drawImage(image, 0, 0);
//return the context to be saved to the imageData.
return context!.getImageData(0, 0, image.width, image.height);
}
public drawImage() {
// Create vertices to draw the image.
for (var y = 0, y2 = this.imageData.height; y < y2; y += 2) {
for (var x = 0, x2 = this.imageData.width; x < x2; x += 2) {
if (this.imageData.data[(x * 4 + y * 4 * this.imageData.width) + 3] > 128) {
let vertex:any = new THREE.Vector3();
vertex.x = Math.random() * 1000 - 500;
vertex.y = Math.random() * 1000 - 500;
vertex.z = -Math.random() * 500;
vertex.destination = {
x: x - this.imageData.width / 2,
y: -y + this.imageData.height / 2,
z: 0
};
vertex.speed = Math.random() / 200 + 0.015;
this.geometry.vertices.push(vertex);
}
}
}
console.log(this.geometry);
this.particles = new THREE.Points(this.geometry, this.material);
this.scene.add(this.particles);
console.log(this.particles);
requestAnimationFrame(this.render);
}
constructor() {
this.render = this.render.bind(this);
}
private get canvas(): HTMLCanvasElement {
return this.canvasRef.nativeElement;
}
private createScene() {
this.scene = new THREE.Scene();
}
private createCamera() {
let aspectRatio = this.getAspectRatio();
this.camera = new THREE.PerspectiveCamera(
this.fieldOfView,
aspectRatio,
this.nearClippingPane,
this.farClippingPane
);
// Set position and look at
this.camera.position.x = 10;
this.camera.position.y = 10;
this.camera.position.z = 100;
}
private getAspectRatio(): number {
let height = this.canvas.clientHeight;
if (height === 0) {
return 0;
}
return this.canvas.clientWidth / this.canvas.clientHeight;
}
private startRendering() {
this.renderer = new THREE.WebGLRenderer({
canvas: this.canvas,
antialias: true
});
this.renderer.setPixelRatio(devicePixelRatio);
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
this.renderer.setClearColor(0xffffff, 1);
this.renderer.autoClear = true;
let component: BackgroundSceneComponent = this;
(function render() {
requestAnimationFrame(render);
component.render();
}());
}
public render() {
this.renderer.render(this.scene, this.camera);
for (var i = 0, j = this.particles.geometry.vertices; i < j; i++) {
var particle = this.particles.geometry.vertices[i];
particle.x += (particle.destination.x - particle.x) * particle.speed;
particle.y += (particle.destination.y - particle.y) * particle.speed;
particle.z += (particle.destination.z - particle.z) * particle.speed;
}
this.particles.geometry.verticesneedupdate = true;
}
public addControls() {
this.controls = new OrbitControls(this.camera);
this.controls.rotateSpeed = 1.0;
this.controls.zoomSpeed = 1.2;
this.controls.addEventListener('change', this.render);
}
private loadCubeModel() {
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var cube = new THREE.Mesh(geometry, material);
this.scene.add(cube);
}
/* Events */
private onResize(event: Event) {
this.canvas.style.width = "100%";
this.canvas.style.height = "100vh";
//console.log("onResize: " + this.canvas.clientWidth + ", " + this.canvas.clientHeight);
this.camera.aspect = this.getAspectRatio();
this.camera.updateProjectionMatrix();
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
this.render();
}
/* LIFECYCLE */
ngAfterViewInit() {
this.createScene();
this.createCamera();
this.loadImage(); // rendering starts here
this.loadCubeModel();
this.addControls();
}
}
我使用 console.log(this.particles.geometry.vertices.length); 的快速示例并获得正确的输出,但它仍然说它不存在。
【问题讨论】:
-
您能否在每个执行的方法中添加一个 console.log(yourmethodname) 并跟踪执行顺序,我认为执行顺序不好,您的代码很大,很难像那...
-
我修复了它,但我只是遇到了问题,说当一切正常执行时出现错误。
标签: javascript typescript properties