【问题标题】:How to redraw mouse movement on a canvas?如何在画布上重绘鼠标移动?
【发布时间】:2016-07-21 20:25:24
【问题描述】:

我在 javascript 中有一个元组数组。是否有现有的库可以让我查看用户执行的鼠标移动?

理想情况下,可以让我从头到尾重播捕获的数据。它看起来像一个视频播放器(即播放、暂停、调整重播速度),但您会看到鼠标光标是如何移动的,而不是视频。这种可视化将在 HTML5 画布上(即,一个白色像素的正方形,表示在黑色 HTML 画布中移动的光标)。

【问题讨论】:

    标签: javascript html canvas html5-canvas mouseevent


    【解决方案1】:

    简单到无需库即可完成。

    • 监听 mousemove 事件
    • 在 mousemove 时,将每个鼠标位置添加到点数组中
    • 如有请求,请运行 requestAnimationFrame 循环,从点数组中重绘每个点。

    示例代码和演示:

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var cw=canvas.width;
    var ch=canvas.height;
    function reOffset(){
      var BB=canvas.getBoundingClientRect();
      offsetX=BB.left;
      offsetY=BB.top;        
    }
    var offsetX,offsetY;
    reOffset();
    window.onscroll=function(e){ reOffset(); }
    window.onresize=function(e){ reOffset(); }
    
    var isDown=false;
    var points=[];
    var nextTime=0;
    var nextN=0;
    var duration=1000/60;
    ctx.lineCap='round';
    
    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUpOut(e);});
    $("#canvas").mouseout(function(e){handleMouseUpOut(e);});
    
    $('#fast').on('click',function(){ duration=1000/60; beginRedrawing(); });
    $('#slow').on('click',function(){ duration=1000/15; beginRedrawing(); });
    
    function beginRedrawing(){
      if(points.length<2){return;}
      nextN=1;
      ctx.lineWidth=3;
      ctx.strokeStyle=randomColor();
      requestAnimationFrame(redraw);
    }
    
    function handleMouseDown(e){
      // tell the browser we're handling this event
      e.preventDefault();
      e.stopPropagation();
      // get current mouse position
      ctx.lineWidth=7;
      ctx.strokeStyle='black';
      points.length=0;
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      points.push({x:mouseX,y:mouseY});
      // Set dragging flag
      isDown=true;
    }
    
    function handleMouseUpOut(e){
      // tell the browser we're handling this event
      e.preventDefault();
      e.stopPropagation();
      // get current mouse position          
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      // Clear dragging flag
      isDown=false;
    }
    
    function handleMouseMove(e){
      if(!isDown){return;}
      // tell the browser we're handling this event
      e.preventDefault();
      e.stopPropagation();
      // get current mouse position
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      points.push({x:mouseX,y:mouseY});
      var n=points.length-1;
      lineSegment(points[n-1],points[n]);
    }
    
    function lineSegment(p0,p1){
      ctx.beginPath();
      ctx.moveTo(p0.x,p0.y);
      ctx.lineTo(p1.x,p1.y);
      ctx.stroke();
    }
    
    function redraw(time){
      if(nextN>points.length-1){return;}
      if(time<nextTime){requestAnimationFrame(redraw);return;}
      nextTime=time+duration;
      lineSegment(points[nextN-1],points[nextN]);
      nextN++;
      requestAnimationFrame(redraw);
    }
    
    function randomColor(){ 
      return('#'+Math.floor(Math.random()*16777215).toString(16));
    }
    body{ background-color: ivory; }
    #canvas{border:1px solid red; }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <h4>Drag to create polyline then click a redraw button below.</h4>
    <button id=fast>Fast Redraw</button>
    <button id=slow>Slow Redraw</button>
    <br>
    <canvas id="canvas" width=512 height=512></canvas>

    【讨论】:

      【解决方案2】:

      我不知道有任何库可以执行您所描述的操作,但是创建一个位置数组然后使用它应该可以大致完成您想要的操作。

      //Capture all mouse movements on the browser window.
      document.onmousemove = mousePos;
      
      //Store all previous mouse locations
      var ary = [];
      
      function mousePos (e) {
      
          //Log the current mouse position
          ary.push({X: e.pageX, Y: e.pageY});
      }
      

      现在您可以循环遍历数组来移动鼠标。

      function replay() {
      
        for (var i = 0; i < ary.length; i++) {
      
          //Draw a point wherever the mouse moved.
          ctx.fillRect(ary[i].X, ary[i].Y, 2, 2);  
        }
      }
      

      您可以添加持续时间的延迟,以您喜欢的任何速度播放。

      【讨论】:

        猜你喜欢
        • 2012-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-04
        • 1970-01-01
        • 1970-01-01
        • 2016-02-11
        相关资源
        最近更新 更多