web-dev-qa-db-fra.com

Remplissage animation d'eau

J'essaie de créer une animation pour effacer un cercle de il se remplit d'eau. J'ai rencontré deux erreurs et je n'ai même pas réussi à m'attaquer à la troisième:

  1. Ça remplit le mauvais chemin
  2. Il se réinitialise pour vider (noir) une fois rempli *
  3. Pour le moment, j'utilise les balises <img>, mais j'aimerais déplacer cet effet vers body { background-image: } et j'ai besoin de quelques conseils sur la façon de procéder.

Ce que j'ai essayé jusqu'à présent:

#banner {
  width: 300px;
  height: 300px;
  position: relative;
}
#banner div {
  position: absolute;
}
#banner div:nth-child(2) {
  -webkit-animation: wipe 6s;
  -webkit-animation-delay: 0s;
  -webkit-animation-direction: up;
  -webkit-mask-size: 300px 3000px;
  -webkit-mask-position: 300px 300px;
  -webkit-mask-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.00, rgba(0, 0, 0, 1)), color-stop(0.25, rgba(0, 0, 0, 1)), color-stop(0.27, rgba(0, 0, 0, 0)), color-stop(0.80, rgba(0, 0, 0, 0)), color-stop(1.00, rgba(0, 0, 0, 0)));
}
@-webkit-keyframes wipe {
  0% {
    -webkit-mask-position: 0 0;
  }
  100% {
    -webkit-mask-position: 300px 300px;
  }
}
<div id="banner">
  <div>
    <img src="http://i.imgur.com/vklf6kK.png" />
  </div>
  <div>
    <img src="http://i.imgur.com/uszeRpk.png" />
  </div>
</div>


Le fait de lui donner une position de masque par défaut comme @anpsmn suggéré ne le réinitialise plus au noir.

58
Arian Faurtosh

Ceci peut être réalisé avec un seul div et un ::before pseudo élément:

  • #banner est donné border-radius: 50% pour créer un cercle et overflow: hidden pour couper ses enfants à l'intérieur

  • Le pseudo-élément ::before est animé à une hauteur de 100% et l'animation est suspendue à 100% à l'aide de la valeur forwards . Cela commence en bas avec l'utilisation de bottom: 0

  • Les images d’arrière-plan seraient appliquées à la place des arrière-plans noir et bleu sur #banner et #banner::before

Compatibilité: IE10 + et tous les navigateurs modernes. La propriété préfixée -webkit- n'est probablement plus nécessaire pour vos animations d'images clés. Consultez le tableau de compatibilité du navigateur ici sur caniuse.com

Exemple de travail

J'ai ajouté le cubic-bezier(.2,.6,.8,.4)qui est expliqué dans la réponse @ChrisSpittles . Il fournit un effet soigné!

#banner {
  width: 300px;
  height: 300px;
  position: relative;
  background: #000;
  border-radius: 50%;
  overflow: hidden;
}
#banner::before {
  content: '';
  position: absolute;
  background: #04ACFF;
  width: 100%;
  bottom: 0;
  animation: wipe 5s cubic-bezier(.2,.6,.8,.4) forwards;
}
@keyframes wipe {
  0% {
    height: 0;
  }
  100% {
    height: 100%;
  }
}
<div id="banner">

</div>

50
misterManSam

Voici quatre versions différentes pour compléter @ la réponse brillante de @ misterManSam .

1. avec assouplissement


Explication

Si vous remplissez un bol circulaire rempli de liquide, il se remplira plus rapidement en bas et en haut qu’au centre (car il ya plus de surface à couvrir dans la partie centrale plus large). Donc, avec cette explication rudimentaire en tête, l’animation doit: commencer vite, lentement au milieu, puis finir vite quand le bol se rétrécit de nouveau au sommet.

Pour ce faire, nous pouvons utiliser une fonction d’accélération CSS3: cubic-bezier(.2,.6,.8,.4).

Regardez l'exemple ci-dessous.

(Si vous voulez modifier l’assouplissement, voici une excellente ressource: http://cubic-bezier.com/#.2,.6,.8,.4

Exemple:

#banner {
  width: 150px;
  height: 150px;
  position: relative;
  background: #000;
  border-radius: 50%;
  overflow: hidden;
}
#banner::before {
  content: '';
  position: absolute;
  background: #04ACFF;
  width: 100%;
  bottom: 0;
  animation: wipe 5s cubic-bezier(.2,.6,.8,.4) forwards;
}
@keyframes wipe {
  0% {
    height: 0;
  }
  100% {
    height: 100%;
  }
}
<div id="banner">

</div>

2. Délices SVG

Allons un peu plus loin? Et si nous voulions ajouter une surface ondulée sur "l'eau" en utilisant CSS? Nous pouvons le faire en utilisant l'incroyable SVG. J'ai créé une image SVG ondulée dans Adobe Illustrator, puis je l'ai animée pour qu'elle parcourt la boucle de gauche à droite avec une animation CSS séparée et le tour est joué:

Exemple

#banner {
    border-radius: 50%;
    width: 150px;
    height: 150px;
    background: #000;
    overflow: hidden;
    backface-visibility: hidden;
    transform: translate3d(0, 0, 0);
}
#banner .fill {
    animation-name: fillAction;
    animation-iteration-count: 1;
    animation-timing-function: cubic-bezier(.2, .6, .8, .4);
    animation-duration: 4s;
    animation-fill-mode: forwards;
}
#banner #waveShape {
    animation-name: waveAction;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
    animation-duration: 0.5s;
    width:300px;
    height: 150px;
    fill: #04ACFF;
}
@keyframes fillAction {
    0% {
        transform: translate(0, 150px);
    }
    100% {
        transform: translate(0, -5px);
    }
}
@keyframes waveAction {
    0% {
        transform: translate(-150px, 0);
    }
    100% {
        transform: translate(0, 0);
    }
}
<div id="banner">
<div class="fill">
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="300px" height="300px" viewBox="0 0 300 300" enable-background="new 0 0 300 300" xml:space="preserve">
      <path fill="#04ACFF" id="waveShape" d="M300,300V2.5c0,0-0.6-0.1-1.1-0.1c0,0-25.5-2.3-40.5-2.4c-15,0-40.6,2.4-40.6,2.4
	c-12.3,1.1-30.3,1.8-31.9,1.9c-2-0.1-19.7-0.8-32-1.9c0,0-25.8-2.3-40.8-2.4c-15,0-40.8,2.4-40.8,2.4c-12.3,1.1-30.4,1.8-32,1.9
	c-2-0.1-20-0.8-32.2-1.9c0,0-3.1-0.3-8.1-0.7V300H300z"/>
    </svg>
</div>
</div>

3. Avec ligne de coulée


Cet exemple inclut une ligne de coulée (la plupart des bols se remplissent par le haut, pas par le bas). La ligne de paiement s'anime d'abord de haut en bas, tandis qu'une propriété animation-delay empêche l'animation de remplissage de se dérouler jusqu'à la fin de la distribution.

#banner {
  border-radius: 50%;
  width: 150px;
  height: 150px;
  background: #000;
  overflow: hidden;
  backface-visibility: hidden;
  transform: translate3d(0, 0, 0);
  position: relative;
}

#banner .fill {
  transform: translateY(150px);
  animation-name: fillAction;
  animation-iteration-count: 1;
  animation-timing-function: cubic-bezier(.2, .6, .8, .4);
  animation-duration: 4s;
  animation-fill-mode: forwards;
  animation-delay: 0.25s;
}

#banner .pour {
  width: 6px;
  position: absolute;
  left: 50%;
  margin-left: -3px;
  bottom: 0;
  top: 0;
  background: #009ae6;
  animation-name: pourAction;
  animation-timing-function: linear;
  animation-duration: 0.25s;
}

#banner #waveShape {
  animation-name: waveAction;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  animation-duration: 0.5s;
  width: 300px;
  height: 150px;
  fill: #04ACFF;
}

@keyframes pourAction {
  0% {
    transform: translateY(-100%);
  }
  100% {
    transform: translateY(0);
  }
}

@keyframes fillAction {
  0% {
    transform: translateY(150px);
  }
  100% {
    transform: translateY(-5px);
  }
}

@keyframes waveAction {
  0% {
    transform: translate(-150px, 0);
  }
  100% {
    transform: translate(0, 0);
  }
}
<div id="banner">
  <div class="pour"></div>
  <div class="fill">
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="300px" height="300px" viewBox="0 0 300 300" enable-background="new 0 0 300 300" xml:space="preserve">
      <path fill="#04ACFF" id="waveShape" d="M300,300V2.5c0,0-0.6-0.1-1.1-0.1c0,0-25.5-2.3-40.5-2.4c-15,0-40.6,2.4-40.6,2.4
c-12.3,1.1-30.3,1.8-31.9,1.9c-2-0.1-19.7-0.8-32-1.9c0,0-25.8-2.3-40.8-2.4c-15,0-40.8,2.4-40.8,2.4c-12.3,1.1-30.4,1.8-32,1.9
c-2-0.1-20-0.8-32.2-1.9c0,0-3.1-0.3-8.1-0.7V300H300z" />
    </svg>
  </div>
</div>

4. Avec sérieux sérieux (avec une belle esthétique)


Cet exemple ajoute quelques propriétés supplémentaires au CSS pour lui donner un aspect un peu plus réaliste.

.bowl {
  position: relative;
  border-radius: 50%;
  width: 150px;
  height: 150px;
  box-shadow: inset 0 -5px 0 0 rgba(0, 0, 0, 0.5), inset 0 -20px 5px 0 rgba(0, 0, 0, 0.2), inset -15px 0 5px 0 rgba(0, 0, 0, 0.1), inset 15px 0 5px 0 rgba(0, 0, 0, 0.1);
  background: -moz-radial-gradient(center, ellipse cover, transparent 0%, transparent 76%, rgba(0, 0, 0, 0.65) 100%);
  background: -webkit-radial-gradient(center, ellipse cover, transparent 0%, transparent 76%, rgba(0, 0, 0, 0.65) 100%);
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 76%, rgba(0, 0, 0, 0.65) 100%);
  margin: 20px;
}
.bowl:before {
  overflow: hidden;
  border-radius: 50%;
  content: "";
  box-shadow: inset 0 -5px 0 0 rgba(0, 0, 0, 0.5), inset 0 -20px 5px 0 rgba(0, 0, 0, 0.2), inset -15px 0 5px 0 rgba(0, 0, 0, 0.1), inset 15px 0 5px 0 rgba(0, 0, 0, 0.1);
  background: -moz-radial-gradient(center, ellipse cover, transparent 0%, transparent 60%, rgba(0, 0, 0, 0.65) 81%, black 100%);
  background: -webkit-radial-gradient(center, ellipse cover, transparent 0%, transparent 60%, rgba(0, 0, 0, 0.65) 81%, black 100%);
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 60%, rgba(0, 0, 0, 0.65) 81%, #000000 100%);
  position: absolute;
  width: 150px;
  height: 150px;
  z-index: 2;
}
.bowl:after {
  content: "";
  width: 60px;
  border-radius: 50%;
  height: 5px;
  background: #039be4;
  box-shadow: inset 0 0 10px 0 #000;
  position: absolute;
  left: 50%;
  margin-left: -30px;
  bottom: 0;
  z-index: 2;
}
.bowl .inner {
  border-radius: 50%;
  width: 150px;
  height: 150px;
  background: -moz-radial-gradient(center, ellipse cover, transparent 0%, transparent 76%, rgba(0, 0, 0, 0.65) 100%);
  background: -webkit-radial-gradient(center, ellipse cover, transparent 0%, transparent 76%, rgba(0, 0, 0, 0.65) 100%);
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 76%, rgba(0, 0, 0, 0.65) 100%);
  overflow: hidden;
  -webkit-backface-visibility: hidden;
  -webkit-transform: translate3d(0, 0, 0);
}
.bowl .inner:before {
  content: "";
  width: 20px;
  height: 20px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  position: absolute;
  right: 40%;
  top: 60%;
  z-index: 2;
}
.bowl .inner:after {
  content: "";
  width: 20px;
  height: 40px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  position: absolute;
  right: 30%;
  top: 15%;
  transform: rotate(-20deg);
  z-index: 2;
}
.bowl .fill {
  -webkit-animation-name: fillAction;
  -webkit-animation-iteration-count: 1;
  -webkit-animation-timing-function: cubic-bezier(0.2, 0.6, 0.8, 0.4);
  -webkit-animation-duration: 4s;
  -webkit-animation-fill-mode: forwards;
}
.bowl .waveShape {
  -webkit-animation-name: waveAction;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear;
  -webkit-animation-duration: 0.5s;
  width: 300px;
  height: 150px;
  fill: #039be4;
}

@-webkit-keyframes fillAction {
  0% {
    -webkit-transform: translate(0, 150px);
  }
  100% {
    -webkit-transform: translate(0, 10px);
  }
}
@-webkit-keyframes waveAction {
  0% {
    -webkit-transform: translate(-150px, 0);
  }
  100% {
    -webkit-transform: translate(0, 0);
  }
}
/* For aesthetics only ------------------------------------------*/
body {
  margin: 0;
  font-family: Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif;
}

h1 {
  font: 200 1.2em "Segoe UI Light", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif;
  font-weight: 200;
  color: #fff;
  background: #039be4;
  padding: 20px;
  margin: 0;
  border-bottom: 10px solid #ccc;
}
h1 strong {
  font-family: "Segoe UI Black";
  font-weight: normal;
}

.explanation {
  padding: 20px 40px;
  float: right;
  background: #e64a19;
  -webkit-box-shadow: inset 0 30px 3px 0 rgba(0, 0, 0, 0.5);
  box-shadow: inset 0 3px 5px 0 rgba(0, 0, 0, 0.2);
  border-bottom: 10px solid #ccc;
  max-width: 300px;
}
.explanation p {
  color: #fff;
  font-size: 0.8rem;
}
<div class="bowl">
  <div class="inner">
    <div class="fill">
      <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="300px" height="300px" viewBox="0 0 300 300" enable-background="new 0 0 300 300" xml:space="preserve">
        <path class="waveShape" d="M300,300V2.5c0,0-0.6-0.1-1.1-0.1c0,0-25.5-2.3-40.5-2.4c-15,0-40.6,2.4-40.6,2.4
	c-12.3,1.1-30.3,1.8-31.9,1.9c-2-0.1-19.7-0.8-32-1.9c0,0-25.8-2.3-40.8-2.4c-15,0-40.8,2.4-40.8,2.4c-12.3,1.1-30.4,1.8-32,1.9
	c-2-0.1-20-0.8-32.2-1.9c0,0-3.1-0.3-8.1-0.7V300H300z" />
      </svg>
    </div>
  </div>
</div>

97
Chris Spittles

Je pense que cela accomplit votre premier objectif:

#banner div:nth-child(2) {
  -webkit-animation: wipe 6s;
  -webkit-animation-delay: 0s;
  -webkit-animation-direction: up;
  -webkit-mask-size: 300px 3000px;
  -webkit-mask-position: 300px 300px;
  -webkit-mask-image: -webkit-gradient(linear, left bottom, left top,
    color-stop(0.00,  rgba(0,0,0,0)),
    color-stop(0.25,  rgba(0,0,0,0)),
    color-stop(0.27,  rgba(0,0,0,0)),
    color-stop(0.80,  rgba(0,0,0,1)),
    color-stop(1.00,  rgba(0,0,0,1)));
 }

 @-webkit-keyframes wipe {
     0% {
    -webkit-mask-position: 300px 300px;
  }
     100% {
    -webkit-mask-position: 0 0;
  }
}
6
jmargolisvt

div{
  width: 200px;
  height: 200px;
  background: #ccc;
  border-radius: 50%;
  overflow: hidden;
  position: relative;
  z-index: 9;
}
div:before{
  content: '';
  position: absolute; top: 100%; left: 0;
  width: 100%;
  height: 100%;
  background: #00BFFF;  
  -webkit-animation: animtop 5s forwards, animtop2 2s forwards;
  animation: animtop 5s forwards, animtop2 2s forwards;
}
@-webkit-keyframes animtop{  
  0%{top: 100%;}  
  75%{top: 0}
}
@keyframes animtop{  
  0%{top: 100%;}  
  100%{top: 25%}
}
@-webkit-keyframes animtop2{  
  75%{top: 25%;}  
  100%{top: 0}
}
@keyframes animtop2{  
  75%{top: 25%;}  
  100%{top: 0}
}
<div></div>

0
Dmitriy

Ici, le codpen de travail de l'eau remplissant une div sur Hover

HTML

<div class="dot">
</div>

CSS

.dot {
  border: 1px;  
  border-style: solid;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  border-color: black;
  color: black;
  padding: 5px;
  background-size: 200% 200%;
  background-image: 
  linear-gradient(to top, #76daff 50%, transparent 50%);
  transition: background-position 3000ms, color 3000ms ease, border-color 3000ms ease;
}

.dot:hover {
  color: white;
  border-color: black;
  background-image: 
    linear-gradient(to top, #76daff 51%, transparent 50%);
  background-position: 0 100%;
  transition: background-position 3000ms, color 3000ms ease, border-color 3000ms ease;
}

https://codepen.io/ajitkumar96/pen/pOYbQm?editors=1100

0
Ajit Kumar