优弧与劣弧以及svg path d属性的A指令
本帖最后由 马黑黑 于 2023-5-24 21:13 编辑 <br /><br /><style>.papa > p { margin: 10px 0; }
.mama { margin-left: 40px; position: relative; }
.hCode, .hLineNum { padding: 10px; width: calc(100% - 40px); background: #f9f9f9; box-sizing: border-box; overflow-x: auto; tab-size: 3; position: absolute; }
.hCode { left: 40px; margin-left: -40px; padding-left: 45px; }
.hLineNum { width: 40px; background: #ccc; border-right: 1px solid #ccc; text-align: right; pointer-events: none; }
.stage { display: grid; place-items: center; }
.hidden { display: none; }
svg { border: 1px solid gray; width: 300px; height: 200px; fill: none; stroke: red; }
.line { stroke: pink; }
.circle { stroke: blue; fill: blue; }
.red { color: red; font-weight: bold; }
.blue {color: blue; font-weight: bold; }
.purple { color: purple; }
</style>
<div class="papa">
<p>对优弧与劣弧的清晰认识有助于理解 svg path 标签的 d 属性的相关参数,故此,有必要研究一下优弧与劣弧。我们以一个圆为例,在 300*200 的 svg 场景下,用一横线将圆划分为大小不一致的两个部分,横线与圆周的交点我们也给标注了出来(本文所有的 svg 代码,均在CSS中制定了相关样式,紫色文本的代码都是指向图形中标记性的元素):</p>
<div class="mama">
<pre class="hCode" contenteditable="true"><svg>
<circle cx="150" cy="100" r="50" />
<span class="purple"><line x1="0" y1="80" x2="300" y2="80" class="line" />
<circle cx="104" cy="80" r="2" class="circle" />
<circle cx="196" cy="80" r="2" class="circle" /></span>
</svg></pre>
<pre class="hLineNum"></pre>
</div>
<p><button class="btnok" type="button" value="运行代码">运行代码</button></p>
<div class="stage"></div>
<p>运行以上代码,圆被横线一分为二,横线上面的弧线较小,叫劣弧,下面的弧线较大,叫优弧。优弧劣弧的主要依据是圆心在不在还弧形之内,圆心若在,则是优弧,否则是劣弧,这是优弧劣弧的数学依据。</p>
<p>下面,了解一下 svg path 标签 d 属性的 A 指令。A 指令用于画弧线,之前我们介绍过,它需要七个参数,这里再介绍一下:</p>
<blockquote>
参数1:X轴半径<br>
参数2:Y轴半径<br>
参数3:X轴旋转度(顺时针方向为正,0表示不旋转)<br>
<span class="red">参数4</span>:1优弧还是0劣弧(大于半圆的弧叫优弧、小于半圆的弧叫劣弧)><br>
<span class="blue">参数5</span>:弧线的方向,0表示从起点到终点沿逆时针画弧,1表示从起点到终点沿顺时针画弧<br>
参数6:终点X坐标<br>
参数7:终点Y坐标<br>
</blockquote>
<p>接下来,我们开始用 path 路径 d 属性 的 A 指令绘制前面的圆的上部分,劣弧:</p>
<div class="mama">
<pre class="hCode" contenteditable="true"><p>凸面朝上的劣弧</p>
<svg>
<path d="M104 80 A50 50 0 <span class="red">0</span> <span class="blue">1</span> 196 80" />
<span class="purple"><line x1="0" y1="80" x2="300" y2="80" class="line" />
<circle cx="104" cy="80" r="2" class="circle" />
<circle cx="196" cy="80" r="2" class="circle" /></span>
</svg></pre>
<pre class="hLineNum"></pre>
</div>
<p><button class="btnok" type="button" value="运行代码">运行代码</button></p>
<div class="stage"></div>
<p>以上代码,红色数值是指令 A 的第四个参数,用于定义优弧(1)或劣弧(0),蓝色数值是第五个参数,用于设定弧线的方向:1 为顺时针方向,0 为逆时针方向。</p>
<p>继续,我们绘制优弧:</p>
<div class="mama">
<pre class="hCode" contenteditable="true"><p>凸面朝下的优弧</p>
<svg>
<path d="M104 80 A50 50 0 <span class="red">1</span> <span class="blue">0</span> 196 80" />
<span class="purple"><line x1="0" y1="80" x2="300" y2="80" class="blue" />
<circle cx="104" cy="80" r="2" class="green" />
<circle cx="196" cy="80" r="2" class="green" /></span>
</svg> </pre>
<pre class="hLineNum"></pre>
</div>
<p><button class="btnok" type="button" value="运行代码">运行代码</button></p>
<div class="stage"></div>
<p>参数4(优弧或劣弧)和参数5(弧线方向)的组合,可以产生四种形态的弧线:凸面朝上(或朝左)的劣弧(0 1)、凸面朝下(或朝右)的优弧(1 0),正如前面两个示例所展示的一样。还有,凸面朝下(或朝右)的劣弧(0 0):</p>
<div class="mama">
<pre class="hCode" contenteditable="true"><p>凸面朝下的劣弧</p>
<svg>
<path d="M104 80 A50 50 0 <span class="red">0</span> <span class="blue">0</span> 196 80" />
<span class="purple"><line x1="0" y1="80" x2="300" y2="80" class="blue" /></span>
</svg></pre>
<pre class="hLineNum"></pre>
</div>
<p><button class="btnok" type="button" value="运行代码">运行代码</button></p>
<div class="stage"></div>
<p>以及,凸面朝上的优弧(1 1):</p>
<div class="mama">
<pre class="hCode" contenteditable="true"><p>凸面朝上的优弧</p>
<svg>
<path d="M104 80 A50 50 0 <span class="red">1</span> <span class="blue">1</span> 196 80" />
<span class="purple"><line x1="0" y1="80" x2="300" y2="80" class="blue" />
<circle cx="104" cy="80" r="2" class="green" />
<circle cx="196" cy="80" r="2" class="green" /></span>
</svg> </pre>
<pre class="hLineNum"></pre>
</div>
<p><button class="btnok" type="button" value="运行代码">运行代码</button></p>
<div class="stage"></div>
<p>以上,① 我们的示例都是基于正圆的弧线,若需要绘制椭圆弧线,只需将 A 指令的第一和第二个参数即X、Y轴半径设置为不同数值即可;② A 指令使用了绝对定位,若需要使用相对定位,把大写 A 写成小写 a 且相关数值要做相应改变即可。</p>
</div>
<script>
let script = document.createElement('script');
script.src = 'https://unpkg.com/css-doodle@0.34.9/css-doodle.min.js';
document.head.appendChild(script);
let btns = document.querySelectorAll('.btnok'),
stages = document.querySelectorAll('.stage'),
hCodes = document.querySelectorAll('.hCode'),
hLineNums = document.querySelectorAll('.hLineNum'),
mamas = document.querySelectorAll('.mama');
btns.forEach((item,key) => {
let lines = hCodes.innerText.trim().split('\n').length;
let str = '';
for(i = 0; i < lines; i ++) {
str += i + 1 + '\n';
}
hLineNums.innerText = str;
mamas.style.cssText += `height: ${hCodes.offsetHeight + 10}px`;
item.onclick = () => {
let val = item.value;
stages.innerHTML = val === '运行代码' ? hCodes.innerText : '';
item.value = item.innerText = val === '运行代码' ? '关闭运行' : '运行代码';
}
});
</script>
南无月 发表于 2023-5-25 17:57
又没出来,不然你再发一次?
估计出不来 南无月 发表于 2023-5-24 22:06
小白踮脚尖够得着不
一点一点来,慢慢就会。我这个,应该是世界上最容易理解的 A 指令的教程了 提示:
一楼的所有示例代码,均支持在线编辑,可以尝试修改相关参数甚至加减代码然后再运行查看效果 优弧劣弧是两段完全不同的弧线呢。从起点到终点拉条线,若不是通过圆心,必然有优弧劣弧,而参数4如此简单就确定了取哪段,这个厉害了。{:4_187:} 感谢老师的代码分享,问好!{:4_190:} 这个讲解还有示例,非常清晰。黑黑辛苦了{:4_190:}
对A命令一直迷迷糊糊的,看到这个,感觉清楚了很多。 红影 发表于 2023-5-24 21:23
这个讲解还有示例,非常清晰。黑黑辛苦了
对A命令一直迷迷糊糊的,看到这个,感觉清楚了很多。
但是还是需要细细体会,才能了然于胸 马黑黑 发表于 2023-5-24 21:24
但是还是需要细细体会,才能了然于胸
没法细细体会了,今天又感冒了,吃了药特别困。准备早点下了。看看早睡明天会不会好点。
我下了,黑黑晚安{:4_204:} 俺来飘过{:4_173:} 难的说来就来了。。先签个到,大块时间再细看{:4_173:} 南无月 发表于 2023-5-24 21:54
难的说来就来了。。先签个到,大块时间再细看
这个是基于论坛之前的一些相关教程的,它特别难 红影 发表于 2023-5-24 21:28
没法细细体会了,今天又感冒了,吃了药特别困。准备早点下了。看看早睡明天会不会好点。
我下了,黑黑晚 ...
88 千羽 发表于 2023-5-24 21:34
俺来飘过
不留下6毛买路钱? 马黑黑 发表于 2023-5-24 22:02
这个是基于论坛之前的一些相关教程的,它特别难
{:4_170:}小白踮脚尖够得着不 马黑黑 发表于 2023-5-24 22:09
一点一点来,慢慢就会。我这个,应该是世界上最容易理解的 A 指令的教程了
黑黑的就是世界级的 南无月 发表于 2023-5-24 22:45
黑黑的就是世界级的
不过你可以去简单教程也瞧瞧一下,说不准它的表述比我的更好 马黑黑 发表于 2023-5-24 22:47
不过你可以去简单教程也瞧瞧一下,说不准它的表述比我的更好
不去 南无月 发表于 2023-5-24 22:58
不去
那个是大而全的 谢谢马黑黑老师教程!{:4_190:}我先收藏,我得慢慢学习,反复试用,才能学得一点!{:5_111:}