Как анимировать многоугольник SVG для заполнения?

У меня есть буква 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

Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
4
0
3 578
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Я решил это с помощью ключевых кадров 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-delay и animation-duration.

Вы действительно можете использовать ключевые кадры, там есть много вещей, которые можно сделать, кроме просто непрозрачности. Вы можете анимировать рисование контуров с помощью stroke-dashoffset и stroke-dasharray. Есть также способы сделать так, чтобы они постепенно исчезали с помощью translateX или translateY. Также анимация вращения. взгляните на CSS в ручке, которую я сделал: https://codepen.io/YilmazTut/pen/JzaQEy.

также есть серия по svg из трюков css: https://css-tricks.com/lodge/svg/ я использовал это, чтобы создать логотип в моей ручке. примерно в уроке 16 он объясняет, как работает анимация, а затем и отрисовка пути. Я надеюсь, что вы можете найти свой путь туда!

я также могу попытаться создать что-то для вашего svg, но мне нужно, чтобы вы были более конкретными в том, как именно это нужно анимировать.

Yilmaz 10.04.2019 13:55

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>

Анимация fill-opacity — лучший выбор.

enxaneta 10.04.2019 15:06

Эй, мужик! ваш ответ был почти идеальным для меня, но веб-тики опубликовали идеальный ответ. Но большое спасибо за ответ брат!

Muktadir Anzan 10.04.2019 21:21
Ответ принят как подходящий

Вы по-прежнему можете рисовать букву (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>

Чувствует руку мастера Жаль, что редко отвечаешь в последнее время

Alexandr_TT 10.04.2019 16:31

@Alexandr_TT, это очень хороший комментарий, спасибо :)

web-tiki 10.04.2019 16:41

Я изучал ваши старые работы. Мне они очень понравились, много переводили на русский язык. ТАК Конечно, я всегда указывал на источник.

Alexandr_TT 10.04.2019 16:47

работает просто отлично, как я просил! Большое тебе спасибо! очень признателен!

Muktadir Anzan 10.04.2019 21:20

Вот пример с чистым 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>

Бонусная версия. Здесь я превратил ваши пути в маску и добавил фоновую анимацию.

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

Другие вопросы по теме