2017-05-02 37 views
0

我正在畫一個簡單的拖動腳本。事情是,當我繪製一條線來連接鼠標位置的點時,畫布會從一些隨機點繪製額外的線條,但始終從初始點開始。在畫布上繪圖會使行從第一個點開始

下面是一個例子,看看問題:http://sktch.io/988111

我參加了一個這樣的鼠標移動捕獲的數據,並通過手工繪製每個點就去了,我可以證實,這個問題並沒有得到解決。令我惱火的是,如果我手動對某些任意點執行moveTo和lineTo操作,則代碼將起作用。鼠標拖拽點存在一些問題。據我所知,收集到的問題不存在問題。

任何指針表示讚賞。我已經嘗試了各種修改,例如beginPath,moveto,lineto和stroke在每個單循環迭代或beginpath中,以及在循環中 - moveto,lineto,然後在循環外敲擊。相同的結果。

有問題的代碼包含在底部。

var App = (function() { 
    var canvas, currentLayer, paint = false, context, socket, room, currentTool = 'line', 
    keysrt = function(key,desc) { 
     return function(a,b){ 
      return desc ? ~~(a[key] < b[key]) : ~~(a[key] > b[key]); 
     } 
    }, 
    reDraw = function() { 
     if (context) { 
      context.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight); 
      Object.keys(layers).sort().forEach(function(key) { 
       let layer = layers[key]; 
       switch(layer.getTool()) { 
        case 'line': 
         var data = layer.getData().sort(keysrt('time')); 
         if(data.length > 1) { 
          for(var i = 1; i < data.length; i++) { 
           context.beginPath(); 
           context.moveTo(data[i-1]['value'][0], data[i-1]['value'][1]); 
           context.lineTo(data[i]['value'][0], data[i]['value'][1]); 
           context.stroke(); 
          } 
         } 
         break; 
        case 'eraser': 
         var data = layer.getData().sort(keysrt('time')); 
         if(data.length > 0) { 
          for(var i = 0; i < data.length; i++) { 
           context.clearRect(data[i][0], data[i][1], 4, 4); 
          } 
         } 
         break; 
        case 'clear': 
         context.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight); 
         break; 
       } 
      }); 
     } 
    }, 
    Layer = function() { 
     var data = [], tool, id = new Date().getTime(); 
     return { 
      push: function(time, value) { 
       data.push({time: time, value: value}) 
      }, 
      toJSON: function() { 
       return { 
        data: data, 
        tool: tool, 
        id: id 
       } 
      }, 
      setTool: function(t) { 
       tool = t; 
      }, 
      getTool: function() { 
       return tool; 
      }, 
      getData: function() { 
       return data; 
      }, 
      getId: function() { 
       return id; 
      }, 
      setId: function(i) { 
       id = i; 
      }, 
      setData: function(d) { 
       data = d; 
      } 
     }; 
    }, 
    layers = {}, 
    events = 0; 
    press = function (e) { 
     var mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX) - this.offsetLeft, mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY) - this.offsetTop; 
     // add a layer 
     paint = true; 
     currentLayer = Layer(); 
     currentLayer.setTool(currentTool); 
     layers[currentLayer.getId()] = currentLayer; 
     events = 1; 
    }, 
    drag = function (e) { 
     var mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX) - this.offsetLeft, mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY) - this.offsetTop; 
     if (paint) { 
      events = events + 1; 
      currentLayer.push(new Date().getTime() * 10 + events, [mouseX, mouseY]); 
      reDraw() 
     } 
     e.preventDefault(); 
    }, 
    release = function() { 
     paint = false; 
     if(currentLayer) { 
      events = 0; 
      reDraw(); 
     } 
     currentLayer = null; 
    }, 
    init = function(id, appendTo, width, height) { 
     room = id; 
     canvas = document.createElement('canvas'); 
     canvas.setAttribute('width', width); 
     canvas.setAttribute('height', height); 
     canvas.setAttribute('id', 'canvas'); 
     appendTo.appendChild(canvas); 

     context = canvas.getContext("2d"); 

     canvas.addEventListener("mousedown", press, false); 
     canvas.addEventListener("mousemove", drag, false); 
     canvas.addEventListener("mouseup", release); 
     canvas.addEventListener("mouseout", release, false); 

     // Add touch event listeners to canvas element 
     canvas.addEventListener("touchstart", press, false); 
     canvas.addEventListener("touchmove", drag, false); 
     canvas.addEventListener("touchend", release, false); 
     canvas.addEventListener("touchcancel", release, false); 

     document.getElementById('clear').addEventListener("click", function() { 
      layer = Layer(); 
      layer.setTool('clear'); 
      layers[layer.getId()] = layer; 
      reDraw(); 
     }, false); 
    } 
    return { 
     init: init 
    } 
})(); 
+0

你缺少'context.clearRect(0,0,canvasWidth,canvasHeight );' – Rayon

+0

@Rayon它在那裏。在reDraw方法中。行號10. – Amit

+0

@Kaiido單擊並拖動包含的鏈接中的框是http://stackoverflow.com/help/mcve – Amit

回答

0

的錯誤就在於你的排序功能,只返回01

因此改變你的keysrt爲更具可讀性

keysrt = function(key,desc) { 
    return function(a,b){ 
     if(desc){ 
      if(a[key] < b[key]) return 1; 
      if(a[key] > b[key]) return -1; 
      return 0; 
      } 
     else{ 
      if(a[key] < b[key]) return -1; 
      if(a[key] > b[key]) return 1; 
      return 0; 
      }    
    } 

修復該問題:

var App = (function() { 
 
    var canvas, currentLayer, paint = false, 
 
    context, socket, room, currentTool = 'line', 
 
    keysrt = function(key, desc) { 
 
     return function(a, b) { 
 
     if (desc) { 
 
      if (a[key] < b[key]) return 1; 
 
      if (a[key] > b[key]) return -1; 
 
      return 0; 
 
     } else { 
 
      if (a[key] < b[key]) return -1; 
 
      if (a[key] > b[key]) return 1; 
 
      return 0; 
 
     } 
 
     } 
 
    }, 
 
    reDraw = function() { 
 
     if (context) { 
 
     context.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight); 
 
     Object.keys(layers).sort().forEach(function(key) { 
 
      let layer = layers[key]; 
 
      switch (layer.getTool()) { 
 
      case 'line': 
 
       var data = layer.getData().sort(keysrt('time')); 
 
       if (data.length > 1) { 
 
       for (var i = 1; i < data.length; i++) { 
 
        context.beginPath(); 
 
        context.moveTo(data[i - 1]['value'][0], data[i - 1]['value'][1]); 
 
        context.lineTo(data[i]['value'][0], data[i]['value'][1]); 
 
        context.stroke(); 
 
       } 
 
       } 
 
       break; 
 
      case 'eraser': 
 
       var data = layer.getData().sort(keysrt('time')); 
 
       if (data.length > 0) { 
 
       for (var i = 0; i < data.length; i++) { 
 
        context.clearRect(data[i][0], data[i][1], 4, 4); 
 
       } 
 
       } 
 
       break; 
 
      case 'clear': 
 
       context.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight); 
 
       break; 
 
      } 
 
     }); 
 
     } 
 
    }, 
 
    Layer = function() { 
 
     var data = [], 
 
     tool, id = new Date().getTime(); 
 
     return { 
 
     push: function(time, value) { 
 
      data.push({ 
 
      time: time, 
 
      value: value 
 
      }) 
 
     }, 
 
     toJSON: function() { 
 
      return { 
 
      data: data, 
 
      tool: tool, 
 
      id: id 
 
      } 
 
     }, 
 
     setTool: function(t) { 
 
      tool = t; 
 
     }, 
 
     getTool: function() { 
 
      return tool; 
 
     }, 
 
     getData: function() { 
 
      return data; 
 
     }, 
 
     getId: function() { 
 
      return id; 
 
     }, 
 
     setId: function(i) { 
 
      id = i; 
 
     }, 
 
     setData: function(d) { 
 
      data = d; 
 
     } 
 
     }; 
 
    }, 
 
    layers = {}, 
 
    events = 0; 
 
    press = function(e) { 
 
     var mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX) - this.offsetLeft, 
 
     mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY) - this.offsetTop; 
 
     // add a layer 
 
     paint = true; 
 
     currentLayer = Layer(); 
 
     currentLayer.setTool(currentTool); 
 
     layers[currentLayer.getId()] = currentLayer; 
 
     events = 1; 
 
    }, 
 
    drag = function(e) { 
 
     var mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX) - this.offsetLeft, 
 
     mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY) - this.offsetTop; 
 
     if (paint) { 
 
     events = events + 1; 
 
     currentLayer.push(new Date().getTime() * 10 + events, [mouseX, mouseY]); 
 
     reDraw() 
 
     } 
 
     e.preventDefault(); 
 
    }, 
 
    release = function() { 
 
     paint = false; 
 
     if (currentLayer) { 
 
     events = 0; 
 
     reDraw(); 
 
     } 
 
     currentLayer = null; 
 
    }, 
 
    init = function(id, appendTo, width, height) { 
 
     room = id; 
 
     canvas = document.createElement('canvas'); 
 
     canvas.setAttribute('width', width); 
 
     canvas.setAttribute('height', height); 
 
     canvas.setAttribute('id', 'canvas'); 
 
     appendTo.appendChild(canvas); 
 

 
     context = canvas.getContext("2d"); 
 

 
     canvas.addEventListener("mousedown", press, false); 
 
     canvas.addEventListener("mousemove", drag, false); 
 
     canvas.addEventListener("mouseup", release); 
 
     canvas.addEventListener("mouseout", release, false); 
 

 
     // Add touch event listeners to canvas element 
 
     canvas.addEventListener("touchstart", press, false); 
 
     canvas.addEventListener("touchmove", drag, false); 
 
     canvas.addEventListener("touchend", release, false); 
 
     canvas.addEventListener("touchcancel", release, false); 
 

 
    } 
 
    return { 
 
    init: init 
 
    } 
 

 
})(); 
 
App.init('', document.body, 800, 800)