3
votes

Comment animer un polygone SVG à remplir?

J'ai une lettre SVG (A) qui se compose de deux polygones et d'un rectangle. Je souhaite les animer de manière à ce que le premier polygone devienne visible, puis le second . Après cela, le rectangle s'agrandira pour être visible. Avant le début de l'animation, le SVG ne sera pas visible.

J'ai essayé les tracés d'images clés, mais comme ils ne sont pas basés sur un chemin mais sur des points de polygone, cela n'a pas fonctionné.

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

Voici un stylo si vous voulez travailler dessus: https: // codepen .io / anon / pen / vMxXaP


0 commentaires

6 Réponses :


2
votes

J'ai résolu ce problème en utilisant des images clés CSS, est-ce ce que vous cherchez?

<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>
    @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;
    }

Si vous souhaitez modifier la durée de l'animation, vous devez envisager de modifier les valeurs de animation-delay et animation-duration . p>


0 commentaires

0
votes

Vous pouvez en effet utiliser des images clés, là-dedans il y a beaucoup de choses à faire en plus de l'opacité. Vous pouvez animer le dessin des contours avec stroke-dashoffset et stroke-dasharray . Il existe également des moyens de les laisser disparaître de let et de droite avec translateX ou translateY . Aussi des animations de rotation. jetez un œil au css dans le stylo que j'ai créé: https://codepen.io/YilmazTut/pen/ JzaQEy .

il existe également une série sur les svg des astuces css: https://css-tricks.com / lodge / svg / je l'ai utilisé pour créer le logo dans mon stylo. à partir du didacticiel 16, il explique comment les animations et plus tard aussi le tracé de chemin fonctionnent. J'espère que vous pourrez y trouver votre chemin!


1 commentaires

Je peux aussi essayer de créer quelque chose pour votre svg, mais j'aurai besoin que vous soyez un peu plus précis dans la façon dont il doit être animé.



4
votes

Solution SVG

Animation de rotation et d'apparence

<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%;
}
#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;
  }
}

Deuxième solution

Tous les éléments d'animation sont invisibles au début. fill-opacity = "0"

Animation d'apparence de l'objet:

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

Voici le code complet:

.container {
width:35%;
height:35%;
}
<animate
      id="an_left"
      attributeName="fill-opacity"
      begin="1s"
      from="0"
      to="1"
      dur="0.3s"
      fill="freeze"/>

La séquence d'animations est réalisée par une chaîne de conditions dans l'attribut - begin = "an_left.end"

Un tel enregistrement signifie que l'animation du rectangle de droite ne commencera qu'après la fin de l'animation du polygone de gauche.

Solution CSS

<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>
.container {
 width:35%;
 height:35%;
 }

2 commentaires

L'animation de fill-opacity est le meilleur choix.


Hé mec! votre réponse était presque parfaite pour moi mais web-tiki a posté la parfaite. Mais merci beaucoup pour la réponse frère!



6
votes

Vous pouvez toujours dessiner la lettre (A) en utilisant des polygones avec un contour au lieu d'un remplissage. L'exemple suivant utilise deux animations d'images clés sur stroke-dasharray pour dessiner la lettre A en deux étapes:

  1. Première étape pour les lignes en haut à gauche et en haut à droite (premier élément de polygone dans le svg)
  2. Deuxième étape pour la ligne horizontale fermant le A (deuxième polygone dans l'élément svg)

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


4 commentaires

Sent la main du maître C'est dommage que vous ayez rarement répondu ces derniers temps


@Alexandr_TT et bien c'est un très beau commentaire, merci :)


J'ai étudié vos anciennes œuvres. Je les ai beaucoup aimés, beaucoup traduits en russe. SO Bien sûr, j'ai toujours indiqué la source.


fonctionne parfaitement comme je l'ai demandé! Merci beaucoup mec! très appréciée!



1
votes

Voici un exemple avec javascript pur et changement d'opacité par delta time

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


0 commentaires

2
votes

Version bonus. Ici, j'ai transformé vos chemins en masque et ajouté une animation d'arrière-plan.

 entrez la description de l'image ici

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


0 commentaires