Javascript 使用HTML5画布为绘画应用程序创建逼真的铅笔工具
首先我想说的是,我做了大量的研究并尝试了自己,但没有取得任何成功 我正在使用Canvas开发一个类似MSPaint的应用程序,我想创建一个铅笔工具,它看起来像手工绘制的图画一样逼真。。。下面是链接中使用默认工具的示例: 我尝试使用mousespeed和linewidth属性,但效果不好(移动鼠标时,整行会放大和缩小)。我不知道对像素原始数据起作用的算法 你知道一些现有的或适用的算法吗?非常感谢你的帮助 编辑 我决定添加我选择的解决方案,因为它似乎引起了很多人的兴趣。 因此,到目前为止,我发现最好的方法是使用此处介绍的技术在画布上绘制图像:。Javascript 使用HTML5画布为绘画应用程序创建逼真的铅笔工具,javascript,image-processing,canvas,html5-canvas,Javascript,Image Processing,Canvas,Html5 Canvas,首先我想说的是,我做了大量的研究并尝试了自己,但没有取得任何成功 我正在使用Canvas开发一个类似MSPaint的应用程序,我想创建一个铅笔工具,它看起来像手工绘制的图画一样逼真。。。下面是链接中使用默认工具的示例: 我尝试使用mousespeed和linewidth属性,但效果不好(移动鼠标时,整行会放大和缩小)。我不知道对像素原始数据起作用的算法 你知道一些现有的或适用的算法吗?非常感谢你的帮助 编辑 我决定添加我选择的解决方案,因为它似乎引起了很多人的兴趣。 因此,到目前为止,我发现最
它就像一个符咒,结果真的令人信服,这是很容易实施。在这里尝试一下:您可以尝试下面的演示 您最有可能使用
moveTo
和lineTo
创建路径,如果这样做,将共享路径的属性,直到您关闭路径。因此,每次更改厚度时,都需要调用closePath
,然后再次调用beginPath
在我的示例中,我使用绘制点。基本上,它开始画画。然后,在MouseMove上,它将当前坐标与最后一个坐标进行比较,并绘制它们之间的所有点。它还可以使用fillRect
进行绘制。根据移动的速度,线条会变粗或变细
这是绘图功能的代码
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
painting = false,
lastX = 0,
lastY = 0,
lineThickness = 1;
canvas.width = canvas.height = 600;
ctx.fillRect(0, 0, 600, 600);
canvas.onmousedown = function(e) {
painting = true;
ctx.fillStyle = "#ffffff";
lastX = e.pageX - this.offsetLeft;
lastY = e.pageY - this.offsetTop;
};
canvas.onmouseup = function(e){
painting = false;
}
canvas.onmousemove = function(e) {
if (painting) {
mouseX = e.pageX - this.offsetLeft;
mouseY = e.pageY - this.offsetTop;
// find all points between
var x1 = mouseX,
x2 = lastX,
y1 = mouseY,
y2 = lastY;
var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
if (steep){
var x = x1;
x1 = y1;
y1 = x;
var y = y2;
y2 = x2;
x2 = y;
}
if (x1 > x2) {
var x = x1;
x1 = x2;
x2 = x;
var y = y1;
y1 = y2;
y2 = y;
}
var dx = x2 - x1,
dy = Math.abs(y2 - y1),
error = 0,
de = dy / dx,
yStep = -1,
y = y1;
if (y1 < y2) {
yStep = 1;
}
lineThickness = 5 - Math.sqrt((x2 - x1) *(x2-x1) + (y2 - y1) * (y2-y1))/10;
if(lineThickness < 1){
lineThickness = 1;
}
for (var x = x1; x < x2; x++) {
if (steep) {
ctx.fillRect(y, x, lineThickness , lineThickness );
} else {
ctx.fillRect(x, y, lineThickness , lineThickness );
}
error += de;
if (error >= 0.5) {
y += yStep;
error -= 1.0;
}
}
lastX = mouseX;
lastY = mouseY;
}
}
var canvas=document.getElementById(“canvas”),
ctx=canvas.getContext(“2d”),
绘画=假,
lastX=0,
lastY=0,
线宽=1;
canvas.width=canvas.height=600;
ctx.fillRect(0,060600);
canvas.onmousedown=函数(e){
绘画=真实;
ctx.fillStyle=“#ffffff”;
lastX=e.pageX-this.offsetLeft;
lastY=e.pageY-this.offsetTop;
};
canvas.onmouseup=函数(e){
绘画=假;
}
canvas.onmousemove=函数(e){
如果(绘画){
mouseX=e.pageX-this.offsetLeft;
mouseY=e.pageY-this.offsetTop;
//找出所有点之间的距离
var x1=鼠标,
x2=lastX,
y1=老鼠,
y2=整形术;
var陡峭=(数学abs(y2-y1)>数学abs(x2-x1));
如果(陡峭){
var x=x1;
x1=y1;
y1=x;
变量y=y2;
y2=x2;
x2=y;
}
如果(x1>x2){
var x=x1;
x1=x2;
x2=x;
变量y=y1;
y1=y2;
y2=y;
}
变量dx=x2-x1,
dy=数学绝对值(y2-y1),
错误=0,
de=dy/dx,
yStep=-1,
y=y1;
if(y1=0.5){
y+=yStep;
误差-=1.0;
}
}
lastX=鼠标;
拉蒂=老鼠;
}
}
@Loktar我尝试使用jquery mobile实现同样的事情。我可以获得touchevents,但无法划定界限。你能帮忙吗?谢谢:)我很难弄明白这是怎么回事。我意识到这很容易看到。有选择地切换出:
if(陡峭){
,if(x1>x2){
,也做else if(x1>x2){
(用于实验),也切换if(y1
您将直观地看到算法在做什么。我想让您知道,您已经在互联网上创建了一个感觉最好的铅笔工具(比许多有绘图工具的网站要好得多)。哇@汤姆帕克,我真的很感激!也许我会将它包装成一个组件或其他东西,然后扔到Github上。