Software drawing programming is one of the topics that most IT students are eager to explore due to its inherent fascination. Simply put, it resembles the Windows Paint software, allowing users to choose colors, select brush thickness, and draw freely on the canvas.

The intricate and complex nature of users’ freehand drawing strokes makes it challenging to represent them with mathematical formulas, often leading to whimsical and carefree doodles. To address this issue, the approach is to consider the drawn line as a collection of numerous extremely short, consecutive straight lines.

vẽ đường cong

According to this understanding, the freehand drawing action with the mouse can be described as follows:

  • When the user clicks the mouse and hasn’t released it (mouse down), the current position is saved, and the variable drawing is set to true to indicate the beginning of the drawing state.
  • As the user holds the mouse and moves it to a different position (mouse move), continuous straight lines are drawn from the previous position to the new position.
  • When the user releases the mouse (mouse up), the variable drawing is set to false to stop further drawing.

You can watch the video to understand the process. The video, created entirely from scratch during a 1-hour live stream

First, we create an object representing the drawing board with basic attributes, create a canvas, and append it to the body.

var draw = function(){
    this.canvas    = null;
    this.context   = null;
    this.width     = 700;
    this.height    = 500;
    this.x         = 0;
    this.y         = 0;
    this.drawing   = false;
    this.lineWidth = 3;
    this.color     = "#000000";

    var self = this;

    this.init = function(){
        this.canvas        = document.createElement('canvas');
        this.context       = this.canvas.getContext('2d');
        this.canvas.width  = this.width;
        this.canvas.height = this.height;

        document.body.appendChild(this.canvas);
    }
}

Next, we set the canvas background by drawing a white rectangle covering the entire canvas.

this.drawBackground = function(){
    this.context.fillStyle = "#ffffff";
    this.context.fillRect(0, 0, this.width, this.height);
}

As mentioned earlier, freehand drawing is a collection of straight lines, so we write a function to draw a straight line from any given position (startX, startY) to (endX, endY).

this.drawLine = function(startX, startY, endX, endY){
    this.context.beginPath();
    this.context.moveTo(startX, startY);
    this.context.lineTo(endX, endY);
    this.context.lineWidth = this.lineWidth;
    this.context.strokeStyle = this.color;
    this.context.stroke();
}

We also create a function to get the mouse cursor position, returning an object with the current x and y coordinates relative to the canvas.

this.getMousePosition = function(event){
    var rect = this.canvas.getBoundingClientRect();
    return {
        x: event.clientX - rect.left,
        y: event.clientY - rect.top
    }
}

We capture mouse events (mousedown, mouseup, and mousemove) to execute corresponding event-handling functions.

this.canvas.addEventListener('mousedown', function(event){
    self.proccessMouseDown(event);
});
this.canvas.addEventListener('mouseup', function(event){
    self.proccessMouseUp(event);
});
this.canvas.addEventListener('mousemove', function(event){
    self.proccessMouseMove(event);
});

For the mouse down event, we save the current position and set the drawing variable to true.

this.processMouseDown = function(event){
    var position = this.getMousePosition(event);
    this.x = position.x;
    this.y = position.y;
    this.drawing = true; // bấm chuột xuống thì bắt đầu vẽ
}

Conversely, for the mouse up event, we set the drawing variable to false, indicating that the user has stopped drawing.

this.proccessMouseUp = function(event){
    this.drawing = false;
}

During mouse move events, if drawing is true (indicating that the mouse button is still pressed), we draw continuous lines from the previous position to the new position, updating the position accordingly.

this.proccessMouseMove = function(event){
    if (this.drawing){
        var newPos = this.getMousePosition(event);
        this.drawLine(this.x, this.y, newPos.x, newPos.y);
        this.x = newPos.x;
        this.y = newPos.y;
    }
}

At this point, you’ve created a freehand drawing effect on the web. In the video, additional features such as selecting the color of the drawing tool are implemented. Feel free to download the code to explore further.