如何设置SVG多边形的动画?

时间:2019-04-10 10:04:42

标签: html css animation svg css-animations

我有一个由两个多边形和一个矩形组成的SVG字母(A)。我想为它们设置动画,以使第一个多边形逐渐变得可见,然后第二个多边形。在那之后,矩形将变得可见。在动画开始之前,SVG将不可见。

我尝试了关键帧笔划,但是由于它们不是基于路径而是多边形点,所以它不起作用。

<svg height="600" width="800">
  <polygon  points="34 537,150 536,289 130,314 53,196 51"/>
    <animate attributeName="points" dur="5s" fill="freeze"  />
  
   <polygon  points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55"/>
   <rect x="120" y="320"  stroke-miterlimit="10" width="270" height="120"/>
 </svg>

如果您想使用它,这里是一支笔:https://codepen.io/anon/pen/vMxXaP

6 个答案:

答案 0 :(得分:6)

您仍然可以通过使用带有笔触的多边形而不是填充来绘制(A)字母。下面的示例在stroke-dasharray上使用两个关键帧动画,分两步绘制A字母:

  1. 左上角和右上角线的第一步(svg中的第一个多边形元素)
  2. 关闭A的水平线的第二步(svg元素中的第二个多边形)

.letter {
  width:200px;height:auto;
  stroke-width:2.5;
  stroke:#000;
  fill:none;
  stroke-dasharray: 0 24;
}
.animateFirst { animation: 0.5s animateFirst ease-in forwards; }
.animateSecond { animation: 0.2s 0.45s animateSecond ease-out forwards; }

@keyframes animateFirst {
  to { stroke-dasharray: 24 24; }
}
@keyframes animateSecond {
  to { stroke-dasharray: 6 24; }
}
<svg class="letter" viewbox="0 0 12 10">
  <polygon class="animateFirst" points="1,11.5 6,0 11,11.5" />
  <polygon class="animateSecond" points="3,6.5 9,6.5" />  
</svg>

答案 1 :(得分:4)

SVG解决方案

旋转和外观动画

.container {
 width:35%;
 height:35%;
 }
<div class="container">

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"  viewBox="0 0 600 800">
  <g fill="black" fill-opacity="0" >
    <polygon
	     id="left" transform="rotate(72 306 200)"  points="34 537,150 536,289 130,314 53,196 51"> 
         <animateTransform
		 attributeName="transform"
		 type="rotate"
		 values="72 306 200;0 306 200"
		 begin="svg1.click"
		 dur="0.5s"
		 fill="freeze" />  
	 <animate
	   id="an_op1"
	   attributeName="fill-opacity"
	   from="0"
	   to="1"
	   begin="svg1.click"
	   dur="0.5s"
	   fill="freeze" /> 
	</polygon>	 
    <polygon id="right"  transform="rotate(-69 457.5 200)" 
	       points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55">
	 <animateTransform
	     attributeName="transform"
		 type="rotate"
		 values="-69 457.5 200;0 457.5 200" 
		 begin="an_op1.end"
		 dur="0.5s"
		 fill="freeze" />  
	 <animate
	    id="an_op2"
		attributeName="fill-opacity"
		from="0"
		to="1"
		begin="an_op1.end"
		dur="0.5s"
		fill="freeze" />
	</polygon> 	 
        <rect id="rect1"  x="800" y="320"    width="270" height="120"> 
          <animate
			  attributeName="x"
			  from="800"
			  to="120"
			  begin="an_op2.end"
			  dur="0.5s"
			  fill="freeze" /> 
		    <animate
			  id="an_op3"
			  attributeName="fill-opacity"
			  from="0"
			  to="1"
			  begin="an_op2.end"
			  dur="0.5s"
			  fill="freeze" />
	    </rect> 	  	
   </g>  
      <text x="0" y="80" font-size="50" fill="purple">Click me</text>
</svg>
</div>

第二个解决方案

所有动画元素在一开始都是不可见的。 fill-opacity="0"

项目外观动画:

<animate
      id="an_left"
      attributeName="fill-opacity"
      begin="1s"
      from="0"
      to="1"
      dur="0.3s"
      fill="freeze"/>

下面是完整代码:

.container {
width:35%;
height:35%;
}
<div class="container">
<svg  version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"  viewBox="0 0 600 800">
  
    <polygon id="right" fill="#008080" fill-opacity="0" 
	   points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55">
	   <animate
	     id="an_right"
		 attributeName="fill-opacity"
		 begin="an_left.end"
		 from="0"
		 to="1"
		 dur="0.3s"
		 fill="freeze"/>
	</polygon>   

 <polygon  id="left" fill="#008080" fill-opacity="0" points="34 537,150 536,289 130,314 53,196 51">
	  <animate
	  id="an_left"
	  attributeName="fill-opacity"
	  begin="0.2s"
	  from="0"
	  to="1"
	  dur="0.3s"
	  fill="freeze"/>
	 </polygon> 

    <rect x="120" y="320" fill="#008080" fill-opacity="0" stroke-miterlimit="10" width="270" height="120"> 
	    <animate
		id="an_rect"
		attributeName="fill-opacity"
		from="0"
		to="1"
		begin="an_right.end"
		dur="0.3s"
		fill="freeze"/>
	</rect> 
</svg>
</div>

动画序列是通过属性-begin="an_left.end"

中的一系列条件来实现的

这样的记录意味着右矩形的动画仅在左多边形的动画结束之后才开始。

CSS解决方案

.container {
width:35%;
height:35%;
}
#left,#right,  #rect1 {
fill-opacity:0;
fill:#008080;

}
#left {
animation:anLeft  0.3s ease forwards;
animation-delay: 0.1s;
}

@keyframes anLeft {
  100% {
    fill-opacity:1;
	
  }
} 
#right {
animation:anRight  0.3s ease forwards;
animation-delay: 0.4s;
}

@keyframes anRight {
  100% {
    fill-opacity:1;
  }
}  

#rect1 {
animation:anRect  0.3s ease forwards;
animation-delay:0.7s;
}

@keyframes anRect {
  100% {
    fill-opacity:1;
  }
}
<div class="container">
<svg  version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"  viewBox="0 0 600 800">
  
    <polygon id="right"  
	   points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55"/>
 <polygon  id="left"  points="34 537,150 536,289 130,314 53,196 51"/>
    <rect id="rect1" x="120" y="320"  stroke-miterlimit="10" width="270" height="120"/> 
</svg>
</div>

答案 2 :(得分:2)

我使用CSS关键帧解决了这个问题,这是您要寻找的吗?

    @keyframes fade {
      from {
        opacity: 0;
      }
      to {
        opacity: 1;
      }
    }
    
    #right {
      animation-delay: 1s;
    }
    
    #center {
      animation-delay: 2s;
    }
    
    .shape {
      opacity: 0;
      animation-fill-mode: forwards;
      animation-iteration-count: 1;
      animation-name: fade;
      animation-duration: 1s;
    }
<svg id="abcdef" height="600" width="800">
      <polygon class="shape" points="34 537,150 536,289 130,314 53,196 51"/>
      <polygon id="right" class="shape" points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55"/>
      <rect id="center" class="shape"  x="120" y="320" filter="#008080" stroke-miterlimit="10" width="270" height="120"/>
    </svg>

如果要调整动画的持续时间,则必须查看更改animation-delayanimation-duration的值。

答案 3 :(得分:1)

这是一个使用纯JavaScript并通过增量时间更改不透明度的示例

let left = document.querySelector('#left')
let right = document.querySelector('#right')
let rect1 = document.querySelector('#rect1')
let time = 3000; // animation time
let delay = 1000; // animation delay

// dt - time from animation start
function animate(dt) { 
 let v = dt - delay;  
 opacity(left, v/time*3);     
 opacity(right, v/time*3 - 1);
 opacity(rect1, v/time*3 - 2);
 dt < time + delay + 50 && requestAnimationFrame(animate)
} 

function opacity(el, v) {
 v = Math.min(1, Math.max(v, 0)); // clamp to 0-1
 el.setAttribute('opacity', v)
}

requestAnimationFrame(animate);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg  version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" height="175" viewBox="0 0 600 800">
  <g fill="#008080">
    <polygon id="right" opacity="0" points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55"/>
    <polygon id="left" opacity="0" points="34 537,150 536,289 130,314 53,196 51"/>
    <rect id="rect1" opacity="0" x="120" y="320"  stroke-miterlimit="10" width="270" height="120"/> 
   </g> 
</svg>

答案 4 :(得分:1)

奖金版本。在这里,我将您的路径变成了蒙版并添加了背景动画。

enter image description here

<svg  version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 800">
   <style>  
    svg {
      height:160px;
      background: url(https://i.imgur.com/Pr8tfnT.png);
      background-position: 0px 111px;
      background-repeat: repeat-x;
      background-size: 100%;
      animation: water 10s forwards;
    }

    @keyframes water {
      100% {
        background-position: 2000px 0px;
      }
    }
   </style>   
   <mask id="mask" fill="black">
    <rect fill="white" width="600" height="800"/>
    <polygon id="right" points="411 537,528 537,364 118,354 91,348 72,341 53,327 53,223 55"/>
    <polygon id="left"  points="34 537,150 536,289 130,314 53,196 51"/>
    <rect id="rect1" x="120" y="320"  stroke-miterlimit="10" width="270" height="120"/> 
   </mask>

   <rect fill="white" width="600" height="800" mask="url(#mask)"/>
</svg>

答案 5 :(得分:0)

您确实可以使用关键帧,除了透明度之外,还有很多事情要做。您可以使用stroke-dashoffsetstroke-dasharray对绘制轮廓进行动画处理。还有一些方法可以让它们通过translateXtranslateY从let和right中淡出。还有旋转动画。 看看我制造的笔https://codepen.io/YilmazTut/pen/JzaQEy中的CSS。

还有来自CSS技巧的SVG系列:https://css-tricks.com/lodge/svg/ 我用它在笔上创建徽标。从教程16开始,他解释了动画以及以后的路径绘制的工作原理。希望您能找到自己的方式!