3

I am trying to animate a path within an svg. The path is of a squiggly line to look like a wave. What I am trying to do is have this path translate horizontally on a infinite loop to make it look as though the water is moving.

You can see a similar effect achieved by the outline, only going vertically and this is not within an SVG: https://theoutline.com/

Here is the JsFiddle I have so far with an svg wave/squiggle.

<g class="wave-container">
  <path class="wave" d="M1,1c1.6,0,1.6,1.6,3.3,1.6S5.9,1,7.6,1c1.6,0,1.6,1.6,3.3,1.6S12.5,1,14.2,1s1.6,1.6,3.3,1.6
                c1.6,0,1.6-1.6,3.3-1.6"/>
</g>

https://jsfiddle.net/bje5rxzs/

I am trying to be able to animate this wave horizontally within it's group/container. I know SVG does not support overflow:hidden; within, so how would this be achieved? Would a mask work? I am open to using a snap.svg if required. I will have other elements within this svg moving, so the squiggle needs to be within the same svg.

Any help much appreciated! Thank you :)

h0bb5
  • 609
  • 1
  • 7
  • 22
  • SVG does support overflow:hidden so what you know is wrong. – Robert Longson Sep 27 '17 at 17:31
  • @RobertLongson Hey man, I said 'within' the SVG. IF you read the spec you will see that what I know is not wrong. "The overflow attribute only applies to elements that establish new viewports, elements and elements. For all other elements, the property has no effect." via MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/overflow Thanks for the helpful response. – h0bb5 Sep 27 '17 at 18:04
  • elements establish new viewports, use one of them. – Robert Longson Sep 27 '17 at 18:28

2 Answers2

3

Updated

Like any animation where you are changing the position of something you can use transforms.

The key here is making the squiggly path wider than the svg viewbox, and setting overflow:hidden on svg (which is supported).

Since your illustration is tiny I had to make the svg viewbox tiny as well, only 15px wide, so that the path could overlap the svg container.

<svg version="1.1" x="0px" y="0px" width="15px" height="3.6px" viewBox="0 0 15 3.6">
   <path class="white-path animate" d="M1,1c1.6,0,1.6,1.6,3.3,1.6S5.9,1,7.6,1c1.6,0,1.6,1.6,3.3,1.6S12.5,1,14.2,1s1.6,1.6,3.3,1.6 c1.6,0,1.6-1.6,3.3-1.6"/>
</svg>

css:

svg {
  overflow:hidden;
}
.white-path {
  fill:none;
  stroke:#FFFFFF;
  stroke-width:2;
  stroke-linecap:round;
  stroke-linejoin:round;
  stroke-miterlimit:10;
 }
 @keyframes squiggle {
   from {
     transform: translateX(-7px)
   }
   to {
     transform: translateX(0px)
   }
 }
 .animate {
   animation: squiggle 1s linear infinite;
 }

I used a negative x translation, and through trial and error picked the right distance so the looping was seamless.

Demo: https://jsfiddle.net/bje5rxzs/6/

inorganik
  • 24,255
  • 17
  • 90
  • 114
  • Hey! Thanks for the attempt but this just draws the wave out in a line. Maybe I should have explained more clearly but I am trying to MOVE the line horizontally and have it repeat giving it the effect of waves. You can see http://theoutline.com to reference the effect. Thanks again for the attempt! – h0bb5 Sep 27 '17 at 18:06
  • Thank you! That does it for me! There is just one issue with the code you've provided. Lets say I want to change the path to a longer one, i've updated the viewbox and svg width but when the longer path is placed in, it is no longer visible. https://jsfiddle.net/bje5rxzs/7/ Am I missing an adjustment? – h0bb5 Sep 27 '17 at 21:21
  • It's probably related to the path, and where it's placed relative to the svg viewBox. You will need to make sure it fits in your artboard and that it is overlapping precisely how you want it and then use that exported svg code, not my existing code. In other words, use my code as an example and than recreate it yourself. – inorganik Sep 28 '17 at 15:49
  • Thanks again, it was indeed the path :) – h0bb5 Sep 28 '17 at 16:22
0

you can just nest 2 svg.

var x = -5
setInterval(() => {
  wave.setAttribute("transform", `translate(${x},0)`)
  if (x >= 0) {
    x = -5
  } else {
    x++
  }
}, 100)
<svg viewBox="0 0 300 300" width="200" height="200">
<circle cx="150" cy="150" r="150" fill="red"/>
  <svg x="50" y="50" viewBox="1 0 10 3.5" width="100" height="35">
    <path id="wave" transform="translate(-5,0)" d="M1,1c1.6,0,1.6,1.6,3.3,1.6S5.9,1,7.6,1c1.6,0,1.6,1.6,3.3,1.6S12.5,1,14.2,1s1.6,1.6,3.3,1.6
                c1.6,0,1.6-1.6,3.3-1.6" fill="none" stroke="black"/>

  </svg>
</svg>
Holger Will
  • 7,228
  • 1
  • 31
  • 39