Dynamic TextPath Curve Example (VML)


Purpose

This example demonstrates how to use the TextPath child element to attach text to a VML bezier curve. It also shows how to dynamically change the control points that define the shape of the curve.

The black squares show the beginning and ending points of the curve. The numbered circles show the control points that define the shape of the curve. A black line shows the path of the bezier curve defined by the end points and the control points.

You can click the mouse within the dimensions of the blue rectangle to move the highlighted control point. This changes the shape of the underlying curve and forces the text to follow the new shape.

To view the coordinates of an end point, use the mouse to point to the square corresponding to that end point. To view the coordinates of a control point, use the mouse to point to the corresponding circle. When you do this, tool tips display the coordinate values.

Example

1 2


 


Code

<!-- Include the VML behavior -->
<style>v\: * { behavior: url(#default#VML);display:inline-block }</style>

<!-- Declare the VML namespace -->
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v"/>

<!-- Containing block defines positioning -->
<div id="pb"
  style="position:relative; left:50; height:150px; width:300px;margin-top:25px;margin-left:25px;background-color:#CFCFFF; border-style:none">

<!-- Control point 1 -->
<v:oval id="oval1" fillcolor="yellow" strokecolor="black"
  style="position:absolute;left:100px;top:50px;width:28px;height:28px;z-index:5">
  <v:textbox>1</v:textbox>
</v:oval>

<!-- Control point 2 -->
<v:oval id="oval2" fillcolor="white" strokecolor="black"
  style="position:absolute;left:200px;top:150px;width:28px;height:28px;z-index:5;mso-fit-text-to-shape:false">
  <v:textbox>2</v:textbox>
</v:oval>

<!-- Beginning point (origin) -->
<v:rect id="rect1" fillcolor="black"
  style="position:absolute;left:0px;top:0px;width:10px;height:10px;z-index:5"/>

<!-- End point (destination) -->
<v:rect id="rect2" fillcolor="black"
  style="position:absolute;left:300px;top:150px;width:10px;height:10px;z-index:5"/>

<!-- Text Curve -->
<v:curve id="tc"
  style="position:absolute;z-index:3" from="0px 0px" to="300px 150px"
  control1="50px 100px" control2="100px 150px">
  <v:stroke weight="1pt" color="blue"  filltype="solid"/>
  <v:fill on="True" color="navy" color2="yellow" type="gradient"/>
  <v:path textpathok="True"/>
  <v:textpath on="True" id="mytp" style="font:normal normal normal 36pt Arial"
    fitpath="True" fitpath="True" string="Hello"/>
</v:curve>

<v:curve id="cv"
  style="position:absolute;z-index:2" from="0px 0px" to="300px 150px"
  control1="50px 100px" control2="100px 150px">
  <v:fill on="False"/>
  <v:stroke weight="1pt" color="black" />
</v:curve>
</div>
<script language="JavaScript">
var clickcount = 0;

rect1.title = pb.offsetLeft + ", " + pb.offsetTop;
rect2.title = ( pb.offsetLeft + pb.offsetWidth ) + ", " +
              ( pb.offsetTop + pb.offsetHeight );
oval1.title = tc.control1;
oval2.title = tc.control2;

pb.onclick=WhereClick;

function MoveCoord( tcc, vcc, o)
{
  var nx = window.event.x;
  var ny = window.event.y;

  tcc.x = nx;
  vcc.x = nx;

  tcc.y = ny;
  vcc.y = ny;

  o.style.left = nx - ( parseInt( o.style.width ) / 2 );
  o.style.top = ny - ( parseInt( o.style.height ) / 2 );
  o.title = tcc;
}

function WhereClick()
{
  clickcount++;
  switch (clickcount)
  {
    case 1: MoveCoord( tc.control1, cv.control1, oval1 );
            break;

    case 2: MoveCoord( tc.control2, cv.control2, oval2 );
            break;

    default: alert("else"); // in case we add a third condition later
  }

  // clean-up interface
  if (clickcount > 1) { clickcount = 0; }
  var oc = (clickcount == 0) ? "yellow" : "white";
  oval1.fillcolor = oc;
  oval2.fillcolor = (oc == "white") ? "yellow" : "white";

}
</script>