svg动画 - 仪表盘

发布时间 2023-08-21 15:29:47作者: 1156740846

案例:

 

<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, …}