Hướng dẫn beginpath trong javascript

Chào các bạn, trong bài viết này chúng ta sẽ cùng nhau làm ứng dụng Paint brush. Nếu các bạn chưa biết Paint brush là gì thì đây là ứng dụng cho phép chúng ta vẽ các đường nét trên 1 vùng không gian nhất định tương tự như ứng dụng Paint trong window. Các bạn có thể mở ứng dụng Paint để tham khảo

Ứng dụng mà chúng ta làm lần này sẽ không phức tạp như Paint mà sẽ đơn giản hơn bao gồm các chức năng sau:

  • Vẽ các nét
  • Reset nét vẽ
  • Chọn màu cho nét vẽ
  • Chọn kích thước cho nét vẽ

Phần tạo giao diện cho ứng dụng, mình để sources code ở đây để các bạn tham khảo, hoặc các bạn có thể tự tạo giao diện cho ứng dụng của mình

Link tham khảo: //github.com/buihien0109/buihien0109.github.io/tree/master/HTML5-Games/game/paint/part-1

Đây là giao diện ban đầu của chúng ta

1. Ý tưởng thực hiện

1. Thành phần

Trong ứng dụng Paint có 2 thành phần:

  • class FreeHand {
        constructor[canvas] {
            this.canvas = canvas;
    
            // Lưu context để vẽ 2D
            this.context = canvas.getContext["2d"];
    
            // Kiểm tra khi nào được draw, khi nào không
            this.isDraw = false;
    
            // Lưu lại tọa độ các point đã vẽ
            this.points = [];
    
            // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
            this.context.lineWidth = 2;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.strokeStyle = "#FFF";
    
            // Memmory canvas, dùng để ghi nhớ các nét vẽ
            this.memCanvas = document.createElement["canvas"];
            this.memCanvas.width = canvas.width;
            this.memCanvas.height = canvas.height;
            this.memCtx = this.memCanvas.getContext["2d"];
        }
    }
    0 : Khu vực thực hiện công việc vẽ
  • class FreeHand {
        constructor[canvas] {
            this.canvas = canvas;
    
            // Lưu context để vẽ 2D
            this.context = canvas.getContext["2d"];
    
            // Kiểm tra khi nào được draw, khi nào không
            this.isDraw = false;
    
            // Lưu lại tọa độ các point đã vẽ
            this.points = [];
    
            // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
            this.context.lineWidth = 2;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.strokeStyle = "#FFF";
    
            // Memmory canvas, dùng để ghi nhớ các nét vẽ
            this.memCanvas = document.createElement["canvas"];
            this.memCanvas.width = canvas.width;
            this.memCanvas.height = canvas.height;
            this.memCtx = this.memCanvas.getContext["2d"];
        }
    }
    1 : Ghi nhớ nét vẽ từ canvas khi kết thúc 1 nét vẽ, và render lại tất cả các nét vẽ sang canvas để thực hiện nét vẽ tiếp theo

2. Quá trình thực hiện

  • Đầu tiên chúng ta sẽ có mảng
    class FreeHand {
        constructor[canvas] {
            this.canvas = canvas;
    
            // Lưu context để vẽ 2D
            this.context = canvas.getContext["2d"];
    
            // Kiểm tra khi nào được draw, khi nào không
            this.isDraw = false;
    
            // Lưu lại tọa độ các point đã vẽ
            this.points = [];
    
            // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
            this.context.lineWidth = 2;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.strokeStyle = "#FFF";
    
            // Memmory canvas, dùng để ghi nhớ các nét vẽ
            this.memCanvas = document.createElement["canvas"];
            this.memCanvas.width = canvas.width;
            this.memCanvas.height = canvas.height;
            this.memCtx = this.memCanvas.getContext["2d"];
        }
    }
    2 để lưu giá trị tọa độ của các điểm
  • Nhấn chuột xuống để bắt đầu vẽ, chúng ta tiến hành xóa toàn bộ canvas, sau đó copy các nét vẽ từ bên
    class FreeHand {
        constructor[canvas] {
            this.canvas = canvas;
    
            // Lưu context để vẽ 2D
            this.context = canvas.getContext["2d"];
    
            // Kiểm tra khi nào được draw, khi nào không
            this.isDraw = false;
    
            // Lưu lại tọa độ các point đã vẽ
            this.points = [];
    
            // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
            this.context.lineWidth = 2;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.strokeStyle = "#FFF";
    
            // Memmory canvas, dùng để ghi nhớ các nét vẽ
            this.memCanvas = document.createElement["canvas"];
            this.memCanvas.width = canvas.width;
            this.memCanvas.height = canvas.height;
            this.memCtx = this.memCanvas.getContext["2d"];
        }
    }
    3 ➡➡
    class FreeHand {
        constructor[canvas] {
            this.canvas = canvas;
    
            // Lưu context để vẽ 2D
            this.context = canvas.getContext["2d"];
    
            // Kiểm tra khi nào được draw, khi nào không
            this.isDraw = false;
    
            // Lưu lại tọa độ các point đã vẽ
            this.points = [];
    
            // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
            this.context.lineWidth = 2;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.strokeStyle = "#FFF";
    
            // Memmory canvas, dùng để ghi nhớ các nét vẽ
            this.memCanvas = document.createElement["canvas"];
            this.memCanvas.width = canvas.width;
            this.memCanvas.height = canvas.height;
            this.memCtx = this.memCanvas.getContext["2d"];
        }
    }
    4, sau đó tiến hành vẽ nét mới, trong quá trình di chuyển chuột để vẽ nét mới lấy tọa độ của các điểm sau đó thêm vào mảng
    class FreeHand {
        constructor[canvas] {
            this.canvas = canvas;
    
            // Lưu context để vẽ 2D
            this.context = canvas.getContext["2d"];
    
            // Kiểm tra khi nào được draw, khi nào không
            this.isDraw = false;
    
            // Lưu lại tọa độ các point đã vẽ
            this.points = [];
    
            // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
            this.context.lineWidth = 2;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.strokeStyle = "#FFF";
    
            // Memmory canvas, dùng để ghi nhớ các nét vẽ
            this.memCanvas = document.createElement["canvas"];
            this.memCanvas.width = canvas.width;
            this.memCanvas.height = canvas.height;
            this.memCtx = this.memCanvas.getContext["2d"];
        }
    }
    2
  • Từ mảng
    class FreeHand {
        constructor[canvas] {
            this.canvas = canvas;
    
            // Lưu context để vẽ 2D
            this.context = canvas.getContext["2d"];
    
            // Kiểm tra khi nào được draw, khi nào không
            this.isDraw = false;
    
            // Lưu lại tọa độ các point đã vẽ
            this.points = [];
    
            // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
            this.context.lineWidth = 2;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.strokeStyle = "#FFF";
    
            // Memmory canvas, dùng để ghi nhớ các nét vẽ
            this.memCanvas = document.createElement["canvas"];
            this.memCanvas.width = canvas.width;
            this.memCanvas.height = canvas.height;
            this.memCtx = this.memCanvas.getContext["2d"];
        }
    }
    6 chúng ta sẽ vẽ nên các nét trên bề mặt canvas
  • Khi nhả chuột ra để kết thúc nét vẽ, lúc này xóa toàn bộ các nét vẽ trên memory canvas đồng thời đưa tất cả các nét trên bề mặt
    class FreeHand {
        constructor[canvas] {
            this.canvas = canvas;
    
            // Lưu context để vẽ 2D
            this.context = canvas.getContext["2d"];
    
            // Kiểm tra khi nào được draw, khi nào không
            this.isDraw = false;
    
            // Lưu lại tọa độ các point đã vẽ
            this.points = [];
    
            // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
            this.context.lineWidth = 2;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.strokeStyle = "#FFF";
    
            // Memmory canvas, dùng để ghi nhớ các nét vẽ
            this.memCanvas = document.createElement["canvas"];
            this.memCanvas.width = canvas.width;
            this.memCanvas.height = canvas.height;
            this.memCtx = this.memCanvas.getContext["2d"];
        }
    }
    4 ➡➡
    class FreeHand {
        constructor[canvas] {
            this.canvas = canvas;
    
            // Lưu context để vẽ 2D
            this.context = canvas.getContext["2d"];
    
            // Kiểm tra khi nào được draw, khi nào không
            this.isDraw = false;
    
            // Lưu lại tọa độ các point đã vẽ
            this.points = [];
    
            // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
            this.context.lineWidth = 2;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.strokeStyle = "#FFF";
    
            // Memmory canvas, dùng để ghi nhớ các nét vẽ
            this.memCanvas = document.createElement["canvas"];
            this.memCanvas.width = canvas.width;
            this.memCanvas.height = canvas.height;
            this.memCtx = this.memCanvas.getContext["2d"];
        }
    }
    8, sau đó cho
    class FreeHand {
        constructor[canvas] {
            this.canvas = canvas;
    
            // Lưu context để vẽ 2D
            this.context = canvas.getContext["2d"];
    
            // Kiểm tra khi nào được draw, khi nào không
            this.isDraw = false;
    
            // Lưu lại tọa độ các point đã vẽ
            this.points = [];
    
            // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
            this.context.lineWidth = 2;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.strokeStyle = "#FFF";
    
            // Memmory canvas, dùng để ghi nhớ các nét vẽ
            this.memCanvas = document.createElement["canvas"];
            this.memCanvas.width = canvas.width;
            this.memCanvas.height = canvas.height;
            this.memCtx = this.memCanvas.getContext["2d"];
        }
    }
    9;
  • Chúng ta sẽ sẽ lặp đi lặp lại quá trình này

2. Xử lý khi vẽ

Đầu tiên chúng ta sẽ truy cập vào canvas thông qua id của nó

const canvas = document.getElementById["canvas"];

Tiếp theo chúng ta định nghĩa class

onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
0, với constructor đầu vào là canvas element

class FreeHand {
    constructor[canvas] {
        this.canvas = canvas;

        // Lưu context để vẽ 2D
        this.context = canvas.getContext["2d"];

        // Kiểm tra khi nào được draw, khi nào không
        this.isDraw = false;

        // Lưu lại tọa độ các point đã vẽ
        this.points = [];

        // Style nét vẽ. Mặc định nét vẽ có chiều rộng 2px, màu trắng
        this.context.lineWidth = 2;
        this.context.lineJoin = "round";
        this.context.lineCap = "round";
        this.context.strokeStyle = "#FFF";

        // Memmory canvas, dùng để ghi nhớ các nét vẽ
        this.memCanvas = document.createElement["canvas"];
        this.memCanvas.width = canvas.width;
        this.memCanvas.height = canvas.height;
        this.memCtx = this.memCanvas.getContext["2d"];
    }
}

Để vẽ 1 nét chúng ta có các thao tác sau:

  • Nhấn chuột xuống để bắt đầu vẽ
  • Vừa nhấn chuột và di chuyển chuột để thực hiện vẽ
  • Nhả chuột ra để kết thúc nét vẽ

Với mỗi thao tác trên chúng ta sẽ định nghĩa method trong class

onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
0 để thực hiên

1. Nhấn chuột xuống để bắt đầu vẽ

Chúng ta thực hiện thao tác này bằng các định nghĩa method

onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
2

Chúng ta sẽ lưu lại tọa độ tại vị trí nhấn chuột xuống và push vào mảng

onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
3 để lưu lại, đồng thời
onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
4 để đặt trạng thái bắt đầu vẽ

onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}

2. Vừa nhấn chuột và di chuyển chuột để thực hiện vẽ

Trong lúc vẽ, chúng ta sẽ xóa hết

onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
5 thông qua method
onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
6. Đồng thời vẽ lại các nét từ
onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
7 sang
onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
5

Tọa độ của các điểm trên đường đi của bút vẽ sẽ được push vào mảng

onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
3 để lưu lại

Cuối cùng gọi methods

onmousemove[event] {
    if[this.isDraw] {
        // Xóa tất cả trên canvas
        this.context.clearRect[0, 0, this.canvas.width, this.canvas.height];

        // Vẽ memory canvas lên trên canvas
        this.context.drawImage[this.memCanvas, 0, 0];

        // Lưu tọa độ khi di chuyển chuột vào mảng points
        this.points.push[{
                x: event.offsetX,
                y: event.offsetY,
        }];

        // Nối các tọa độ trong mảng points lại thành 1 đường
        this.drawPoints[];
    }
}
0 để nối các điểm trong mảng
onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
3 lại và hiển thị lên thành nét vẽ

Phần tiếp theo chúng ta sẽ định nghĩa method

onmousemove[event] {
    if[this.isDraw] {
        // Xóa tất cả trên canvas
        this.context.clearRect[0, 0, this.canvas.width, this.canvas.height];

        // Vẽ memory canvas lên trên canvas
        this.context.drawImage[this.memCanvas, 0, 0];

        // Lưu tọa độ khi di chuyển chuột vào mảng points
        this.points.push[{
                x: event.offsetX,
                y: event.offsetY,
        }];

        // Nối các tọa độ trong mảng points lại thành 1 đường
        this.drawPoints[];
    }
}
0 để tạo nét vẽ từ mảng
onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
3

onmousemove[event] {
    if[this.isDraw] {
        // Xóa tất cả trên canvas
        this.context.clearRect[0, 0, this.canvas.width, this.canvas.height];

        // Vẽ memory canvas lên trên canvas
        this.context.drawImage[this.memCanvas, 0, 0];

        // Lưu tọa độ khi di chuyển chuột vào mảng points
        this.points.push[{
                x: event.offsetX,
                y: event.offsetY,
        }];

        // Nối các tọa độ trong mảng points lại thành 1 đường
        this.drawPoints[];
    }
}

3. Nhả chuột ra để kết thúc nét vẽ

Khi nhả chuột ra chúng ta set giá trị

onmousemove[event] {
    if[this.isDraw] {
        // Xóa tất cả trên canvas
        this.context.clearRect[0, 0, this.canvas.width, this.canvas.height];

        // Vẽ memory canvas lên trên canvas
        this.context.drawImage[this.memCanvas, 0, 0];

        // Lưu tọa độ khi di chuyển chuột vào mảng points
        this.points.push[{
                x: event.offsetX,
                y: event.offsetY,
        }];

        // Nối các tọa độ trong mảng points lại thành 1 đường
        this.drawPoints[];
    }
}
4 để kết thúc 1 chu trình vẽ

Đồng thời clear

onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
7 và vẽ lại các nét từ
onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
5 sang
onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
7

Clear

onmousemove[event] {
    if[this.isDraw] {
        // Xóa tất cả trên canvas
        this.context.clearRect[0, 0, this.canvas.width, this.canvas.height];

        // Vẽ memory canvas lên trên canvas
        this.context.drawImage[this.memCanvas, 0, 0];

        // Lưu tọa độ khi di chuyển chuột vào mảng points
        this.points.push[{
                x: event.offsetX,
                y: event.offsetY,
        }];

        // Nối các tọa độ trong mảng points lại thành 1 đường
        this.drawPoints[];
    }
}
8 để tiếp tục cho lần vẽ tiếp theo

onmouseup[] {
    if [this.isDraw] {
        // Đặt lại trạng vẽ => kết thúc nét vẽ
        this.isDraw = false;

        // Xóa toàn bộ memory canvas
        this.memCtx.clearRect[0, 0, this.canvas.width, this.canvas.height];

        // Vẽ canvas lên trên memory canvas
        this.memCtx.drawImage[this.canvas, 0, 0];

        // Clear mảng point cho nét vẽ khác
        this.points = [];
    }
}

3. Làm mượt nét vẽ

Để tạo nét vẽ chúng ta sẽ nối lần lượt tọa độ của các điểm trong mảng

onmousedown[event] {
    // Lấy tạo độ x,y của chuột tạo vị trí bắt đầu vẽ
    this.x = event.offsetX;
    this.y = event.offsetY;

    // Lưu cặp tọa độ vào mảng points
    this.points.push[{
        x: this.x,
        y: this.y,
    }];

    // Đặt trạng thái bắt đầu vẽ
    this.isDraw = true;
}
3 lại với nhau. Nhưng nếu đơn thuần chỉ nối thì các nét vẽ này sẽ không mượt và bị gấp khúc

Để làm mượt nét vẽ chúng ta sẽ sử dụng method

onmouseup[] {
    if [this.isDraw] {
        // Đặt lại trạng vẽ => kết thúc nét vẽ
        this.isDraw = false;

        // Xóa toàn bộ memory canvas
        this.memCtx.clearRect[0, 0, this.canvas.width, this.canvas.height];

        // Vẽ canvas lên trên memory canvas
        this.memCtx.drawImage[this.canvas, 0, 0];

        // Clear mảng point cho nét vẽ khác
        this.points = [];
    }
}
0

Cụ thể phương thức này như thế nào, các bạn có thể tham khảo tại đây: //www.w3schools.com/tags/canvas_quadraticcurveto.asp

drawPoints[] {
    let ctx = this.context;

    // Nếu mảng point có 1 điểm -> bỏ qua không vẽ
    if[this.points.length  nối 2 điểm đó với nhau
    if[this.points.length == 2] {
        ctx.beginPath[];
        ctx.moveTo[this.points[0].x, this.points[0].y];
        ctx.lineTo[this.points[1].x, this.points[1].y];
        ctx.stroke[];
        return
    }

    // Trường hợp mảng points có nhiều điểm -> sử dụng quadraticCurveTo để nối các điểm lại
    ctx.beginPath[];
    ctx.moveTo[this.points[0].x, this.points[0].y];
    for [var i = 1; i  {
    freehand.onmousedown[event];
};

// Lắng nghe sự kiện onmousemove [di chuyển chuột] của đối tượng canvas để vẽ nét
canvas.onmousemove = [event] => {
    freehand.onmousemove[event];
};

// Lắng nghe sự kiện onmouseup [nhả chuột ra] của đối tượng canvas để kết thúc nét vẽ
canvas.onmouseup = [] => {
    freehand.onmouseup[];
};

và đây là kết quả của chúng ta

Ở bài viết tiếp theo chúng ta sẽ thực hiện các chức năng còn lại của ứng dụng

onmouseup[] {
    if [this.isDraw] {
        // Đặt lại trạng vẽ => kết thúc nét vẽ
        this.isDraw = false;

        // Xóa toàn bộ memory canvas
        this.memCtx.clearRect[0, 0, this.canvas.width, this.canvas.height];

        // Vẽ canvas lên trên memory canvas
        this.memCtx.drawImage[this.canvas, 0, 0];

        // Clear mảng point cho nét vẽ khác
        this.points = [];
    }
}
4

  • Chọn nét vẽ
  • Chọn màu vẽ
  • Xóa toàn bộ nét vẽ

Sources phần này các bạn có thể tham khảo tại đây: //github.com/buihien0109/buihien0109.github.io/tree/master/HTML5-Games/game/paint/part-2

Chủ Đề