马黑黑老师SVG A指令绘制优弧劣弧演示
<style>@import 'https://638183.freep.cn/638183/web/css/hl.css';
.artBox { margin: 20px auto; font: normal 18px/26px sans-serif; max-width: 1200px; }
.artBox mark { padding: 2px 6px; background: #ccc; }
.artBox blockquote { padding: 14px; border: solid gray; border-width: 0 4px; border-radius: 10px; background: #ddd; }
.artBox p { margin: 10px 0; }
.stage { display: grid; place-items: center; }
.btnAdd, .btnDel { border: 1px solid gray; border-radius: 14px; padding: 4px 16px; cursor: pointer; margin-left: 10px; }
.btnAdd:hover, .btnDel:hover { background: #eee; }
.msvg { border: 1px solid gray; margin: 30px 0; }
.msvg path { fill: none; stroke-width: 2; }
.tRed { color: red; }
.tBlue { color: blue; }
</style>
<div class="artBox">
<p>SVG <mark>A指令</mark>在给定起点 (x1,y1) 到终点 (x2,y2) 之间绘制弧线,如果弧线的长轴半径大于两点之间距离的一半,这两点间的弧线就存在四种可能:两个凸面朝向不同(左右或上下)的弧线都可以各绘制一个优弧(大弧)和一个劣弧(小弧)。</p>
<blockquote>
<p><strong>A指令语法(红色部分)及参数解释:</strong></p>
<p>语法:<code class="hlCode"><span class="tBlue">M x1 y1</span> <span class="tRed">A rx ry, x-axis-rotation large-arc-flag sweep-flag, x2 y2</span></code></p>
<ol>
<li>M x1 y1 :非 A指令范畴,但A指令视 x1 y1 为弧线的起点坐标</li>
<li>rx ry :圆弧的两个半轴(长度)</li>
<li>x-axis-rotation :圆弧相对于坐标系的旋转角度(角度)</li>
<li>large-arc-flag :绘制大弧(1)还是小弧(0)部分</li>
<li>sweep-flag :按顺时针(1)还是逆时针(0)方向绘制弧线</li>
<li>x2 y2 :圆弧终点坐标</li>
</ol>
<p>【例】<code class="hlCode"><path d="M 10 10 A 100 60,0 0 1, 190 10" /></code></p>
</blockquote>
<p>以下演示,将从 点(100,160) 绘制圆弧线到 点(300,270),由于圆弧的长轴半径已设置为大于弧线起、止两点间距离的一半,可以绘制四段圆弧线:</p>
<div class="stage">
<svg class="msvg" width="400" height="400">
<circle cx="100" cy="160" r="10" fill="rgba(0,0,0,.25)" />
<circle cx="300" cy="270" r="10" fill="rgba(0,0,0,.25)" />
<line x1="100" y1="160" x2="300" y2="270" stroke="gray"/>
<path d="M 100 160 A 140 100,0 1 0,300 270" />
<path d="M 100 160 A 140 100,0 0 0,300 270" />
<path d="M 100 160 A 140 100,0 1 1,300 270" />
<path d="M 100 160 A 140 100,0 0 1,300 270" />
</svg>
<p>优弧(弧面朝下):<code></code><span class="btnAdd">✔️</span><span class="btnDel">❌</span></p>
<p>劣弧(弧面朝下):<code></code><span class="btnAdd">✔️</span><span class="btnDel">❌</span></p>
<p>优弧(弧面朝上):<code></code><span class="btnAdd">✔️</span><span class="btnDel">❌</span></p>
<p>劣弧(弧面朝上):<code></code><span class="btnAdd">✔️</span><span class="btnDel">❌</span></p>
</div>
<p><strong>核心小结:</strong></p>
<ol>
<li>优弧劣弧出现的前提:圆弧长轴半径大于圆弧线端点到终点距离的一半;</li>
<li>若上一条规则成立,A指令倒数第三个参数 large-arc-flag 设为 1 绘制优弧、设为 0 绘制劣弧;</li>
<li>A指令倒数第二个参数 sweep-flag 设为 1 按顺时针、设为 0 按逆时针方向绘制圆弧,因此此参数决定了圆弧凸面的朝向。</li>
</ol>
</div>
<script>
const paths = document.querySelectorAll('.msvg path');
const btnAdds = document.querySelectorAll('.btnAdd');
const btnDels = document.querySelectorAll('.btnDel');
const codes = document.querySelectorAll('.stage code');
const colors = ['red', 'blue', 'green', 'magenta'];
codes.forEach((code, k) => {
code.classList.add('hlCode');
code.textContent = paths.getAttribute('d');
});
btnAdds.forEach((btn, k) => {
btn.title = '绘制弧线';
btn.onclick = () => {
paths.setAttribute('stroke', colors);
};
});
btnDels.forEach((btn, k) => {
btn.title = '删除弧线';
btn.onclick = () => paths.setAttribute('stroke', 'none');
});
</script>
实用的教程,谢谢分享
页:
[1]