Thứ hai, ngày 5 tháng 12 năm 2016

HTML5 – Vẽ hình bằng chuột trong Canvas

Ngày đăng: 11/4/2012, 8:33:27AM | Lượt xem: 3,515
Hot!

Trong bài viết này, tôi sẽ giới thiệu cách bắt và xử lý các thao tác chuột trên Canvas để thực hiện một ứng dụng vẽ hình đơn giản. Bên cạnh đó, bạn có thể biết được cách để lưu và phục hồi lại dữ liệu của canvas khi cần thiết. Các ví dụ trong bài khá đơn giản nên tôi sẽ không đi vào giải thích chi tiết.

drawing_penTrong bài viết này, tôi sẽ giới thiệu cách bắt và xử lý các thao tác chuột trên Canvas để thực hiện một ứng dụng vẽ hình đơn giản. Bên cạnh đó, bạn có thể biết được cách để lưu và phục hồi lại dữ liệu của canvas khi cần thiết. Các ví dụ trong bài khá đơn giản nên tôi sẽ không đi vào giải thích chi tiết.

Xem demo.

Xác định tọa độ chuột

Để xác định được tọa chuột trên canvas, tôi sẽ sử dụng tham số của các sự kiện như mousedown, mousemove, … Tham số của các sự kiện này chứa tọa độ chuột lưu trong hai biến pageX và pageY. Tôi sẽ dùng tọa độ này trừ đi tọa độ của canvas (canvas.offsetLeft và canvas.offsetTop) để lấy được vị trí chính xác của chuột trên canvas.

Đầu tiên là việc mô phỏng công cụ Pen cho phép vẽ tự do trong canvas:

<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
var preX;
var preY;
var paint;
var canvas;
var context;

$(function(){
	canvas = document.getElementById("canvas");
	context = canvas.getContext("2d");

	$('#canvas').mousedown(function(e){
		preX = e.pageX - this.offsetLeft;
		preY = e.pageY - this.offsetTop;

		paint = true;
	});
	$('#canvas').mousemove(function(e){
	  if(paint){
		var x = e.pageX - this.offsetLeft;
		var y = e.pageY - this.offsetTop;
		context.moveTo(preX,preY);
		context.lineTo(x,y);
		context.stroke();
		preX = x;
		preY = y;
	  }
	});
	$('#canvas').mouseenter(function(e){
		if(paint)
		{
		preX = e.pageX - this.offsetLeft;
		preY = e.pageY - this.offsetTop;
		}
	});
	$("#canvas").mouseup(function(){
		paint = false;
	});
	$('#canvas').mouseleave(function(e){
		paint = false;
	});

});

</script>
</head>
<body>
   <canvas id="canvas" width="500px" height="500px" style="border: 1px solid gray;"></canvas>
</body>
</html>  

Lưu nội dung của Canvas

Để lưu lại dữ liệu của Canvas nhằm phục hồi khi cần thiết (chẳng hạn như chức năng Undo, Redo), tôi sẽ sử dụng phương thức context.getImageData() (xem bài HTML5 – Canvas: Vẽ ảnh và thao tác với pixel).Tôi sẽ sử dụng phương pháp này để thực hiện chức năng vẽ đoạn thẳng trên Canvas. Trước khi bắt đầu vẽ một đoạn thằng, canvas cần được lưu lại nội dung và mỗi khi chuột di chuyển, tôi sẽ phục hồi lại nội dung được lưu đó đồng thời vẽ một đoạn thẳng từ điểm bắt đầu đến vị trí chuột.

Tôi cũng sửa ví dụ trên thành một jQuery plugin để tiện sử dụng:

<html>
<head>

<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>

(function( $ ) {

	var preX;
	var preY;
	var tool;	 // pen, line
	var canvas;
	var context;
	var imageData;
	var paint;

  $.fn.makeDrawable = function() {

	canvas = this[0];
	if( !$(canvas).is("canvas") )
		throw "The target element must be a canvas";

	context = canvas.getContext("2d");

	$(canvas).mousedown(function(e){
		preX = e.pageX - canvas.offsetLeft;
		preY = e.pageY - canvas.offsetTop;
		paint = true;
		if(tool=="line")
		{
			imageData = context.getImageData(0, 0, canvas.width, canvas.height);
		}
	});
	$(canvas).mousemove(function(e){
		if(paint)
		{
			var x = e.pageX - canvas.offsetLeft;
			var y = e.pageY - canvas.offsetTop;

			if(tool=="pen")
			{
				context.moveTo(preX,preY);
				context.lineTo(x,y);
				context.stroke();

				preX = x;
				preY = y;
			}
			else if(tool=="line")
			{
				canvas.width=canvas.width; // clear canvas content
				context.putImageData(imageData,0,0);

				context.moveTo(preX,preY);
				context.lineTo(x,y);
				context.stroke();
			}

		}
	});

	$(canvas).mouseup(function(e){
		if(tool=="line")
		{
			var x = e.pageX - canvas.offsetLeft;
			var y = e.pageY - canvas.offsetTop;

			context.moveTo(preX,preY);
			context.lineTo(x,y);
			context.stroke();
		}
		paint = false;
	});
	$(canvas).mouseleave(function(e){
		paint = false;
	});

	return $(canvas);
  };

  $.fn.setTool = function(newTool) {
	tool=newTool;
	return $(canvas);
  }
 $.fn.clear = function() {
	canvas.width=canvas.width;
	return $(canvas);
  }
})( jQuery );

$(function(){

	$("#canvas").makeDrawable();
	$("#button1").click(function(){
		$("#canvas").clear();
	});

	$("#pen").change(function(){
		if(this.value)
			$("#canvas").setTool("pen");
	});
	$("#line").change(function(){
		if(this.value)
			$("#canvas").setTool("line");
	});

	$("#canvas").setTool("pen");
});

</script>
</head>
<body>
	<div>
	<button id="button1">Clear</button>
	<input name="tool" type="radio" id="pen" checked="true">Pen</input>
	<input name="tool" type="radio" id="line">Line</input>
	</div>
   <canvas id="canvas" width="500px" height="500px" style="border: 1px solid gray;"></canvas>
</body>
</html>  

Kết quả:

Canvas drawing example

YinYang’s Programming Blog

 Chia sẻ qua: 
Hot!
Ý kiến bạn đọc

These items will be permanently deleted and cannot be recovered. Are you sure?

Gallery

image

Maecenas viverra rutrum pulvinar

Maecenas viverra rutrum pulvinar! Aenean vehicula nulla sit amet metus aliquam et malesuada risus aliquet. Vestibulum rhoncus, dolor sit amet venenatis porta, metus purus sagittis nisl, sodales volutpat elit lorem…

Read more

Text Links

Thiết kế logo chuyên nghiệp Insky
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
Copyright © 2011 - 2012 vietshare.vn by phamkhuong102@gmail.com doanhkisi2315@gmail.com. All rights reserved.