经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » CSS3 » 查看文章
【动画进阶】神奇的卡片 Hover 效果与 Blur 的特性探究
来源:cnblogs  作者:ChokCoco  时间:2024/8/19 15:47:19  对本文有异议

本文,我们将一起探讨探讨,如下所示的一个卡片 Hover 动画,应该如何实现:

这个效果的几个难点:

  1. 鼠标移动的过程中,展示当前卡片边缘的 border 以及发光效果;

效果只出现在鼠标附近?这一块的实现方法就有很多种了,可以计算鼠标附近的范围,在范围内去实现的效果,但是这样成本太高了。

转换一下思维,其实也可以利用遮罩的思想。在一开始就已经实现好了整体效果,也就是渐变色的整个边框以及整体的内发光效果,通过遮罩的思想,让整个遮罩层跟随鼠标进行移动。

  1. 整体的效果需要适配鼠标的移动,跟随鼠标移动,进行效果的切换;

基于上述动图中,到目前为止,纯 CSS 在鼠标移动效果跟随上,是没法解决的,这里需要引入一定量的 Javascript 代码。

基于上述难点(1)(2),下面我们就一起看看如何一步一步实现这个效果。

搭建整个静态效果

首先,我们需要搭建整个静态效果。也就是在没任何 hover 的状态下的效果,如下所示:

由于,每张图背后的虚化图效果,应该是基于图片不同而千图千面,因此,不可能能够用一张背景图 Cover 所有情况。

并且,图片背后的虚化图的效果,需要与实际图片的颜色保持大致一致。

基于上述两点,我们很容易想到使用 filter: blur() 模糊来处理此类情况。

代码也比较简单:

  1. <div></div>
  1. :root {
  2. --pic: url("https://oss.aiyuzhou8.com/2023/05/08-.jpg");
  3. }
  4. div {
  5. position: relative;
  6. margin: auto;
  7. width: 350px;
  8. height: 500px;
  9. border-radius: 30px;
  10. overflow: hidden;
  11. &::before,
  12. &::after {
  13. content: "";
  14. position: absolute;
  15. background: var(--pic);
  16. background-size: cover;
  17. background-position: center;
  18. border-radius: 30px;
  19. }
  20. &::before {
  21. inset: 0;
  22. filter: blur(20px);
  23. }
  24. &::after {
  25. inset: 50px;
  26. }
  27. }

这里,我们用元素的一层伪元素实现原图,另外一层伪元素实现虚化后的图片:

这种好处是,背后的虚化图层,可以适配任意的不同图片:

实现渐变色边框

接下来,我们需要实现渐变色的边框效果。

这个需要借助 conic-gradient 实现。

我们需要借助另外一个 div 实现我们的效果:

  1. <div></div>
  1. div {
  2. width: 350px;
  3. height: 500px;
  4. border-radius: 30px;
  5. background: conic-gradient(#03a9f4, #e91e63, #9c27b0, #ff5722, #03a9f4);
  6. }

这样,我们就得到了一个这样的图形:

把它叠加到我们上述的效果之上,让整个图形,稍微比上述虚化背景大一点点即可,如此一来,效果就变成了这样:

仔细看,图片带上了渐变色的边框。

等等,再仔细看!除了渐变色边框之外,当前的效果,居然还自带了内发光(内阴影)效果,真是歪打正着,这不正是我们需要实现的吗:

探究 filter: blur() 的透明效果

这是为何呢?原因在于,设置了 filter: blur() 的元素,会从边缘处向中心处,带有透明衰减的效果。

我们简单来做个实验:

  1. <div></div>
  2. <div></div>
  1. div {
  2. position: relative;
  3. width: 200px;
  4. height: 300px;
  5. border-radius: 10px;
  6. border: 1px solid #000;
  7. background: conic-gradient(#03a9f4, #e91e63, #9c27b0, #ff5722, #03a9f4);
  8. &::before {
  9. content: "";
  10. position: absolute;
  11. inset: 10px;
  12. border-radius: 10px;
  13. background: #fff;
  14. border: 1px solid #000;
  15. }
  16. }

我们设置了两个一模一样的 div,其中,元素本身设置了一个角向渐变背景。

接着,利用其伪元素,在元素中间相距边界 10px 的地方,设置一个背景为白色的元素。效果如下:

此时此刻,两个元素没有任何不一样。但是接下来,我们给第二个元素的伪元素,添加上一个 filter: blur() 高斯模糊效果:

  1. div:nth-child(2) {
  2. &::before {
  3. filter: blur(20px);
  4. }
  5. }

此时,再看看效果:

在白色元素的边缘处,向内的方向,其实是有逐渐减弱的透明效果。

当然,由于高斯模糊还会产生向外扩散的效果,因此上述 DEMO 示意图看起来不是很清晰,我们可以通过多套一层容器,通过 overflow: hidden 阻止高斯模糊的向外扩散。

我们再调整一下布局:

  1. <div class="g-father">
  2. <div class="g-child"></div>
  3. </div>
  4. <div class="g-father">
  5. <div class="g-child"></div>
  6. </div>
  1. .g-father {
  2. position: relative;
  3. width: 200px;
  4. height: 300px;
  5. border-radius: 10px;
  6. border: 1px solid #000;
  7. background: conic-gradient(#03a9f4, #e91e63, #9c27b0, #ff5722, #03a9f4);
  8. .g-child {
  9. position: absolute;
  10. inset: 10px;
  11. border-radius: 10px;
  12. border: 1px solid #000;
  13. overflow: hidden;
  14. &::before {
  15. content: "";
  16. position: absolute;
  17. inset: 0;
  18. background: #fff;
  19. border-radius: 10px;
  20. }
  21. }
  22. }
  23. .g-father:nth-child(2) {
  24. .g-child::before {
  25. filter: blur(20px);
  26. }
  27. }

此时,我们再看整个效果,设置了 filter: blur() 的元素,会从边缘处向中心处,带有透明衰减的效果就非常明显了:

完整的 DEMO,你可以戳这里:CodePen Demo -- filter: blur 透明效果示意

鼠标移动事件监听配合 mask,实现整体效果

好,到这里,我们已经成功得到了这么一个效果:

基于上述效果,我们最后要做的,就是最终实现这么个效果:

这里,我们会利用鼠标移动事件监听配合 mask 来实现。

由于我们上述的效果是分层实现的,其中边框和内发光层,其实是这么个背景效果:

我们要做的就是:

  1. 利用 radial-gradient() 实现一个径向渐变 mask 遮罩;
  2. 监听鼠标移动事件,移动 mask 遮罩的中心点;
  3. 可以通过多设置一层,实现 Hover 时背景角向渐变元素才出现,鼠标离开元素区域,背景角向渐变元素消失;

大致代码如下:

  1. <div id="g-container">
  2. <div id="g-img"></div>
  3. </div>
  1. :root {
  2. --x: 0;
  3. --y: 0;
  4. }
  5. #g-container {
  6. position: relative;
  7. width: 350px;
  8. height: 500px;
  9. border-radius: 30px;
  10. }
  11. #g-img {
  12. position: absolute;
  13. inset: 0px;
  14. border-radius: 30px;
  15. background: conic-gradient(#03a9f4, #e91e63, #9c27b0, #ff5722, #03a9f4);
  16. mask: radial-gradient(
  17. circle at var(--x) var(--y),
  18. #000,
  19. #000,
  20. transparent,
  21. transparent,
  22. transparent
  23. );
  24. }
  1. const container = document.getElementById("g-container");
  2. const img = document.getElementById("g-img");
  3. container.addEventListener("mousemove", (event) => {
  4. img.style.visibility = 'visible';
  5. const target = event.target;
  6. const rect = target.getBoundingClientRect();
  7. var offsetX = event.clientX - rect.left;
  8. var offsetY = event.clientY - rect.top;
  9. var percentX = (Math.min(Math.max(offsetX / rect.width, 0), 1) * 100).toFixed(2);
  10. var percentY = (Math.min(Math.max(offsetY / rect.height, 0), 1) * 100).toFixed(2);;
  11. console.log('X: ' + percentX + '%');
  12. console.log('Y: ' + percentY + '%');
  13. container.setAttribute('style', `--x: ${percentX}%;--y: ${percentY}%;`);
  14. });
  15. container.addEventListener("mouseout", (event) => {
  16. img.style.visibility = 'hidden';
  17. });

在图形上方移动鼠标,我们可以得到这么一个效果:

好,将上述的前面两个图层也合并进来,这样,我们就最终完美的实现了我们想要的效果:

完整的代码散落在上方,就不重复贴影响阅读体验了,感兴趣的同学,可以戳这里获取完整 DEMO 效果及源码:

CodePen Demo -- CSS 3D Rotate With Mouse Move DEMO

最后

好了,本文到此结束,希望本文对你有所帮助 ??

想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 -- iCSS前端趣闻 ??

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

原文链接:https://www.cnblogs.com/coco1s/p/18358267

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号