2012-01-16 29 views
5

Aşağıdaki 3 okları çizmeye çalışıyorum. Üst kısmı doğru çizebilirim ama diğer 2 ok başlığını doğru çizemiyorum. Bu okları çizmek için HTML5 Canvas kullanıyorum.Çizim Ok Başı Eğriler HTML5 Canvas

enter image description here

sorun benim arcTo çağrılarıyla oluşur. Bir sebepten dolayı doğru eğriyi alamıyorum. Belki bir Bezier eğrisi kullanmalıyım? Yukarıdaki ok başlarını üretmek için hangi HTML5/Javascript işlevlerinin kullandığımı bana söyleyebilir mi?

Yukarıdaki ok başlarına nasıl erişeceğinize dair bir örnek verebilir misiniz?

İşte JSFiddle yanlış whats going göstermek için:

<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

ben bir JSFiddle gönderdiniz @rkmax beklenen sonuçların – rkmax

+0

bir örneğini (resim) sağlayabilir şimdi bu benim girişimi gösteriyor , ok başı çok çömelti –

cevap

9

http://jsfiddle.net/hJX8X/ yüzden bir ok yapar bu yolu var. Bunu açıklamalı ettik:

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); 

Biz gerçekten son nokta (ve arka) sadece düz bir çizgi daha farklı bir şekilde almak istiyorum haricinde mümkün olduğunca benzer tutmak istiyoruz. Biz biz kesinlikle birincisi hariç hiçbir moveTo komutları kullanmak istemiyoruz. Bu gerçekten şeyleri karıştırıyor ve anlaması zorlaştırıyor. Bir yayın (pastada olduğu gibi) bir parçasına gerçekten ihtiyacınız olmadıkça arcTo kullanmaktan da kaçınmam gerekir çünkü diğer yol komutlarına kıyasla oldukça kafa karıştırıcı.

Bu nedenle bezers gibi olan ancak yalnızca bir kontrol noktasına sahip olan kuadratik eğrileri kullanacağız. this (on the left) gibi bir denetim noktası belirterek çalışırlar.

Bu nedenle, aynı kesin ok kodunu alıp, sıska bir ok yapmak için iki kuadratik düzenleyiciyi ekliyoruz. Biz kontrol noktaları sorta "içeride" içeriye Karesel bükülmesini sağlamak için okun kütlesi olmak istiyorum:

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); 

Ya da bir yağ bir, biz en üstteki ve en alttaki noktası olarak aynı yükseklikte kontrol noktasını koymak ve son nokta ile aynı X etrafında:

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); 
burada

Canlı örnek: http://jsfiddle.net/Yp7DM/

İlgili konular