2010-08-25 4 views
5

Étant donné les lignes dessinées par les fonctions de contexte de canevas 2d bezierCurveTo, quadraticCurveTo ou arcTo, comment trouver des points le long de ces lignes?Trouver des points sur les courbes en HTML 5 2d Contexte Canevas

Mon intention est de dessiner un objet au milieu d'une courbe. En utilisant le DOM SVG, je peux le faire avec les méthodes getPointAtLength & getTotalLength, mais je ne peux pas voir un équivalent dans le canevas HTML.

Répondre

10

On les trouve à la dure :(

Il n'y a pas d'équivalent en toile HTML. Vous devez trouver les points médians vous avec les mathématiques ancienne plaine.

Je l'ai fait un exemple de la façon de trouver milieu des courbes de Bézier pour vous. voir vivre à jsFiddle here. une copie du javascript est collé ci-dessous.

courbe réelle est rouge, point médian est le petit rectangle vert. Tout le reste est tout simplement une aide visuelle.

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

Wow! C'est beaucoup plus utile. Tout ce que je cherchais, c'était que quelqu'un confirme l'existence ou l'absence d'un moyen facile, avant que je craque et ne le fasse à la dure. –

Questions connexes