svg动画 第二节

目录

动画类型

css类型

说明

html

css

效果

标签类型

说明

html

效果


入门了svg的基本知识后接下来进阶svg动画。

动画类型

svg的动画类型可以分类css和html标签两种方式来实现。

css类型

说明

svg动画
  svg为dom元素可以很好的和css结合
  css样式中的stroke-dasharray为svg专用的线段间隔
  这里有个需要注意的地方!!!封装svg的"总svg"标签被加上display: none样式后,通过id引用之后的css动画无效化


描边
  主要是css样式的stroke-dashoffset偏移和stroke-dasharray虚线间隔属性stroke-linecap较宽的线角上的形状
  document.getElementsById('svg').getTotalLength()可以获得对应svg 的绘制长度可以用css相关的长度中

html

useEffect(() => {
  setTimeout(() => {
    const SVGstrokeLength: any = document.getElementsByClassName('logo')[0]
    console.log(SVGstrokeLength.getTotalLength()) // 获取svg的path画图长度
  }, 1000)
}, [])

return (
  <svg
    width="200"
    height="200"
    viewBox="0 0 200 200"
    className='logoBox'
    preserveAspectRatio="xMidYMid meet">
    <g viewBox='0 0 100 100'>
        <circle 
          cx='50' 
          cy='50' 
          r='45' 
          strokeWidth='5' 
          stroke='#fff' 
          fill='transparent'></circle>
        <circle
          className="SVG_circle"
          cx='50'
          cy='50'
          r='45'
          strokeWidth='5'
          stroke='green'
          fill='transparent'></circle>
    </g>
    <g viewBox='0 0 100 100'> {/*描边*/}
        <line y1='45' x1='10' x2='90' y2='45' className='logo' stroke='red' strokeWidth='10'></line>
    </g>
  </svg>
)

css

@keyframes circle {
  from {
    stroke-dasharray: 0 283;/*svgz中的线段间隔*/
  }
  to {
    stroke-dasharray: 283 283;
  }
}
.SVG_circle{
  animation: circle 5s linear infinite;
}
.logo{
  stroke-dasharray: 90;
  stroke-dashoffset: 90;
  transition: stroke-dashoffset 0.5s ease-out;
}
.logoBox{
  &:hover{
    .logo{
      stroke-dashoffset: 0;
    }
  }
}

效果

标签类型

说明

tranform变换
    translate位移
    rotate旋转
    skewX和skewY倾斜
    scale缩放
    matrix复杂变形
SMIL:通过html标签实现svg动画主要是以下几种标签(无需js和css不支持ie)
  <set>
    设置属性的变化例如<set attributeName='x' attributeType='XML' to='20' begin='2s' />
    begin='2'为2秒后开始,attributeName='x'为改变x这个属性
    attributeType='XML'为可以对svg属性进行修改为'CSS'时可以对css修改
  <animate>
    同set一样属性变化但是具有动画效果例如<animate attributeName='cx' attributeType='XML' from='0' to='25' repeatCount='2' dur='2s' fill='remove'></animate>
    其中fill='remove'是动画结束回到原点fill='freeze'动画定个在最后一格
    dur='2s'为每次动画进行2秒
    repeatCount='2'为动画进行两次当等于indefinite为无限循环
  <animateColor>
    即<animate attributeName='fill'></animate>
  <animateTransform>
    对比animate多了type属性主要值为svg的transform变换类型
    type为rotate时from='0 100 100'表示从0开始以(100, 100)点为圆心旋转
    from和to传入多个值时可以用values='0 100 100;360 100 100'或values='red;blue;red'
  <animateMotion>
    可以让图形沿着path轨迹运动
    rotate='auto'代表在路径上运动过程中的转弯策略roeetate='0'在拐弯的时候就不会发生抖动
    path属性代表沿着这条路径运动
  begin属性
    可以通过animateMotion上的id来获取animateMotion动画的结束时间如begin='forword.end + 0.5s'
    begin='0; backword.end + 0.5s'表示下一次循环在上一次循环之后继续进行造成无限循环
    begin='forword.click'表示可以通过id为forword的svg标签点击之后执行

html

<svg
    width="200"
    height="200"
    viewBox="0 0 200 200"
    className='logoBox'
    preserveAspectRatio="xMidYMid meet">
    <def>
        <linearGradient id='linearGradient'>
            <stop offset='0' stopColor='red'></stop>
            <stop offset='50%' stopColor='green' stopOpacity='0.5'></stop>
            <stop offset='100%' stopColor='blue'></stop>
        </linearGradient>
        <radialGradient r='50%' cx='50%' cy='50%' fx='50%' fy='50%' id='radialGradient'>
            <stop offset='0' stopColor='red'></stop>
            <stop offset='50%' stopColor='green' stopOpacity='0.5'></stop>
            <stop offset='100%' stopColor='blue'></stop>
        </radialGradient>
        <symbol id='linearGradientBox' viewBox='0 0 100 100'>
            <rect x='0' y='0' height='100' width='100' fill='url(#radialGradient)'></rect>
        </symbol>
        <symbol id='loading' viewBox='0 0 200 200' fill='none'>
            <circle cx='100' cy='100' stroke='red' strokeWidth='10' r='90' strokeDasharray='142' strokeLinecap='round'>
              <animateTransform attributeName='transform' type='rotate' from='0 100 100' to='360 100 100' dur='3s' repeatCount='indefinite'></animateTransform>
              <animate attributeName='stroke' values='red;blue;red' dur='6s' repeatCount='indefinite'></animate>
            </circle>
            <circle cx='100' cy='100' stroke='blue' strokeWidth='10' r='60' strokeDasharray='94' strokeLinecap='round'>
              <animateTransform attributeName='transform' type='rotate' values='360 100 100;0 100 100' dur='3s' repeatCount='indefinite'></animateTransform>
              <animate attributeName='stroke' values='blue;red;blue' dur='6s' repeatCount='indefinite'></animate>
            </circle>
        </symbol>
    </def>
    <svg viewBox='-50 0 100 100'>
        <rect x='0' y='0' height='50' width='50' fill='red'>
            <set attributeName='x' attributeType='XML' to='20' begin='1s' />
            <set attributeName='x' attributeType='XML' to='20' begin='2s' />
            <set attributeName='fill' attributeType='XML' to='blue' begin='3s' />
        </rect>
    </svg>
    <svg viewBox='-50 -50 100 100'>
        <circle cx='0' cy='0' r='24' stroke='red' strokeWidth='1' fill='blue'>
            <animate attributeName='cx' attributeType='XML' from='0' to='25' repeatCount='2' dur='2s' fill='freeze'></animate>
            <animate attributeName='cy' attributeType='XML' from='0' to='25' repeatCount='1' dur='2s' fill='freeze'></animate>
            <animateTransform attributeName='transform' attributeType='XML' begin='0' from='1' to='2' dur='3s' type='scale' repeatCount='2'></animateTransform>
        </circle>
    </svg>
    <svg viewBox='0 -50 100 100'>
        <rect x='0' y='0' height='10' width='10' fill='red'>
            <animateMotion id='forword' begin='0' dur='5s' rotate='0' fill='freeze' path='M10 10 L10 30 L30 30 L30 10 Z'></animateMotion>
            <animateMotion id='back' begin='forword.end + 0.5s' dur='5s' rotate='0' fill='freeze' path='M30 10 L30 30 L10 30 L10 10 Z'></animateMotion>
        </rect>
          {/* 下面的path标签可以不用 */}
        <path d='M10 10 L10 30 L30 30 L30 10 Z' fill='none' stroke='green'></path>
    </svg>
</svg>


<span style={{color: 'green', display: 'block'}}>
    <Icon style={{width: 100, height: 100}} svgId='loading' />
    <Icon style={{width: 100, height: 100}} svgId='linearGradientBox' />
</span>

效果

总结

无论是css还是标签都可以实现svg动画各有独特的使用场景。标签动画更适用于实现复杂的动画,对于相对简单的动画则可以使用css动画来实现。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值