SVG path 標簽根據兩點和角度繪制弧線


同步發布:https://blog.jijian.link/2020-04-14/svg-arc/

由於功能受限,此處不能放 iframe 嵌入鏈接,如需看到實時效果,請移步 https://blog.jijian.link/2020-04-14/svg-arc/

解析

<path> 標簽應該算是 SVG 中最為強大的標簽了,各種圖形都可以用他繪制。

本文使用 path 標簽的貝塞爾曲線 Q 指令繪制弧線。

用法

<path d="M30 90 Q115 139 200 90"></path>

<path> 標簽常用指令:

  • M = moveto
  • L = lineto
  • H = horizontal lineto
  • V = vertical lineto
  • C = curveto
  • S = smooth curveto
  • Q = quadratic Belzier curve
  • T = smooth quadratic Belzier curveto
  • A = elliptical Arc
  • Z = closepath

注釋:以上所有命令均允許小寫字母。大寫表示絕對定位,小寫表示相對定位。

繪制線條

常見效果:繪制實線、繪制虛線、繪制弧線、繪制漸變線條、繪制箭頭線條。

 

源碼:

<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <!-- 箭頭 -->
    <marker id="arrow" markerUnits="strokeWidth" markerWidth="12" markerHeight="12" viewBox="0 0 12 12" refX="6" refY="6" orient="auto">
      <path d="M2,2 L10,6 L2,10 L6,6 L2,2" style="fill: #000000;"/>
    </marker>
    <linearGradient id="line-gradient" x1="0" y1="0" x2="1" y2="0">
      <stop offset="0" stop-color="#990000" stop-opacity="0" />
      <stop offset="1" stop-color="#990000" stop-opacity="1" />
    </linearGradient>
  </defs>
  <!-- 實線 -->
  <path class="line" d="M30 30 L200 30"></path>
  <!-- 虛線 -->
  <path class="line" d="M30 60 L200 60" style="stroke-dasharray: 5;"></path>
  
  <!-- 弧線 -->
  <path class="line" d="M30 90 Q115 139 200 90"></path>
  <!-- 漸變線條 -->
  <path class="line" d="M30 120 Q115 169 200 120" style="stroke: url(#line-gradient)"></path>
  <!-- 箭頭線條 -->
  <path class="line" d="M30 150 Q115 199 200 150" style="marker-end:url(#arrow)"></path>
  
  <!-- 無瀏覽器潤色的線條,有鋸齒像素 -->
  <path class="line" d="M30 180 Q115 229 200 180" style="shape-rendering: optimizeSpeed;"></path>
</svg>

實際應用

實際應用場景不一定會有詳細坐標點,需要我們根據已有條件去計算。

比如:已有開始左邊和結束坐標,根據這兩個坐標繪制一條弧線。

SVG 繪制弧線:

<path d="M30 90 Q115 139 200 90"></path>

M30 90 :表示開始點 x:30 y:90
Q115 139 :表示控制點在 x:115 y:139
200 90 :表示結束點 x:200 y:90

計算控制點圖解:

 

換算為 JS 算法:

const pos = getPosition ({left: 30, top: 90}, {left: 200, top: 90}, 30);
console.log(pos); // [{"x":115,"y":139},{"x":115,"y":41}]
function getPosition (dot1, dot2, angle) {
  var x1 = dot1.left;
  var y1 = dot1.top;
  var x2 = dot2.left;
  var y2 = dot2.top;
  var PI = Math.PI;

  // 兩點間的x軸夾角弧度
  var xAngle=Math.atan2((y2-y1), (x2-x1));
  // 轉為角度
  xAngle = 360*xAngle/(2*PI);
  // 兩點間的長度
  var L=Math.sqrt((y2-y1)*(y2-y1)+(x2-x1)*(x2-x1));
  // 計算等腰三角形斜邊長度
  var L2 = L/2 / Math.cos(angle* 2*PI/360);

  // 求第一個頂點坐標,位於下邊
  var val1={};
  // 求第二個頂點坐標,位於上邊
  var val2={};
  val1['x']=x1+Math.round(L2 * Math.cos((xAngle+angle)* 2*PI/360));
  val1['y']=y1+Math.round(L2 * Math.sin((xAngle+angle)* 2*PI/360));
  val2['x']=x1+Math.round(L2 * Math.cos((xAngle-angle)* 2*PI/360));
  val2['y']=y1+Math.round(L2 * Math.sin((xAngle-angle)* 2*PI/360));

  return [val1,val2];
}

應用場景:

總結:path 運用遠不止此,比如常見的字體圖標,SVG 圖標等,都可見 path 標簽運用,一些炫酷的動畫效果也可以使用 path 標簽實現。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM