First I want to say that I made a lot of research and tries myself without any success.
I am working on a MSPaint-like application using Canvas, and I would like to create a pencil tool which looks realistic like handmade drawings... Here is an example in the link below with the default tool : http://www.onemotion.com/flash/sketch-paint/
I tried to play with mousespeed and linewidth properties but it is not working well (the entire line enlarge and shrink as I move the mouse). I have no idea of an algorithm acting on pixel raw data.
Do you know something existing or a suitable algorithm to apply ? Thank you very much for your help
EDIT
I decided to add the solution I've chosen because it seems to interest lot of people. So, the best thing I found so far is to draw an image onto the canvas, using the technique explained here : http://css.dzone.com/articles/sketching-html5-canvas-and. It works like a charm, the result is really convincing and this is quite easy to implement. Try it out here : http://tricedesigns.com/portfolio/sketch/brush.html#
You could try something like the following demo
Live Demo
Your most likely using moveTo
and lineTo
to create the paths, if you do it that way the properties will be shared for the path until you close the path. So everytime you change the thickness youd need to call closePath
and then beginPath
again.
In my example I use Bresenham's line algorithm to plot the points. Basically onmousedown it starts painting. Then onmousemove it compares the current coordinates with the last coordinates and plots all of the points between. Its also using fillRect
to paint. Based on how fast your moving the line will be thicker or thinner.
Heres the code for the drawing function
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With