Have a text follow a Bezier curve

Hello,

I have some Bezier curves that represent the transitions of automata: https://imgur.com/a/aOsZvtZ
These Bezier curves are draggable: https://imgur.com/DycuyKP

I want to have the text follow the Bezier curve when it’s being dragged, how can I do that?

Thanks,
sevaus.

1 Like

If you are using the bezier function to draw your curves, then you could use bezierPoint to get the moving position and assign this position to your text.

Kf

1 Like

Thanks, I will try it.

Do you know how can I do to have the text displayed only when I’m clicking on the Bézier curve? I want it to be gone if I click elsewhere.

That depends in your code. Provide an MCVE and you could get some suggestions. But yes, it is doable.

Kf

The relevant portion of code that creates the arcs using Bezier curves is

//function drawArc draw arrows with parameters :
//e1 : the outgoing state ; e2 : the incoming state ; a : the number of the automata
//k : the number of the arrow of this automata ; num_arc : the number of the arrow in total (to allow the displacement)
//coordonnees : array containing the coordinates of each arrow ; first : boolean that indicates if it's the first time arrows are
//drawn (to create divs if it the case)
function drawArc(e1,e2,a,k,num_arc, coordonnees, first){

  var x = 155+(a-1)*230,
      y= 140+(4-e1)*50-(e2-e1)*25,
      h = 2+(e2-e1)*50, x1, x2, x3, x4,y1, y2, y3, y4;

  if (first){
    first = false;

    if (k%2==0){

      if (e2<e1){
        coordonnees[num_arc][0] = x-30+50*((k+1)/2)+(e1-e2-1)*15;
        coordonnees[num_arc][1] = y;
        }
      else {
        coordonnees[num_arc][0] = x-30-50*((k+1)/2)-(e1-e2-1)*15;
        coordonnees[num_arc][1] = y;
        }
    }


    else {

      if (e2>=e1){
        coordonnees[num_arc][0] = x+50*((k+1)/2)+(e2-e1-1)*15;
        coordonnees[num_arc][1] = y ;
        }

      else {
        coordonnees[num_arc][0] = x-55-50*(k+1)/2-(e2-e1-1)*15+30;
        coordonnees[num_arc][1] = y ;
      }
    }
    var arc_div = document.createElement('div');
    arc_div.className = "arc";
    arc_div.id = num_arc;
    document.body.appendChild(arc_div);
    arc_div.onmousedown = function(evt) {
        dragged = true;
        xi = num_arc; xj = 0;
        yi = num_arc; yj = 1;
    }

  }


  if (k%2==0){

    if (e2<e1){
      x1 = x4 = x;
      y1 = y+26+(e1-e2-1)*25;
      y4 = y-26-(e1-e2-1)*25;
      line(x,y-h/2, x+8,y-h/2-8);
      line(x,y-h/2, x+8,y-h/2+8);
      noFill();
      bezier(x1, y1, coordonnees[num_arc][0], coordonnees[num_arc][1]+(e1-e2-1)*25+20, coordonnees[num_arc][0], coordonnees[num_arc][1]-(e1-e2-1)*25-20, x4, y4);
      xx = bezierPoint(x1, coordonnees[num_arc][0], coordonnees[num_arc][0], x4, 1/2);
      yy = bezierPoint(y1, coordonnees[num_arc][1]+(e1-e2-1)*25+20,  coordonnees[num_arc][1]-(e1-e2-1)*25-20, y4, 1/2);
      }
    else {
      x1 = x4 = x-30;
      y1 =  y+24+(e2-e1-1)*25;
      y4 =  y-26-(e2-e1-1)*25;
      line(x-38,y-h/2-9, x-30,y-h/2-1);
      line(x-38,y-h/2+7, x-30,y-h/2-1);
      noFill();
      bezier(x1, y1, coordonnees[num_arc][0]-30, coordonnees[num_arc][1]+(e2-e1-1)*25+20, coordonnees[num_arc][0]-30,coordonnees[num_arc][1]-(e2-e1-1)*25-20, x4, y4);
      xx = bezierPoint(x1, coordonnees[num_arc][0]-30, coordonnees[num_arc][0]-30, x4, 1/2);
      yy = bezierPoint(y1, coordonnees[num_arc][1]+(e2-e1-1)*25+20,  coordonnees[num_arc][1]-(e2-e1-1)*25-20, y4, 1/2);
     }
  }

  else {

    if (e2>=e1){
      x1 = x4 = x;
      y1 = y+26+(e2-e1-1)*25;
      y4 =  y-26-(e2-e1-1)*25;
      line(x,y-h/2, x+8,y-h/2-8);
      line(x,y-h/2, x+8,y-h/2+8);
      noFill();
      bezier(x1, y1, coordonnees[num_arc][0], coordonnees[num_arc][1]+(e2-e1-1)*25+20, coordonnees[num_arc][0], coordonnees[num_arc][1]-(e2-e1-1)*25-20, x4, y4);
      xx = bezierPoint(x1, coordonnees[num_arc][0], coordonnees[num_arc][0], x4, 1/2);
      yy = bezierPoint(y1, coordonnees[num_arc][1]+(e2-e1-1)*25+20,  coordonnees[num_arc][1]-(e2-e1-1)*25-20, y4, 1/2);
      }
    else {
      x1 = x4 = x-30;
      x2 = x3 = x-55-50*(k+1)/2-(e2-e1-1)*15;
      y1 = y+24+(e1-e2-1)*25;
      y4 = y-26-(e1-e2-1)*25;
      line(x-38,y-h/2-9, x-30,y-h/2-1);
      line(x-38,y-h/2+7, x-30,y-h/2-1);
      noFill();
      bezier(x1, y1, coordonnees[num_arc][0]-30, coordonnees[num_arc][1]+(e1-e2-1)*25+20, coordonnees[num_arc][0]-30,coordonnees[num_arc][1]-(e1-e2-1)*25-20, x4, y4);
      xx = bezierPoint(x1, coordonnees[num_arc][0]-30, coordonnees[num_arc][0]-30, x4, 1/2);
      yy = bezierPoint(y1, coordonnees[num_arc][1]+(e1-e2-1)*25+20,  coordonnees[num_arc][1]-(e1-e2-1)*25-20, y4, 1/2);
      }
  }
  divs[num_arc].style.top = yy + "px";
  divs[num_arc].style.left = xx + "px";
  fill(255);
  ellipse(xx, yy, 5,5);

}

The function that displays the text is

function afficheTrans(texte, e1, e2, a, k){

  var x = 155+(a-1)*230;
  var y= 140+(4-e1)*50-(e2-e1)*25;
  var h = 2+(e2-e1)*50;

  if (dist(mouseX, mouseY, x+8,y-h/2-8) < 50) {
    fill(255, 0, 0); //rouge
    //noStroke();
     text(texte,x+(e2-e1)*50, y);
}

}

Thanks a lot!

1 Like

You may be interested in the tutorial “Placing text along a path using Geomerative and Processing”:

Previous related discussion:

Some generic approaches to circle-curve text: