简体   繁体   English

如何动画SVG多边形来填充?

[英]How to animate a SVG polygon to fill?

I have a SVG letter (A) that consists of two polygon and a rectangle. 我有一个SVG字母(A),由两个多边形和一个矩形组成。 I want to animate them in a way that the first polygon grows to visible and then the second one . 我希望以第一个多边形增长到可见,然后是第二个多边形的方式为它们设置动画。 After that, the rectangle will grow to be visible. 之后,矩形将变得可见。 Before the start of the animation, the SVG will not be visible. 在动画开始之前,SVG将不可见。

I have tried keyframe strokes but as they are not path based but points of polygon, it didn't work. 我尝试过关键帧笔划,但因为它们不是基于路径而是多边形的点,所以它不起作用。

 <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> 

Here is a pen if you want to work on it : https://codepen.io/anon/pen/vMxXaP 如果你想使用它,这是一支笔: https//codepen.io/anon/pen/vMxXaP

You can still draw the (A) letter by using polygons with stroke instead of fill. 您仍然可以使用具有笔划而不是填充的多边形来绘制(A)字母。 The following example uses two keyframe animations on stroke-dasharray to draw the A letter in two steps : 以下示例在stroke-dasharray上使用两个关键帧动画,分两步绘制A字母:

  1. First step for the top left and top right line (first polygon element in the svg) 左上角和右上角的第一步(svg中的第一个多边形元素)
  2. Second step for the horizontal line closing the A (second polygon in the svg element) 关闭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> 

SVG solution SVG解决方案

Rotation and appearance animation 旋转和外观动画

 .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> 

Second solution 二解决方案

All animation elements are invisible at the beginning. 所有动画元素在开头都是不可见的。 fill-opacity="0"

Item appearance Animation: 项目外观动画:

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

Below is the full code: 以下是完整代码:

 .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> 

The sequence of animations is achieved by a chain of conditions in the attribute - begin="an_left.end" 动画序列是通过属性中的一系列条件实现的 - begin="an_left.end"

Such a record means that the animation of the right rectangle will begin only after the end of the animation of the left polygon. 这样的记录意味着右方框的动画将仅在左多边形的动画结束之后开始。

CSS solution 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> 

I solved this using CSS keyframes, is this what you're looking for? 我用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> 

If you want to tweak the duration of the animation you have to look at changing the values of animation-delay and animation-duration . 如果要调整动画的持续时间,则必须考虑更改animation-delayanimation-duration

Here an example with pure javascript and changing opacity by delta time 这里有一个纯javascript示例和delta时间改变不透明度

 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> 

Bonus version. 奖金版。 Here i turned your paths into mask and added background animation. 在这里,我将您的路径转换为蒙版并添加了背景动画。

在此输入图像描述

 <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> 

You can indeed use keyframes, in there there a lot of things to do besides just the opacity. 你确实可以使用关键帧,除了不透明度之外,还有很多事情要做。 You can animate drawing the outlines with stroke-dashoffset and stroke-dasharray . 您可以使用stroke-dashoffsetstroke-dasharray为轮廓绘制动画。 There are also ways to let them fade in from let and right with translateX or translateY . 还有一些方法可以让他们使用translateXtranslateY从let和right淡入。 Also rotation animations. 还有旋转动画。 take a look at the css in the pen i made: https://codepen.io/YilmazTut/pen/JzaQEy . 看看我制作的笔中的CSS: https//codepen.io/YilmazTut/pen/JzaQEy

there also is a series on svg's from css tricks: https://css-tricks.com/lodge/svg/ i used that to create the logo in my pen. 还有一系列svg来自css技巧: https//css-tricks.com/lodge/svg/我用它在我的笔中创建徽标。 from about tutorial 16 he explains how animations and later on also pathdrawing works. 从大约16教程,他解释了动画如何以及后来的绘图工作。 I hope you can find your way there! 我希望你能找到自己的方式!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM