【问题标题】:Filling water animation灌水动画
【发布时间】:2015-06-26 15:23:42
【问题描述】:

我正在尝试制作擦拭动画以使圆圈看起来像它充满了水。我遇到了两个错误,甚至无法解决第三个错误:

  1. 填错方式
  2. 填满后重置为空(黑色) *
  3. 目前,我正在使用<img> 标签,但我想将此效果移至body { background-image: },并且需要一些有关如何执行此操作的指导。

What I have tried so far:

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

按照@anpsmn 的建议为其设置默认蒙版位置,不再将其重置为黑色。

【问题讨论】:

  • 给一个默认的蒙版位置-webkit-mask-position: 300px 300px;,让它重置为蓝色。

标签: css svg css-animations css-shapes


【解决方案1】:

我认为这实现了你的第一个目标:

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

【讨论】:

    【解决方案2】:

    这可以通过单个 div 和 ::before pseudo element: 来实现

    • #banner 被赋予 border-radius: 50% 以创建一个圆圈,overflow: hidden 将其子对象夹在其中

    • ::before 伪元素动画到 100% 高度,并且使用 the forwards value 在 100% 处暂停动画。它从底部开始使用bottom: 0

    • 将应用背景图像代替#banner#banner::before 上的黑色和蓝色背景

    兼容性: IE10+ 和所有现代浏览器。 -webkit- 前缀属性很可能不再需要您的关键帧动画。 Check the browser compatibility chart over here on caniuse.com

    工作示例

    我添加了cubic-bezier(.2,.6,.8,.4) which is explained in @ChrisSpittles answer。它提供了一个整洁的效果!

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

    【讨论】:

      【解决方案3】:

      这里有四个不同的版本来补充@misterManSam's brilliant answer

      1。带缓动


      说明

      如果您将一个圆形碗装满液体,它在底部和顶部的填充速度会比在中间的填充速度更快(因为在较宽的中间部分有更多的区域可以覆盖)。所以,考虑到这个粗略的解释,动画需要:开始快,中间慢,然后当碗在顶部再次变窄时快速结束。

      为此,我们可以使用 CSS3 缓动函数:cubic-bezier(.2,.6,.8,.4)

      看看下面的例子。

      (如果你想在这里调整缓动是一个很好的资源:@​​987654322@)

      示例:

      #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。 SVG 美味

      让我们更进一步?如果我们想使用 CSS 在“水”上添加一个波浪形表面怎么办?我们可以使用令人惊叹的 SVG 来做到这一点。我在 Adob​​e Illustrator 中创建了一个波浪形 SVG 图像,然后使用单独的 CSS 动画在循环中从左到右移动,瞧:

      示例

      #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。带浇注线


      此示例包括浇注线(大多数碗从顶部填充,而不是底部填充)。浇筑线首先从上到下进行动画处理,而 animation-delay 属性阻止填充动画在浇筑完成之前发生。

      #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。带有严肃的金光闪闪(具有美丽的美学)


      此示例向 CSS 中添加了更多属性,使其看起来更逼真。

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

      【讨论】:

      • Svg 非常好! +1
      • 出色的工作,克里斯先生!谢谢你的分享!我真的很喜欢 svg 选项实现的简单性。我真的很想准确解释为什么path#waveShape 会达到蒙版效果:为什么?为什么? :)
      • @j4v1 #waveShape 通过将overflow: hidden 应用于外部容器#banner 来屏蔽。看看这个没有overflow: hidden 的 jsFiddle,希望它能让你更好地了解发生了什么:jsfiddle.net/kqbbhsyf
      • @ChrisSpittle 这太棒了。做得好!我一直在尝试对其进行调整并使其更大,但我遇到了调整大小的问题。有没有办法更进一步,并创建某种变量来控制碗/水的大小?如果是这样,您认为您可以发布另一个代码笔吗?
      • @JamesBarracca 这使用 SASS 设置大小:codepen.io/chrissp26/pen/KWvPjG?editors=0100 更改 $width 变量以满足您的需要。
      【解决方案4】:

      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}
      }
      &lt;div&gt;&lt;/div&gt;

      【讨论】:

        【解决方案5】:

        这里是 Water 在 Hover 上填充 div 的工作代码

        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

        【讨论】:

          【解决方案6】:

          纯 CSS,没有 JavaScript,没有 SVG。在.shape 中关闭overflow: hidden,看看它是多么简单。

          使用CSS animation 制作。你可以罚款 fill-upanimate @keyframes

          如果您希望使用 JavaScript 进行加载填充 - 您可以访问 .wave 元素。 top: 50%; 为 0%,top: -75% 为 100% 的加载。您可以随意使用这些数字。

          .shape {
            width: 180px;
            height: 180px;
            border-radius: 50%;
            overflow: hidden;
            position: relative;
          }
          
          .shape:after {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            border-radius: 50%;
            box-shadow: inset 0px 0px 30px 0px rgba(0, 0, 0, 0.3);
            overflow: hidden;
            z-index: 3;
          }
          
          .wave {
            position: absolute;
            top: 50%;
            left: 0;
            width: 200%;
            height: 200%;
            transform: translate(-25%, 0);
            background: #4973ff;
            animation: fill-up 10s ease infinite;
          }
          
          @keyframes fill-up {
            to {
              top: -75%;
            }
          }
          
          .wave:before,
          .wave:after {
            content: '';
            position: absolute;
            width: 110%;
            height: 100%;
            top: 0;
            left: 50%;
            transform: translate(-50%, -75%);
            background: #000;
          }
          
          .wave:before {
            border-radius: 45%;
            background: rgba(179, 241, 255, 1);
            animation: animate 3s linear infinite;
          }
          
          .wave:after {
            border-radius: 40%;
            background: rgba(179, 241, 255, 0.5);
            animation: animate 3s linear infinite;
          }
          
          @keyframes animate {
            0% {
              transform: translate(-50%, -75%) rotate(0deg);
            }
            100% {
              transform: translate(-50%, -75%) rotate(360deg);
            }
          }
          <div class="shape">
            <div class="wave">
            </div>
          </div>

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-20
            • 2023-03-04
            • 2014-06-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多