我试图创建一个简单的,纯粹的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;
有没有办法获得持续的绘图流程并仍然保持100%JS?
答案 0 :(得分:0)
使用lineTo并结束arc中的每一行,以制作连续流畅的线条。
//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;
答案 1 :(得分:0)
不是绘制弧线而是从先前的鼠标位置绘制线段到新的位置。由于您不希望从上一次绘制的末尾绘制线条,您还需要指示新线条何时开始并将前一个鼠标位置设置为当前鼠标。
为此,我添加了3个变量lastX
,lastY
和lineStart
lastX
设置为true。在绘图函数中,如果行开始为真,则lastY
和x
设置为y
,lineStart
,lastX
设置为false。
lastY
,x
保留上一个鼠标位置。它们在每次绘制调用结束时设置为y
,ctx.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