将背景过滤器应用于svg path元素

Mic*_*kov 21 html css svg filter

我有一个带有一些背景图片的页面.

在body标签中,我有一个只有一个内部路径元素的svg元素.

如何将path-filter添加到路径元素,以便它可以模糊非矩形形状的背景?

svg路径背景 - 过滤方案

$(function() {

  var pattern = "M0,{offsetTop} C{ax1},{power},{ax2},{power},{width},{offsetTop} L{width},{height},0,{height}Z";

  var $svg = $('svg#footer');
  var $path = $svg.find('path');

  var settings = {
    width: 1200,
    height: 200,
    offsetTop: 200,
    power: 200
  }

  settings.ax1 = settings.width / 3 * 1;
  settings.ax2 = settings.width / 3 * 2;

  function render() {
    var newPath = pattern;
    for (var i in settings) {
      newPath = newPath.split('{' + i + '}').join(settings[i]);
    }
    $path.attr('d', newPath);
  }

  TweenMax.set($svg, {
    force3D: true
  })

  var opened = false;

  function open() {
    if (opened) {
      return
    }
    opened = true;
    TweenMax.to(settings, 0.35, {
      overwrite: true,
      offsetTop: 80,
      ease: Strong.easeOut,
      onUpdate: render
    })
    TweenMax.to(settings, 1, {
      power: 80,
      ease: Elastic.easeOut,
      onUpdate: render
    })
  }

  function close() {
    if (!opened) {
      return
    }
    opened = false;
    TweenMax.to(settings, 0.35, {
      overwrite: true,
      offsetTop: 200,
      ease: Back.easeIn,
      onUpdate: render
    })
    TweenMax.to(settings, 0.35, {
      power: 200,
      delay: 0.15,
      ease: Back.easeOut,
      onUpdate: render
    })
  }

  $(window).on('mousedown touchstart', function(e) {
    opened ? close() : open();
  })

  open();
})
Run Code Online (Sandbox Code Playgroud)
html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

body {
  background-image: url('http://i839.photobucket.com/albums/zz314/mrkanpuc/stuffs/1PZ1.jpg');
  background-repeat: no-repeat;
  background-size: cover;
}

svg {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 200px;
}

svg path {
  fill: rgba(0, 0, 0, 0.5);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js"></script>

<svg id="footer" viewBox="0 0 1200 200" preserveAspectRatio="none"><path/></svg>
Run Code Online (Sandbox Code Playgroud)

Pao*_*gia 8

如果不对代码进行太多更改,则可以通过增加power和/或减少offsetTop开放函数来实现.

TweenMax.to(settings, 0.35, {overwrite: true, offsetTop: 80, ease: Strong.easeOut, onUpdate: render })
TweenMax.to(settings, 1, {power: 120, ease: Elastic.easeOut, onUpdate: render })
Run Code Online (Sandbox Code Playgroud)

$(function() {

  var pattern = "M0,{offsetTop} C{ax1},{power},{ax2},{power},{width},{offsetTop} L{width},{height},0,{height}Z";

  var $svg = $('svg#footer');
  var $path = $svg.find('path');

  var settings = {
    width: 1200,
    height: 200,
    offsetTop: 200,
    power: 200
  }

  settings.ax1 = settings.width / 3 * 1;
  settings.ax2 = settings.width / 3 * 2;

  function render() {
    var newPath = pattern;
    for (var i in settings) {
      newPath = newPath.split('{' + i + '}').join(settings[i]);
    }
    $path.attr('d', newPath);
  }

  TweenMax.set($svg, {
    force3D: true
  })

  var opened = false;

  function open() {
    if (opened) {
      return
    }
    opened = true;
    TweenMax.to(settings, 0.35, {
      overwrite: true,
      offsetTop: 80,
      ease: Strong.easeOut,
      onUpdate: render
    })
    TweenMax.to(settings, 1, {
      power: 150,
      ease: Elastic.easeOut,
      onUpdate: render
    })
  }

  function close() {
    if (!opened) {
      return
    }
    opened = false;
    TweenMax.to(settings, 0.35, {
      overwrite: true,
      offsetTop: 200,
      ease: Back.easeIn,
      onUpdate: render
    })
    TweenMax.to(settings, 0.35, {
      power: 200,
      delay: 0.15,
      ease: Back.easeOut,
      onUpdate: render
    })
  }

  $(window).on('mousedown touchstart', function(e) {
    opened ? close() : open();
  })

  open();
})
Run Code Online (Sandbox Code Playgroud)
html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

body {
  background-image: url('http://i839.photobucket.com/albums/zz314/mrkanpuc/stuffs/1PZ1.jpg');
  background-repeat: no-repeat;
  background-size: cover;
}

svg {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 200px;
}

svg path {
  fill: rgba(0, 0, 0, 0.5);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js"></script>

<svg id="footer" viewBox="0 0 1200 200" preserveAspectRatio="none"><path/></svg>
Run Code Online (Sandbox Code Playgroud)


二次Bézier曲线

另一种解决方案是在矩形中添加一条曲线路径(称为二次贝塞尔曲线).曲线构建如下:

M{startWidth}, {startHeight} q {curvePeak}, {curveHeight}, {endWidth}, {endHeight}
Run Code Online (Sandbox Code Playgroud)
  • startWidth - x轴定位P0:曲线开始的x坐标
  • startHeight - y轴定位P0:y曲线开始的坐标
  • curvePeak - x轴定位P1:曲线达到峰值的位置
  • curveHeight - y轴定位P1:曲线的高度
  • endWidth - x轴定位P2:曲线的尺寸
  • endHeight - y轴定位P2:曲线的倾斜度

另请参阅:二次贝塞尔曲线:计算点或单击此处获取二次贝塞尔曲线的交互式示例.

在使用两种不同的动画和持续时间时,此解决方案存在一些问题,例如您的情况.

$(function() {

  var pattern = "M0,{offsetTop} C{ax1},{power},{ax2},{power},{width},{offsetTop} L{width},{height},0,{height}Z q 600, 100, 1200, 0";

  var $svg = $('svg#footer');
  var $path = $svg.find('path');

  var settings = {
    width: 1200,
    height: 200,
    offsetTop: 200,
    power: 200
  }

  settings.ax1 = settings.width / 3 * 1;
  settings.ax2 = settings.width / 3 * 2;

  function render() {
    var newPath = pattern;
    for (var i in settings) {
      newPath = newPath.split('{' + i + '}').join(settings[i]);
    }
    $path.attr('d', newPath);
  }

  TweenMax.set($svg, {
    force3D: true
  })

  var opened = false;

  function open() {
    if (opened) {
      return
    }
    opened = true;
    TweenMax.to(settings, 0.35, {
      overwrite: true,
      offsetTop: 80,
      ease: Strong.easeOut,
      onUpdate: render
    })
    TweenMax.to(settings, 1, {
      power: 80,
      ease: Elastic.easeOut,
      onUpdate: render
    })
  }

  function close() {
    if (!opened) {
      return
    }
    opened = false;
    TweenMax.to(settings, 0.35, {
      overwrite: true,
      offsetTop: 200,
      ease: Back.easeIn,
      onUpdate: render
    })
    TweenMax.to(settings, 0.35, {
      power: 200,
      delay: 0.15,
      ease: Back.easeOut,
      onUpdate: render
    })
  }

  $(window).on('mousedown touchstart', function(e) {
    opened ? close() : open();
  })

  open();
})
Run Code Online (Sandbox Code Playgroud)
html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

body {
  background-image: url('http://i839.photobucket.com/albums/zz314/mrkanpuc/stuffs/1PZ1.jpg');
  background-repeat: no-repeat;
  background-size: cover;
}

svg {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 200px;
}

svg path {
  fill: rgba(0, 0, 0, 0.5);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js"></script>

<svg id="footer" viewBox="0 0 1200 200" preserveAspectRatio="none"><path/></svg>
Run Code Online (Sandbox Code Playgroud)

相反,它在使用相同的动画和持续时间时效果很好.

两者都Elastic.easeOut:1.00s

$(function() {

  var pattern = "M0,{offsetTop} C{ax1},{power},{ax2},{power},{width},{offsetTop} L{width},{height},0,{height}Z q 600, 100, 1200, 0";

  var $svg = $('svg#footer');
  var $path = $svg.find('path');

  var settings = {
    width: 1200,
    height: 200,
    offsetTop: 200,
    power: 200
  }

  settings.ax1 = settings.width / 3 * 1;
  settings.ax2 = settings.width / 3 * 2;

  function render() {
    var newPath = pattern;
    for (var i in settings) {
      newPath = newPath.split('{' + i + '}').join(settings[i]);
    }
    $path.attr('d', newPath);
  }

  TweenMax.set($svg, {
    force3D: true
  })

  var opened = false;

  function open() {
    if (opened) {
      return
    }
    opened = true;
    TweenMax.to(settings, 1, {
      overwrite: true,
      offsetTop: 80,
      ease: Elastic.easeOut,
      onUpdate: render
    })
    TweenMax.to(settings, 1, {
      power: 80,
      ease: Elastic.easeOut,
      onUpdate: render
    })
  }

  function close() {
    if (!opened) {
      return
    }
    opened = false;
    TweenMax.to(settings, 0.35, {
      overwrite: true,
      offsetTop: 200,
      ease: Back.easeIn,
      onUpdate: render
    })
    TweenMax.to(settings, 0.35, {
      power: 200,
      ease: Back.easeIn,
      onUpdate: render
    })
  }

  $(window).on('mousedown touchstart', function(e) {
    opened ? close() : open();
  })

  open();
})
Run Code Online (Sandbox Code Playgroud)
html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

body {
  background-image: url('http://i839.photobucket.com/albums/zz314/mrkanpuc/stuffs/1PZ1.jpg');
  background-repeat: no-repeat;
  background-size: cover;
}

svg {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 200px;
}

svg path {
  fill: rgba(0, 0, 0, 0.5);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js"></script>

<svg id="footer" viewBox="0 0 1200 200" preserveAspectRatio="none"><path/></svg>
Run Code Online (Sandbox Code Playgroud)

  • 不能代表OP,但我不认为这回答了这个问题.问题是如何将背景滤镜应用于非矩形形状.我亲自尝试了很多方法(边界半径,svg元素,剪切),但在每种方法中,背投滤镜应用为矩形,而不是您想要的非矩形形状. (3认同)