Canvas là bitmap (pixel) - không lưu trữ đối tượng (object model). Khi bạn vẽ hình lên canvas, nó chỉ thay đổi màu pixel. Canvas không nhớ bạn vẽ gì, ở đâu, thuộc tính gì.
Tại sao không lấy được giá trị?
<canvas id="myCanvas" width="500" height="300"></canvas>
<script>
var ctx = document.getElementById('myCanvas').getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 100, 100); // Vẽ hình vuông đỏ
// ❌ KHÔNG THỂ LÀM ĐƯỢC:
var shapes = canvas.getShapes(); // Không tồn tại!
var rect = canvas.getElementById('myRect'); // Không tồn tại!
</script>
Canvas chỉ là "bức tranh" - sau khi vẽ xong, thông tin hình học bị mất, chỉ còn pixel màu.
Giải pháp: Lưu trữ trạng thái (State Management)
Bạn phải tự quản lý mô hình dữ liệu (model) riêng, đồng bộ với việc vẽ:
// Model: Lưu thông tin hình vẽ
var shapes = [
{ type: 'rect', x: 10, y: 10, w: 100, h: 100, color: 'red', id: 'rect1' },
{ type: 'circle', x: 200, y: 100, r: 30, color: 'blue', id: 'circle1' }
];
// View: Hàm vẽ từ model
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
shapes.forEach(function(shape) {
ctx.fillStyle = shape.color;
if (shape.type === 'rect') ctx.fillRect(shape.x, shape.y, shape.w, shape.h);
else if (shape.type === 'circle') { ctx.beginPath(); ctx.arc(shape.x, shape.y, shape.r, 0, Math.PI*2); ctx.fill(); }
});
}
render();
// Controller: Thao tác trên model, rồi render lại
function moveShape(id, newX, newY) {
var shape = shapes.find(s => s.id === id);
if (shape) { shape.x = newX; shape.y = newY; render(); }
}
// Lấy giá trị: Đọc từ MODEL, không từ canvas
console.log(shapes.find(s => s.id === 'rect1')); // {type: 'rect', x:10, y:10, w:100, h:100, color: 'red', id: 'rect1'}
Pattern: MVC cho Canvas
- Model: Mảng objects mô tả hình (type, vị trí, kích thước, style, metadata).
- View: Hàm
render()vẽ toàn bộ từ model. - Controller: Xử lý input (click, drag) → cập nhật model → gọi render().
Thư viện đã implement pattern này
- Fabric.js - Object model, event per object, serialization JSON.
- Konva.js - Stage/Layer/Node tree, hit detection, drag & drop, animation.
- Paper.js - Project/Path/Group, vector-based, boolean operations.
- Two.js - Unified API cho Canvas, SVG, WebGL.
Khi nào CÓ THỂ đọc pixel từ canvas
Chỉ đọc được màu pixel (image data), không phải đối tượng logic:
var imageData = ctx.getImageData(x, y, 1, 1); // 1 pixel var r = imageData.data[0]; var g = imageData.data[1]; var b = imageData.data[2]; var a = imageData.data[3];
Dùng cho: color picker, collision detection pixel-perfect, image processing.