stroke-dasharray的应用实战

1,063 阅读3分钟

上一节我们讲了svg的基本图形和路径,这一节我们来看看这些基本图形主要是路径描边的一些应用,主要讲一些css不太好处理的效果。

文字描边特效

这种事比较常用的,原理是改变stroke-dashoffset的值,让描边沿文字路径移动。效果如下:

testblock.gif.gif svg代码:

<svg width="1000" height="200" xmlns="https://www.w3.org/2000/svg"> <text text-anchor="middle" x="50%" y="50%" class="text" style="font-size:80px;stroke:aqua;stroke-width: 5px;stroke-dasharray: 70 150;"> dota 2 <animate attributeName="stroke-dashoffset" from="140" to="360" begin="0s" dur="3s" repeatCount="indefinite"/> </text> <text text-anchor="middle" x="50%" y="50%" class="text" style="font-size:80px;stroke:brown;stroke-width: 5px;stroke-dasharray: 70 150;"> dota 2 <animate attributeName="stroke-dashoffset" from="70" to="290" begin="0s" dur="3s" repeatCount="indefinite"/> </text> <text text-anchor="middle" x="50%" y="50%" class="text" style="font-size:80px;stroke:cornflowerblue;stroke-width: 5px;stroke-dasharray: 70 150;"> dota 2 <animate attributeName="stroke-dashoffset" from="0" to="220" begin="0s" dur="3s" repeatCount="indefinite"/> </text> </svg>
需要注意的地方:
1,多种颜色的描边需要将多个相同的文字叠加在一起。
2,需要根据字体大小手动调配stroke-dasharray的值,在动画开始的状态和结束状态,效果是相同的,这样动画比较流畅。
3,如果是三种颜色的线,那么stroke-dashoffset是递增的。并且递增的数值正好是stroke-dasharray的第一个值。

炫酷的边框效果

边框效果也是比较常见的,一般要和css结合使用,如果有点击事件的话,还需要利用到dom元素的事件冒泡。原理是利用css的transition属性,修改stroke-dasharray和stroke-dashoffset,效果如下:

dota2.gif.gif

     #dash{
        stroke-width: 8px;
        fill: none;
        stroke: rgb(248, 68, 68);
        stroke-dasharray: 100 400; /*表示虚线长度和每段虚线之间的间距*/
        stroke-dashoffset: 200; 
        transition:  all 500ms cubic-bezier(0.5,0,.1,1);
    }
    .svg-box{
        width: 200px;
        height:50px;
        position: relative;
        background-color: #03035e;
    }

   
    .svg-box .svg-text{
        position: absolute;
        width:100%;
        height: 50px;
        top:0;
        left:0;
        text-align: center;
        line-height: 50px;
        color:#d7daf1;
        z-index: 1;
        font-size: 26px;
    }
    .svg-box .svg-stoke{
        cursor: pointer;
        position: absolute;
        z-index: 2;
    }
    .svg-box:hover #dash{
        stroke-dasharray: 80 0;
        stroke-dashoffset: 0;
        stroke:cornflowerblue;
    }
    
    <div class="svg-box" onclick="downLoadPic()">
        <svg width="200" class="svg-stoke" height="50" xmlns="https://www.w3.org/2000/svg">
            <rect id="dash" height="50" width="200"/>
        </svg>
        <div class="svg-text">卸载dota 2</div>
    </div>

图片橡皮擦

这是一个图像的入场动画,像是图片上有灰尘,擦去灰尘把图片显示出来的效果:

pic1.gif.gif 这里用到了svg的混合模式mix-blend-mode,我们会在接下来的系列文章李介绍。源码如下:

    @-webkit-keyframes scribble {
        to {
            stroke-dashoffset: 0;
        }
    }
    @keyframes scribble {
        to {
            stroke-dashoffset: 0;
        }
    }
    body {
        background: #000;
    }
    div#stripped {
        max-width: 750px;
        margin: 0 auto;
        background: #000;
        background-image: url(./img/olga.jpg);
        background-size: cover;
        font-size: 0;
    }
    div#stripped svg {
        background: #000;
        mix-blend-mode: darken;
    }
    div#stripped svg polyline {
        fill: none;
        stroke: #f00;
        stroke-width: 200;
        stroke-dasharray: 50000;
        stroke-dashoffset: 50000;
        -webkit-animation: scribble 3s linear forwards;
        animation: scribble 3s linear forwards;
    }
    @media (-webkit-min-device-pixel-ratio: 2),
    (min-resolution: 192dpi) {
        div#stripped {
            background-image: url(./img/olga.jpg);
        }
    }
    
        <div id="stripped">
    <svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 1500 1062">
        <polyline points="0,154 131,0 0,348 269,0 0,562 437,0 
    0,766 565,14 0,1062 719,0 289,1062 843,0 543,1062 995,0 729,1062 1161,0 947,1062 1307,0 1143,1062 1500,162 1299,1062 1500,830" />
    </svg>
</div>

他就是利用svg的混合模式将svg后面的图片显示出来。看起来还是比较炫酷的。

特殊字体描边

特殊字体不是我们的常用字体,例如一些艺术字,怎么做这些字体的描边动画呢?关键是要得到这些特殊字体的path路径,假如美工设计的特殊字体,让美工导出svg格式的文件,得到path路径后再做简单的描边动画,不过这里有需要注意的地方每个path标签里面不能有多个M命令,否则会造成动画多段开始,有兴趣的同学可以尝试一下。下面我我做的动画效果:

pic22.gif
代码:

    <svg width="608.638550" height="292.583862" viewBox="0 0 608.639 292.584" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M8 27.5839C71.2 27.5839 86.3333 120.917 86 167.584C86 259.984 34 283.084 8 283.084V19.5" stroke="brown" stroke-dasharray="595"  stroke-width="17">
            <animate id="c1" attributeName="stroke-dashoffset" from="595" to="0" begin="0s" dur="1.5s" fill="freeze"/>
        </path>
        <path d="M263.96 143.584C263.627 182.917 248.36 261.584 189.96 261.584C131.56 261.584 122.626 182.917 125.46 143.584C126.96 111.917 141.96 48.5839 189.96 48.5839C249.16 48.5839 263.96 111.917 263.96 143.584Z" 
        stroke-dasharray="566" stroke="aqua" stroke-width="16.000000" stroke-dashoffset="566">
            <animate id="c2" attributeName="stroke-dashoffset" from="566" to="0" begin="c1.end" dur="1.5s" fill="freeze"/>
        </path>
        <line x1="271.500000" y1="39.083862" x2="422.500000" y2="18.083862" stroke="cornflowerblue" stroke-dasharray="155" stroke-dashoffset="155" stroke-width="16.000000">
            <animate id="c3" attributeName="stroke-dashoffset" from="155" to="0" begin="c2.end" dur="0.6s" fill="freeze"/>
        </line>
        <line x1="342.000000" y1="27.583862" x2="345.000000" y2="250.583862" stroke="cornflowerblue" stroke-dasharray="223" stroke-dashoffset="223" stroke-width="16.000000">
            <animate id="c4" attributeName="stroke-dashoffset" from="223" to="0" begin="c3.end" dur="0.9s" fill="freeze"/>
        </line>
        <path d="M460 267.084L524 26.5839L601.5 267.084" stroke="brown" stroke-width="15.000000" stroke-dasharray="503" stroke-dashoffset="503">
            <animate id="c5" attributeName="stroke-dashoffset" from="503" to="0" begin="c4.end" dur="1s" fill="freeze"/>
        </path>
        <line x1="494.500000" y1="144.083862" x2="598.500000" y2="144.083862" stroke="brown" stroke-width="7.000000" stroke-dasharray="105" stroke-dashoffset="105">
            <animate id="c6" attributeName="stroke-dashoffset" from="105" to="0" begin="c5.end" dur="0.4s" fill="freeze"/>
        </line>
        <path d="M589.5 129.584L602.5 144.584L589.5 158.084" stroke="brown" stroke-width="7.000000" stroke-dasharray="43" stroke-dashoffset="43">
            <animate id="c7" attributeName="stroke-dashoffset" from="43" to="0" begin="c6.end" dur="0.1s" fill="freeze"/>
        </path>
    </svg>

这里要找到路径长度可以用到一点js,代码如下:

    let paths = document.querySelectorAll('#youPath path');
    for(let i=0;i<paths.length;i++){
        console.log(paths[i].getTotalLength());
    }
    

控制台输出的值向上取整作为stroke-dasharray的值就行了。

结束语

这里面的例子只是抛砖引玉,当然还有其它用法,希望能评论区留言。