svg动画

作者: 易路先登 | 来源:发表于2021-09-02 16:09 被阅读0次

    1、translate

    正常矩形
            <svg width="500" height="200" viewBox="0 0 500 200">
                <rect x="0" y="0" width="100" height="50" fill="red"  />
            </svg>
    
    右移10px
            <svg width="500" height="200" viewBox="0 0 500 200">
                <rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,0)" />
            </svg>
    
    左右各移10px
            <svg width="500" height="200" viewBox="0 0 500 200">
                <rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,10)" />
            </svg>
    

    2、rotate

    旋转
            <svg width="500" height="200" viewBox="0 0 500 200">
                <rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,10) rotate(30)"  />
            </svg>
    

    3、skewX(30)倾斜

    沿X轴倾斜30度
    <svg width="500" height="200" viewBox="0 0 500 200">
                <rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,10) skewX(30)"  />
    </svg>
    

    4、skewY

    沿Y轴倾斜30度
            <svg width="500" height="200" viewBox="0 0 500 200">
                <rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,10) skewY(30)"  />
            </svg>
    

    5、scale放大缩小

    正常
    缩小为原来一半
            <svg width="500" height="200" viewBox="0 0 500 200">
                <rect x="0" y="0" width="100" height="50" fill="red" transform="translate(10,10) scale(.5)"  />
            </svg>
    

    6、matrix复杂变形

    正常形状
    复杂变形后
            <!-- 
                [2,-1,50] => 2*_x+(-1)*_y+50 = x
                [1,2,0] =>1*_x+2*_y+0=y
                顶点坐标
                [0,0] => [50,0]
                [100,0] => [250,100]
                [100,50] => [200,200]
                [0,50] => [0,100]
             -->
            <svg width="500" height="200" viewBox="0 0 500 200">
                <rect x="0" y="0" width="100" height="50" fill="red" transform="matrix(2 1 -1 2 50 0)"  />
            </svg>
    

    7、环形进度条

    stroke-dasharray的用法

    散状绘制
    <template>
        <div>
        <div class="container">
            <!-- 
                [2,-1,50] => 2*_x+(-1)*_y+50 = x
                [1,2,0] =>1*_x+2*_y+0=y
                顶点坐标
                [0,0] => [50,0]
                [100,0] => [250,100]
                [100,50] => [200,200]
                [0,50] => [0,100]
             -->
            <svg width="500" height="200" viewBox="0 0 500 200">
                <rect 
                class="rect"
                x="0" 
                y="0" 
                width="100" 
                height="50" 
                fill="none"
                stroke="blue"
                stroke-width="5" />
            </svg>
        </div>
        <div class="container">
            <svg 
           
            width="400" 
            height="400">
                <circle cx="200" cy="200" r="180" stroke-width="20" stroke="#d1d3d7" fill="none"></circle>
                <circle  
                class="circle" 
                cx="200" 
                cy="200" 
                r="180" 
                stroke-width="20" 
                stroke="#00a5e0" 
                fill="none"></circle>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
    }
    .rect{
        stroke-dasharray:10 20 30;
    }
    .circle{
        stroke-dasharray:10 1131;
    }
    </style> 
    

    环形动态进度条

    进度条.gif
    <template>
        <div>
        <div class="container">
            <svg width="500" height="200" viewBox="0 0 500 200">
                <rect 
                class="rect"
                x="0" 
                y="0" 
                width="100" 
                height="50" 
                fill="none"
                stroke="blue"
                stroke-width="5" />
            </svg>
        </div>
        <div class="container">
            <svg 
           
            width="400" 
            height="400">
                <circle cx="200" cy="200" r="180" stroke-width="20" stroke="#d1d3d7" fill="none"></circle>
                <circle  
                class="circle" 
                cx="200" 
                cy="200" 
                r="180" 
                stroke-width="20" 
                stroke="#00a5e0" 
                fill="none"></circle>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
    }
    .rect{
        stroke-dasharray:10 20 30;
    }
    .circle{
        animation:circle 5s linear infinite;
    }
    @keyframes circle{
        from {
            stroke-dasharray:0 1131;
        }
        to {
            stroke-dasharray: 1131 0;
        }
    }
    </style> 
    

    如果想让起点旋转到正上方,可任意取三点,根据计算公式解出一元三次方程,

                [2,-1,50] => 2*_x+(-1)*_y+50 = x
                [1,2,0] =>1*_x+2*_y+0=y
    

    得出

     transform="matrix(0 -1 1 0 0 400)"
    

    8、矩形动态进度条

    rect动态进度条.gif
    <template>
        <div>
        <div class="container">
            <svg width="500" height="200" viewBox="0 0 500 200">
                <rect 
                class="rect"
                x="0" 
                y="0" 
                width="100" 
                height="50" 
                fill="none"
                stroke="blue"
                stroke-width="5" />
            </svg>
        </div>
        <div class="container">
            <svg 
           
            width="400" 
            height="400"
            viewBox="0 0 400 400"
            >
                <circle cx="200" cy="200" r="180" stroke-width="20" stroke="#d1d3d7" fill="none"></circle>
                <circle  
                class="circle" 
                cx="200" 
                cy="200" 
                r="180" 
                stroke-width="20" 
                stroke="#00a5e0" 
                fill="none"
                transform="matrix(0 -1 1 0 0 400)"
                ></circle>
            </svg>
        </div>
        <div class="container">
            <svg 
           
            width="200" 
            height="200"
            viewBox="0 0 200 200"
            >
                <rect x="0" y="0" width="200" height="200" stroke-width="8" stroke="grey" fill="none"></rect>
                 <rect x="0" y="0" width="200" height="200" stroke-width="8" stroke="blue" fill="none" class="rect-process" transform="matrix(0,1,-1,0,200,0)"></rect>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
    }
    .rect{
        stroke-dasharray:10 20 30;
    }
    .circle{
        animation:circle 5s linear infinite;
    }
    @keyframes circle{
        from {
            stroke-dasharray:0 1131;
        }
        to {
            stroke-dasharray: 1131 0;
        }
    }
    .rect-process{
        animation:rect-process 5s linear infinite;
    }
    @keyframes rect-process{
        from {
            stroke-dasharray:0 800;
        }
        to {
            stroke-dasharray:800 0;
        }
    }
    </style> 
    

    9、描边动画

    (1)、矩形描边


    rect描边.gif
        <div class="container">
            <svg class="line-container" width="400" height="400" viewBox="0 0 400 400">
                <line class="line" x1="0" y1="50" x2="400" y2="50" fill="none" stroke-width="20" stroke="red"/>
            </svg>
        </div>
    .container{
        border:1px solid #000;
        width:400px;
    }
    .line {
        stroke-dasharray:400;
        stroke-dashoffset:400;
        transition:stroke-dashoffset .5s ease-out;
    }
    .line-container:hover .line{
        stroke-dashoffset:0;
    }
    

    (2)、心形描边

    心描边.gif
    获取path长度
    const path = documet.getElementById('logo')
    const pathLen = path.getTotalLength()
    
    心描边定长.gif
        <div class="container">
            <svg t="1630632068637"  viewBox="0 0 1024 1024"  p-id="1844" width="64" height="64">
                <path class="logo" d="M629.28 200.192a213.056 213.056 0 0 0-111.616 37.28l-5.696 4.032-5.696-4.032a212.704 212.704 0 0 0-120.32-37.472c-120.8 0-217.952 101.568-217.952 225.376 0 59.872 16.768 97.856 56.32 157.216 30.144 45.248 79.104 95.392 140.416 148.48l16.8 14.368 16.32 13.6 15.552 12.64 21.312 16.864 12.48 9.6 10.784 8.064a90.656 90.656 0 0 0 108.256-0.224l15.36-11.52 12.032-9.344 13.216-10.464 14.144-11.456 14.912-12.32 15.424-13.056 7.872-6.72c61.312-53.12 110.272-103.264 140.416-148.48 39.648-59.456 56.384-97.344 56.384-157.248-0.096-123.84-97.28-225.376-218.048-225.376l-8.64 0.192zM637.952 256c89.28 0 161.984 75.968 162.048 169.376 0 45.856-17.664 80.448-35.584 108.8l-7.68 11.744-3.712 5.632c-14.88 22.304-35.232 45.92-57.632 68.992l-12.384 12.48-12.672 12.352-6.4 6.08-12.832 11.904-19.168 17.152-12.48 10.88-18.08 15.36-27.2 22.24-21.824 17.216-19.552 14.88c-11.264 8.384-26.24 9.152-38.176 2.272l-4.128-2.752-18.912-14.4-21.824-17.216-21.44-17.44-11.68-9.76-18.368-15.744-19.008-16.864-12.864-11.744a1183.712 1183.712 0 0 1-6.4-6.016l-12.768-12.192-12.544-12.416c-22.72-22.944-43.744-46.624-59.584-69.152l-4.16-6.112a1241.6 1241.6 0 0 1-7.552-11.392l-7.68-12.16C239.264 500.864 224 467.968 224 425.376 224 331.936 296.64 256 385.984 256c49.6 0 95.648 23.776 125.984 62.976C542.304 279.776 588.384 256 637.952 256z" p-id="1845"></path>
            </svg>
        </div>
    .logo{
        fill:none;
        stroke:#333;
        stroke-width:10;
        animation:logos 5s linear forwards;
    }
    @keyframes logos{
        0% {
            stroke:#333;
            fill:white;
            stroke-dasharray:3812;
            stroke-dashoffset:3812;
        }
        50%{
            stroke:#333;
            fill:white;
            stroke-dasharray:3812;
            stroke-dashoffset:0;
        }
        75%{
            stroke:#aaa;
            fill:red;
        }
        100%{
            stroke:#aaa;
            fill:blue;
        }
    }
    

    10、SMIL动画

    全称:Synchronized Multimedia Integration Language。通过HTML标签实现动画效果,可以用于:

    • 实现过渡动画
    • 实现补间动画
    • 动画颜色变换
    • 路径运动动画
      包含以下标签:
    <set>
    <animate>
    <animateColor>
    <animateTransform>
    <animateMotion>
    

    (1)、set用法

    set用法.gif
    <template>
        <div>
        <div class="container">
            <svg width="200" height="200">
                <rect x="0" y="0" fill="red" width="100" height="50">
                    <set attributeName="x" attributeType="XML" to="10" begin="1s"></set>
                    <set attributeName="x" attributeType="XML" to="20" begin="2s"></set>
                    <set attributeName="fill" attributeType="XML" to="blue" begin="3s"></set>
                </rect>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    import { onMounted } from 'vue'
    onMounted(()=>{
        
    })
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
        width:200px;
    }
    </style> 
    

    (2)、animate的用法

    SMILanimate.gif
    <template>
        <div>
        <div class="container">
            <svg width="200" height="200">
                <circle cx="0" cy="0" r="30" fill="blue" stroke="black" stroke-width="2">
                    <animate attributeName="cx" attributeType="XML" from="0" to="100" dur="2s" repeatCount="indefinite"></animate>
                </circle>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    import { onMounted } from 'vue'
    onMounted(()=>{
        
    })
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
        width:200px;
    }
    </style> 
    

    attributeType的值有XMLcss,后者的话标识所操作属性从css中获取
    fill的值有freeze表示动画停留在截止时状态。remove动画结束时回归原位。

    动画可叠加

    SMILanimate叠加.gif
    <template>
        <div>
        <div class="container">
            <svg width="200" height="200">
                <circle cx="0" cy="0" r="30" fill="blue" stroke="black" stroke-width="2">
                    <animate attributeName="cx" attributeType="XML" from="0" to="100" dur="2s" repeatCount="1" fill="freeze"></animate>
                    <animate attributeName="cy" attributeType="XML" from="0" to="50" dur="2s" repeatCount="1" fill="freeze"></animate>
                </circle>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    import { onMounted } from 'vue'
    onMounted(()=>{
        
    })
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
        width:200px;
    }
    </style>
    

    匪夷所思的补间动画

    SMILanimate酷炫.gif
    <template>
        <div>
        <div class="container">
            <svg width="400" height="400">
               <polygon fill="#fcc" stroke="black">
                   <animate attributeName="points" attributeType="XML" from="30 30 70 30 90 70 10 70" to="50 30 70 50 50 90 30 50" dur="2s" repeatCount="1" fill="freeze"></animate>
               </polygon>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    import { onMounted } from 'vue'
    onMounted(()=>{
        
    })
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
        width:200px;
    }
    </style> 
    

    (3)、animationColor
    animationColor已经很少使用(废弃状态),可以使用animate替换

    <animate attributeName="fill" from="red" to="blue" dur="5s" repeatCount="indefinite"></animate>
    

    (4)、animateTransform

    SMILanimateMotion.gif
    <template>
        <div>
        <div class="container">
            <svg width="200" height="200">
                <circle cx="0" cy="0" r="30" fill="blue" stroke="black" stroke-width="2">
                    <animateTransform attributeName="transform" attributeType="XML" begin="0" dur="2s" type="scale" from="1" to="2" repeatCount="1" fill="freeze"></animateTransform>
                </circle>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    import { onMounted } from 'vue'
    onMounted(()=>{
        
    })
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
        width:200px;
    }
    </style> 
    

    (5)、animateMotion

    SMILanimateMotion1.gif
    <template>
        <div>
        <div class="container">
            <svg width="200" height="200">
               <rect x="0" y="0" fill="red" width="10" height="10">
                   <animateMotion
                    path="M10 10 L110 10 L110 110 L10 110 Z"
                    dur="5s"
                    rotate="auto"
                    fill="freeze"
                    repeatCount="1"
                    />
               </rect>
               <path d="M10 10 L110 10 L110 110 L10 110 Z" fill="none" stroke="green"></path>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    import { onMounted } from 'vue'
    onMounted(()=>{
        
    })
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
        width:200px;
    }
    </style> 
    

    rotate值改为0,在转弯处就不会抖动

    归程动画

    SMILanimateMotion2.gif
    <template>
        <div>
        <div class="container">
            <svg width="200" height="200">
               <rect x="00" y="0" fill="red" width="10" height="10">
                   <animateMotion
                    id="forward"
                    path="M10 10 L110 10 L110 110 L10 110"
                    dur="5s"
                    rotate="0"
                    fill="freeze"
                    begin="0"
                    />
                    <animateMotion
                    id="backward"
                    path="M10 110 L110 110 L110 10 L10 10"
                    dur="5s"
                    rotate="0"
                    fill="freeze"
                    begin="forward.end"
                    />
               </rect>
               <path d="M10 10 L110 10 L110 110 L10 110" fill="none" stroke="green"></path>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    import { onMounted } from 'vue'
    onMounted(()=>{
        
    })
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
        width:200px;
    }
    </style> 
    

    复合归程动画

    SMILanimateMotion3.gif
    <template>
        <div>
        <div class="container">
            <svg width="200" height="200">
               <rect x="00" y="0" fill="red" width="10" height="10">
                   <animateMotion
                    id="forward"
                    path="M10 10 L110 10 L110 110 L10 110"
                    dur="5s"
                    rotate="0"
                    fill="freeze"
                    begin="0;backward.end+0.5s"
                    />
                    <animateMotion
                    id="backward"
                    path="M10 110 L110 110 L110 10 L10 10"
                    dur="5s"
                    rotate="0"
                    fill="freeze"
                    begin="forward.end + 0.5s"
                    />
                    <animate
                    id="red-to-blue"
                    attributeName="fill"
                    attributeType="XML"
                    from="red"
                    to="blue"
                    dur="5s"
                    begin="0;backward.end+0.5s"
                    fill="freeze"
                     />
                    <animate
                    id="blue-to-red"
                    attributeName="fill"
                    attributeType="XML"
                    from="blue"
                    to="red"
                    dur="5s"
                    begin="red-to-blue.end+0.5s"
                    fill="freeze"
                     />
               </rect>
               <path d="M10 10 L110 10 L110 110 L10 110" fill="none" stroke="green"></path>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    import { onMounted } from 'vue'
    onMounted(()=>{
        
    })
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
        width:200px;
    }
    </style> 
    

    复杂动画

    SMILanimateMotion4.gif
    <template>
        <div>
        <div class="container">
            <svg width="200" height="200" viewBox="0 0 200 200">
               <g id="rect1">
                   <rect x="0" y="0" rx="0" ry="0" width="100" height="100" fill="red">
                       <animate
                        attributeType="XML"
                        attributeName="fill"
                        from="red"
                        to="green"
                        begin="rect1.click"
                        dur="2s"
                        fill="freeze"
                       ></animate>
                   </rect>
               </g>
               <animateTransform
                    attributeType="XML"
                    attributeName="transform"
                    type="translate"
                    from="0,0"
                    to="50,50"
                    begin="rect1.click"
                    dur="2s"
                    fill="freeze"
                />
               <rect x="0" y="100" width="100" height="100" fill="blue">
                   <animate
                    attributeType="XML"
                    attributeName="fill"
                    from="blue"
                    to="green"
                    fill="freeze"
                   ></animate>
               </rect>
            </svg>
        </div>
        </div>
    </template>
    <script setup>
    import { onMounted } from 'vue'
    onMounted(()=>{
        
    })
    </script>
    <style type="text/css" scoped>
    .container{
        border:1px solid #000;
        width:200px;
    }
    </style> 
    

    相关文章

      网友评论

          本文标题:svg动画

          本文链接:https://www.haomeiwen.com/subject/lwccwltx.html