Chatbox

Các bạn vui lòng dùng từ ngữ lịch sự và có văn hóa,sử dụng Tiếng Việt có dấu chuẩn. Chúc các bạn vui vẻ!
19/05/2013 14:05 # 1
vnttqb
Cấp độ: 13 - Kỹ năng: 8

Kinh nghiệm: 5/130 (4%)
Kĩ năng: 39/80 (49%)
Ngày gia nhập: 21/03/2011
Bài gởi: 785
Được cảm ơn: 319
HTML5 – Chọn và di chuyển đối tượng trên Canvas


 

HTML5 – Chọn và di chuyển đối tượng trên Canvas 

<Nguồn: http://yinyangit.wordpress.com >

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, tôi 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.

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

Đầu tiên tôi 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. Tôi 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
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, tôi 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]. Tôi 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]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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;
        }
    }
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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();
    }
}

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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;
}

Mã nguồn hoàn chỉnh

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<html>
<head>
 
<script>
const RECT_SIZE = 20;
 
var _canvas;
var _context;
var _list = new ShapeList;
var _ismoving = false;
 
function Rect() {
  this.isSelected = false;
  this.x = 0;
  this.y = 0;
  this.width = 1;
  this.height = 1;
}
Rect.prototype.contains = 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;
}
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;
        }
    }
}
 
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;
}
 
function clear(deleteData){
 
    _context.clearRect(0,0,_canvas.width,_canvas.height);
    if(deleteData)
        _list.items = [];
}
 
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();
    }
}
 
$(function(){
 
    _canvas = document.getElementById("canvas");
    _context = _canvas.getContext("2d");
    _context.fillStyle = "wheat";
 
    _canvas.onmousedown = canvas_mousedown;
    _canvas.onmousemove = canvas_mousemove;
    _canvas.onmouseup = canvas_mouseup;
 
    $("#button1").click(function(){
        clear(true);
    });
});
</script>
</head>
<body>
    <div>
    <button id="button1">Clear</button>
    </div>
   <canvas id="canvas" width="400px" height="400px" style="border: 1px solid gray;"></canvas>
</body>
</html>
 

 

 



======================================================================================================

Cuộc đời là một dòng sông. Ai không bơi thì chết. 
 

Name: Tien (Tory) TRAN
Email: TranTien29@gmail.com


 
07/01/2014 09:01 # 2
minhdai1992
Cấp độ: 4 - Kỹ năng: 1

Kinh nghiệm: 9/40 (22%)
Kĩ năng: 1/10 (10%)
Ngày gia nhập: 19/12/2013
Bài gởi: 69
Được cảm ơn: 1
Phản hồi: HTML5 – Chọn và di chuyển đối tượng trên Canvas


code này là code gì vậy bác. bác co code newyear ball hover vào nghe tiếng chuông của diễn đàn chap.vn phần banerko send cho em với mail emlaf: ngominhdaicd@gmail.com đó thank bancs nhiều



Dịch Vụ Vận chuyển hàng thái lan và order hàng thái về việt nam tai siêu thị hàng thái lan. 0903-393978 để biết thêm


 
Copyright© Đại học Duy Tân 2010 - 2024