svg动画 - 仪表盘
案例:
<svg width="65" height="66" viewBox="0 0 65 66" fill="none" xmlns="http://www.w3.org/2000/svg"> <path opacity="0.102" fill-rule="evenodd" clip-rule="evenodd" d="M32.4409 0.808594C50.2637 0.808594 64.7115 15.2563 64.7115 33.0786C64.7115 50.9008 50.2637 65.3486 32.4409 65.3486C14.6186 65.3486 0.170898 50.9008 0.170898 33.0786C0.170898 15.2563 14.6186 0.808594 32.4409 0.808594Z" fill="#0094FF"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M27.4463 55.4393H37.7239C38.1166 55.4393 38.4348 55.7576 38.4348 56.1503C38.4348 56.5435 38.1166 56.8618 37.7239 56.8618H27.4463C27.0536 56.8618 26.7354 56.5435 26.7354 56.1503C26.7354 55.7576 27.0536 55.4393 27.4463 55.4393Z" fill="#0084FD"/> <circle class="small-circle-mid-bg" fill="none" cx="32.4410" cy="33.0789" r="24.5621" stroke="#297FFF" stroke-opacity="0.26" stroke-width="8" stroke-dasharray="119.2595 153.3337" transform="rotate(130 32.4410 33.0789)" /> <circle class="small-circle-mid" fill="none" cx="32.4410" cy="33.0789" r="24.5621" stroke="blue" stroke-width="8" stroke-dasharray="119.2595 153.3337" transform="rotate(130 32.4410 33.0789)" /> <path opacity="0.502" fill-rule="evenodd" clip-rule="evenodd" d="M32.2407 15.1298C42.0432 15.1298 49.9902 23.0762 49.9902 32.8787C49.9902 42.6818 42.0432 50.6282 32.2407 50.6282C22.4382 50.6282 14.4912 42.6818 14.4912 32.8787C14.4912 23.0762 22.4382 15.1298 32.2407 15.1298Z" stroke="#0066FE"/> </svg> <script type="text/javascript"> const midc = document.querySelector(".small-circle-mid"); const totalLen = midc.getTotalLength(); const maxLen = totalLen * 280 / 360; let rate = 0; let currLen = 0; document.onkeydown = function(event){ if (event.key == 'w') { rate = rate + 0.5; } else if (event.key == 's') { rate = rate - 0.5; } else { return; } (rate > 100) && (rate = 100); (rate < 0) && (rate = 0); currLen = rate * maxLen / 100; midc.setAttribute('stroke-dasharray', `${currLen} ${totalLen}`); } </script>
讲解:
js功能:按w增长,按s降低
stroke-dasharray:接收一个数组,【实心线长度 空白线长度 实心线长度 空白线长度 。。。】, 起始点是x轴的正轴方向
<svg width="65" height="66" viewBox="0 0 65 66" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle class="small-circle-mid-bg" fill="none" cx="32.4410" cy="33.0789" r="24.5621" stroke="#297FFF" stroke-opacity="0.26" stroke-width="8"></circle> <circle class="small-circle-mid" fill="none" cx="32.4410" cy="33.0789" r="24.5621" stroke="blue" stroke-width="8" stroke-dasharray="10 153.3337" transform="rotate(0 32.4410 33.0789)"></circle> </svg>
可以通过旋转角度改变起始点
<svg width="65" height="66" viewBox="0 0 65 66" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle class="small-circle-mid-bg" fill="none" cx="32.4410" cy="33.0789" r="24.5621" stroke="#297FFF" stroke-opacity="0.26" stroke-width="8"></circle> <circle class="small-circle-mid" fill="none" cx="32.4410" cy="33.0789" r="24.5621" stroke="blue" stroke-width="8" stroke-dasharray="10 153.3337" transform="rotate(30 32.4410 33.0789)"></circle> </svg>
也可以通过改变 stroke-dashoffset 改变起始点,设置的是起始点的偏移长度,如果要用角度换算长度,可以用 总【长度 * 角度 / 360】 来获取长度
153.3337 * 90 / 360 = 38.333425
<svg width="65" height="66" viewBox="0 0 65 66" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle class="small-circle-mid-bg" fill="none" cx="32.4410" cy="33.0789" r="24.5621" stroke="#297FFF" stroke-opacity="0.26" stroke-width="8"></circle> <circle class="small-circle-mid" fill="none" cx="32.4410" cy="33.0789" r="24.5621" stroke="blue" stroke-width="8" stroke-dasharray="10 153.3337" transform="rotate(0 32.4410 33.0789)" stroke-dashoffset="-38.33"></circle> </svg>
几个比较好用的svg原生函数:
midc <circle class="small-circle-mid" fill="none" cx="32.4410" cy="33.0789" r="24.5621" stroke="blue" stroke-width="8" stroke-dasharray="10 153.3337" transform="rotate(0 32.4410 33.0789)" stroke-dashoffset="-38.33"></circle> midc.getBBox(): 获取左上角定点的位置和宽高,中心位置可以计算的出来 cx = x + width / 2 , cy = y + height / 2 SVGRect {x: 7.878902435302734, y: 8.516799926757812, width: 49.12419891357422, height: 49.12419891357422} midc.getTotalLength(): 可以获取路径的总长度 153.333740234375 midc.getPointAtLength(38.333425):可以获取路径上指定位置的点的坐标 SVGPoint {x: 32.44101333618164, y: 57.64099884033203} midc.getBoundingClientRect():这个还不能确定有啥用,但是给的好像是在屏幕上的位置和宽高 DOMRect {x: 15.878902435302734, y: 16.516799926757812, width: 49.12419509887695, height: 49.12419891357422, top: 16.516799926757812, …}