2014-03-06 4 views
3

내가 Reactive Extensions for Javascript (RX-JS)를 사용하여 게시하는 것과 동일한 효과를 얻으려고합니다. 나는 그것을하는 방법에 약간 의아해합니다. 나는 내가 mouseDown, mouseMove 나와와 mouseUp 이벤트에 대한 관찰 가능한을 작성해야한다고 생각RXJS html5 캔버스에 선을 그립니다.

 <!DOCTYPE html> 
     <html> 
     <head> 
     <title>drag and drop</title> 
     </head> 
     <style type="text/css"> 

     canvas { 
     border:1px solid steelblue; 
     background-color: whitesmoke; 
     } 

     </style> 
     <body> 
     <canvas id="canvas" width=300 height=300></canvas> 
     <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script> 
     <script type="text/javascript"> 
     $(function() { 
      var canvas = document.getElementById("canvas"); 
      var ctx = canvas.getContext("2d"); 

      var canvasOffset = $("#canvas").offset(); 
      var offsetX = canvasOffset.left; 
      var offsetY = canvasOffset.top; 

      var drawing = false; 
      var mouseX = 0; 
      var mouseY = 0; 


      function handleMouseDown(e) { 
       mouseX = parseInt(e.clientX - offsetX); 
       mouseY = parseInt(e.clientY - offsetY);   
       drawing= true;     
     } 

     function handleMouseUp(e) {    
      drawing = false;  
     } 
     function handleMouseMove(e) { 
      if(drawing){ 
       mouseeX = parseInt(e.clientX - offsetX); 
       mouseeY = parseInt(e.clientY - offsetY); 
       $("#movelog").html("Move: " + mouseX + "/" + mouseY); 

       var ctx = canvas.getContext("2d"); 
       // some cleanup code 
       ctx.save(); 
       ctx.setTransform(1, 0, 0, 1, 0, 0); 
       ctx.clearRect(0, 0, canvas.width, canvas.height); 
       ctx.restore();   
       ctx.beginPath(); 
       ctx.moveTo(mouseX,mouseY); 
       ctx.lineTo(mouseeX,mouseeY); 
       ctx.stroke(); 
      } 
     } 

     $("#canvas").mousedown(function(e) { 
      handleMouseDown(e); 
     }); 
     $("#canvas").mousemove(function(e) { 
      handleMouseMove(e); 
     }); 
     $("#canvas").mouseup(function(e) { 
      handleMouseUp(e); 
     }); 

     }); 
     </script> 
     </body> 
     </html> 

: 다음은 페이지입니다.

var mouseDown = Rx.Observable.fromEvent(canvas, 'mousedown'); 
    var mouseMove = Rx.Observable.fromEvent(canvas, 'mousemove'); 
    var mouseUp = Rx.Observable.fromEvent(canvas, 'mouseup'); 

그러나 나는 그들을 결합하는 방법을 모른다. mousedown을 관찰하기 시작한 다음 mouseup이 발생할 때까지 모든 동작을 수집하고 시작 지점에서 mousemove 동안 마우스가있는 현재 지점까지 선을 다시 그려야합니다. 아이디어가 있으십니까? 고마워.

°°°°°°°° 당신이 하나를 대표하는 이벤트의 흐름을 그래서

   $(function() { 

        var canvas = document.getElementById('canvas'); 
        var ctx = canvas.getContext("2d"); 
        var canvasOffset = $("#canvas").offset(); 
        var offsetX = canvasOffset.left; 
        var offsetY = canvasOffset.top; 

        var mouseDown = Rx.Observable.fromEvent($("#canvas"), 'mousedown'); 
        var mouseMove = Rx.Observable.fromEvent($("#canvas"), 'mousemove'); 
        var mouseUp = Rx.Observable.fromEvent($("#canvas"), 'mouseup'); 

        // keep a reference to the pisition when the mouse down was fired 
        // then flatten the stream with concatAll 


        var traceLineStream = mouseDown.map(function(md) { 
         var movesFromMouseDown = mouseMove.takeUntil(mouseUp); 
         var movesFromMouseDownAndMouseDown = movesFromMouseDown.map(function(mm) { 
          return { 
           mouseDownPoint: md, 
           mouseMovePoint: mm 
          } 
         }); 
         return movesFromMouseDownAndMouseDown; 
        }).concatAll(); 


        var subscription = traceLineStream.subscribe(
         function(y) { 

          var mouseDown = y.mouseDownPoint; 
          var mouseMove = y.mouseMovePoint; 

          var mouseDownX = parseInt(mouseDown.clientX - offsetX); 
          var mouseDownY = parseInt(mouseDown.clientY - offsetY);    

          var mouseMoveX = parseInt(mouseMove.clientX - offsetX); 
          var mouseMoveY = parseInt(mouseMove.clientY - offsetY); 

          ctx.save(); 
          ctx.setTransform(1, 0, 0, 1, 0, 0); 
          ctx.clearRect(0, 0, canvas.width, canvas.height); 
          ctx.restore(); 
          ctx.beginPath(); 
          ctx.moveTo(mouseDownX, mouseDownY); 
          ctx.lineTo(mouseMoveX, mouseMoveY); 
          ctx.stroke(); 

         }, 
         function(e) { 
          console.log('onError: ' + e.message); 
         }, 
         function() { 
          console.log('onCompleted'); 
         }); 
       }); 

답변

6

먼저, 스트림을 결합 : °°°°°°°°°°°°° 여기

브랜든로 대답 한 후 내 코드입니다 견인.

var drag = mouseDown.first().concat(mouseMove.takeUntil(mouseUp)); 

다음으로이 이벤트 스트림을 previous,current 튜플 스트림에 투영하십시오.

var moves = drag 
    .scan({}, function(acc, x) { 
     return { previous: acc.current, current: x }; 
    }) 
    .skip(1); 

이제 스트림이 처음으로 작동합니다. 그것은이 종료되면, 우리는 다음 드래그 대기를 시작하려면 :

var allMoves = moves.repeat(); 

마지막으로, 가입 :

mouseDown 
    .first() 
    .concat(mouseMove.takeUntil(mouseUp)) 
    .scan({}, function(acc, x) { 
     return { previous: acc.current, current: x }; 
    }) 
    .skip(1) 
    .repeat() 
    .subscribe(function (move) { 
     var mouseX = move.previous.clientX - offsetX, 
      mouseY = move.previous.clientY - offsetY, 
      mouseeX = move.current.clientX - offsetX, 
      mouseeY = move.current.clientY - offsetY, 
     ... 
    }); 
+0

안녕 :

allMoves.subscribe(function (move) { var mouseX = move.previous.clientX - offsetX, mouseY = move.previous.clientY - offsetY, mouseeX = move.current.clientX - offsetX, mouseeY = move.current.clientY - offsetY, ... }); 

중간 모든 변수없이 모두 함께 퍼팅 브랜든, 대답 해줘서 고마워. 내가 원한 것이 아니라 영감의 원천이었습니다. 나는 그것에 노력했고 내가 성취하고자하는 것을 얻었다. – JayZee