在画布上绘制会导致线路从第一点开始



我正在做一个简单的拖动来在画布上绘制脚本。问题是,当我绘制一条线以连接鼠标位置的点时,画布会从某些随机点中绘制额外的线,但总是从初始点开始。

这是一个示例,可以查看问题:http://sktch.io/988111

我以这样的鼠标移动捕获了捕获的数据,然后手动通过绘制每个点,我可以确认问题无法解决。让我烦恼的是,如果我手动执行Moveto和Lineto的某些任意点,则代码可行。鼠标阻力点有一些问题。据我所知,收集的点没有问题。

任何指针都将受到赞赏。我已经尝试了各种修改,例如每个单个循环迭代或开始手路径中的BeginPath,Moveto,Lineto和Stroke,以及在循环 - 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
    }
})();

该错误在于您的排序功能,仅返回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)

最新更新