Monday, June 3, 2024
5
rated 0 times [  8] [ 3]  / answers: 1 / hits: 19780  / 12 Years ago, thu, april 12, 2012, 12:00:00

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#


More From » image-processing

 Answers
170

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;

}
}



[#86285] Wednesday, April 11, 2012, 12 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
irvinjovannix

Total Points: 416
Total Questions: 94
Total Answers: 117

Location: South Korea
Member since Sun, Aug 8, 2021
3 Years ago
;