header-object

[Webapp Tutorial] Xây dựng ứng dụng di động dùng HTML5 - Bài 7

 

 

7. Xử lý vẽ hình trên canvas trong widget dwdrawing

Đầu tiên, chúng ta sẽ thay đổi phương thức _create() để thực hiện một số thiết lập liên quan đến khởi tạo context như sau:

_create: function(){
	/*tạo một vài biến sẽ dùng tới sau*/
	var self = this,
	canvas = this.element,
	o = this.options;
	
	/*lấy về context*/
	this.options.context = canvas[0].getContext('2d');
	
	/*thiết lập một số thuộc tính*/
	this.options.context.lineJoin = 'round';
	this.options.context.lineWidth = 5;
	this.options.context.strokeStyle = o.color;
	
	this._changeColorListener();
	this._changePenListener();
}

 
Như các bạn thấy ở trên, chúng ta đã lấy về context, việc lấy về context khi sử dụng JQuery có chút ít khác biệt so với khi chúng ta dùng Javascript.
Sau đó, chúng ta thiết lập màu, độ rộng nét… cho context.
Bây giờ, mỗi khi người dùng chọn một màu mới, chúng ta lại phải thực hiện lại việc thiết lập lại giá trị màu cho context. Chúng ta sẽ thay đổi chút ít trong phương thức  _changeColorListener() như sau:

/*nghe ngóng việc bấm chọn màu mới*/
_changeColorListener:function(){
	/*bắt sự kiện bấm vào một cây bút (thẻ li)*/
	var self = this;
	$("#"+this.options.colorsId+" li" )
	.bind('vclick',function(e){
		/*Việc 1. hiệu ứng làm mờ bút màu hiện tại*/
		$("#"+self.options.colorsId+" li.active" )
		.animate({opacity:0.4,width:40},150)
		.removeClass('active');
		
		/*Việc 2. hiệu ứng hiện rõ bút màu mới click*/
		$(this).animate({opacity:0.9,width:60},
			200,
			"linear",
			function(){
				/*Việc 3. thiết lập màu mới chọn vào options*/
				self.options.color = "#"+$(this).attr('class').substring(1);
				$(this).addClass('active');
				
				/*thiết lập lại màu cho context*/
				self.options.context.strokeStyle = self.options.color;
			});
		});
},//kết thúc _changeColorListener

Tiếp tục, bây giờ là đến việc bắt sự kiện người dùng vẽ trên canvas. Chúng ta phải bắt sự kiện mousedown, mousemove và mouseup.

  • mousedown: chúng ta sẽ lấy vị trí mà người dùng chạm ở trên canvas và gán cho thuộc tính x1, y1 của đối tượng widget
  • mousemove: chúng ta sẽ lấy vị trí mà ngón gay người  dùng vừa di chuyển tới gán cho thuộc tính x2, y2 của đối tượng widget rồi gọi phương thức vẽ hình _onDraw()
  • mouseup: chúng ta sẽ lấy vị trí mà ngón tay người dùng vừa rời khỏi gán cho thuộc tính x2, y2 của đối tượng widget rồi gọi phương thức vẽ hình _onDraw(). Sau đó chúng ta sẽ hủy thuộc tính x1, y1 (để bắt đầu 1 chu kì vẽ mới).

Mã nguồn thực hiện điều này sẽ được cài đặt ở trong phương thức _onDrawListener() như sau:

_onDrawListener:function(){
	var self = this;
	
	/*sự kiện nhấn chuột (chạm ngón tay) vào canvas*/
	$(this.element).bind('vmousedown',function(e){
		self.x1 = e.pageX - this.offsetLeft;
		self.y1 = e.pageY - this.offsetTop;
	});
	
	/*sự kiện rời chuột (rời ngón tay) lên khỏi canvas*/
	$(this.element).bind('vmouseup',function(e){
		if(self.x1!=undefined){
			self.x2 = e.pageX - this.offsetLeft;
			self.y2 = e.pageY - this.offsetTop;
			self._onDraw();
			self.x1 = undefined;
			self.y1 = undefined;
		}
	});
	
	/*sự kiện di chuột (ngón tay) trên canvas*/
	$(this.element).bind('vmousemove',function(e){
		if(self.x1!=undefined){
			self.x2 = e.pageX - this.offsetLeft;
			self.y2 = e.pageY - this.offsetTop;
			self._onDraw();
			self.x1 = self.x2;
			self.y1 = self.y2;
		}
	});
},

Tiếp sau chúng ta sẽ thực thi việc nghe ngóng này ngay khi khởi tạo widget. Mở phương thức _onreate() và thêm vào dòng gọi thực thi phương thức _onDrawListener() như sau:

_create: function(){
	/*tạo một vài biến sẽ dùng tới sau*/
	var self = this,
	canvas = this.element,
	o = this.options;
	
	/*lấy về context*/
	this.options.context = canvas[0].getContext('2d');
	
	/*thiết lập một số thuộc tính*/
	this.options.context.lineJoin = 'round';
	this.options.context.lineWidth = 5;
	this.options.context.strokeStyle = o.color;
	
	this._changeColorListener();
	this._changePenListener();
	this._onDrawListener();
},

Ở trong phương thức _onDrawListener() trên chúng ta đã có gọi đến phương thức _onDraw(). Bây giờ chúng ta sẽ hiện thực hóa phương thức này. Phương thức này sẽ dựa vào giá trị của thuộc tính options.pen để lựa chọn một trong 3 phương thức vẽ

  • _drawPath(): vẽ đoạn
  • _drawRect(): vẽ chữ nhật
  • _drawElip(): vẽ hình Elip

mã của phương thức _onDraw() như sau:

/*thực hiện vẽ hình*/
_onDraw:function(){
	switch(this.options.pen){
	case 'path':
		this._drawPath();
		break;
	case 'rect':
		this._drawRect();
		break;
	case 'cycle':
		this._drawElip();
	}
},

Phương thức vẽ đoạn sẽ như sau:

/*vẽ đoạn thẳng từ (x1,y1) tới (x2,y2)*/
_drawPath:function(){
	this.options.context.beginPath();
	this.options.context.moveTo(this.x1,this.y1);
	this.options.context.lineTo(this.x2,this.y2);
	this.options.context.closePath();
	this.options.context.stroke();
},

Phương thức vẽ hình chữ nhật sẽ như sau:

/*vẽ hình chữ nhật từ (x1,y1) tới (x2,y2)*/
_drawRect:function(){
	/*điểm đầu tiên của hình*/
	if(this.rx==undefined){
		this.rx = this.x1;
		this.ry = this.y1;
	}else{
		this.options.context.fillStyle = this.options.color;
		
		if(this.crx!=undefined) 
			this.options.context.clearRect(this.rx, this.ry, this.crx-this.rx, this.cry-this.ry);
		
		this.options.context.fillRect(this.rx, this.ry, this.x2-this.rx, this.y2-this.ry);
		this.crx = this.x2;
		this.cry = this.y2;
	}
},

Và phương thức vẽ Elip như sau

_drawElip:function(){
	/*điểm đầu tiên của hình*/
	if(this.rx==undefined){
		this.rx = this.x1;
		this.ry = this.y1;
	}else{
		this.options.context.fillStyle = this.options.color;
		
		if(this.crx!=undefined) 
			this.options.context.clearRect(this.rx, this.ry, this.crx-this.rx, this.cry-this.ry);
		
		this.options.context.beginPath();
		this.options.context.moveTo((this.x2-this.rx)/2+this.rx,this.ry); // A1
		//vẽ cung tròn thứ nhất
		this.options.context.bezierCurveTo(
		  this.x2,this.ry, 	// C1
		  this.x2,this.y2, 	// C2
		  (this.x2-this.rx)/2+this.rx,this.y2); 	// A2
		//vẽ cung tròn thứ hai
		this.options.context.bezierCurveTo(
		  this.rx,this.y2, 	// C3
		  this.rx,this.ry, 	// C4
		  (this.x2-this.rx)/2+this.rx,this.ry); 	// A1
		this.options.context.closePath();
		this.options.context.fill();	
		
		this.crx = this.x2;
		this.cry = this.y2;
	}
},

Phù! như vậy là xong. Toàn bộ mã javascript của widget chúng ta đã viết bạn có thể tải tại đây: dwdrawing.js
Tới giờ này, ứng dụng của chúng ta đã hoàn tất như thiết kế ban đầu. Chúng ta cũng đã đi cùng nhau một đoạn dài từ đầu tới đây, đã đến lúc tự thưởng cho mình thành quả ban đầu rồi. Đây là bức vẽ đầu tiên sử dụng ứng dụng Danweb.vn Drawing :D
h15 Code hoàn chỉnh chúng ta có cho tới thời điểm này các bạn có thể tải tại đây: dwdrawing-v4.zip
Ở các bài tiếp sau, chúng ta sẽ thực hiện nhúng các nội dung đã làm trên vào ứng dụng cho Android và cho IOS. Bạn sẽ được học các kiến thức cơ bản để tạo ra một ứng dụng với mỗi hệ điều hành này.

 

còn tiếp...

 

Đào Ngọc Giang

Thêm ý kiến


Security code
Làm mới


2

Facebook

Thống kê truy cập

Hiện có 412 khách đang truy cập
2546538