svg - 为什么我的 SVG 看起来不像波纹(关于 feDisplacementMap 过滤器)
问题描述
我正在尝试制作波纹过滤器:
<radialGradient id="g" cx=".6" cy=".6" r=".05" spreadMethod="reflect">
<stop offset="0" stop-color="#000"></stop>
<stop offset="1" stop-color="#fff"></stop>
</radialGradient>
这非常有效,因为它产生了许多圈子。但是当我对这两个过滤器求和时,我只会得到filter
( #f
) 效果;为什么我的radialGradient
( #g
) 效果会丢失?(请参阅下面的完整代码。)
我期望它看起来像下面这样:
参考:
- https://www.oxxostudio.tw/articles/201410/svg-28-filter-feDisplacementMap.html
- https://www.oxxostudio.tw/articles/201410/svg-29-filter-water-ripple.html
<svg width="340" height="231">
<defs>
<filter id="f" filterUnits="objectBoundingBox" primitiveUnits="objectBoundingBox" x="0" y="0" width="1.1"
height="1.1">
<feImage result="pict1" xlink:href="#m1" x="0" y="0" width="1.1" height="1.1"></feImage>
<feImage result="pict2" xlink:href="#m2" x="0" y="0" width="1.1" height="1.1"></feImage>
<feDisplacementMap id="fdm" scale=".1" xChannelSelector="R" yChannelSelector="R" in2="pict2" in="pict1">
</feDisplacementMap>
</filter>
<radialGradient id="g" cx=".6" cy=".6" r=".05" spreadMethod="reflect">
<stop offset="0" stop-color="#000"></stop>
<stop offset="1" stop-color="#fff"></stop>
</radialGradient>
<rect id="m2" x="-10" y="0" width="410" height="300" fill="url(#g)"></rect>
<image id="m1" x="0" y="0" width="400" height="300"
xlink:href="http://www.oxxostudio.tw/img/articles/201410/20141009_1_demo3.JPG"></image>
</defs>
<rect x="0" y="0" width="400" height="300" filter="url(#f)" transform="translate(-60 -60)"></rect>
</svg>
===================2020 03 17=====================
谢谢回答我的问题
让我找到重点
==============================
对于 feImage,您需要使用外部 svg,或者像我一样使用 data:uri。如果你想使用 data:uri 你可以使用这个 svg-encoder
现在它的工作完美
参考:
const filterFeImage = document.querySelector("#f feImage");
const xlink = "http://www.w3.org/1999/xlink";
let div = document.getElementById('div');
let svg = document.getElementById('svg');
let width = div.offsetWidth;
let height = div.offsetHeight;
svg.innerHTML = '<g id="svgandg" filter="url(#f)"><image id="Darwin" xmlns:xlink="http://www.w3.org/1999/xlink"xlink:href="http://www.oxxostudio.tw/img/articles/201410/20141009_1_demo3.JPG" width="' + width + '" height="'+ height +'"></image><text id="text" text-anchor="middle" x="' + (width / 2) +'" y="' + (height / 2) +'" style="font-size:180px;font-weight:900;"> How Are You </text></g>';
let displacement = 0;
let speed = 0.2;
function setXlinkHref() {
/*
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width="300" height="300">
<defs>
<radialGradient id="rg" r=".9">
*/
let xlinkHref =
"data:image/svg+xml;utf8,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='" + width + "' height='" + height + "'%3E%3Cdefs%3E%3CradialGradient id='rg' r='.9'%3E";
/*
<stop offset='0%' stop-color='#f00'></stop>
<stop offset='10% 'stop-color='#000'></stop>
<stop offset='20%' stop-color='#f00'></stop>
<stop offset='30%' stop-color='#000'></stop>
<stop offset='40%' stop-color='#f00'></stop>
<stop offset='50%' stop-color='#000'></stop>
<stop offset='60%' stop-color='#f00'></stop>
<stop offset='70%' stop-color='#000'></stop>
<stop offset='80% 'stop-color='#f00'></stop>
<stop offset='90%' stop-color='#f00'></stop>
<stop offset='100%' stop-color='#f00'></stop>
*/
for (var i = 0; i < 11; i++) {
// offset='${(i - 2) * 20 + displacement * 2}%25' 可以控制每一個波的波長
xlinkHref += `%3Cstop
offset='${(i - 2) * 20 + displacement * 2}%25'
stop%2Dcolor='%23${i % 2 == 0 ? "f00" : "000"}'%3E%3C/stop%3E`;
}
/*
</radialGradient>
<rect id="witness" width="300" height="300" fill="url(#rg)"></rect>*/
xlinkHref +=
"%3C/radialGradient%3E%3C/defs%3E%3Crect id='witness' width='"+ width +"' height='" + height + "' fill='url(%23rg)'%3E%3C/rect%3E%3C/svg%3E";
return xlinkHref;
}
function AnimateOffset() {
let xlinkHref = setXlinkHref();
filterFeImage.setAttributeNS(xlink, "href", xlinkHref);
// ripples.setAttributeNS(xlink, "href", xlinkHref);
if (displacement <= 20) {
displacement += speed;
} else {
displacement = 0;
}
// window.requestAnimationFrame(AnimateOffset);
}
// 設定楨數的地方
setInterval(() => {
AnimateOffset();
}, 66);
// window.requestAnimationFrame(AnimateOffset);
*{
margin: 0;
padding: 0;
list-style: none;
}
.div{
width: 100%;
height: 100vh;
background: url("20180319090858589.jpg");
}
.div svg{
width: 100%;
height: 100%;
}
<svg>
<defs>
<filter id="f" primitiveUnits="objectBoundingBox">
<feImage result="pict2" xlink:href=""></feImage>
<feDisplacementMap scale=".05" xChannelSelector="R" yChannelSelector="R" in2="pict2" in="SourceGraphic">
<!-- 需要重複漣漪所以需要改能用透明度去互相覆蓋 -->
</feDisplacementMap>
</filter>
</defs>
</svg>
<div class="div" id="div">
<svg id="svg">
<!-- <g id="svgandg" filter="url(#f)">
<image id="Darwin" xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg">
</image>
<text id="text" x="0" y="150" style="font-size:50px;font-weight:900;"> How Are You </text>
</g> -->
</svg>
</div>
解决方案
几件事:
由于您使用xChannelSelector="R" yChannelSelector="R"
R 代表红色,因此渐变需要有一些红色。
您需要使用渐变填充 feImage 的矩形。
<svg>
<radialGradient id="g" cx=".6" cy=".6" r=".05" spreadMethod="reflect">
<stop offset="0" stop-color="#000"></stop>
<stop offset="1" stop-color="#f00"></stop>
</radialGradient>
<rect id="m1" width="410" height="300" fill="url(#g)"></rect>
</svg>
对于 feImage,您需要使用外部 svg,或者像我一样使用 data:uri。如果你想使用 data:uri 你可以使用这个svg-encoder
您将过滤器应用于图像。
我希望它有所帮助。
<svg width="340" height="231">
<filter id="f" >
<feImage result="pict1" xlink:href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3CradialGradient id='g' cx='.6' cy='.6' r='.05' spreadMethod='reflect'%3E%3Cstop offset='0' stop-color='%23000'%3E%3C/stop%3E%3Cstop offset='1' stop-color='%23f00'%3E%3C/stop%3E%3C/radialGradient%3E%3Crect id='m1' width='340' height='230' fill='url(%23g)'%3E%3C/rect%3E%3C/svg%3E" x="0" y="0" width="100%" height="100%"></feImage>
<feDisplacementMap scale="20" xChannelSelector="R" yChannelSelector="R" in2="pict1" in="SourceGraphic">
</feDisplacementMap>
</filter>
<image filter="url(#f)" width="100%" xlink:href="http://www.oxxostudio.tw/img/articles/201410/20141009_1_demo3.JPG"></image>
</svg>
推荐阅读
- javascript - .Net-Core 对象属性字符串(月/年)在 JS 中划分
- javascript - 在这种情况下,为什么我不能分配财产的价值?
- javascript - 如何重置选择元素,以便再次提示“需要”属性?
- javascript - 平面数组到树 Javascript
- javascript - 在 React 中导入数据
- android - android/react native:位图或图像视图
- c# - 如何在另一个脚本中调用对象的“移动”方法?统一
- autohotkey - 自动热键脚本,用于从 Doc 文件复制数据并使用应用程序或 chrome 浏览器通过电子邮件发送
- javascript - 当孩子具有混合混合模式和动画时,Chrome 上的 CSS 溢出隐藏问题
- python - 添加动画会减慢我在 Python 中的程序吗?