Phương thức ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise) vẽ cung tròn/elip. Hiểu đúng startAngle và endAngle là chìa khóa.
Tham số
| Tham số | Kiểu | Mô tả |
|---|---|---|
x, y | Number | Tọa độ tâm đường tròn |
radius | Number | Bán kính (pixels) |
startAngle | Number (radian) | Góc bắt đầu, đo từ trục X dương (3 giờ), theo chiều kim đồng hồ |
endAngle | Number (radian) | Góc kết thúc, cùng hệ trục |
anticlockwise | Boolean | true: vẽ ngược chiều kim đồng hồ; false (mặc định): theo chiều kim đồng hồ |
Hệ tọa độ góc (Radian)
0 radian = 0° = 3 giờ (trục X dương) Math.PI / 2 = 90° = 6 giờ (trục Y dương - xuống dưới) Math.PI = 180° = 9 giờ (trục X âm) Math.PI * 3 / 2 = 270° = 12 giờ (trục Y âm - lên trên) Math.PI * 2 = 360° = Quay vòng tròn
Lưu ý: Canvas Y-axis hướng xuống (khác toán học chuẩn Y lên). Do đó góc tăng theo chiều kim đồng hồ.
Ví dụ minh họa
<canvas id="c" width="300" height="300"></canvas>
<script>
var ctx = document.getElementById('c').getContext('2d');
ctx.lineWidth = 4;
ctx.strokeStyle = '#333';
// 1. Cung tròn 90° (góc trên phải) - theo chiều kim đồng hồ
ctx.beginPath();
ctx.arc(150, 150, 80, 0, Math.PI/2, false);
ctx.stroke(); // Vẽ từ 3h → 6h
// 2. Cung tròn 180° (nửa dưới) - ngược chiều kim đồng hồ
ctx.beginPath();
ctx.arc(150, 150, 60, 0, Math.PI, true);
ctx.strokeStyle = 'red';
ctx.stroke(); // Vẽ từ 3h → 9h qua 12h (ngược)
// 3. Đường tròn tròn (360°)
ctx.beginPath();
ctx.arc(150, 150, 40, 0, Math.PI * 2);
ctx.strokeStyle = 'blue';
ctx.stroke();
// 4. Góc độ (degree) → Radian helper
function degToRad(deg) { return deg * Math.PI / 180; }
ctx.beginPath();
ctx.arc(150, 150, 100, degToRad(45), degToRad(135));
ctx.strokeStyle = 'green';
ctx.stroke(); // 45° đến 135° (góc trên)
</script>
Các lỗi thường gặp
| Lỗi | Nguyên nhân | Sửa |
|---|---|---|
| Cung vẽ ngược chiều mong đợi | Nhầm anticlockwise | Thử true/false, nhớ Y-axis xuống |
| Vẽ full circle nhưng có đường nối | startAngle = endAngle | endAngle = startAngle + 2*PI |
| Góc âm | JS cho phép góc âm | OK: -Math.PI/2 = 270° (12h) |
arcTo() - Cung tiếp tuyến
ctx.arcTo(x1, y1, x2, y2, radius); // Vẽ cung nối giữa 2 đoạn thẳng (x1,y1) và (x2,y2) với bán kính cho trước // Dùng cho bo góc (rounded corners) path phức tạp