定位和样式SVG tspans?

时间:2018-10-29 03:13:12

标签: javascript html svg

此SVG存在两个问题。首先,我需要它来使用Raleway字体。其次,我需要将文本反过来。我尝试使用CSS平移和旋转,但是它们没有提供我想要的结果。我已经阅读了有关SVG样式的文档,但是它没有多大用处,并且不能满足我的特殊需求。我也通过Google搜索过,他们只建议我已经尝试过的东西。

我在下面提供了一些代码以供参考。

// JavaScript that was graciously provided for me:

const rad = Math.PI / 180;

let cx = 50, cy = 100, R = 50, r = 35, A = 40 , a = 5, o=4;
// o for offset
testGroupC2.setAttributeNS(null, "transform", `rotate(${-90 -(A / 2) - a} ${cx} ${cy})`)


// control points for the quadratic Bézier
let px1 = cx + R * Math.cos(0);
let py1 = cy + R * Math.sin(0);
let px2 = cx + R * Math.cos((2*a + A)*rad);
let py2 = cy + R * Math.sin((2*a + A)*rad);
let px3 = cx + r * Math.cos((2*a + A)*rad);
let py3 = cy + r * Math.sin((2*a + A)*rad);
let px4 = cx + r * Math.cos(0);
let py4 = cy + r * Math.sin(0);

// points used to draw the shape
let x11 = cx + (R-o) * Math.cos(0);
let y11 = cy + (R-o) * Math.sin(0);

let x1 = cx + R * Math.cos(a*rad);
let y1 = cy + R * Math.sin(a*rad);

let x2 = cx + R * Math.cos((a + A)*rad);
let y2 = cy + R * Math.sin((a + A)*rad);

let x21 = cx + (R-o) * Math.cos((2*a + A)*rad);
let y21 = cy + (R-o) * Math.sin((2*a + A)*rad);

let x31 = cx + (r+o) * Math.cos((2*a + A)*rad);
let y31 = cy + (r+o) * Math.sin((2*a + A)*rad);

let x3 = cx + r * Math.cos((a + A)*rad);
let y3 = cy + r * Math.sin((a + A)*rad);

let x4 = cx + r * Math.cos(a*rad);
let y4 = cy + r * Math.sin(a*rad);

let x41 = cx + (r+o) * Math.cos(0);
let y41 = cy + (r+o) * Math.sin(0);

/*
No rounded corners
let d = `M${x1},${y1} A${R},${R},0 0,1 ${x2},${y2}
         L${x3},${y3} A${r},${r},0 0,0 ${x4},${y4}
         L${x1},${y1}Z`;*/

/*
Beveled corners
let d = `M${x1},${y1} 
         A${R},${R},0 0,1 ${x2},${y2}
         L${x21},${y21} 
         L${x31},${y31}
         L${x3},${y3}
         A${r},${r},0 0,0 ${x4},${y4}
         L${x41},${y41}
         L${x11},${y11}
         L${x1},${y1}Z`;*/

// Rounded corners with quadratic Bézier curves
    d = `M${x1},${y1} 
         A${R},${R},0 0,1 ${x2},${y2}
         Q${px2},${py2} ${x21},${y21} 
         L${x31},${y31}
         Q${px3},${py3} ${x3},${y3}
         A${r},${r},0 0,0 ${x4},${y4}
         Q${px4},${py4} ${x41},${y41}
         L${x11},${y11}
         Q${px1},${py1} ${x1},${y1}Z`;

testPath2.setAttributeNS(null,"d",d);
<svg viewBox="0 40 100 40">
  <g id="testGroupC2" >
	   <style type="text/css">
        <![CDATA[   
  
  @import url('https://fonts.googleapis.com/css?family=Raleway:thin');
			  text{font-family:Raleway; z-index: 20}
     
             ]]> 
  </style>
	  <path id="testPath2"/>
	   <text>
         <textpath style="font-size:4pt;" xlink:href="#testPath2" startOffset="63%" >
            <tspan x="-3" y="10">Home</tspan>
      </textpath>
    </text>
    
  </g>
</svg>

1 个答案:

答案 0 :(得分:1)

您可以采用底部曲线并将其用作文本的路径。它必须是相反的顺序,否则(如代码中的情况),文本将显示在路径下方并旋转​​(实际上是路径的方向)。

所以:这是一条仅用于文本的路径,并且对文本对齐方式进行了一些调整

结果如下:

// JavaScript Document

const rad = Math.PI / 180;

let cx = 50, cy = 100, R = 50, r = 35, A = 40 , a = 5, o=4;
// o for offset
testGroupC2.setAttributeNS(null, "transform", `rotate(${-90 -(A / 2) - a} ${cx} ${cy})`)


// control points for the quadratic Bézier
let px1 = cx + R * Math.cos(0);
let py1 = cy + R * Math.sin(0);
let px2 = cx + R * Math.cos((2*a + A)*rad);
let py2 = cy + R * Math.sin((2*a + A)*rad);
let px3 = cx + r * Math.cos((2*a + A)*rad);
let py3 = cy + r * Math.sin((2*a + A)*rad);
let px4 = cx + r * Math.cos(0);
let py4 = cy + r * Math.sin(0);

// points used to draw the shape
let x11 = cx + (R-o) * Math.cos(0);
let y11 = cy + (R-o) * Math.sin(0);

let x1 = cx + R * Math.cos(a*rad);
let y1 = cy + R * Math.sin(a*rad);

let x2 = cx + R * Math.cos((a + A)*rad);
let y2 = cy + R * Math.sin((a + A)*rad);

let x21 = cx + (R-o) * Math.cos((2*a + A)*rad);
let y21 = cy + (R-o) * Math.sin((2*a + A)*rad);

let x31 = cx + (r+o) * Math.cos((2*a + A)*rad);
let y31 = cy + (r+o) * Math.sin((2*a + A)*rad);

let x3 = cx + r * Math.cos((a + A)*rad);
let y3 = cy + r * Math.sin((a + A)*rad);

let x4 = cx + r * Math.cos(a*rad);
let y4 = cy + r * Math.sin(a*rad);

let x41 = cx + (r+o) * Math.cos(0);
let y41 = cy + (r+o) * Math.sin(0);

/*
No rounded corners
let d = `M${x1},${y1} A${R},${R},0 0,1 ${x2},${y2}
         L${x3},${y3} A${r},${r},0 0,0 ${x4},${y4}
         L${x1},${y1}Z`;*/

/*
Beveled corners
let d = `M${x1},${y1} 
         A${R},${R},0 0,1 ${x2},${y2}
         L${x21},${y21} 
         L${x31},${y31}
         L${x3},${y3}
         A${r},${r},0 0,0 ${x4},${y4}
         L${x41},${y41}
         L${x11},${y11}
         L${x1},${y1}Z`;*/

// Rounded corners with quadratic Bézier curves
    d = `M${x1},${y1} 
         A${R},${R},0 0,1 ${x2},${y2}
         Q${px2},${py2} ${x21},${y21} 
         L${x31},${y31}
         Q${px3},${py3} ${x3},${y3}
         A${r},${r},0 0,0 ${x4},${y4}
         Q${px4},${py4} ${x41},${y41}
         L${x11},${y11}
         Q${px1},${py1} ${x1},${y1}Z`;
		 
testPath2.setAttributeNS(null,"d",d);


/* based on the 2nd A-curve of the testPath,
   but last point and starting point switched,
   as well as the sweep-flag of the curve */
   
    dtext = `M${x4},${y4}
         A${r},${r},0 0,1 ${x3},${y3}`;
         
textPath.setAttributeNS(null,"d",dtext);
<svg viewBox="0 40 100 40">
	<defs><path id="textPath"/></defs>
	<g id="testGroupC2" >
	  <style type="text/css">
		 <![CDATA[
		  @import url('https://fonts.googleapis.com/css?family=Raleway:thin');
		  text{
		  	font-size: 4pt;
			  fill: #ffffff;
			  text-anchor: middle;
			  font-family: 'Raleway';
			  z-index: 2;
		  }
		 ]]> 
	  </style>
      <path id="testPath2"/>
	  <text>
		  <textpath xlink:href="#textPath" startOffset="50%" >
			  <tspan x="0" dy="-5.5">Home</tspan>
		  </textpath>
	  </text>
  </g>
</svg>