最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - SVG water fill animation - Stack Overflow

programmeradmin1浏览0评论

I am to get a wipe animation to look like water is filling up inside of a drop. It currently is a square with a wave animation over top of the drop logo. It does the wave animation correctly but I can't get it to stay inside the drop and also fill up.

I'm getting closer but I still need the actual logo to be inside the circle at least.

My progress:

<!DOCTYPE html>
<html lang="en">
<head>

    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>SVG Line Animation Demo</title>

</head>
<body>
<style>

    .st0{fill:none;stroke:#000000;stroke-width:4;stroke-miterlimit:5;}
    .st1{fill:none;stroke:#000000;stroke-width:3;stroke-miterlimit:5;}

    #logo2 {
        width: 150px !important;
        height: 150px !important;
        position: relative;
        margin-top: -100px;
    }

    #banner {
        border-radius: 50%;
        width: 150px;
        height: 150px;
        background: #fff;
        overflow: hidden;
        backface-visibility: hidden;
        transform: translate3d(0, 0, 0);
        z-index: -1;
        margin-bottom: -50px;
    }

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

</style>

<div>
    <div id="banner">
        <div class="fill">

            <svg version="1.1" id="logo" xmlns="" xmlns:xlink="" x="0px" y="0px"
     viewBox="0 0 136 195" style="enable-background:new 0 0 136 195;" 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>        

    <svg version="1.1" id="logo2" xmlns="" xmlns:xlink="" x="0px" y="0px"
     viewBox="0 0 136 195" style="enable-background:new 0 0 136 195;" xml:space="preserve">

        <path class="st0" d="M68.2,6.7c0,0-62.4,70.9-62.4,124.7c0,32.3,28,58.4,62.4,58.4s62.4-26.2,62.4-58.4
    C130.7,77.6,68.3,6.7,68.2,6.7z"/>
        <g><path class="st1" d="M61,77.5c0.8,0,1.5,0.7,1.5,1.5v20.6c2.7-3.6,7.6-5.7,13.1-5.7c12.2,0,19.4,6.9,19.4,18.7v37.2
        c0,0.8-0.7,1.5-1.5,1.5H75.6c-0.8,0-1.5-0.7-1.4-1.5v-32c0-4.1-1.8-6.4-5-6.4c-5.8,0-6.7,5.7-6.7,5.7v32.7c0,0.8-0.7,1.5-1.5,1.5
        H43.1c-0.8,0-1.5-0.7-1.5-1.5V79c0-0.8,0.7-1.5,1.5-1.5H61z"/></g>
    </svg>
</div>
</body>
</html>

I am to get a wipe animation to look like water is filling up inside of a drop. It currently is a square with a wave animation over top of the drop logo. It does the wave animation correctly but I can't get it to stay inside the drop and also fill up.

I'm getting closer but I still need the actual logo to be inside the circle at least.

My progress:

<!DOCTYPE html>
<html lang="en">
<head>

    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>SVG Line Animation Demo</title>

</head>
<body>
<style>

    .st0{fill:none;stroke:#000000;stroke-width:4;stroke-miterlimit:5;}
    .st1{fill:none;stroke:#000000;stroke-width:3;stroke-miterlimit:5;}

    #logo2 {
        width: 150px !important;
        height: 150px !important;
        position: relative;
        margin-top: -100px;
    }

    #banner {
        border-radius: 50%;
        width: 150px;
        height: 150px;
        background: #fff;
        overflow: hidden;
        backface-visibility: hidden;
        transform: translate3d(0, 0, 0);
        z-index: -1;
        margin-bottom: -50px;
    }

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

</style>

<div>
    <div id="banner">
        <div class="fill">

            <svg version="1.1" id="logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 136 195" style="enable-background:new 0 0 136 195;" 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>        

    <svg version="1.1" id="logo2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 136 195" style="enable-background:new 0 0 136 195;" xml:space="preserve">

        <path class="st0" d="M68.2,6.7c0,0-62.4,70.9-62.4,124.7c0,32.3,28,58.4,62.4,58.4s62.4-26.2,62.4-58.4
    C130.7,77.6,68.3,6.7,68.2,6.7z"/>
        <g><path class="st1" d="M61,77.5c0.8,0,1.5,0.7,1.5,1.5v20.6c2.7-3.6,7.6-5.7,13.1-5.7c12.2,0,19.4,6.9,19.4,18.7v37.2
        c0,0.8-0.7,1.5-1.5,1.5H75.6c-0.8,0-1.5-0.7-1.4-1.5v-32c0-4.1-1.8-6.4-5-6.4c-5.8,0-6.7,5.7-6.7,5.7v32.7c0,0.8-0.7,1.5-1.5,1.5
        H43.1c-0.8,0-1.5-0.7-1.5-1.5V79c0-0.8,0.7-1.5,1.5-1.5H61z"/></g>
    </svg>
</div>
</body>
</html>

Share Improve this question edited Jan 23, 2018 at 12:37 Machado 10.3k6 gold badges45 silver badges50 bronze badges asked Feb 2, 2017 at 22:49 user3029128user3029128 1271 gold badge1 silver badge7 bronze badges 4
  • The wave is entirely above the drop, if I clip the wave to the drop then the drop will simply appear to be full all the time as it rises. Please explain more clearly what you want to see here. – Robert Longson Commented Feb 2, 2017 at 23:32
  • Basically I want the animation to fill the entire drop. As seen in the "SVG Deliciousness" section on this thread stackoverflow.com/questions/29738787/filling-water-animation/… – user3029128 Commented Feb 2, 2017 at 23:35
  • You just want a blue drop that moves upwards then with no wave effect? – Robert Longson Commented Feb 2, 2017 at 23:35
  • I don't want the drop logo to move I just want the water animation to fill up the drop. – user3029128 Commented Feb 2, 2017 at 23:38
Add a comment  | 

1 Answer 1

Reset to default 20

The following modifies your code to:

  • remove the viewport (I just find it easier to use transform),
  • make a copy of both the drop and the "h" letter,
  • merge the copies into a single path,
  • place that merged path inside a <clipPath> element inside a <defs> element in the <svg> and give it an id ("drop")
  • place an enclosing <g> element around the <g class="fill"> group,
  • clip that enclosing <g> element using the "drop", and
  • scale and translate both the black-bordered drop-and-h as well as the clip path drop-and-h by the same amounts so that they are centered on the waveshape.

You can read about clipPath on MDN.

By the way, note that your wave shape animation may continue forever even if you can't see the waves sloshing around any more (though I didn't check this rigorously), which is probably not what you want.

<!DOCTYPE html>
<html lang="en">

<head>

  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>SVG Line Animation Demo</title>

</head>

<body>
  <style>
    .st0 {
      fill: none;
      stroke: #000000;
      stroke-width: 4;
      stroke-miterlimit: 5;
    }
    .st1 {
      fill: none;
      stroke: #000000;
      stroke-width: 3;
      stroke-miterlimit: 5;
    }
    #logo2 {
      width: 150px !important;
      height: 150px !important;
      position: relative;
      margin-top: -100px;
    }
    #banner {
      border-radius: 50%;
      width: 150px;
      height: 150px;
      background: #fff;
      overflow: hidden;
      backface-visibility: hidden;
      transform: translate3d(0, 0, 0);
      z-index: -1;
      margin-bottom: -50px;
    }
    #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);
      }
    }
  </style>


  <div>
    <div id="banner">
      <div>
        <svg version="1.1" id="logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" xml:space="preserve">

          <defs>
            <clipPath id="drop">
              <path transform="scale(0.75), translate(32,0)" d="M68.2,6.7c0,0-62.4,70.9-62.4,124.7c0,32.3,28,58.4,62.4,58.4s62.4-26.2,62.4-58.4
    C130.7,77.6,68.3,6.7,68.2,6.7z M61,77.5c0.8,0,1.5,0.7,1.5,1.5v20.6c2.7-3.6,7.6-5.7,13.1-5.7c12.2,0,19.4,6.9,19.4,18.7v37.2
        c0,0.8-0.7,1.5-1.5,1.5H75.6c-0.8,0-1.5-0.7-1.4-1.5v-32c0-4.1-1.8-6.4-5-6.4c-5.8,0-6.7,5.7-6.7,5.7v32.7c0,0.8-0.7,1.5-1.5,1.5
        H43.1c-0.8,0-1.5-0.7-1.5-1.5V79c0-0.8,0.7-1.5,1.5-1.5H61z" />
            </clipPath>
          </defs>

          <g clip-path="url(#drop)">
            <g class="fill">
              <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" />
            </g>
          </g>
          <g transform="scale(0.75), translate(32,0)">
            <path class="st0" d="M68.2,6.7c0,0-62.4,70.9-62.4,124.7c0,32.3,28,58.4,62.4,58.4s62.4-26.2,62.4-58.4
    C130.7,77.6,68.3,6.7,68.2,6.7z" />
            <path class="st1" d="M61,77.5c0.8,0,1.5,0.7,1.5,1.5v20.6c2.7-3.6,7.6-5.7,13.1-5.7c12.2,0,19.4,6.9,19.4,18.7v37.2
        c0,0.8-0.7,1.5-1.5,1.5H75.6c-0.8,0-1.5-0.7-1.4-1.5v-32c0-4.1-1.8-6.4-5-6.4c-5.8,0-6.7,5.7-6.7,5.7v32.7c0,0.8-0.7,1.5-1.5,1.5
        H43.1c-0.8,0-1.5-0.7-1.5-1.5V79c0-0.8,0.7-1.5,1.5-1.5H61z" />
          </g>
        </svg>
      </div>
    </div>
  </div>
</body>

</html>

发布评论

评论列表(0)

  1. 暂无评论