原文地址:http://icaoguo.com/2018/12/04/bilibili%E8%A7%86%E9%A2%91%E9%A2%84%E8%A7%88%E5%89%8D%E7%AB%AF%E5%AE%9E%E6%88%98%E6%95%99%E7%A8%8B/
哈喽大家好,我是挂面。
今天在逛B站的时候发现一个听炫酷的效果——视频预览。
如果常常上各大视频网址的朋友应该会看到各种不同的预览策略,有优酷、A站那种播放其中一小段视频的,也有油管那种播放好几段小视频的,但我个人还是比较喜欢B站这种不用点进视频就可以看到其中更多信息的设计,也是非常佩服B站产品经理们的脑洞。
我们先来看看效果。
![](https://img.haomeiwen.com/i3914863/e5f23fa4b43d4135.gif)
具体的代码我已经实现过一遍了,给大家看看我做的效果。
![](https://img.haomeiwen.com/i3914863/f967d68e66733af0.gif)
代码我放在文章最后了,想要的同学可以去拿走。
如果你想直到它的实现原理,可以接着往下看。
在首页随机找到一个视频,然后点击右键——检查。
观察代码可以看到,此处有一个类似图片的地址,我们右键open in new tab。
![](https://img.haomeiwen.com/i3914863/d869303c588f219f.png)
可以看到,这里面的图片就是刚刚鼠标放上去时候出现的那些预览图。
![](https://img.haomeiwen.com/i3914863/f39ad2119120582c.png)
###
这里我们可以推断出,单个视频的所有预览图都存在于一张图片之上,通过鼠标在目标上的位置移动,修改bakcground-position这个css属性的参数,实现预览效果。
###
不知道大家看懂了没有呢?
没看懂的童鞋请多看几遍,如果还是没看懂可以在评论区留言,我会详细解答。
接下来我来讲讲实现的思路。
1、建立事件委托,获取鼠标在目标上的位置。
2、修改目标的bakcground-position到对应的位置。
具体实现:
1、我们先需要一个简单的组图
2、然后给它们绑定上事件,关于如何做事件委托,在网络中有大量优秀的文章,例如知乎用户桐城 这篇就讲的还不错。
https://zhuanlan.zhihu.com/p/26536815
这个我们作为明天的视频再来详细讲解。
3、把整个图片切成若干份,这个份数要与图片总数相对应。
简单来说,就是你有几张预览图,就用160除以预览图的数量。例如一共有12张预览图,那就是160/12=13.33333333333333。这一步是要得出 每一份的像素大小。
4、获取当前鼠标所在的位置,用这个x坐标除以每一份的宽度 也就是第3步得到的数字。
例如:鼠标的x坐标是 60,那么就是60/13.3333≈4.5,取进位得到数字5。(取整进位用Math.ceil() 方法。
也就是我们需要在当前的位置显示第5张预览图。
5、通过第4步我们直到了当前要调用第几张预览图,然后我们就可以来修改目标的background-position属性,让它显示对应的图片了。
4.png
现在我们需要知道 对应图片在大图中的第几行第几列,才能获得具体的xy坐标。
其实很简单,例如你想要第3张图片。
只要 3 / 10 = 0 … 3 就可以知道,第三张图片在 第1行 第3列
例如你想要 第24张图片
只要 24 / 10 = 2 … 4 图片在第 3 行 第4列。
已知每幅图的大小是 160*90
那么只要用所在列数乘以 160 就可以获得 横坐标
只要用所在行数乘以 160 就可以获得 纵坐标
那么假如我们想调用第3幅图片,
只要用 3/10 取余 再乘以 160就可以得到横坐标
用 3-10 再除以10 再乘以90 就可以得到纵坐标。
下面是公式:(Javascript中 %符号 是取余数 运算符
x = number%10*160
y = (Math.ceil(num/10) – 1 )*90 (需要用Math.ceil() 取整)
当然,最后还是要都加上 负号
因为background-position所设置的图片想要往左或往上移动,需要用负数。
下面是具体实现的代码。
<!DOCTYPE html>
<html lang=”en”>
<head>
<metacharset=”UTF-8″>
<metaname=”viewport”content=”width=device-width, initial-scale=1.0″>
<metahttp-equiv=”X-UA-Compatible”content=”ie=edge”>
<title>清汤挂面的草果游戏</title>
<style>
*{
margin: 0;
padding: 0;
border: none;
list-style-type: none;
}
li{
width: 160px;
height: 90px;
float: left;
margin: 10px;
}
</style>
</head>
<body>
<ulid=”wjh”>
<lidata-num=”11″style=”background:url(https://i3.hdslb.com/bfs/videoshot/64508286.jpg@.webp?vsign=c1b01ba448824025643fd327b64c99b5bf31700f&ver=110043440);”></li>
<lidata-num=”11″style=”background:url(https://i3.hdslb.com/bfs/videoshot/64508286.jpg@.webp?vsign=c1b01ba448824025643fd327b64c99b5bf31700f&ver=110043440);”></li>
<lidata-num=”11″style=”background:url(https://i3.hdslb.com/bfs/videoshot/64508286.jpg@.webp?vsign=c1b01ba448824025643fd327b64c99b5bf31700f&ver=110043440);”></li>
</ul>
<script>
varele = document.getElementById(“wjh”);
ele.addEventListener(“mousemove”, function(e){
if(e.target.nodeName == “LI”){
// 图片大小 除以 多少份 得到每一份多大
vartotal = e.target.attributes[0].nodeValue;
//每份宽度
varitem_width = 160 / total;
//要调用第几张图片 鼠标位置 除以 每份宽度
varnum = Math.ceil(e.offsetX / item_width);
//第几张图片 除以 10
varx = num – 1 % 10;
vary = Math.ceil(num / 10) – 1;
console.log(x + “:” + y);
//修改背景图
e.target.style.backgroundPosition = “-” + x * 160 + “px -” + y * 90 + “px”;
}
});
</script>
</body>
</html>
网友评论