在html5画布上移动已绘制的形状

时间:2013-03-15 15:46:48

标签: html5 debugging canvas drag-and-drop clipping

我无法在画布上保留一个对象。最初绘制的框将其渲染到正确的位置,但是当我拖动它时它会消失:

    var canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d'),
    eraseAllButton = document.getElementById('eraseAllButton'),
    strokeStyleSelect = document.getElementById('strokeStyleSelect'),
    guidewireCheckbox = document.getElementById('guidewireCheckbox'),
    drawingSurfaceImageData,
    mousedown = {},
    rubberbandRect = {},
    dragging = false,
    guidewires = guidewireCheckbox.checked,
    w = 90, h = 90;
    count = 0;
    boxesXCo = 0;
    boxesYCo = 0;
    i = 0;

// Functions..........................................................
function drawGrid(color, stepx, stepy) {
   context.save()

   context.strokeStyle = color;
   context.lineWidth = 0.5;
   context.clearRect(0, 0, context.canvas.width, context.canvas.height);

   for (var i = stepx + 0.5; i < context.canvas.width; i += stepx) {
     context.beginPath();
     context.moveTo(i, 0);
     context.lineTo(i, context.canvas.height);
     context.stroke();
   }

   for (var i = stepy + 0.5; i < context.canvas.height; i += stepy) {
     context.beginPath();
     context.moveTo(0, i);
     context.lineTo(context.canvas.width, i);
     context.stroke();
   }

   context.restore();
}

function windowToCanvas(x, y) {
   var bbox = canvas.getBoundingClientRect();
   return { x: x - bbox.left * (canvas.width  / bbox.width),
            y: y - bbox.top  * (canvas.height / bbox.height) };
}

// Save and restore drawing surface...................................
function saveDrawingSurface() {
   drawingSurfaceImageData = context.getImageData(0, 0,
                             canvas.width,
                             canvas.height);
}

function restoreDrawingSurface() {
   context.putImageData(drawingSurfaceImageData, 0, 0);
}


function drawRubberbandShape(loc) {
   context.beginPath();
   context.moveTo(mousedown.x, mousedown.y);
   //context.lineTo(loc.x, loc.y);

   context.stroke();
}

function updateRubberband(loc) {
   //updateRubberbandRectangle(loc);
   context.restore();
   drawRubberbandShape(loc);
}

// Guidewires.........................................................
function drawHorizontalLine (y) {
   context.beginPath();
   context.moveTo(0,y+0.5);
   context.lineTo(context.canvas.width,y+0.5);
   context.stroke();
}

function drawVerticalLine (x) {
   context.beginPath();
   context.moveTo(x+0.5,0);
   context.lineTo(x+0.5,context.canvas.height);
   context.stroke();
}

function drawGuidewires(x, y) {
   context.save();
   context.strokeStyle = 'rgba(0,0,230,0.4)';
   context.lineWidth = 0.5;
   drawVerticalLine(x);
   drawHorizontalLine(y);
   context.restore();
}

// Canvas event handlers..............................................
canvas.onmousedown = function (e) {
   var loc = windowToCanvas(e.clientX, e.clientY);

   e.preventDefault(); // prevent cursor change
   context.restore();
   saveDrawingSurface();
   mousedown.x = loc.x;
   mousedown.y = loc.y;
   dragging = true;
   if (i ==0)
   i++;
   else if(((mousedown.x<=(boxesXCo+w)&&(mousedown.x>=boxesXCo))&&
                  ((mousedown.y<=(boxesYCo+h)&&(mousedown.y>=boxesYCo)))))
   i--;

};

canvas.onmousemove = function (e) {
   var loc; 

   if (dragging) {
      e.preventDefault(); // prevent selections

      loc = windowToCanvas(e.clientX, e.clientY);
      restoreDrawingSurface();
      //updateRubberband(loc);

      if(guidewires) {
         drawGuidewires(loc.x, loc.y);
      }
   }

   if(((mousedown.x<=(boxesXCo+w)&&(mousedown.x>=boxesXCo))&&
                  ((mousedown.y<=(boxesYCo+h)&&(mousedown.y>=boxesYCo))))
   && (dragging)&&(i == 1 )){
         context.restore();
         restoreDrawingSurface();
         context.fillStyle = strokeStyleSelect.value;
         context.fillRect(e.clientX,e.clientY,w,h);


      };

   //Trying to implement moving shapes but need to store values of drawn objs

};

canvas.onmouseup = function (e) {
   loc = windowToCanvas(e.clientX, e.clientY);
   restoreDrawingSurface();
   updateRubberband(loc);
   dragging = false;


      if(i == 0);
      else {
         saveDrawingSurface();
      restoreDrawingSurface();
      context.fillRect(e.clientX,e.clientY, w, h);
      boxesXCo = e.clientX;
      boxesYCo = e.clientY;

      context.restore(); 
      i++;}

      /*else if(i == 1)
      {
         context.restore();
      }*/




   //context.fillRect(mousedown.x,mousedown.y,w,h,"FF0982");
};

// Controls event handlers.......................................

eraseAllButton.onclick = function (e) {
   context.clearRect(0, 0, canvas.width, canvas.height);
   drawGrid('lightgray', 10, 10);
   saveDrawingSurface();
   count =0;
   context.restore();
};

strokeStyleSelect.onchange = function (e) {
   context.strokeStyle = strokeStyleSelect.value;
    context.fillStyle = strokeStyleSelect.value;
};

guidewireCheckbox.onchange = function (e) {
   guidewires = guidewireCheckbox.checked;
};

// Initialization................................................
context.strokeStyle = strokeStyleSelect.value;
context.fillStyle = strokeStyleSelect.value;
drawGrid('lightgray', 10, 10);


//context.fillRect(mousedown.x,mousedown.y,(mousedown.x+50),(mousedown.x+50),"FF0982");
//context.drawRect(mousedown.x-50,mousedown.y-50,mousedown.x+50,mousedown.y+50);
再次

再次

1 个答案:

答案 0 :(得分:0)

不要在每次鼠标移动时绘制到画布,而是使用window.requestFrameAnimation不断绘制。

猜测一下,我认为浏览器渲染干扰或坐标已经出来但是我无法运行你的代码来确保。

我写了一些伪代码,展示了我为渲染事物所做的工作。你需要自己实现它,它不会开箱即用,它只是作为指导。

var Box = function() {
};
Box.prototype = {
    x: 0,
    y: 0,
    draw: function (canvas) {
        // draw the item on the canvas
    }
};

var box = new Box();

window.requestAnimationFrame(function() {
    box.draw(canvas);
    window.requestAnimationFrame();
});

canvas.onmousemove = function(e) {
    if (dragging) {
        box.x = e.clientX;
        box.y = e.clientY;
    }
}