将背景过滤器应用于 svg 路径元素
Posted
技术标签:
【中文标题】将背景过滤器应用于 svg 路径元素【英文标题】:Apply backdrop filter to svg path element 【发布时间】:2016-03-06 17:28:04 【问题描述】:我有一个带有一些背景图片的页面。
在 body 标记中,我有一个 svg 元素,其中只有一个内部路径元素。
如何为路径元素添加背景滤镜,使其可以模糊非矩形形状的背景?
$(function()
var pattern = "M0,offsetTop Cax1,power,ax2,power,width,offsetTop Lwidth,height,0,heightZ";
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>
【问题讨论】:
我相信这是不可能的,获得类似效果的常用技巧是将背景复制到单独的对象中,为其添加过滤器并添加剪辑路径。 也许看here(第二种解决方案)可能会帮助遇到同样问题的人。 将 url 路径/掩码与 rect/custom 交换可能会诡计! 【参考方案1】:无需对代码进行太多更改,您可以通过在 open 函数中增加 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 Cax1,power,ax2,power,width,offsetTop Lwidth,height,0,heightZ";
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)。曲线是这样构建的:
MstartWidth, 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 以查看二次贝塞尔曲线的交互式示例。
否定
当使用两个不同的animations 和持续时间时,此解决方案会出现一些问题,就像您的情况一样。
Strong.easeOut
: 0.35s
Elastic.easeOut
: 1.00s
$(function()
var pattern = "M0,offsetTop Cax1,power,ax2,power,width,offsetTop Lwidth,height,0,heightZ 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 Cax1,power,ax2,power,width,offsetTop Lwidth,height,0,heightZ 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>
【讨论】:
不能代表 OP,但我认为这不能回答问题。问题是如何将背景滤镜应用于非矩形形状。我个人尝试了许多方法(边框半径、svg 元素、切口),但在每种方法中,背景过滤器都应用为矩形,而不是您想要的非矩形。 您的解决方案未应用背景过滤器。检查 SVG 形状的背景模糊的问题的屏幕截图。 OP的尝试没有这样做,您的回答也没有。 我对 svg 动画没有任何问题。但问题是如何将背景滤镜应用于非矩形形状。正如我所测试的那样,没有画布和大量魔法就没有机会做到这一点。以上是关于将背景过滤器应用于 svg 路径元素的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 CSS 将阴影过滤器应用于 SVG 特定元素/路径