Анимация появления текстового символа

261
21 января 2020, 11:50

У меня есть svg изображение буквы А которая составлена из трех элементов: двух параллелограммов и прямоугольника - перекладины.

Необходимо сделать последовательную анимацию появления сначала левой наклонной части буквы, затем правой части и в конце анимации появление перекладины.

<svg  version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" height="600" width="800" viewBox="0 0 600 800"> 
  <g fill="#008080"> 
    <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"/>  
   </g>  
</svg>

Answer 1

Вот вариант, где opacity считается по дельта времени между кадрами.

let left = document.querySelector('#left') 
let right = document.querySelector('#right') 
let rect1 = document.querySelector('#rect1') 
let time = 3000; // время анимации  
let delay = 1000; // задержка перед анимацией 
 
// dt - кол-во миллисекунд с начала анимации 
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)); // приводим к диапазону 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>

Answer 2

Вот такой вот эффект c background-image и keyframes.

Для этого группа фигур из оригинала была переделана в маску для прямоугольника.

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

В ходе выполнения было замечено что у оригинала svg viewbox и width, height перепутаны...

Answer 3

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

Источник ответа:@web-tiki

Answer 4

SVG решение

Все элементы анимации в начале невидимы fill-opacity="0"

Анимация появления одного элемента:

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

Последовательность выполнения анимаций достигается цепочкой условиё в атрибуте begin="an_left.end"

Такая запись означает что анимация правого прямоугольника начнется только после окончания анимации левого многоугольника

Ниже полный код:

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

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>

Второй вариант

.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="#008080" 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>

Источник ответа:@Alexandr_TT

READ ALSO
Yii2 темизация. Как подставить только CSS?

Yii2 темизация. Как подставить только CSS?

Всем приветЕсть уже готовый проект

133
Сгруппировать элементы массива

Сгруппировать элементы массива

Имеется массив объектов

196
Создать конструктор объектов

Создать конструктор объектов

Снова прошу помощи у сообщества/*2

149
Telegram бот Последовательный ввод данных NodeJS telegraph

Telegram бот Последовательный ввод данных NodeJS telegraph

Пишу бота на NodeJS, используя telegraph и вот уже в который раз сталкиваюсь с одной и той же проблемойКак ввести последовательно данные и сделать...

290