2017-01-20 3 views
0

私は、オブジェクト(この場合はパーティクル)のかなり標準的な軌道制御を実装しているthree.jsプロジェクトに取り組んでいます。外部モジュールで使用するとMouseupとmousemoveイベントが失敗する

このロジックをルートクラス(つまり、すべてのthree.jsコード)で使用すると、完全に機能します。しかし、私がやりたいことは、この論理を外部クラスに抽象化することです。

この場合、私のmousemovemouseupイベントは発生しません。しかし、タッチイベントはすべて完全に発射され、軌道は期待通りに機能します。

私はpreventDefault()で電話してみましたが、大きな違いはありません。私はモジュールになっているので、 '文書'の代わりに 'ウィンドウ'を使用しようとしましたが、どちらも機能していないようです。

私には何が欠けていますか?モジュールは次のようになります。

var orbitElement; 
var targetRotation = 0; 
var targetRotationOnMouseDown = 0; 
var mouseX = 0; 
var mouseXOnMouseDown = 0; 
var windowHalfX = window.innerWidth/2; 
var windowHalfY = window.innerHeight/2; 

var Controls = { 

    enableOrbiting: function(target) { 
     orbitElement = target; 
     document.addEventListener('mousedown', this.onDocumentMouseDown, false); 
     document.addEventListener('touchstart', this.onDocumentTouchStart, false); 
     document.addEventListener('touchmove', this.onDocumentTouchMove, false); 
    }, 

    onDocumentMouseDown: function(event) { 
     document.addEventListener('mousemove', this.onDocumentMouseMove, false); 
     document.addEventListener('mouseup', this.onDocumentMouseUp, false); 
     document.addEventListener('mouseout', this.onDocumentMouseOut, false); 
     mouseXOnMouseDown = event.clientX - windowHalfX; 
     targetRotationOnMouseDown = targetRotation; 
    }, 

    onDocumentMouseMove: function(event) { 
     mouseX = event.clientX - windowHalfX; 
     targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.02; 
    }, 

    onDocumentMouseUp: function(event) { 
     document.removeEventListener('mousemove', this.onDocumentMouseMove, false); 
     document.removeEventListener('mouseup', this.onDocumentMouseUp, false); 
     document.removeEventListener('mouseout', this.onDocumentMouseOut, false); 
    }, 

    onDocumentMouseOut:function(event) { 
     document.removeEventListener('mousemove', this.onDocumentMouseMove, false); 
     document.removeEventListener('mouseup', this.onDocumentMouseUp, false); 
     document.removeEventListener('mouseout', this.onDocumentMouseOut, false); 
    }, 

    onDocumentTouchStart: function(event) { 
     if (event.touches.length == 1) { 
      event.preventDefault(); 
      mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX; 
      targetRotationOnMouseDown = targetRotation; 
     } 
    }, 

    onDocumentTouchMove: function(event) { 
      if (event.touches.length == 1) { 
      event.preventDefault(); 
      mouseX = event.touches[ 0 ].pageX - windowHalfX; 
      targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.05; 
     } 
    }, 

    updateOrbit: function() { 
     orbitElement.rotation.y += (targetRotation - orbitElement.rotation.y) * 0.04; 
    } 
} 

module.exports = Controls; 

答えて

0

thisあなたはそれだと思うものではありません。

controls.enableOrbiting()に電話すると、enableOrbitingthiscontrolsと同じです。しかし、this.onDocumentMouseDownをイベントハンドラとして登録すると、内のthisは、documentではなくcontrolsのイベントエミッタと同じです。

EDIT:割り当て後にControlsにバインドします。

あなたはこのように、Controlsに各機能をバインドすることができます。

var Controls = {} 
Controls.onDocumentMouseDown = function (event) { 
... 
}.bind(Controls); 

この方法thisは関係なく、常にメソッドの呼び出しで使用されるthisの、Controlsになります。

+0

ああ、面白いです。私はbind()を使用しようとしましたが、そうすることで、私はより効果的な静的ヘルパークラスであることに気づきました。 'document.addEventListener( 'mousedown'、Controls.onDocumentMouseDown、false);' このアプローチには欠点はありますか? –

+0

絶対に欠点はありません。これは本質的に、関数の終了時に 'this'を保存する一般的な' var self = this'の形式です。もちろん、その場合、「自己」がどこでも一貫して使用されるよう注意しなければなりません。 –

+0

どちらも有効なアプローチですが、これは今うまくいっています。ありがとう! –

関連する問題