HTML5: Chọn và di chuyển đối tượng

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Thay vì lưu trữ nội dung của Canvas dưới dạng ImageData, ta có thể lưu trữ các đối tượng đồ họa dưới dạng cấu trúc dữ liệu và thực hiện vẽ từng phần tử lên Canvas. Với phương pháp này, ta sẽ minh họa bằng một ví dụ sử dụng chuột để chọn và di chuyển các hình vẽ trên Canvas.

1. Tạo cấu trúc dữ liệu

Đầu tiên ta sẽ tạo một lớp Rect dùng để chứa dữ liệu của một hình chữ nhật. Lớp này ngoài các biến lưu trữ tọa độ, kích thước và trạng thái (selected) thì cần một phương thức dùng để kiểm tra xem một tọa độ [x,y] có nằm bên trong nó không. Ta gọi phương thức này là isContain() và có kiểu trả về là boolean. Mã nguồn của lớp này có dạng:

function Rect() {

this.isSelected = false;

this.x = 0;

this.y = 0;

this.width = 1;

this.height = 1;

}

Rect.prototype.isContain = function(x,y){

var right = this.x + this.width;

var bottom = this.y + this.height;

return x > this.x && x < right &&

y > this.y && y < bottom;

}

Tiếp theo, ta tạo một lớp ShapeList dùng để chứa các đối tượng Rect trong một kiểu dữ liệu mảng. Ngoài ra, ShapeList sẽ có thêm một biến dùng để chỉ ra đối tượng Rect đang được chọn (selectedItem), và hai biến dùng để lưu vị trí của chuột khi click lên một đối tượng Rect (offsetX, offsetY). Hai biến offset này dùng để tính tọa độ chính xác khi người dùng sử dụng chuột để di chuyển đối tượng Rect.

ShapeList còn có hai phương thức:

- addItem(): thêm một đối tượng Rect vào danh sách.

- selectAt(): tìm và chọn đối tượng Rect chứa tọa độ [x,y]. Ta sẽ duyệt ngược từ cuối mảng để đảm bảo các đối tượng nằm sau sẽ được chọn trước trong trường hợp nhiều Rect cùng chứa điểm [x,y].

function ShapeList(){

this.items = [];

this.selectedItem = null;

this.offsetX = -1;

this.offsetY = -1;

}

ShapeList.prototype.addItem = function(x,y,width,height){

var rect = new Rect;

rect.x = x;

rect.y = y;

rect.width = width;

rect.height = height;

this.items.push(rect);

}

ShapeList.prototype.selectAt = function(x,y){

if(this.selectedItem)

this.selectedItem.isSelected = false;

this.selectedItem = null;

for (var i = 0; i < this.items.length; i++) {

var rect = this.items[i];

if(rect.contains(x,y))

{

this.selectedItem = this.items[i];

this.offsetX = x - this.items[i].x;

this.offsetY = y - this.items[i].y;

this.items[i].isSelected = true;

break;

}

}

}

2. Các phương thức vẽ bằng context

function draw(){

clear();

for (var i = _list.items.length-1;i>=0; i--) {

drawRect(_list.items[i]);

}

}

function drawRect(rect){

_context.fillRect(rect.x,rect.y,rect.width,rect.height);

if(rect.isSelected)

{

_context.save();

_context.strokeStyle = "red";

_context.strokeRect(rect.x,rect.y,rect.width,rect.height);

_context.restore();

}

}

3. Các sự kiện chuột của Canvas

Trong các sự kiện này, ta sẽ dùng cờ _ismoving để xác định xem một đối tượng có đang được chọn hay không và thực hiện di chuyển đối tượng ShapeList.selectedItem trong mousemove. Giá trị _ismoving này sẽ được xác định trong sự kiện mousedown và bị hủy khi mouseup.

function canvas_mousedown(e){

var x = e.pageX - _canvas.offsetLeft;

var y = e.pageY - _canvas.offsetTop;

_list.selectAt(x,y)

if(!_list.selectedItem)

_list.addItem(x-RECT_SIZE,y-
RECT_SIZE,RECT_SIZE*2,RECT_SIZE*2);

_ismoving = true;

draw();

}

function canvas_mousemove(e){

if(_ismoving && _list.selectedItem){

var x = e.pageX - _canvas.offsetLeft;

var y = e.pageY - _canvas.offsetTop;

_list.selectedItem.x = x - _list.offsetX;

_list.selectedItem.y = y - _list.offsetY;

draw();

}

}

function canvas_mouseup(e){

_ismoving = false;

}

Kết quả:

http://v1study.com/public/images/article/game2d-ket-qua-vi-du-di-chuyen-doi-tuong.png

» Tiếp: Sử dụng bàn phím
« Trước: Vẽ hình bằng chuột
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!