三个JS拖动控件未捕获的TypeError:无法设置未定义的属性“ x”

时间:2019-01-22 10:50:29

标签: javascript vue.js three.js vuetify.js

因此,我尝试在场景中拖动球体。只要按下“ m”键,就应该激活拖动控件。当前的问题是,每当我尝试拖动一个对象时,它都不会移动,并且出现“ Uncaught TypeError:无法在HTMLCanvasElement.onDocumentMouseMove处设置未定义的属性'x'”。你们知道为什么会这样吗? (我尝试为问题代码省略尽可能多的不必要的内容。很抱歉,如果看起来很乱)

<template>
  <div class="flex fill-height wrap">
    <div id="map"  class="flex fill-height wrap "  v-on:dblclick="addNewPoi3d" ></div>
  </div>
</template>
<script>

import { mapState, mapActions } from 'vuex';
import * as THREE from 'three';
import  DragControls from 'drag-controls';

var OrbitControls = require('three-orbit-controls')(THREE);

var PLYLoader = require('three-ply-loader');

PLYLoader(THREE);

export default {
  name: 'ThreeTest',
  data() {
    return {
      scene: null,
      renderer: null,
      camera: null,
      controls: null,
      mouse: new THREE.Vector2(),
      canvasPosition: null,
      rayCaster: new THREE.Raycaster(),
      spheres: [],
      objects: [],
      moveIt: false,
      plymap: null,
      mapWidth: null,
      mapHeight: null,
      mapDimensions: null,
      intersectsScene: null,
      intersectsPoi:null
    };
  },
  created() {
    this.mapId = this.$route.params.mapId;
    this.fetchMapData(this.mapId);
    this.plymap = this.MapStore.ply;
  },
  methods: {
    init() {
      let map = document.getElementById('map');
      this.mapDimensions = map.getBoundingClientRect();
      this.mapWidth = this.mapDimensions.width;
      this.mapHeight = this.mapDimensions.height;
      this.scene = new THREE.Scene();
      this.scene.background = new THREE.Color( 0xf0f0f0 );
      this.camera = new THREE.PerspectiveCamera(
        60,
        this.mapWidth/this.mapHeight,
        0.1,
        1000,
      );
      this.camera.position.z = 3;

      this.renderer = new THREE.WebGLRenderer();
      this.renderer.setSize(this.mapWidth, this.mapHeight);
      map.appendChild(this.renderer.domElement);


      // EVENT LISTENERS:
      map.addEventListener('mousedown', this.movePoi, false);
      document.addEventListener('keydown', this.onDocumentKeyDown, false);
      document.addEventListener('keyup', this.onDocumentKeyUp, false);

    },

    // FUNCTIONS:
    onDocumentKeyDown(event) {

      let keycode = event.which;
      if (keycode === 77) {
        this.moveIt = true;
        this.controls.enabled = false;
      }
    },
    onDocumentKeyUp(event){
      let keycode = event.which;
      if (keycode === 77) {
        this.moveIt = false;
        this.controls.enabled = true;
      }
    },
    mouseOverScene (event) {
      event.preventDefault();
      let rect = event.target.getBoundingClientRect();
      let x = event.clientX - rect.left;
      let y = event.clientY - rect.top;

      this.mouse.x = ( x / this.mapWidth) * 2 - 1;
      this.mouse.y = - ( y / this.mapHeight ) * 2 + 1;

      this.rayCaster.setFromCamera(this.mouse, this.camera);
    },

    //POI placement:

    addNewPoi3d(event) {
      if (event) {
        this.mouseOverScene(event);
      };
      event.preventDefault();

      let sphereGeometry = new THREE.SphereGeometry( 0.1, 32, 32);
      let sphereMaterial = new THREE.MeshBasicMaterial( { color: 0x00ff0 } );
      let sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
      sphere.name = 'spherePOI';

      let intersects = this.intersectsScene;
      intersects = this.rayCaster.intersectObject(this.scene.getObjectByName('floor'));

      sphere.position.set(
        intersects[0].point.x,
        intersects[0].point.y + sphereGeometry.parameters.radius,
        intersects[0].point.z
      );

      this.spheres.push(this.scene.getObjectByName('spherePOI'));
      this.objects.push(sphere);
      this.scene.add( sphere );


    },

    //POI movement around the scene:
    movePoi (event) {
      if (this.moveIt) {
        this.mouseOverScene(event);
        event.preventDefault();

      let intersectsPoi = this.intersectsPoi;
      intersectsPoi = this.rayCaster.intersectObject(this.scene.getObjectByName('spherePOI'));
      console.log(intersectsPoi[0].object);
      console.log(intersectsPoi[0].object.name);

      if (intersectsPoi.length > 0 && intersectsPoi[0].object.name === 'spherePOI') {
        let controlsDrag = new DragControls(this.objects, this.camera, this.renderer.domElement);
      };
      };
    },



    animate() {
      requestAnimationFrame(this.animate);
      this.render();
    },
    render() {
      this.controls.update();
      this.renderer.render(this.scene, this.camera);
    },
  },

  mounted() {
    this.init();
    this.animate();
  },
};
</script>

预期:这些对象应该是可拖动的。

实际:嗯,它们不是:D我收到“未捕获的TypeError:无法在HTMLCanvasElement.onDocumentMouseMove处设置未定义的属性'x'”。

1 个答案:

答案 0 :(得分:0)

问题已解决!我需要做的就是将DragControls.install({THREE: THREE})添加到init()阶段。