大家好,咱们是明源云前端团队。
家喻户晓,B 站 是个适宜学习的好网站,咱们团队的小伙伴也是常常上 B 站
学习。
某一天在 B 站
学习的时候,发现 B 站
曾经开启了秋季主题,并且在头图的这个交互上还内有乾坤。随着咱们的鼠标变换位置,头图也跟随着咱们的鼠标地位进行变换,配上秋季主题,显得特地治愈。(如下图)
小编对这个交互也是挺感兴趣的,那接下来咱们间接进入主题,来试着实现这种动画成果吧!
原理剖析
咱们先进行实现原理剖析,关上控制台,能够发现这个成果是通过几个图层变换位置和高斯含糊来实现的(如下图)
除此之外,还有个小女孩的 眨眼
特效,是通过切换图片来实现的。所以咱们实现的步骤合成为四步:
- 获取对应的图片;
- 将图片依照效果图,摆放在对应的地位,设置默认的高斯含糊;
- 通过切换图片制作
眨眼
特效; - 依据鼠标地位切换图片地位和高斯含糊;
那咱们遵循下面的步骤,开始制作吧!
获取图片
首先,咱们关上控制台(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));
如上图所示,咱们将这几张图片下载到本人的电脑中(如下图)
还有个动画轮播图,咱们应用上面这行代码来获取不同的几张图片。
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);
如上图所示,咱们能够失去几张不同状态的图片,咱们下载到本人的电脑里即可。
摆放图片
咱们下载的几张图片都是 png
格局的,咱们能够应用定位将其重叠到一起。
间接新建一个 index.html
,填充内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Document</title>
</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">
![](./assets/1.png)
</div>
<div class="layer">
![](./assets/2_1.png)
</div>
<div class="layer">
![](./assets/3.png)
</div>
<div class="layer">
![](./assets/4.png)
</div>
<div class="layer">
![](./assets/5.png)
</div>
<div class="layer">
![](./assets/6.png)
</div>
</section>
</body>
</html>
下面做了简略的图片排列,实现的成果如下图所示:
从上图能够看出,咱们将多张图片重叠后,曾经有初步的雏形了,接下来咱们来设置默认的高斯含糊吧。
因为咱们的地位偏移和高斯含糊在前面须要波及到交互,所以咱们间接应用 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 < imgList.length; 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>
在设置好了地位偏移和高斯含糊后,咱们的动态页面曾经和效果图完全一致了(如下图)。
制作眨眼特效
咱们的动态页面曾经制作的差不多了,接下来咱们来用 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();
而后,咱们来看看咱们的 眨眼
特效吧!(如下图)
如上图所示,咱们的 眨眼
特效曾经能够做到以假乱真啦!
动静交互
最初,咱们来为咱们的图层合集增加上交互成果吧!
咱们从 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 < imgList.length; 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 < imgList.length; 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 站
的秋季主题挺有意思的,这里分享进去给大家,用几张图片组合出这么一个创意交互,也是挺乏味的~
求贤若渴
明源云链前端团队是个充斥激情的团队,明源云也是对技术非常重视的公司。
咱们有欠缺的福利:六险一金 +(丰富)年终奖 + 带薪休假 + 通信补贴
咱们的工作气氛:弹性工作,扁平构造,崇尚以解决问题为外围、简略高效的互联网文化,激励技术创新分享,每年举办黑客马拉松(最高奖 3W 奖金)、极客大赛、挪动社群等技术性赛事
咱们有人文关心:花式下午茶(每周都有)、生日礼金、收费游览、流动经费、结婚礼金、收费体检
咱们还有丰盛的业余社团活动:篮球、足球、瑜伽、羽毛球、台球、棋牌赛
咱们招聘的岗位有:(中高级)前端工程师
、(中高级)测试工程师
、(中高级)Java 工程师
、(中高级)PHP 工程师
。
Base:深圳
、 武汉
。
欢送投递简历到邮箱 lit31@mingyuanyun.com
,或者增加上面微信备注 明源云
进行征询吧!