欢迎光临散文网 会员登陆 & 注册

使用前端技术实现静态图片局部流动效果

2023-04-18 19:14 作者:unlexx  | 我要投稿

声明:本文涉及图文和模型素材仅用于个人学习、研究和欣赏,请勿二次修改、非法传播、转载、出版、商用、及进行其他获利行为。

背景

如果你有玩过 🎮 《王者荣耀》《阴阳师》 等手游,一定注意到过它的启动动画、皮肤立绘卡片等场景,经常采用静态底图加局部液态流动效果的简单动画,这些流动动画可能出现在缓缓流动的水流 🌊、迎风飘动的旗帜 🎏、游戏角色衣袖 🧜‍♀️、随着时间缓动的云、雨、雾天气效果  等。这种过渡效果不仅节省了开发全量动画的成本,而且使得游戏画面更加热血、冒险、奥德赛、高级,也更加容易吸引玩家氪金 💰

本文使用前端开发技术,结合 SVG 和 CSS 来实现类似的液化流动效果。本文包含的知识点主要包括:mask-image 遮罩、feTurbulence 和 feDisplacementMap 滤镜、filter 属性、canvas 绘制方法、TimelineMax 动画以及input[type=file] 本地图片资源加载等。


封面图动态流动效果

效果

先来看看实现效果,下面几个示例以及 👆 文章 Banner 图都是应用了由本文内容生成的液态流动动画效果。由于GIF 图压缩比较严重,动画效果看起来不是很流畅 🙃,大家不妨通过以下演示页面链接,亲自体验一下效果,生成自己的 传说典藏 皮肤立绘吧 😅

  • 👁‍🗨 在线体验:https://dragonir.github.io/paint-heat-map/

  • 👁‍🗨 在线体验:https://codepen.io/dragonir/full/qBoxQKW

🌀 雾气扩散 塞尔达传说:旷野之息


💃 衣袖飘动 貂蝉:猫影幻舞

🌅 湖光波动

🔠 文字液化

📌 ps:体验页面部署在 Gitpage 上传图片功能不是真正上传到服务器,而是只会加载到浏览器本地,页面不会获取任何信息,大家可以放心体验,不用担心隐私泄漏问题。

实现

页面主要由 2 部分构成,顶部用于加载图片 ,并且可以通过按住 🖱 鼠标划动的方式绘制热点路径,给图片添加流动效果;底部是控制区域,点击按钮 🔘 清除画布,可以清除绘制的流动动画效果、点击按钮 🔘 切换图片可以加载本地的图片。

📌 注意,还有一个隐形的功能,当你绘制完成时,可以点击 🖱 鼠标右键,然后选择保存图片,保存的这张图片就是我们绘制流体动画路径的热点图,利用这张热点图,使用本文的 CSS 知识,就能把静态图片转化成动态图啦!

HTML 页面结构

#sketch 元素主要是用于绘制和加载流动效果热点图的画板;#button_container 是页面底部的按钮控制区域;svg 元素用于利用其 filter 滤镜实现液态流动动画效果,包括 feTurbulence 和 feDisplacementMap 滤镜。

💡 feTurbulence 和 feDisplacementMap

  • feTurbulence:滤镜利用 Perlin 噪声函数创建了一个图像,利用它可以实现人造纹理比如说云纹、大理石纹等模拟滤镜效果。

  • feDisplacementMap:映射置换滤镜,该滤镜用来自图像中从 in2 到空间的像素值置换图像从 in 到空间的像素值。即它可以改变元素和图形的像素位置,通过遍历原图形的所有像素点,feDisplacementMap 重新映射替换一个新的位置,形成一个新的图形。该滤镜在业界的主流应用是对图形进行形变,扭曲,液化。

CSS 样式

接着看看样式的实现,main 元素作为主容器并将主图案作为背景图片;canvas 作为画布占据 100% 的空间位置;.mask 和 .mask-inner 用于生成如下图所示热点路径与背景图相溶的效果,这种效果是借助 mask-image 实现的。最后,为了生成动态流动效果,.mask-inner 通过 filter: url(#heat) 将前面生成的 svg 作为滤镜来源,后续即将在 JavaScript 中通过不间断修改 svg 滤镜的属性,来生成液态流动动画。

💡 mask-image

mask-image CSS 属性用于设置元素上遮罩层的图像。

语法

兼容性

 此功能某些浏览器尚在开发中,需要使用浏览器前缀以兼容不同浏览器。

JavaScript 方法

① 绘制热点图

监听鼠标移动和点击事件,在 canvas 上绘制波动路径热点。

绘制完成后,可以在页面中右键保存生成的波动路径热点图,直接将绘制满意的热点图放到 CSS 中,就能给喜欢的图片添加局部波动效果了,下面这张图片就是本示例页面使用的波动的热点路径图。

② 生成动画

为了生成实时更新的波动效果,本文使用了 TweenMax 来通过改变 feTurbulence 的 baseFrequency 属性值来实现,使用其他动画库或使用 requestAnimationFrame 也是可以实现相同的功能。

③ 清除画布

点击清除画布按钮,可以清空已经绘制的波动路径,主要是通过清除页面元素 mask-image 的属性值以及清 canvas 画布来实现的。

④ 切换图片

点击切换图片,可以加载本地的一张图片作为绘制底图,该功能是通过 input[type=file] 来实现图片资源的获取,然后通过修改 CSS 将它设置成新的画布背景。

到这里,全部功能都实现完毕了,大家赶快制作一张自己喜欢的 史诗皮肤 或 奥德赛小游戏 的启动页面吧 🤣

📥 源码地址:https://github.com/dragonir/paint-heat-map

总结

本文包含的新知识点主要包括:

  • mask-image 遮罩元素

  • feTurbulence 和 feDisplacementMap svg滤镜

  • filter 属性

  • Canvas 绘制方法

  • TimelineMax 动画

  • input[type=file] 本地图片资源加载

想了解其他前端知识或其他未在本文中详细描述的 Web 3D 开发技术相关知识,可阅读我往期的文章。转载请注明原文地址和作者。如果觉得文章对你有帮助,不要忘了一键三连哦 👍

参考

  • [1]. https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/feTurbulence

  • [2]. https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/feDisplacementMap

  • [3]. https://developer.mozilla.org/zh-CN/docs/Web/CSS/mask-image

  • [4]. https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter


使用前端技术实现静态图片局部流动效果的评论 (共 条)

分享到微博请遵守国家法律