Question amusante ! J'ai écrit une implémentation personnalisée des lignes en pointillés ; vous pouvez Essayez-le ici . J'ai suivi l'exemple d'Adobe Illustrator et je vous ai permis de spécifier un ensemble de longueurs de tirets/intervalles.
Pour la postérité de stackoverflow, voici mon implémentation (légèrement modifiée pour les largeurs de ligne s/o) :
var CP = window.CanvasRenderingContext2D && CanvasRenderingContext2D.prototype;
if (CP && CP.lineTo){
CP.dashedLine = function(x,y,x2,y2,dashArray){
if (!dashArray) dashArray=[10,5];
if (dashLength==0) dashLength = 0.001; // Hack for Safari
var dashCount = dashArray.length;
this.moveTo(x, y);
var dx = (x2-x), dy = (y2-y);
var slope = dx ? dy/dx : 1e15;
var distRemaining = Math.sqrt( dx*dx + dy*dy );
var dashIndex=0, draw=true;
while (distRemaining>=0.1){
var dashLength = dashArray[dashIndex++%dashCount];
if (dashLength > distRemaining) dashLength = distRemaining;
var xStep = Math.sqrt( dashLength*dashLength / (1 + slope*slope) );
if (dx<0) xStep = -xStep;
x += xStep
y += slope*xStep;
this[draw ? 'lineTo' : 'moveTo'](x,y);
distRemaining -= dashLength;
draw = !draw;
}
}
}
Pour tracer une ligne de 20,150
à 170,10
avec des tirets de 30px de long suivis d'un espace de 10px, vous utiliserez :
myContext.dashedLine(20,150,170,10,[30,10]);
Pour dessiner des tirets et des points alternés, utilisez (par exemple) :
myContext.lineCap = 'round';
myContext.lineWidth = 4; // Lines 4px wide, dots of diameter 4
myContext.dashedLine(20,150,170,10,[30,10,0,10]);
La longueur du tiret "très court" de 0
combinée avec le capuchon de ligne arrondi donne des points le long de votre ligne.
Si quelqu'un connaît un moyen d'accéder au point actuel d'un chemin de contexte de canevas, j'aimerais bien le savoir, car cela me permettrait d'écrire ceci sous la forme suivante ctx.dashTo(x,y,dashes)
au lieu de vous demander de spécifier à nouveau le point de départ dans l'appel de la méthode.