2010-08-25 89 views
5

給定由2d畫布上下文函數bezierCurveTo,quadraticCurveToarcTo繪製的線條,我該如何找到沿着這些線條的點?查找HTML5中的曲線上的點2d Canvas上下文

我的意圖是在曲線的中點畫一個對象。使用SVG DOM,我可以使用方法getPointAtLength & getTotalLength執行此操作,但我無法在HTML畫布中看到等效項。

回答

10

你發現它們的艱辛的道路:(

沒有在HTML畫布等價物。你必須自己找到中點與普通的舊的數學。

我做的如何找到一個例子你貝塞爾曲線的中點。看到它住在的jsfiddle here。在JavaScript的一個拷貝粘貼下面。

真實曲線是紅色的,中點是微小的綠色矩形。其他的一切只是視覺輔助。

var ctx = $("#test")[0].getContext("2d") 
function mid(a,b) { 
return (a+b)/2; 
} 


var cp1x = 100; 
var cp1y = 150; 
var cp2x = 175; 
var cp2y = 175; 
var x = 200; 
var y = 0; 

ctx.lineWidth = 4; 
ctx.strokeStyle = "red"; 
ctx.fillStyle = "rgba(0,0,0,0.6)"; 

ctx.beginPath(); 
ctx.moveTo(0, 0); 
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); 
ctx.stroke(); 

//line goes from start to control point 1 
ctx.strokeStyle = "rgba(0,0,200,0.4)"; 
ctx.beginPath(); 
ctx.moveTo(0, 0); 
ctx.lineTo(cp1x , cp1y); 
ctx.stroke(); 

//line goes from end to control point 2 
ctx.beginPath(); 
ctx.moveTo(x, y); 
ctx.lineTo(cp2x , cp2y); 
ctx.stroke(); 

//line goes from control point to control point 
ctx.strokeStyle = "rgba(200,0,200,0.4)"; 
ctx.beginPath(); 
ctx.moveTo(cp1x, cp1y); 
ctx.lineTo(cp2x , cp2y); 
ctx.stroke(); 

// now find the midpoint of each of those 3 lines 
var ax = mid(cp1x,0); 
var bx = mid(cp2x,x) 
var cx = mid(cp1x,cp2x) 

var ay = mid(cp1y,0)  
var by = mid(cp2y,y)  
var cy = mid(cp1y,cp2y) 


// draw midpoints for visual aid 
// not gonna look exact 'cause square 
// will be drawn from top-right instead of center 
ctx.fillRect(ax, ay, 4, 4); 
ctx.fillRect(bx, by, 4, 4); 
ctx.fillRect(cx, cy, 4, 4); 


//now draw lines between those three points. These are green 
ctx.strokeStyle = "rgba(0,200,0,0.4)"; 
ctx.beginPath(); 
ctx.moveTo(ax, ay); 
ctx.lineTo(cx , cy); 
ctx.stroke(); 

ctx.beginPath(); 
ctx.moveTo(bx, by); 
ctx.lineTo(cx , cy); 
ctx.stroke(); 

//now the midpoint of the green lines: 
// so g1 and g2 are the green line midpoints 
var g1x = mid(ax,cx); 
var g2x = mid(bx,cx); 

var g1y = mid(ay,cy); 
var g2y = mid(by,cy); 

//draw them to make sure: 
ctx.fillRect(g1x , g1y, 4, 4); 
ctx.fillRect(g2x , g2y, 4, 4); 

//now one final line, in gray 
ctx.strokeStyle = "rgba(20,20,20,0.4)"; 
ctx.beginPath(); 
ctx.moveTo(g1x , g1y); 
ctx.lineTo(g2x , g2y); 
ctx.stroke(); 

//whew! We made it! 
var FinallyTheMidpointx = mid(g1x,g2x); 
var FinallyTheMidpointy = mid(g1y,g2y); 

//draw something at the midpoint to celebrate 
ctx.fillStyle = "rgba(0,255,0,1)"; 
ctx.fillRect(FinallyTheMidpointx, FinallyTheMidpointy, 4, 4); 

+0

哇!這是遠遠超出有用的。我一直在尋找的是讓人們確認是否存在一種簡單的方法,然後纔開始實施並以艱難的方式實施。 – 2010-08-27 08:58:42