众所周知,B 站 是个适合学习的好网站,我们团队的小伙伴也是经常上 B站 学习。

某一天在 B站 学习的时候,发现 B站 已经开启了秋季主题,并且在头图的这个交互上还内有乾坤。随着我们的鼠标变换位置,头图也跟随着我们的鼠标位置进行变换,配上秋季主题,显得特别治愈。(如下图)


小编对这个交互也是挺感兴趣的,那接下来我们直接进入主题,来试着实现这种动画效果吧!

原理分析

我们先进行实现原理分析,打开控制台,可以发现这个效果是通过几个图层变换位置和高斯模糊来实现的(如下图)

image

除此之外,还有个小女孩的 眨眼 特效,是通过切换图片来实现的。所以我们实现的步骤分解为四步:

  1. 获取对应的图片;
  2. 将图片按照效果图,摆放在对应的位置,设置默认的高斯模糊;
  3. 通过切换图片制作 眨眼 特效;
  4. 根据鼠标位置切换图片位置和高斯模糊;

那我们遵循上面的步骤,开始制作吧!

获取图片

首先,我们打开控制台(F12),在控制台输入下面这行代码来获取图片。

var images = document.querySelectorAll(".animated-banner .layer img");var urlList = [].slice.call(images).map((item) => item.src);console.log(JSON.stringify(urlList, null, 2));

image

如上图所示,我们将这几张图片下载到自己的电脑中(如下图)

image

还有个动画轮播图,我们使用下面这行代码来获取不同的几张图片。

var animateImgList = [];setInterval(() => {  var imgSrc = document.querySelector(    ".animated-banner >.layer:nth-child(2) img"  ).src;  if (!animateImgList.includes(imgSrc)) {    console.log(imgSrc);    animateImgList.push(imgSrc);  }}, 200);

image

如上图所示,我们可以得到几张不同状态的图片,我们下载到自己的电脑里即可。

摆放图片

我们下载的几张图片都是 png 格式的,我们可以使用定位将其堆叠到一起。

直接新建一个 index.html,填充内容如下:

html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta name="viewport" content="width=device-width,initial-scale=1.0" />    <title>Documenttitle>  head>  <style>    * {margin: 0;padding: 0;    }.img-list {width: 100%;min-width: 1000px;height: 155px;position: relative;overflow: hidden;    }.img-list .layer {position: absolute;left: 0;top: 0;width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;    }style>  <body>    <section class="img-list">      <div class="layer">        <img width="3000" height="250" src="./assets/1.png" alt="" />      div>      <div class="layer">        <img width="1800" height="165" src="./assets/2_1.png" alt="" />      div>      <div class="layer">        <img width="3000" height="250" src="./assets/3.png" alt="" />      div>      <div class="layer">        <img width="1800" height="150" src="./assets/4.png" alt="" />      div>      <div class="layer">        <img width="1800" height="165" src="./assets/5.png" alt="" />      div>      <div class="layer">        <img width="1950" height="178" src="./assets/6.png" alt="" />      div>    section>  body>html>

上面做了简单的图片排列,实现的效果如下图所示:

image

从上图可以看出,我们将多张图片堆叠后,已经有初步的雏形了,接下来我们来设置默认的高斯模糊吧。

由于我们的位置偏移和高斯模糊在后面需要涉及到交互,所以我们直接使用 JS 进行设置,这里我们借助一下 Jquery,在 body 后引入 jquery,然后写入我们的 javascript 脚本(如下)。

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.10.0/jquery.js">script><script>const imgList = $(".img-list .layer img");// 默认的位置偏移与高斯模糊值const defaultStyles = [    { translateX: 0, translateY: 0, blur: 4 },    { translateX: 0, translateY: 0, blur: 0 },    { translateX: -50, translateY: 0, blur: 1 },    { translateX: 0, translateY: 4.2, blur: 4 },    { translateX: 0, translateY: -1.8, blur: 5 },    { translateX: 0, translateY: 0, blur: 6 },  ];function setDefaultImgStyle() {for (let i = 0; i       const imgItem = imgList[i];const defaultStyle = defaultStyles[i];const { translateX, translateY, blur } = defaultStyle;// 设置位置偏移以及高斯模糊      $(imgItem).css({// 位置偏移transform: `translate(${translateX}px, ${translateY}px)`,// 高斯模糊filter: `blur(${blur}px)`,      });    }  }  setDefaultImgStyle();script>

在设置好了位置偏移和高斯模糊后,我们的静态页面已经和效果图完全一致了(如下图)。

image

制作眨眼特效

我们的静态页面已经制作的差不多了,接下来我们来用 JS 简单实现 眨眼 特效吧。

这个比较简单,我们只需要设置一个定时器,每 3 秒切换一次图片集即可,代码实现如下:

function setShakeAnimation() {  // 第二张小女孩图片  const imgGirl = $(".img-list .layer:nth-child(2) img");

  // 每 3 秒眨一次眼睛  setInterval(() => {    // 半闭眼    $(imgGirl).attr("src", "./assets/2_2.png");

    // 100 毫秒后完全闭上眼眼睛    setTimeout(() => {      $(imgGirl).attr("src", "./assets/2_3.png");    }, 100);

    // 300 毫秒后半睁开眼睛    setTimeout(() => {      $(imgGirl).attr("src", "./assets/2_2.png");    }, 300);

    // 400 毫秒后完全睁开眼睛    setTimeout(() => {      $(imgGirl).attr("src", "./assets/2_1.png");    }, 400);  }, 3000);}setShakeAnimation();

然后,我们来看看我们的 眨眼 特效吧!(如下图)

image

如上图所示,我们的 眨眼 特效已经可以做到以假乱真啦!

动态交互

最后,我们来为我们的图层合集添加上交互效果吧!

我们从 B站 原有的交互中可以发现,当我们把鼠标放上去左右移动时,图片发生了位置和高斯模糊度的变化。所以我们先把鼠标移动的事件监听加上,代码实现如下:

// 屏幕宽度const width = document.body.clientWidth;// 鼠标进入的事件$(".img-list").mouseenter((e) => {  // 鼠标离开时解除事件监听,并重置状态  $(".img-list").mouseleave(() => {    setDefaultImgStyle();    $(".img-list").off("mousemove");    $(".img-list").off("mouseleave");  });

  // 鼠标进入时记录位置  const originalX = e.pageX;  $(".img-list").mousemove((e) => {    // 鼠标移动时记录位置    const currentX = e.pageX;    // 根据屏幕宽度和移动距离,计算移动的比例    const offsetRatio = (currentX - originalX) / width;    // 鼠标左移    if (offsetRatio 0) {      setLeftImgStyle(Math.abs(offsetRatio));      // 鼠标右移    } else {      setRightImgStyle(offsetRatio);    }  });});

接下来,我们经过大致测量一下后会发现,高斯模糊变化的效果如下表所示。

图片序号 初始值(高斯模糊值) 从最右侧到最左侧(高斯模糊值) 从最左侧到最右侧(高斯模糊值)
1 4 4 -> 0 4 -> 8
2 0 0 -> 10 0 -> 8
3 1 1 -> 5 1 -> 4
4 4 4 -> 13 4 -> 0 -> 4
5 5 5 -> 14 5 -> 0 -> 4
6 6 6 -> 12 6 -> 0

位置变化的效果如下表所示。

图片序号 初始值(X 轴位置) 从最右侧到最左侧(X 轴位置) 从最左侧到最右侧(X 轴位置)
1 0 0 0
2 0 -9 9
3 -50 -80 21
4 0 -36 35
5 0 -78 77
6 0 -97 96

根据上面两张表,我们就可以开始写代码啦,代码实现如下:

// 鼠标左移后的最终目标位置const leftStyles = [  {    translateX: 0,    translateY: 0,    blur: 0,  },  {    translateX: -9,    translateY: 0,    blur: 10,  },  {    translateX: -80,    translateY: 0,    blur: 5,  },  {    translateX: -36,    translateY: 4.2,    blur: 13,  },  {    translateX: -78,    translateY: -1.8,    blur: 14,  },  {    translateX: -97,    translateY: 0,    blur: 12,  },];

function setLeftImgStyle(offsetRatio) {  for (let i = 0; i     const imgItem = imgList[i];    const {      translateX: defaultTranslateX,      translateY: defaultTranslateY,      blur: defaultBlur,    } = defaultStyles[i];    const leftStyle = leftStyles[i];    // 根据移动比例计算最终坐标和高斯模糊值    const translateX =      (leftStyle.translateX - defaultTranslateX) * offsetRatio +      defaultTranslateX;    const blur = (leftStyle.blur - defaultBlur) * offsetRatio + defaultBlur;

    // 设置位置偏移以及高斯模糊    $(imgItem).css({      // 位置偏移      transform: `translate(${translateX}px, ${defaultTranslateY}px)`,      // 高斯模糊      filter: `blur(${blur}px)`,    });  }}

// 鼠标右移后的最终目标位置const rightStyles = [  {    translateX: 0,    translateY: 0,    blur: 8,  },  {    translateX: 9,    translateY: 0,    blur: 8,  },  {    translateX: 21,    translateY: 0,    blur: 4,  },  {    translateX: 35,    translateY: 4.2,    blur: [0, 4],  },  {    translateX: 77,    translateY: -1.8,    blur: [0, 4],  },  {    translateX: 96,    translateY: 0,    blur: 0,  },];

function setRightImgStyle(offsetRatio) {  for (let i = 0; i     const imgItem = imgList[i];    const {      translateX: defaultTranslateX,      translateY: defaultTranslateY,      blur: defaultBlur,    } = defaultStyles[i];    const rightStyle = rightStyles[i];    let rightBlur = rightStyle.blur;    let blur = defaultBlur;    // 根据移动比例计算最终坐标和高斯模糊值    const translateX =      (rightStyle.translateX - defaultTranslateX) * offsetRatio +      defaultTranslateX;    if (Array.isArray(rightBlur)) {      const targetBlur = offsetRatio 0.5 ? rightBlur[0] : rightBlur[1];      const ratio =        offsetRatio 0.5 ? offsetRatio * 2 : (offsetRatio - 0.5) * 2;      const currentBlur = offsetRatio 0.5 ? defaultBlur : rightBlur[0];      blur = (targetBlur - currentBlur) * ratio + currentBlur;    } else {      blur = (rightBlur - defaultBlur) * offsetRatio + defaultBlur;    }    // 设置位置偏移以及高斯模糊    $(imgItem).css({      // 位置偏移      transform: `translate(${translateX}px, ${defaultTranslateY}px)`,      // 高斯模糊      filter: `blur(${blur}px)`,    });  }}

在上面的代码实现中,我们在鼠标左移右移的过程中添加了图片位置偏移与高斯模糊值,最后我们实现的效果就和 B站 的原版很相近了!(如下图)

好了,大功告成啦!

总结

经过简单的步骤分析,我们将几张图片组合起来就模拟出了 B站 的秋季主题效果啦!

这个案例是在某次学习(发呆)的时候发现 B站 的秋季主题挺有意思的,这里分享出来给大家,用几张图片组合出这么一个创意交互,也是挺有趣的~

最后,附上 源码地址

转载自:https://github.com/a1029563229/blogs/blob/master/BestPractices/bilibili/Banner.md

html中如何设置几张图片在一个div里来回切换_从 B 站的秋季主题中学习 “图层组合动画”...相关推荐

  1. SSH中后台传到前台一个信息集合,tr td中怎么进行排列,类似在一个div里排列书籍...

    总觉得描述问题不对,这里详细说一下,就是把下面图片变成排列整齐,一行四个,多出来的两个排到下一行. 我问过群里的,给的答案都有些简介:1:后台排好了,前台循环出来: 2:前台直接循环,多出来的加< ...

  2. 在一个div里,列表样式图片进行float,实现水平排序

    <div class="xiangce"><ul> <li><a href="#"><img src=&q ...

  3. 前端获取div里面的标签_「HTML」什么是 HTML 中的 div 标签

    1:语法 2:作用 div 标签可以用来划分 HTML 结构,从而配合 CSS 来整体控制某一块的样式. div 标签是块级元素,它可用做组合其它 HTML 元素的容器. div 标签可以用作严格的组 ...

  4. html中单选按钮设置监听事件,浅谈监听单选框radio改变事件(和layui中单选按钮改变事件),单选框radio...

    浅谈监听单选框radio改变事件(和layui中单选按钮改变事件),单选框radio 若是只引用jquery的话,监听单选按钮改变事件如下: 男 女 $(document).ready(functio ...

  5. 如何获取元素在父级div里的位置_关于元素的浮动你了解多少

    首先,在介绍什么是浮动之前我们先介绍一下html中元素的普通流布局方式.在普通流中,元素是按照它在 HTML 中的出现的先后顺序自上而下依次排列布局的,在排列过程中所有的行内元素水平排列,直到当行被占 ...

  6. 如何获取元素在父级div里的位置_前端面试题--元素的BFC特性和实例

    1.BFC 是什么? Block Formatting Contexts 块级格式化上下文.(不懂? 没关系,后文有介绍.) 2.为什么需要BFC? 在传统布局中出现的问题需要一种统一的解决方案. 首 ...

  7. 大闹天竺里的机器人_在《大闹天竺》中哪一位演员是你喜欢的

    <大闹天竺>是由北京光线影业有限公司.霍尔果斯青春光线影业有限公司联合出品发行的动作喜剧电影,由王宝强执导,王宝强.白客.岳云鹏.柳岩领衔主演,林永健.马浴柯主演,陈佩斯.朱时茂.王祖蓝. ...

  8. java在一个类里实现存款_用Java编写一个简单的存款

    package desposit.money; public class DespositMoney { public static void main(String[] args) { Custom ...

  9. cad打印样式ctb丢失_CAD制图软件中如何设置CAD打印样式表(CTB)?

    在浩辰CAD制图软件中绘制完成图纸后经常需要将其打印出来,一般情况下是用CAD打印样式表来控制打印输出效果,最主要的是输出颜色和线宽,当然还包括其他一些细节效果.有些CAD制图初学入门者不知道如何设置 ...

最新文章

  1. java 获取utc,如何在Java 8中获取UTC + 0日期?
  2. 【Qt】使用sqlite3数据库时,主键自增和获取自增后的主键的
  3. backdrop-filter 和filter 写出高斯模糊效果 以及两者区别
  4. JQuery选中的对象和非选中的其他对象分别执行不同动作
  5. Oracle数据库常用技术
  6. 用DataTable.Merge()解决了一个排序问题
  7. 蔚来汽车回应“十四万元补胎”纠纷:车主未及时报案 除轮胎外底盘也严重受损...
  8. 记录开发移动端项目过程中的各种问题、插件及教程(不定时更新)
  9. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_1_IO概述(概念分类)...
  10. 2022年10 款最佳计算机视觉开源数据标注工具
  11. v-for中为何要使用key
  12. Log4j2-Log4j 2介绍及使用
  13. 植树问题java,云南省优秀多媒体育软件大赛公示.doc
  14. 路由器技术彻底解决路由器IP地址冲突问题
  15. delphi7中的局部变量和全局变量
  16. PicGo+Gitee(码云)搭建个人博客的免费图床
  17. linux环境查看cpu是否开启睿频
  18. 射线与圆、球相交检测
  19. 如何防范SQL注入 SQL注入测试
  20. BZOJ3590【状压DP】

热门文章

  1. Java的synchronized的使用_Java中synchronized的用法
  2. 双向链表的常用基本操作
  3. python实现输入三角形边长自动作图求面积案例
  4. MySQL5.7 安装(Redhat)
  5. ASP.NET状态管理之一(概括篇)
  6. 《scikit-learn》SVM(一)
  7. 漫步微积分二——微积分是什么
  8. 神经网络-损失函数是不是凸的
  9. 去哪儿-08-city-search
  10. Java多线程网络爬虫(时光网为例)