CSS SVG波形

时间:2018-08-09 12:43:27

标签: css svg

这就是我想要达到的结果

enter image description here

这就是我所做的:https://codepen.io/demedos/pen/gjQNOM

HTML结构:

.container
  .header
  .page-1
    #wave
    #dot
    #text

但是有一些问题:

  • 使用绝对定位来定位项目,而我希望将它们锚定到主波浪线上
  • 容器小于其内容
  • 我希望线条位于屏幕的50%处,并用背景色填充以上空间

1 个答案:

答案 0 :(得分:2)

这是一个使用少量Javascript的解决方案。我已经简化了您的示例,以使事情保持清楚。

  

我希望线条位于屏幕的50%处,并用背景色填充以上空间

  • 我们使用垂直伸缩框排列来填充屏幕的高度。
  • 我们将viewBox设置为适合波浪曲线,并让浏览器进行正常的SVG居中。
  • 我们使用非常高的波浪路径,并依靠SVG溢出使波浪填充到单元格的顶部。
  • 我们使用SVGPathElement.getPointAtLength()为每个点计算路径上的正确位置。

function positionDot(dotId, fractionAlongWave) {
  // Get a reference to the "wave-curve" path.
  var waveCurve = document.getElementById("wave-curve");
  // Get the length of that path
  var curveLength = waveCurve.getTotalLength();
  // Get the position of a point that is "fractionAlongWave" along that path
  var pointOnCurve = waveCurve.getPointAtLength(curveLength * fractionAlongWave);
  // Update the dot position
  var dot = document.getElementById(dotId);
  dot.setAttribute("cx", pointOnCurve.x);
  dot.setAttribute("cy", pointOnCurve.y);
}


// Position the first dot 25% the way along the curve
positionDot("dot1", 0.25);

// Position the second dot 90% of the way along the curve
positionDot("dot2", 0.90);
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  padding: 0;
}

.container {
  display: flex;
  flex-direction: column;
  width: 640px;
  height: 100vh;
  margin: 0 auto;
  border: 1px solid blue;
}

.header {
  background-color: #333835;
}

.page-1 {
  flex: 1;
  border: 1px solid red;
  position: relative;
}

.page-1 svg {
  position: absolute;
  width: 100%;
  height: 100%;
  border: 1px solid red;
}

#wave {
  fill:#333835;
}

#dot1,
#dot2 {
  fill:#e05a5a;
}
<div class='container'>
  <div class='header'>
    header 
  </div>
  <div class='page-1'>
    <!-- Set the viewBox to match the curve part of the wave.
         Then we can rely on the browser to centre the SVG (and thus the curve) in the parent container. -->
    <svg viewBox="0 342 1366 283">
      <defs>
        <!-- A copy of the curve part of the wave, which we will use to calculate
             the correct position of the dot using getPointAtLength(). -->
        <path id="wave-curve" d="M0,342c595,0,813,283,1366,283"/>
      </defs>
      <!-- SVGs are "overflow: visible" by default.
           If we make this path extend vertically a long way, it will fill to the
           top of the SVG no matter how high the page is. -->
      <path id="wave" d="M0,342c595,0,813,283,1366,283 V -10000 H 0 Z"/>

      <circle id="dot1" cx="0" cy="0" r="12.5"/>
      <circle id="dot2" cx="0" cy="0" r="12.5"/>
    </svg>
  </div>
</div>