利用SVG滤镜实现水波倒影效果

2023-11-15

        SVG滤镜用来增加对SVG图形的特殊效果。多种滤镜巧妙结合起来可以实现很棒的视觉效果。下面利用svg的feTurbulence滤镜和feDisplacementMap来模拟真实的水波倒影特效。效果如下图

 代码并不复杂,首先设置两张图片:

<div class="container">
    <div class='wrap'>		
	<img src="./p.jpg"><br/>
    </div>
    <div class='wrap'>
	<img src="./p.jpg" class="reflect">		
    </div>
</div>

设置样式,将倒影图旋转,调整到合适的位置:

<style type="text/css">
	.reflect{
		transform:scaleY(-1);
		margin-top:-5px;
		filter:url(#displacementFilter);
	}
	.container {
		width: -moz-fit-content;
		width: fit-content;
		clip-path: inset(10px);
		background-color: #0E6CAA;
	}
</style>

重点是滤镜的样式:filter:url(#displacementFilter);

在文档中定义svg滤镜:

<svg width="0" height="0" style="posiotion:absolute;">
    <filter id="displacementFilter">
        <feTurbulence type="turbulence" baseFrequency="0.01 .1" numOctaves="1" result="turbulence" seed="53" />
        <feDisplacementMap in2="turbulence" in="SourceGraphic" scale="20" xChannelSelector="R" yChannelSelector="B" />
    </filter>
</svg>

此时,得到的效果是静态的 ,但已经得到了倒影的效果。

 下面通过设置动画让倒影波动起来,添加动画:

<script type="text/javascript">
	var img = document.querySelector("#displacementFilter feTurbulence");
	var frames = 0;
	var rad = Math.PI / 180;

	function AnimateBaseFrequency() {
		var bf = "0.01 .1";
		bfx = Number(bf.split(" ")[0]);
		bfy = Number(bf.split(" ")[1]);
		frames += .5
		bfx += 0.001 * Math.cos(frames * rad);
		bfy += 0.005 * Math.sin(frames * rad);
		bf = bfx.toString() + ' ' + bfy.toString();
		img.setAttributeNS(null, 'baseFrequency', bf);
		requestAnimationFrame(AnimateBaseFrequency);
	}
	window.requestAnimationFrame(AnimateBaseFrequency);
</script>

至此,整体效果达成。

        简短的代码实现了真实的水波效果,这主要归功于svg的强大滤镜功能。SVG滤镜用来增加对SVG图形的特殊效果。这里重点说说我们用到的两个滤镜feTurbulence和feDisplacementMap。

        feTurbulence滤镜

该滤镜利用 Perlin 噪声函数创建了一个图像。它实现了人造纹理比如说云纹、大理石纹的合成。除了svg滤镜的通用属性外,该滤镜支持5种专属属性的设置:

feTurbulence参数
属性 默认值 说明
baseFrequency 0 柏林噪波函数的基频参数
numOctaves 1 柏林噪波函数的八度音阶数。
seed 0 柏林澡波函数生成的伪随机数的开始数字。
stitchTiles noStitch 柏林噪波瓷砖在边界处的行为。
type turbulence 以噪声函数还是湍流函数执行过滤

以上参数看起来很抽象,我们通过示例来体验每个参数的作用:

baseFrequency

<svg viewBox="0 0 420 200" xmlns="http://www.w3.org/2000/svg">
  <filter id="noise1" x="0" y="0" width="100%" height="100%">
    <feTurbulence baseFrequency="0.025" />
  </filter>
  <filter id="noise2" x="0" y="0" width="100%" height="100%">
    <feTurbulence baseFrequency="0.05" />
  </filter>

  <rect x="0" y="0" width="200" height="200" style="filter: url(#noise1);" />
  <rect x="0" y="0" width="200" height="200" style="filter: url(#noise2); transform: translateX(220px);" />
</svg>

效果:

如果提供两个数字,第一个数字表示水平方向上的基频,第二个数字表示垂直方向上的基频。如果提供了一个数字,则该值同时用于x和y。不支持使用负值。

 numOctaves

当我们设置了这个属性之后,算法会在原来的噪声函数上叠加若干个频率不同的他自己,形成细节更加丰富的噪声,看一下numOctaves增加时的动态效果。倍频程是由其频率和振幅定义的噪声函数。湍流是通过增加频率和降低振幅来累积几个八度音阶而形成的。八度音阶越高,噪音看起来就越自然。

<svg viewBox="0 0 420 200" xmlns="http://www.w3.org/2000/svg">
  <filter id="noise1" x="0" y="0" width="100%" height="100%">
    <feTurbulence baseFrequency="0.025" numOctaves="1" />
  </filter>
  <filter id="noise2" x="0" y="0" width="100%" height="100%">
    <feTurbulence baseFrequency="0.025" numOctaves="3" />
  </filter>

  <rect x="0" y="0" width="200" height="200" style="filter: url(#noise1);" />
  <rect x="0" y="0" width="200" height="200" style="filter: url(#noise2); transform: translateX(220px);" />
</svg>

效果:

seed 

seed是种子的意思,这是每一个随机数算法都需要用到的一个输入,所有的伪随机数算法中,当输入的种子一样的时候,输出总是一致的。

stitchTiles

该属性定义了对平铺边界处实现平滑过渡,可选值为noStitch | stitch。

<svg viewBox="0 0 420 200" xmlns="http://www.w3.org/2000/svg">
  <filter id="noise1" x="0" y="0" width="100%" height="100%">
    <feTurbulence baseFrequency="0.025" stitchTiles="noStitch" />
  </filter>
  <filter id="noise2" x="0" y="0" width="100%" height="100%">
    <feTurbulence baseFrequency="0.025" stitchTiles="stitch" />
  </filter>

  <rect x="0" y="0" width="100" height="100" style="filter: url(#noise1);" />
  <rect x="0" y="0" width="100" height="100" style="filter: url(#noise1); transform: translate(100px, 0);" />
  <rect x="0" y="0" width="100" height="100" style="filter: url(#noise1); transform: translate(0, 100px);" />
  <rect x="0" y="0" width="100" height="100" style="filter: url(#noise1); transform: translate(100px, 100px);" />

  <rect x="0" y="0" width="100" height="100" style="filter: url(#noise2); transform: translate(220px, 0);" />
  <rect x="0" y="0" width="100" height="100" style="filter: url(#noise2); transform: translate(320px, 0);" />
  <rect x="0" y="0" width="100" height="100" style="filter: url(#noise2); transform: translate(220px, 100px);" />
  <rect x="0" y="0" width="100" height="100" style="filter: url(#noise2); transform: translate(320px, 100px);" />
</svg>

效果:

 type

可选值 fractalNoise | turbulence

turbulence是指将柏林函数进行合成时,只取函数的绝对值,合成后的函数在0处不可导,其图像会有一些尖锐效果,形似湍流。fractalNoise则是在原来的噪声中叠加白噪声,让最终的结果呈现出高斯模糊的效果。

feDisplacementMap滤镜

映射置换滤镜,该滤镜用来自图像中从in2 (en-US)到空间的像素值置换图像从in到空间的像素值。
 

属性 默认值 取值 说明
in SourceGraphic SourceGraphic | SourceAlpha | BackgroundImage | BackgroundAlpha | FillPaint | StrokePaint | 自定义的滤镜的原始引用 in 属性标识输入的源
in2  

第一个过滤器原语的源图形,否则为上一个过滤器原形的结果

SourceGraphic | SourceAlpha | BackgroundImage | BackgroundAlpha | FillPaint | StrokePaint | 自定义的滤镜的原始引用 in2属性标识给定过滤器原语的第二输入。它的工作原理与in属性完全相同。
scale 0 缩放比例 通常使用正数值处理,值越大,偏移越大
xChannelSelector A R | G | B | A 使用in2中的哪个颜色通道沿x轴置换像素。
yChannelSelector A R | G | B | A 属性指示使用in2中的哪个颜色通道沿y轴置换像素。

feDisplacementMap 是一个位置替换滤镜,就是改变元素和图形的像素位置的。遍历原图形的所有像素点,使用feDisplacementMap重新映射替换一个新的位置,形成一个新的图形。feDisplacementMap滤镜在业界的主流应用是对图形进行形变,扭曲。

P'(x,y) ← P( x + scale * (XC(x,y) - 0.5), y + scale * (YC(x,y) - 0.5))

  •  P'(x,y)指的是转换之后的x, y坐标。
  •  x + scale * (XC(x,y) - 0.5), y + scale * (YC(x,y) - 0.5)指的是具体的转换规则。
  •  XC(x,y)表示当前x,y坐标像素点其X轴方向上设置的对应通道的计算值,范围是0~1。
  •  YC(x,y)表示当前x,y坐标像素点其Y轴方向上设置的对应通道的计算值,范围是0~1。
  •  -0.5是偏移值,因此XC(x,y) - 0.5范围是-0.5~0.5YC(x,y) - 0.5范围也是-0.5~0.5
  •  scale表示计算后的偏移值相乘的比例,scale越大,则偏移越大。

 简单讲就是根据设定的通道颜色对原图的x, y坐标进行偏移。

最后,欢迎小伙伴关注:

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用SVG滤镜实现水波倒影效果 的相关文章

  • 如何修复“没有这样的文件或目录,lstat 'scss/'”?

    我正在尝试遵循 youtube 上的简单教程他尝试使用终端运行 npm 脚本 sass 文件 当我执行命令时npm 运行 sass显示错误消息错误 ENOENT 没有这样的文件或目录 lstat scss 我认为问题在于文件的路径或文件的权
  • 如何保留用户的输入打印?

    我正在尝试添加用户的评论 所以我只是尝试读取输入并将其发送以进行打印 但问题是 一旦我刷新页面或输入另一个输入 打印的输入就会消失 因此 即使刷新页面或重新输入新评论 我也希望始终保持所有用户的显示 代码 div div
  • html 电子邮件内的背景图像 css - Gmail 不支持

    我想向我的用户发送如下所示的带有背景图像 css 的 html 正文电子邮件 div style width 500px height 1000px background color black background image none
  • div 中的中心文本?

    我有一个div 30px高和500px宽的 这div可以包含两行文本 一行在一行 并相应地设置样式 填充 但有时它只包含一行 我希望它居中 这可能吗 要水平居中 请使用text align center 要垂直居中 只能使用vertical
  • 滚动时的 CSS 背景模糊

    我有固定的背景图像 滚动时我希望图像变得模糊 我知道如何在 css 中进行模糊 但在特定的滚动位置进行 这是一个例子 https medium com good music f160ba9e6c52 https medium com goo
  • 如何在Yii框架中向Form添加类?

    我在 Yii 中有一个表单 我想向该表单添加一个类
  • 如何使用javascript确保元素仅在圆上朝一个方向移动?

    好吧 我承认我对三角学真的很糟糕 出于上下文的考虑 我将添加我在这里提到的问题中的内容 参考问题 https stackoverflow com a 39429290 168492 https stackoverflow com a 394
  • 删除 IE9 边缘周围的 2px 灰色边框

    我正在尝试对这个网站进行编码 尝试关键字 并且我正在尝试找出如何删除这个阴影2px灰色边框延伸到 IE9 窗口的内部 至少顶部 左侧和底部 我的边距设置为零 因此所有页面元素都到达页面的最边缘 但使用 IE9 它们会停在这个灰色边框处 我没
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 使用 CSS 的响应式图像

    我发现调整图像大小以使其具有响应能力很棘手 我正在开发一个 php 应用程序来自动将网站转换为响应式版本 我有点被图像困住了 我已经成功地为网站上的每个图像添加了一个包装类 并且可以很好地调整图像的大小 我的问题在于自然小于窗口的图像 例如
  • 使用 CSS 折叠和展开元素

    我正在尝试构建一个页面 加载时仅可见标题 并且 当用户单击标题时 每个标题下方的表格会在隐藏和显示状态之间切换 我的限制是只能在 CSS 中执行此操作 这是我到目前为止想到的 https jsfiddle net Argoron c1ypx
  • 主页(网格)上的缩略图现在显得模糊。如何纠正?

    我不知道这看起来是否愚蠢 但从早上开始我就无法纠正这个突然出现在我的博客网站上的错误www candidopinions in http www candidopinions in 我有一个网格视图模板 其中博客文章中的特色图像作为调整大小
  • 将 SVG 的高度设置为行高?

    我想将我的 SVG 图像作为图标包含在标题旁边 h1 img src icon sell svg class icon Verkaufen h1 字体大小为h1 is 36px和line heigt is 1 1 我使用检查器工具发现计算出
  • Chrome:当父级固定时,无法将一个绝对 div 放置在另一个 div 上

    我发现 当我想要位于顶部的 div 的父级固定时 我无法将一个绝对定位的 div 放置在 Chrome 中的另一个 div 上 div div div div div div 这是演示该问题的 JSFiddle http jsfiddle
  • 如何为 HTML 元素创建鼠标拖动滑块?

    我发现的许多滑块插件要么仅单击以查看下一个图像 要么如果它们确实具有鼠标拖动或触摸拖动功能 则仅允许图像 有谁知道为任何 html 元素编写鼠标拖动滑块的插件或可能的方法 我专门使用 SVG 但将来如果能在 div 元素之间滑动就更好了 H
  • 在 React 中切换 css 类

    如何使用布尔值切换 React 中元素上 css 类的存在 在 Angular 2 中我可以这样做 class red isRed 如何在 React 中做熟悉的事情 在 React 中 元素使用如下语法获取它们的类 div div 但请注
  • 如何在不使用变换或顶部/左侧的情况下转换列表中项目的位置

    有一天我偶然发现一个例子 https codepen io itslit pen gvKrMY它使用 Vue js 但我的问题更多是关于 Vue 用于实现状态之间转换的 CSS 和 HTML 卡片暂时获得等级 shuffleMedium m
  • 为 Angular2 中的组件加载多个样式表

    我正在构建一个 angular2 应用程序 当我尝试为同一组件加载多个样式表时 我面临多个问题 这是我正在做的代码 import Component from angular core Component selector my tag t
  • 如何选择具有“A”类但不具有“B”类的 div?

    我有一些 div div class A Target div div class A B NotMyTarget div div class A C NotMyTarget div div class A D NotMyTarget di
  • 如何创建适合屏幕宽度的等宽/高框? [复制]

    这个问题在这里已经有答案了 我正在尝试建立一个网站 其中有很多宽度和高度相等的框 例如 我有一个页面 其中并排有两个相同大小的框 简单的解决方案是将宽度和高度设置为 50vw 这在出现滚动条之前效果很好 我已经用谷歌搜索了几个小时 但无法理

随机推荐

  • 使用cloudflare tunnel免费内网穿透,实现网站的外网访问和远程桌面

    前言 Cloudflare Tunnel是Cloudflare Zero Trust中的一个产品 它能够帮助用户将位于内网中的服务暴露到公网上 从而使得外部用户可以通过互联网访问这些服务 相比较于frp ngrok等内网穿透工具 使用Clo
  • 人工智能数学基础--概率与统计9:概率运算、加法公理、事件的独立性、概率乘法定理、条件概率、全概率公式以及贝叶斯公式

    一 概述 这大半年都很忙 学习时间太少 导致概率论的学习停滞不前 期间AI大佬herosunly推荐了陈希孺老先生的概率论教材 与最开始学习的美版M R 斯皮格尔等著作的 概率与统计 表示差异比较大 具体请见 人工智能数学基础 概率与统计7
  • ESP32-IDF环境搭建以及使用

    1默认已经安装了esp32 idf和vscode配置 离线版的esp32idf安装 windows eap32安装这里参考博客ESP32c3开发环境搭建 IDF V4 4离线版安装使用 esp idf v4 4 2 可能会遇到的问题 问题篇
  • 修改elementUI样式未生效问题(挂载到了body标签上)

    修改挂载到body标签上elementUI样式问题 目录 修改挂载到body标签上elementUI样式问题 前言 一 适用范围 二 示例 1 目标 2 实现思路 修改自带样式方法 最后看效果 总结 前言 在使用element ui库的时候
  • Aspose.Slides for Java Crack

    Aspose Slides for Java Crack Added support for changing the color of leader lines in pie charts Added new AfterAnimation
  • 2012年终总结 - I T征途

    2012年终总结 I T征途 在2012年年初的时候 自己曾写了一个规划 2012 这一年我该做些啥 里面简单的介绍了一下2012年 我应该做的事儿 如今到了为2012结账的时候 我想借助那篇文档来总结这一年我的所作所为 2012年 我该给
  • 用Sipp 对Asterisk 进行性能测试的工作笔记-1

    公司需要 对Asterisk 进行一定的性能测试 测试目标 1 IVR 支持多少路2 一对一通话 支持多少路3 不同编解码的性能影响 4 通话中 录音 支持多少路 测试工具 sipp http sipp sourceforge net 辅助
  • createrepo:创建本地源

    4月20日 createrepo 创建本地源 repodata作为软件的仓库 其目录下有四个必要文件 filelists xml gz other xml gz primary xml gz 和repomd xml md 意思是 metad
  • IDEA 中 .properties文件的中文显示乱码问题的解决办法

    今天使用IDEA 搭建Spring Boot 项目 配置application properties 配置文件 录入中文 在右下角出现如下截图提示语 重新打开application properties 文件出现汉字乱码 依据提示信息修改源
  • “你爱我,我爱你,蜜雪冰城甜蜜蜜“秋天的第一杯奶茶!Python安排!!

    立秋了 大家秋天的第一杯奶茶都安排上了么 前一段时间我相信很多人都被 你爱我 我爱你 蜜雪冰城甜蜜蜜 这首歌洗脑了 所以今天就爬取了某度地图上蜜雪冰城门店分布 看看全国有多少家蜜雪冰城 能不能满足大家的需求啦 哈哈哈 数据采集 首先 我们打
  • Linux部署宝塔

    1 linux服务器安装宝塔 宝塔地址 https www bt cn new download html 点击上方地址 进入下方页面 点击安装版本 复制第一个命令 得确认你服务器是centos 远程连接服务器 复制此命令运行 运行成功后
  • [CISCN2019 华东南赛区]Web11 SSTI

    这道SSTI 差点给我渗透的感觉了 全是API 我还想去访问API看看 发现这里读取了我们的ip 我们抓包看看是如何做到的 没有东西 我们看看还有什么提示 欸 那我们可不可以直接修改参数呢 我们传递看看 发现成功了 是受控的 这里我就开始没
  • mysql某批量更新导致死锁

    查询当前数据库全部线程 show full processlist 查询当前运行的全部事务 select from information schema innodb trx 查询锁情况 select from information sc
  • 碰撞改变材质颜色_bp

    感谢来自程序员的暴击 学习资料来于 https www bilibili com video BV125411h7c4 p 22 最大的收获是 材质编辑器上 1维向量到4维向量的生成 会者不难 难者不会 方法很简单 鼠标左键 数字1就会生成
  • 2023年电赛E题完整设计暨电赛全记录

    目录 一 2023年E题完整设计 lt 1 gt 选择方案 任务一 实现按键按下复位 基础部分 任务二 实现激光点绕边框一周 基础部分 任务三 实现激光点绕A4纸边缘一周 基础部分 任务四 实现绿色激光追踪红色激光 发挥部分 lt 2 gt
  • 【信号与系统】傅里叶变换

    傅里叶变换 文章目录 傅里叶变换 傅里叶级数 基本公式 常用公式 基本性质 其他公式 卷积公式 周期信号的傅里叶变换 抽样信号的傅里叶变换 提供延时的理想滤波器 无失真传输 傅里叶级数 https blog csdn net lafea a
  • 【Flink】Flink 消费kafka报错 AMRMClientAsyncImpl Interrupted while waiting for queue InterruptedException

    1 背景 一个flink etl程序 读取一个kafka集群的数据 到两外一个集群 然后报错 2020 06 06 15 56 00 PM Thread flink akka actor default dispatcher 20 Clas
  • redis缓存一致性延时双删代码实现

    不废话 如下 1 自定义注解 author caoyue 延时双删 Retention RetentionPolicy RUNTIME Documented Target ElementType METHOD public interfac
  • shell脚本判断变量是否包含某个字符串的几种方法

    方法一 利用grep查找 strA long string strB string result echo strA grep strB if result then echo 包含 else echo 不包含 fi 先打印长字符串 然后在
  • 利用SVG滤镜实现水波倒影效果

    SVG滤镜用来增加对SVG图形的特殊效果 多种滤镜巧妙结合起来可以实现很棒的视觉效果 下面利用svg的feTurbulence滤镜和feDisplacementMap来模拟真实的水波倒影特效 效果如下图 代码并不复杂 首先设置两张图片 di