Jascination Jascination - 7 months ago 9
Javascript Question

Finding the midway between two points

I have a bunch of HTML elements that I want to connect with lines via Canvas. Here's a mockup of what I'm trying to achieve:

Mockup

Currently, I just have the lines, with no text. I want to place text halfway between each line, but seeing as they're diagonals I'm not sure how to do it.

Current code:

// 'connectors' is an array of points corresponding to
// the middle of each big blue buttons' x-value

ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<connectors.length;i++){
var wpoint = connectors[i];
var pos1 = {w: wpoint, h: 0};
var pos2 = {w: canvas.width / 2, h: canvas.height};
ctx.beginPath();
ctx.moveTo(pos1.w,pos1.h);
ctx.lineTo(pos2.w,pos2.h);
ctx.stroke();

// Write Text Halfway
ctx.fillStyle = "blue";
ctx.font = "bold 16px Arial";
ctx.fillText("2702", 100, canvas.height / 2);
// No idea what to put as the x value here

}


What's the best way to achieve this? Potentially drawing half the line, writing the text, then drawing the rest of the line?

EDIT: Perhaps a better title / question would be: How do I find the midpoint between two arbitrary points in HTML Canvas? I want to draw text there.

Answer

enter image description here

Here's how:

  • Calculate the line's midpoint
  • Draw the line
  • Erase the line at its midpoint
  • Tell canvas to horizontally & vertically center any drawn text around a specified [x,y]
  • Draw the text at the midpoint

Here's annotated code and a Demo:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");

var line={x0:20,y0:20,x1:150,y1:150};

textAtMidLine(line,'2702','verdana',14)

function textAtMidLine(line,text,fontface,fontsize){

  // save the unmodified context state
  ctx.save();

  // calc line's midpoint
  var midX=line.x0+(line.x1-line.x0)*0.50;
  var midY=line.y0+(line.y1-line.y0)*0.50;

  // calc width of text
  ctx.font=fontsize+'px '+fontface;
  var textwidth=ctx.measureText(text).width;

  // draw the line
  ctx.beginPath();
  ctx.moveTo(line.x0,line.y0);
  ctx.lineTo(line.x1,line.y1);
  ctx.lineWidth=2;
  ctx.strokeStyle='lightgray';
  ctx.stroke();

  // clear the line at the midpoint
  ctx.globalCompositeOperation='destination-out'; // "erases" 
  ctx.fillRect(midX-textwidth/2,midY-fontsize/2,textwidth,fontsize*1.286);
  ctx.globalCompositeOperation='source-over';  // reset to default

  // tell canvas to horizontally & vertically center text around an [x,y]
  ctx.textAlign='center';
  ctx.textBaseline='middle'

  // draw text at the midpoint
  ctx.fillText(text,midX,midY);

  // restore the unmodified context state
  ctx.restore();

}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>