在画布中动态绘制

时间:2017-10-17 08:18:38

标签: javascript html5 canvas drawing

我试图创建一个简单的,纯粹的JS程序,用于在画布中绘图。我现在有一个可以接受的解决方案,但是如果我画得非常快,我的画笔不是连续的,我会得到分散的圈子,可能是因为电脑无法跟上节奏。



var draw = false;

function yesDraw() {
  draw = true;
}

function mouseCoordinates(e) {
  if (draw) {
    var x = e.offsetX;
    var y = e.offsetY;
    drawing(x, y);
  }
}

function noDraw() {
  draw = false;
}
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

function drawing(x, y) {
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, 2 * Math.PI);
  ctx.fillStyle = "black";
  ctx.fill();
}

<canvas id="myCanvas" height="400" ; width="1000" onmousedown="yesDraw()" onmousemove="mouseCoordinates(event)" onmouseup="noDraw()" onmouseout="noDraw()" style="border: solid 1px black;">Your browser does not support canvas.</canvas>
&#13;
&#13;
&#13;

有没有办法获得持续的绘图流程并仍然保持100%JS?

2 个答案:

答案 0 :(得分:0)

使用lineTo并结束arc中的每一行,以制作连续流畅的线条。

&#13;
&#13;
//Create Canvas
//(You can do this in HTML)
var c = document.body.appendChild(document.createElement("canvas"));
c.height = 400;
c.width = 1000;
var ctx = c.getContext("2d");
ctx.lineWidth = 20;
//Control drawing variable
var drawing = false;
c.onmousedown = c.onmouseout = c.onmouseup = function(evt) {
  drawing = (evt.type === "mousedown");
};
//Keep track of last position
var oldX = null;
var oldY = null;
/**
 * Draw the latest line
 *
 * @param {number} x
 * @param {number} y
 */
function draw(x, y) {
  if (drawing) {
    if (oldX !== null) {
      //If drawing, move to old coordinates for continual line
      ctx.beginPath();
      ctx.moveTo(oldX, oldY);
    } else {
      //Else simply move to current coordinates
      ctx.moveTo(x, y);
      ctx.beginPath();
    }
    //Draw a line
    ctx.lineTo(x, y);
    ctx.closePath();
    ctx.stroke();
    //Add an arc to the end of the line to make it smooth
    ctx.beginPath();
    ctx.arc(x, y, 0, 0, Math.PI * 2);
    ctx.closePath();
    ctx.stroke();
    //Save new coordinates as old for next draw cycle
    oldX = x;
    oldY = y;
  } else {
    //If not drawing, cut line byt setting "old" to null
    oldX = null;
    oldY = null;
  }
}
//Bind drawing
c.onmousemove = function(evt) {
  draw(evt.offsetX, evt.offsetY);
};
&#13;
canvas {
  border: solid 1px black;
  background-color: #eee;
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

以前鼠标位置的线段。

不是绘制弧线而是从先前的鼠标位置绘制线段到新的位置。由于您不希望从上一次绘制的末尾绘制线条,您还需要指示新线条何时开始并将前一个鼠标位置设置为当前鼠标。

为此,我添加了3个变量lastXlastYlineStart

触发鼠标按下事件时,

lastX设置为true。在绘图函数中,如果行开始为真,则lastYx设置为ylineStartlastX设置为false。 lastYx保留上一个鼠标位置。它们在每次绘制调用结束时设置为yctx.lineWidth

线段需要将2D上下文属性ctx.lineCap设置为线宽。为确保该行是连续的,"round"属性设置为document。这会在行的开头和结尾添加一个半圆。

越过边缘

当鼠标移出时关闭笔是令人讨厌的,你这样做是因为如果你不这样做,你会丢失鼠标按钮事件,鼠标会继续用鼠标按钮绘图。

如果将鼠标添加到const c = document.getElementById("myCanvas"); const ctx = c.getContext("2d"); const r = 10; // draw radius ctx.lineWidth = r * 2; ctx.lineCap = "round"; ctx.fillStyle = "black"; var draw = false; var lineStart = true; var lastX, lastY; function yesDraw() { draw = true; lineStart = true } function mouseMove(e) { const bounds = c.getBoundingClientRect(); const x = e.pageX - bounds.left - scrollX; const y = e.pageY - bounds.top - scrollY; if(draw && x > -r && x < c.width + r && y > -r && y < c.height + r){ drawing(x,y); } } function noDraw() { draw = false } document.addEventListener("mousemove",mouseMove); document.addEventListener("mousedown",yesDraw); document.addEventListener("mouseup",noDraw); function drawing(x, y) { if(lineStart){ lastX = x; lastY = y; lineStart = false; } ctx.beginPath(); ctx.lineTo(lastX, lastY); ctx.lineTo(x, y); ctx.stroke(); lastX = x; lastY = y; }而不是画布,则不必担心鼠标会移到框架之外。即使鼠标完全是标签和浏览器,您仍然可以获得鼠标左键事件。

虽然您将不得不使用稍微不同的获取鼠标坐标的方法,因为您仍然希望在离开画布时仍然至少绘制一半的绘制线宽度。请参阅有关如何获取鼠标坐标的代码。

<canvas id="myCanvas" height="400" ; width="1000" style="border: solid 1px black;">Your browser does not support canvas.</canvas>
$i = 0