8

How It Works

The .png image represented below is clipped to the text with animation;

wave with text


In Action

body { background: #000000; }

.Wave-Loader {
 text-transform: uppercase;
 font-family: 'Cabin Condensed', sans-serif;
 font-weight: bold;
 font-size: 100pt;
 text-align: center;
 height: 120px;
 line-height: 110px;
 vertical-align: bottom;
 position: absolute;
 left: 0;
 right: 0;
 top: 100px;
 bottom: 0;
}

.Wave-Loader.Wave {
 background-image: url("http://i.imgur.com/uFpLbYt.png");
 -moz-background-clip: text;
 -o-background-clip: text;
   -webkit-background-clip: text;
  background-clip: text;
 color: transparent;
 text-shadow: 0px 0px rgba(255, 255, 255, 0.06);
 animation: Wave-Loader 1s infinite linear;
 background-size: 200px 100px;
 background-repeat: repeat-x;
 opacity: 1;
}
@keyframes Wave-Loader {
 0% { background-position: 0 bottom; }
 100% { background-position: 200px bottom; }
}
<div class="Wave-Loader Wave">loading</div>

Question

Instead of using an image, how can I replace with a pure CSS shape as I would like to implement my colour tween which will change the colour of the white wave you see in my demo above going from red to green.

NOTE: Black background is only being used for StackOverflow whereas my background may vary in colour.


Examples Of A Wave Effect

#wave {
  position: relative;
  height: 70px;
  width: 600px;
  background: #000000;
}
#wave:before {
  content: "";
  display: block;
  position: absolute;
  border-radius: 100% 50%;
  width: 340px;
  height: 80px;
  background-color: white;
  right: -5px;
  top: 40px;
}
#wave:after {
  content: "";
  display: block;
  position: absolute;
  border-radius: 100% 50%;
  width: 300px;
  height: 70px;
  background-color: #000000;
  left: 0;
  top: 27px;
}
<div id="wave"></div>

svg {
  display: inline-block;
  position: absolute;
  top: 0;
  left: 0;
}
.container {
  display: inline-block;
  position: relative;
  width: 100%;
  padding-bottom: 100%;
  vertical-align: middle;
  overflow: hidden;
}
<div class="container">
  <svg viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet">
    <path d="M0,100 C150,200 350,0 500,100 L500,00 L0,0 Z" style="stroke: none; fill:red;"></path>
  </svg>
</div>
web-tiki
  • 99,765
  • 32
  • 217
  • 249
Tyler
  • 854
  • 1
  • 10
  • 26
  • 1
    Does this help --> http://stackoverflow.com/questions/17202548/wavy-shape-with-css – sol Jan 02 '17 at 12:26
  • @ovokuro this is where I got the "Examples Of A Wave Effect", never noticed the SVG though which I just added to my question. The wave effect isn't as much as the problem, it's the clipping. – Tyler Jan 02 '17 at 12:29
  • 1
    See the footer of [this site](http://www.peixeurbano.com.br/) (mouse hover between white and blue) but is canvas, not css, just to see if you help with anything... – rafaelfndev Jan 02 '17 at 13:27
  • @rafaelfndev as long as the loading text can be easily modified as I show a progressive percentage and the colour of the wave can be modified using jQuery? – Tyler Jan 02 '17 at 13:37
  • @rafaelfndev please see this [JSFiddle](https://jsfiddle.net/undkmgmf/) which shows a bit more towards what I'm working towards. – Tyler Jan 02 '17 at 13:49

1 Answers1

18

You may achieve text filled by an animated wave with several techniques. Here is an approach with SVG using the pattern element. The text is filled with a wave shaped pattern and the pattern is animated with SMIL animations. Here is what it looks like :

Animated wave clipped by text

This approach will allow you to fill the pattern with a non plain background (like a gradient) and display your text over an image or any non plain background.

You can see this in action here : Animated wave clipped with text.

body,html{margin:0;padding:0;height:100%;}
body{
  background:url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');
  background-size:cover;
  font-family: 'Cabin Condensed', sans-serif;
  display:flex;
  flex-direction:column;
  justify-content:center;
  align-items:center;
}
svg{font-weight:bold;max-width:600px;height:auto;}
<svg viewbox="0 0 100 20">
  <defs>
    <linearGradient id="gradient" x1="0" x2="0" y1="0" y2="1">
      <stop offset="5%" stop-color="#326384"/>
      <stop offset="95%" stop-color="#123752"/>
    </linearGradient>
    <pattern id="wave" x="0" y="0" width="120" height="20" patternUnits="userSpaceOnUse">
      <path id="wavePath" d="M-40 9 Q-30 7 -20 9 T0 9 T20 9 T40 9 T60 9 T80 9 T100 9 T120 9 V20 H-40z" fill="url(#gradient)"> 
        <animateTransform attributeName="transform" type="translate" begin="0s" dur="1.5s" from="0,0" to="40,0" repeatCount="indefinite" />
      </path>
    </pattern>
  </defs>
  <text text-anchor="middle" x="50" y="15" font-size="17" fill="url(#wave)"  fill-opacity="0.6">LOADING</text>
  <text text-anchor="middle" x="50" y="15" font-size="17" fill="url(#gradient)" fill-opacity="0.1">LOADING</text>
</svg>

EDIT ----

I switched from CSS keyframe animations to SMIL animations for this example as Firefox doesn't support CSS keyframes on the elements defined in the <defs> tag yet (see https://bugzilla.mozilla.org/show_bug.cgi?id=1118710).

albert
  • 8,112
  • 3
  • 47
  • 63
web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • This looks like a fantastic new start! What percent is the fluid line up to? I'd like to modify this as seen in my [JSFiddle](https://jsfiddle.net/5d17a5ac/) to go from the bottom to out of perspective so another words, one colour. +1 – Tyler Jan 02 '17 at 16:25
  • 1
    @TimMarshall if you wan the text to be filled up by the wave, you could do this : http://codepen.io/web-tiki/pen/rjBbEr – web-tiki Jan 02 '17 at 17:00
  • 1
    @TimMarshall just to make sure you saw, I switched to SMIL animations for the wave as it didn't work in FF. – web-tiki Jan 02 '17 at 17:52
  • This is out of my area of programming, absolutely amazing, I've got some work to do with it and then I'll be done and with what you've done, it seems easy enough to achieve what I want to with jQuery. Thank you very much – Tyler Jan 03 '17 at 13:14
  • How can I set this going using jQuery as I need to modify the percentage from 0-100 depending on how much has loaded and modify the colour of the text via `ProgressColourTween[value]` which is my colour tween from red -> orange -> green. – Tyler Jan 03 '17 at 13:37
  • 1
    @TimMarshall to manipulate svg with JS, you can use the snap.svg library, it is lightweight and makes it so much easier. Here is an example : http://codepen.io/web-tiki/pen/rjBbEr . You can then use your colour tween to change the fill value for the svg wave to change it's colour. – web-tiki Jan 03 '17 at 14:03
  • @TimMarshall you will need to get your hands in the dirt for that. I think I have answered your question and beyond already. Both snap.svg and SVG are very well documented. I suggest you make your own research to understand how all this works. If you struggle, you can still ask another question on SO. Now for the colour of the text, I would suggest you comment out the JS animation to make it steady and fiddle around with the `linearGradient` in the SVG code. – web-tiki Jan 03 '17 at 17:10
  • Am I missing something here or is the mask actually missing? There is a reference to `url(#mask)`in the SVG markup and I had expected it to be followed by the actual mask somewhere? – DroidOS Jun 29 '17 at 08:37
  • 1
    @DroidOS sorry about that, the mask reference isn't needed, I removed it in my answer. – web-tiki Jun 29 '17 at 09:16