Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> HTML

Lấy giá trị từ HTML5 Canvas sang JavaScript - Không thể trực tiếp

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.