Search code examples
htmlcsssvgadobe-illustrator

Easiest way to make complex div with waves


I would like to create divs with complex waves, I'm coming across a lot of tutorials and I tried a lot of things but I can not do it. What is the best way to make waves and the background goes around and stops at the wave? What is the best/simplest way, I heard about the SVG but no skill with that. Is it complicated to realize? I wish I could draw curves and change the background accordingly as on this WordPress theme: https://www.elegantthemes.com/blog/theme-releases/shape-dividers

I wish I could do that: http://www.zupimages.net/viewer.php?id=19/22/jr0r.png

I have to learn SVG ? or use illustrator, too complicated directly in CSS if I have several waves. A software like an illustrator to do that for free with SVG exist?

and then do the rest of my style with bootstrap 4 etc? ...thank you


Solution

  • Normally you can do this using Perlin noise. However you can do it also by setting a number of points with successive x and random y on the svg canvas, and connecting the points with Béziers.

    let w = 1000;
    let h = 300;
    svg.setAttributeNS(null,"viewBox",`0 0 ${w} ${h}`)
    let n = 18; //number of points
    let points = [];// the points array used to draw the curve
    
    // add points to the points array
    for(let x=0; x <= w; x+= w/n){
      let y = h - Math.random()*h;
      points.push({x:x,y:y})
    }
    
    
    // a function to connect all the points in the points array with beziers
    function  connect(points) {    
       let d = "";// the d attribute for the path
       // move to the first point of the array
       d+= `M${points[0].x}, ${points[0].y}`;
        //build the path
        for (var i = 1; i < points.length - 2; i++) {
          var cp = {};
          cp.x = (points[i].x + points[i + 1].x) / 2;
          cp.y = (points[i].y + points[i + 1].y) / 2;
          
          d+=`Q${points[i].x},${points[i].y} ${cp.x},${cp.y}`
        }
        //the last curve
        let index = points.length-2
       d+=`Q${points[index].x},${points[index].y} ${points[index + 1].x},${points[index + 1].y}`;
       //close the path
       d+=`V${h}H0z`
        return d;
      }
    //set the attribute `d` for the wave
    wave.setAttributeNS(null,"d",connect(points))
    svg{border:1px solid}
    <svg id="svg" >
      <path id="wave" />
    </svg>