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

时间:2015-12-02 12:54:07

标签: html css svg filter

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

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

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

svg path backdrop-filter scheme



$(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();
})

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);
}

<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>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分: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 })

$(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();
})
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);
}
<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>

二次贝塞尔曲线

另一种解决方案是在曲面中添加一个弯曲路径(称为quadratic Bézier curve)。曲线构建如下:

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

另请参阅:Quadratic Bézier Curve: Calculate Points或点击here获取二次Bézier曲线的交互式示例。

<强>否定

在使用两个不同的animations和持续时间时,此解决方案存在一些问题,就像您的情况一样。

$(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();
})
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);
}
<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>

<强>正

相反,当使用相同的动画和持续时间时效果很好。

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();
})
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);
}
<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>