2012-01-16 45 views
5

Tôi đang cố gắng vẽ 3 mũi tên bên dưới. Tôi có thể vẽ phần trên cùng một cách chính xác nhưng tôi không thể vẽ chính xác 2 đầu mũi tên khác. Tôi đang sử dụng Canvas HTML5 để vẽ các mũi tên này.Vẽ các đường cong đầu mũi tên trong HTML5 Canvas

enter image description here

Sự cố xảy ra với cuộc gọi arcTo của tôi. Tôi chỉ không thể có được đường cong chính xác xảy ra vì một lý do nào đó. Có lẽ tôi nên sử dụng một đường cong Bezier? Có ai có thể cho tôi biết chức năng HTML5/Javascript nào tôi sử dụng để sản xuất các đầu mũi tên trên không?

Bạn có thể cung cấp ví dụ về cách đạt được các mũi tên trên không?

Heres JSFiddle để hiển thị những gì đang diễn sai: http://jsfiddle.net/hJX8X/

<canvas id="testCanvas" width="400px" height="400px"> 

</canvas> 
<script type="text/javascript"> 
<!-- 
    var canvas = document.getElementById("testCanvas"); 
    var dc  = canvas.getContext("2d"); 

    // Points which are correct (when I draw straight lines its a perfect arrow 
    var width = 400; 
    var height = 100; 
    var arrowW = 0.35 * width; 
    var arrowH = 0.75 * height; 
    var p1  = {x: 0,    y: (height-arrowH)/2}; 
    var p2  = {x: (width-arrowW), y: (height-arrowH)/2}; 
    var p3  = {x: (width-arrowW), y: 0}; 
    var p4  = {x: width,   y: height/2}; 
    var p5  = {x: (width-arrowW), y: height}; 
    var p6  = {x: (width-arrowW), y: height-((height-arrowH)/2)}; 
    var p7  = {x: 0,    y: height-((height-arrowH)/2)}; 

    dc.clearRect(0, 0, canvas.width, canvas.height); 
    dc.fillStyle = "#FF0000"; 

    dc.beginPath(); 

    dc.moveTo(p1.x, p1.y); 
    dc.lineTo(p2.x, p2.y); 
    dc.lineTo(p3.x, p3.y);  
    dc.moveTo(p3.x, p3.y); 
    dc.arcTo(p3.x, p3.y, p4.x, p4.y, 50); 
    dc.moveTo(p4.x, p4.y); 
    dc.arcTo(p4.x, p4.y, p5.x, p5.y, 50); 
    dc.moveTo(p5.x, p5.y); 
    dc.lineTo(p6.x, p6.y); 
    dc.lineTo(p7.x, p7.y); 

    dc.closePath(); 
    dc.fill(); 

    /* Draw arrow without curves 
    dc.moveTo(p1.x, p1.y); 
    dc.lineTo(p2.x, p2.y); 
    dc.lineTo(p3.x, p3.y);  
    dc.lineTo(p4.x, p4.y); 
    dc.lineTo(p5.x, p5.y); 
    dc.lineTo(p6.x, p6.y); 
    dc.lineTo(p7.x, p7.y); 
    */ 
--> 
</script> 
+0

bạn có thể cung cấp một ví dụ (hình ảnh) của các kết quả mong đợi – rkmax

+0

@rkmax tôi đã đăng tải một JSFiddle bây giờ mà chứng tỏ nỗ lực của tôi , đầu mũi tên quá mập mạp –

Trả lời

9

Vì vậy, chúng tôi đã có con đường này mà làm cho một mũi tên. Tôi đã chú thích nó:

dc.moveTo(p1.x, p1.y); 
dc.lineTo(p2.x, p2.y); // end of main block 
dc.lineTo(p3.x, p3.y); // topmost point  
dc.lineTo(p4.x, p4.y); // endpoint 
dc.lineTo(p5.x, p5.y); // bottommost point 
dc.lineTo(p6.x, p6.y); // end at bottom point 
dc.lineTo(p7.x, p7.y); 

Chúng tôi thực sự muốn giữ nó tương tự nhất có thể ngoại trừ chúng tôi muốn đến điểm cuối (và ngược lại) theo cách khác với đường thẳng. Chúng tôi hoàn toàn không muốn sử dụng bất kỳ lệnh moveTo nào trừ lệnh đầu tiên. Điều đó thực sự làm xáo trộn mọi thứ và làm cho chúng khó hiểu. Tôi cũng tránh sử dụng arcTo trừ khi bạn thực sự cần một phần của một vòng cung (như trong một chiếc bánh) vì nó khá khó hiểu so với các lệnh đường dẫn khác.

Vì vậy, chúng tôi sẽ sử dụng các đường cong bậc hai giống như beziers nhưng chỉ có một điểm kiểm soát, làm cho chúng khá đơn giản. Chúng hoạt động bằng cách chỉ định một điểm điều khiển như this (on the left).

Vì vậy, chúng tôi lấy cùng một mã mũi tên chính xác và chèn hai beziers bậc hai để tạo một mũi tên gầy. Chúng tôi muốn các điểm kiểm soát được sorta "bên trong" khối lượng của mũi tên để làm cho quadratics uốn cong vào bên trong:

dc.moveTo(p1.x, p1.y); 
dc.lineTo(p2.x, p2.y); // end of main block 
dc.lineTo(p3.x, p3.y); // topmost point 
// control point is based on p3 (topmost point) 
dc.quadraticCurveTo(p3.x + 20, p3.y + 30, p4.x, p4.y); // endpoint 
// control point is based on p5 (bottommost point) 
dc.quadraticCurveTo(p5.x + 20, p5.y - 30, p5.x, p5.y); // bottommost point 
dc.lineTo(p6.x, p6.y); // end at bottom point 
dc.lineTo(p7.x, p7.y); 

Hoặc một chất béo một, chúng tôi đặt điểm điều khiển ở độ cao tương tự như các điểm trên cùng và dưới cùng , và xung quanh cùng X là thiết bị đầu cuối:

dc.beginPath(); 
// Draw arrow without curves 
dc.moveTo(p1.x, p1.y); 
dc.lineTo(p2.x, p2.y); // end of main block 
dc.lineTo(p3.x, p3.y); // topmost point 
// control point is based on p3 (topmost point) 
dc.quadraticCurveTo(p3.x + 120, p3.y, p4.x, p4.y); // endpoint 
// control point is based on p5 (bottommost point) 
dc.quadraticCurveTo(p5.x + 120, p5.y, p5.x, p5.y); // bottommost point 
dc.lineTo(p6.x, p6.y); // end at bottom point 
dc.lineTo(p7.x, p7.y); 

sống ví dụ ở đây: http://jsfiddle.net/Yp7DM/

Các vấn đề liên quan