
写在前面
我最开始是用 Angular 去实现了B站的 Banner ,那时候还没有人做这东西,可以看到下面那一长串 Bannet 图片的第一个图是好几年以前的了。然后随着逐步完善,在这几年偶尔也看到有人发过这东西的实现方法。
但我为什么要写这篇文章?「因为我打算用原生 JS 和三大框架都去实现一遍,以满足所有人的需求,让你能直接复制到你的项目」。而且我作为几乎每一期都 copy 的玩家,存货多,也知道最简单通用的 copy 方法。
本文的原生 JS 代码我直接从我已经完善的 Angular 代码基础上提取出来,然后再用 React 与 Vue 各自实现一遍。主要讲讲我大致的方法原理,里面的具体实现细节就不讲了,毕竟讲起来费劲,主要就是一些根据鼠标移动计算图片位置,自己认真读起来不会很难。
「代码与相关静态资源已提交至 gitee ,需要的直接去看完整代码即可。」
https://gitee.com/CrimsonHu/bilibili-banner
这是我的个人网站,我在我的网站上面用它很久了~~~


B站是怎么实现 Banner 的
我们打开控制台,首先找到它的 DOM 结构,可以看到 Banner 里面有一个个 class 为 layer 的 div:

点开 div,会看到一个 img 与控制这个 img 位置与大小的样式:

Banner 的本质就是一层层的图片,按照特定的宽度、高度、位置( translate 的 X 与 Y 属性)、以及角度、缩放、透明度这些来进行排列的。
在 Banner 上移动鼠标,我们会发现 「transform 属性的各项值会随着鼠标的移动而更新」:

所以实现思路就有了:「把这些图片按照指定的样式进行排列,然后做一个鼠标移动的监听事件即可」。
那么如何知道鼠标移动了一定的距离,每个图片各自的移动量是多少呢?
这个也简单。因为它的移动量基本都是线性的。目前我只看到有两期是在线性移动的基础上加了点额外的效果,这个在这里就把它忽略。把它的线性动画的移动量拿过来后已经显示的很不错了。
于是我发现了一个很好用的方法:
「以某一张图片为基准,以它的移动量为一个基准单位,去看其它每个图片移动了多少。」
例如,我以图片 A 移动了 5px 为基准,那么我就看图片 A 移动了 5px 的时候,其它的各个图片分别移动了多少。所以,通过这个取基准的方法,我们可以得出,「根据鼠标的移动,带动图片 A 的位置更新,从而得出其它各个图片的位置的更新值」。
使用原生代码实现
1. 资源获取
现在理清了原理,那么我们就先将每张图片的静态资源获取下来,这一步就省略不写了。
2. 定义基准移动量
现在我们以第一张图片为基准,去定义移动量:
{
type: 'image',
file: '477fb7a2f5e2cc1b2aa00c679c8ab168b47ff1b9.png@1c.webp',
width: 1728,
height: 162,
x: 0, // 原始 translateX 值
y: 0, // 原始 translateY 值
r: 0, // 原始 rotate 值
s: 1, // 原始 scale 值
o: 1, // 原始 opacity 值
newX: -1.17573, // 更新后的 translateX 值
newY: 0, // 更新后的 translateY 值
newRotate: 0, // 更新后的 rotate 值
bench: -1.17573
},
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
其实没更新的值可以省略不写,比如这段定义里面的 newOpacity 我省略了,而且 newY 和 newRotate 也可以省略,因为后续代码我会处理省略的字段不进行计算更新。
这段定义代码需要注意的地方就是 x、 newX、 bench 这三个,这是我们定义的一个基准移动量。
「鼠标在 Banner 上移动,这个图片的 translateX 值从 0 更新到 -1.17573,以此为基准,基准字段记为 bench。」
于是,需要你花亿点点时间,去看第一个图片的 translateX 在 -1.17573 这个值的时候,其它的图片的位置值各自是多少:

因为每次重新打开页面重新打开控制台时,这种细微操作的移动,更新的值都不会完全一致,图中的值会与我记录的稍微不一致,所以在完成所有图片的数据采集之前不要更改窗口尺寸与开关控制台。
[
{ type: 'image', file: '477fb7a2f5e2cc1b2aa00c679c8ab168b47ff1b9.png@1c.webp', width: 1728, height: 162, x: 0, y: 0, r: 0, s: 1, o: 1, newX: -1.17573, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'dd4aa5af4898a15dde074fe6b833bdfbc045dd47.png@1c.webp', width: 1632, height: 153, x: -42.5, y: 0, r: 0, s: 1, o: 1, newX: -46.2014, newY: 1.48055, newRotate: -2.17727, bench: -1.17573 },
{ type: 'image', file: 'ae64c474ba2748b4fea1a1433b9b373598d3e686.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: 0, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'd41b0292d9d1b0fce37a35f6efacac579093cdb3.png@1c.webp', width: 1728, height: 162, x: -63, y: -18, r: 0, s: 1, o: 1, newX: -68.8786, newY: -18, newRotate: -2.17727, bench: -1.17573 },
{ type: 'image', file: 'a12cbab877db2b6d3b96ec012735cfe3998de399.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: 3.70136, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '6f27fe80f495e83546921c2c58b2107c2ee89706.png@1c.webp', width: 1824, height: 171, x: 9.5, y: 0, r: 0, s: 1, o: 1, newX: -0.842045, newY: -2.06841, newRotate: 0, newScale: 0.978227, bench: -1.17573 },
{ type: 'image', file: 'ac580ac636595e27b5d5c8b1f9d802751823f02f.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: 14.8055, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '987a407da2e02a12be549ad7f011dc11f73216e9.png@1c.webp', width: 1632, height: 153, x: 0, y: 8.5, r: 0, s: 1, o: 1, newX: 5.55205, newY: 7.38959, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '843ee84b16bab6274b98b317b3adaf1351b4be76.png@1c.webp', width: 1632, height: 153, x: 8.5, y: 0, r: 0, s: 1, o: 1, newX: -2.60409, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'a5607001ac06b4780106e2a10aa835657e553f07.png@1c.webp', width: 1632, height: 153, x: 8.5, y: 0, r: 0, s: 1, o: 1, newX: 15.9027, newY: -12.9548, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'b14cad3c76e957705810c26f4c6acc236f280721.png@1c.webp', width: 1632, height: 153, x: 17, y: 0, r: 0, s: 1, o: 1, newX: 11.448, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'f569be6834a5968c038bcc0fb0403f8f77e24c18.png@1c.webp', width: 1632, height: 153, x: 8.5, y: 0, r: 0, s: 1, o: 1, newX: 1.09727, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'eb98a42561de7d45f8856407c4531d2724ac6fc6.png@1c.webp', width: 1344, height: 126, x: 21, y: 21, r: 0, s: 1, o: 1, newX: -9.48182, newY: 17.9518, newRotate: 2.17727, newScale: 1.13064, bench: -1.17573 },
{ type: 'image', file: '480a5c02dbcd3afd5f790cf621efbd1b2d39efcb.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: -18.5068, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'cc1405d4d805baf9c459f67c03f095f70ec864c6.png@1c.webp', width: 1632, height: 153, x: 0, y: 17, r: 0, s: 1, o: 1, newX: -5.55205, newY: 18.8507, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '1696ffeacb26bcce7ad50037952620ee43614a4a.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: -7.40273, newY: -2.96109, newRotate: 0, newScale: 1.08709, bench: -1.17573 },
{ type: 'image', file: 'b0747b7f64e0e07e379a4bd416a0891b3e52c7d9.png@1c.webp', width: 1651.2, height: 154.8, x: 34.4, y: 0, r: 0, s: 1, o: 1, newX: 11.9305, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'ec9f99bf71be9408a359d7cd48dfb47e48ebce2c.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: -9.25341, newY: 6.29232, newRotate: -8.70909, newScale: 1.13064, bench: -1.17573 },
{ type: 'image', file: 'c4cef2b063a853521c7f413d8e7782ff653e4126.png@1c.webp', width: 1632, height: 153, x: 17, y: 0, r: 0, s: 1, o: 1, newX: -12.6109, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '567e0221b3bd89e34d85c604549d915c95ca17d1.png@1c.webp', width: 1920, height: 180, x: 30, y: 0, r: 0, s: 1, o: 1, newX: 73.5455, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '23c05e4d9e0ffbc16671e14c406fbe785b06ff9f.png@1c.webp', width: 1632, height: 153, x: 15.3, y: 17, r: 0, s: 1, o: 1, newX: -18.0123, newY: 17, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'fbfeb5de7e41fd1e888fca7ac76cbf2f8a42f3d3.png@1c.webp', width: 1920, height: 180, x: 0, y: 0, r: 0, s: 1, o: 1, newX: -43.5455, newY: 0, newRotate: 0, bench: -1.17573 },
]
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
3. 展示静态效果
有了这些数据后,先来把每个图层的图片按照这些位置数据显示出来,用原生 JS 做一个静态展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.bili-banner {
position: relative;
width: 100%;
height: 100%;
background-color: #f9f9f9;
display: flex;
justify-content: center;
background-repeat: no-repeat;
background-position: center 0;
background-size: cover;
filter: brightness(var(--img-filter-brightness));
}
.animated-banner {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
}
.layer {
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
}
.logo {
position: absolute;
width: 220px;
height: 105px;
left: 0;
top: 0;
transform: scale(0.4) translate(-60%, -60%);
}
.logo>img {
width: 100%;
height: 100%;
}
.banner-container {
position: relative;
width: 800px;
height: 150px;
}
</style>
</head>
<body>
<div class="banner-container" id="winter-5"></div>
</body>
<script>
const baseSrc = './assets/winter-5/';
const imgData = [...];
const container = document.getElementById('winter-5');
const biliBanner = document.createElement('div');
biliBanner.className = 'bili-banner';
const animatedBanner = document.createElement('div');
animatedBanner.className = 'animated-banner';
for (let i = 0; i < imgData.length; i++) {
const layer = document.createElement('div');
layer.className = 'layer';
const img = document.createElement('img');
img.src = baseSrc + imgData[i].file;
img.style.width = imgData[i].width + 'px';
img.style.height = imgData[i].height + 'px';
img.style.transform = '' +
'translate(' +
imgData[i].x + 'px, ' +
imgData[i].y + 'px' +
')' + ' ' +
'rotate(' + imgData[i].r + 'deg)' + ' ' +
'scale(' + imgData[i].s + ')';
img.style.opacity = imgData[i].o;
layer.appendChild(img);
animatedBanner.appendChild(layer);
}
biliBanner.appendChild(animatedBanner);
container.appendChild(biliBanner);
</script>
</html>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
上述代码的效果如图所示:

4. 实现完整功能
现在能够看到每张图片能够按照正确的位置显示出来了,接下来的主要工作就是「添加鼠标移动事件,去计算每个图片的移动量」。具体就不详细讲了。

可以看到,已经基本达到了B站首页 Banner 的效果。
「使用三大框架各自实现的代码直接在 gitee 上看,文中就不贴出来了。」
https://gitee.com/CrimsonHu/bilibili-banner
下面是原生 JS 实现的完整代码,贴在这里供大家学习参考。「这里我使用了面向对象的方式将其进行封装,方便初始化多个实例与销毁」。同时我也建议前端人应该同时掌握面向对象与函数式,「在合适的地方用合适的方法」,而不是一味地吹捧函数式编程,去拒绝面向对象的思维。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.bili-banner {
position: relative;
width: 100%;
height: 100%;
background-color: #f9f9f9;
display: flex;
justify-content: center;
background-repeat: no-repeat;
background-position: center 0;
background-size: cover;
filter: brightness(var(--img-filter-brightness));
}
.animated-banner {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
}
.layer {
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
}
.logo {
position: absolute;
width: 220px;
height: 105px;
left: 0;
top: 0;
transform: scale(0.4) translate(-60%, -60%);
}
.logo>img {
width: 100%;
height: 100%;
}
.banner-container {
position: relative;
width: 800px;
height: 150px;
}
</style>
</head>
<body>
<div class="banner-container" id="winter-5"></div>
</body>
<script>
class ResizeObserverWrap {
observer;
dom;
constructor(dom, callback) {
this.dom = dom;
this.observer = new ResizeObserver((entries) => {
if (!Array.isArray(entries) || !entries.length) {
return;
}
for (let entry of entries) {
callback(entry.target);
}
});
this.observer.observe(this.dom);
}
unmount() {
this.observer.unobserve(this.dom);
}
}
class BilibiliBannerBase {
baseSrc = './assets/winter-5/';
imgDomList = [];
imgData = [];
imgNewData = [];
resizeObserver;
container;
containerWidth = 0;
// 声明自定义参数
marginLeft = 0;
moveRate = 300;
maxMove = null;
maxLeftPosition = null;
maxRightPosition = null;
// 声明状态信息
isReseting = false;
isInResetingEnter = false;
startPoint = { x: 0, y: 0 }
transition = 0.75;
moveX = 0;
// 声明loop与render方法更新界面
isDestroyed = false;
frameTime = 0;
fps = 60;
// 监听事件
mouseenter = (e) => {
if (this.isReseting) {
this.isInResetingEnter = true;
} else {
this.bilibiliStart(e.clientX, e.clientY);
}
}
mousemove = (e) => {
if (!this.isReseting) {
if (this.isInResetingEnter) {
this.bilibiliStart(e.clientX, e.clientY);
this.isInResetingEnter = false;
} else {
this.bilibiliMove(e.clientX, e.clientY);
}
}
}
mouseleave = (e) => {
this.bilibiliEnd();
this.reset();
}
constructor(param = {
container,
imgData,
marginLeft,
moveRate,
maxMove: { left, right },
maxLeftPosition: { index, cut },
maxRightPosition: { index, cut },
}) {
window.requestAnimationFrameFunc = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
this.container = param.container;
this.imgData = param.imgData;
this.init();
}
init() {
const biliBanner = document.createElement('div');
biliBanner.className = 'bili-banner';
const animatedBanner = document.createElement('div');
animatedBanner.className = 'animated-banner';
for (let i = 0; i < this.imgData.length; i++) {
const layer = document.createElement('div');
layer.className = 'layer';
const img = document.createElement('img');
img.src = this.baseSrc + this.imgData[i].file;
img.style.width = this.imgData[i].width + 'px';
img.style.height = this.imgData[i].height + 'px';
img.style.transform = '' +
'translate(' +
this.imgData[i].x + 'px, ' +
this.imgData[i].y + 'px' +
')' + ' ' +
'rotate(' + this.imgData[i].r + 'deg)' + ' ' +
'scale(' + this.imgData[i].s + ')';
img.style.opacity = this.imgData[i].o;
img.style.filter = this.imgData[i].filter == undefined ? 'none' : this.imgData[i].filter;
this.imgDomList.push(img);
layer.appendChild(img);
animatedBanner.appendChild(layer);
}
biliBanner.appendChild(animatedBanner);
this.container.appendChild(biliBanner);
this.resizeObserver = new ResizeObserverWrap(this.container, (e) => {
this.containerWidth = e.clientWidth;
});
this.imgData.forEach((each, i) => {
each.x += this.marginLeft;
each.newX += this.marginLeft;
this.imgNewData.push({
currentX: each.x,
currentY: each.y == undefined ? 0 : each.y,
currentRotate: each.r == undefined ? 0 : each.r,
currentScale: each.s == undefined ? 0 : each.s,
currentOpacity: each.o == undefined ? 1 : each.o,
});
});
// 添加鼠标移动事件
this.container.addEventListener('mouseenter', this.mouseenter);
this.container.addEventListener('mousemove', this.mousemove);
this.container.addEventListener('mouseleave', this.mouseleave);
this.loop(0);
}
destroy() {
this.isDestroyed = true;
this.resizeObserver.unmount();
this.container.removeEventListener('mouseenter', this.mouseenter);
this.container.removeEventListener('mousemove', this.mousemove);
this.container.removeEventListener('mouseleave', this.mouseleave);
this.container.innerHTML = '';
}
render() {
this.imgDomList.forEach((img, i) => {
img.style.transform = '' +
'translate(' +
this.imgNewData[i].currentX + 'px, ' +
this.imgNewData[i].currentY + 'px' +
')' + ' ' +
'rotate(' + this.imgNewData[i].currentRotate + 'deg)' + ' ' +
'scale(' + this.imgNewData[i].currentScale + ')';
img.style.opacity = this.imgNewData[i].currentOpacity;
img.style.filter = this.imgNewData[i].filter == undefined ? 'none' : this.imgNewData[i].filter;
img.style.transition = this.transition + 's';
})
}
loop(e) {
if (e - this.frameTime >= 1000 / this.fps) {
this.frameTime = e;
this.render();
}
window.requestAnimationFrameFunc((e1) => {
if (!this.isDestroyed) {
this.loop(e1);
}
});
}
bilibiliStart(x, y) {
this.startPoint.x = x;
this.startPoint.y = y;
this.transition = 0;
}
bilibiliMove(x, y) {
let moveX = (x - this.startPoint.x) / this.moveRate;
this.startPoint.x = x;
this.moveX += moveX;
if (this.maxMove) {
let v = this.moveX * this.moveRate;
if (moveX < 0 && v * -1 > this.maxMove.left) {
return;
} elseif (moveX > 0 && v > this.maxMove.right) {
return;
}
}
if (this.moveX > 0) {
if (Math.abs(this.moveX) > this.getLeftWidth()) {
this.moveX -= moveX;
return;
}
} else {
if (Math.abs(this.moveX) > this.getRightWidth()) {
this.moveX -= moveX;
return;
}
}
for (let i = 0; i < this.imgData.length; i++) {
this.moveFunction(i);
}
}
bilibiliEnd() {
this.startPoint.x = 0;
this.startPoint.y = 0;
}
getLeftWidth() {
let leftWidth;
if (this.maxLeftPosition) {
let i = this.maxLeftPosition.index;
let r = (this.imgData[i].newX - this.imgData[i].x) / this.imgData[i].bench;
leftWidth = (this.imgData[i].width - this.containerWidth) / 2 - this.imgData[i].x;
leftWidth = leftWidth - this.maxLeftPosition.cut;
leftWidth = leftWidth / r;
console.log(leftWidth)
} else {
leftWidth = this.containerWidth / 2 - this.marginLeft;
}
return leftWidth;
}
getRightWidth() {
let rightWidth;
if (this.maxRightPosition) {
let i = this.maxRightPosition.index;
let r = (this.imgData[i].newX - this.imgData[i].x) / this.imgData[i].bench;
rightWidth = (this.imgData[i].width - this.containerWidth) / 2 + this.imgData[i].x;
rightWidth = rightWidth - this.maxRightPosition.cut;
rightWidth = rightWidth / r;
} else {
rightWidth = this.containerWidth / 2 + this.marginLeft;
}
return rightWidth;
}
moveFunction(i) {
let bench = this.imgData[i].bench;
// 移动量 - X
let x = this.imgData[i].x;
let newX = this.imgData[i].newX;
if (x != null && newX != null && x != newX) {
let x1 = (newX - x) / bench;
this.imgNewData[i].currentX = x1 * this.moveX + x;
}
// 移动量 - Y
let y = this.imgData[i].y;
let newY = this.imgData[i].newY;
if (y != null && newY != null && y != newY) {
let y1 = (newY - y) / bench;
this.imgNewData[i].currentY = y1 * this.moveX + y;
}
// 移动量 - Rotate
let r = this.imgData[i].r;
let newRotate = this.imgData[i].newRotate;
if (r != null && newRotate != null && r != newRotate) {
let r1 = (newRotate - r) / bench;
this.imgNewData[i].currentRotate = r1 * this.moveX + r;
}
// 移动量 - Scale
let s = this.imgData[i].s;
let newScale = this.imgData[i].newScale;
if (s != null && newScale != null && s != newScale) {
let s1 = (newScale - s) / bench;
this.imgNewData[i].currentScale = s1 * this.moveX + s;
}
// 移动量 - Opacity
let o = this.imgData[i].o;
let newOpacity = this.imgData[i].newOpacity;
if (o != null && newOpacity != null && o != newOpacity) {
let o1 = (newOpacity - o) / bench;
this.imgNewData[i].currentOpacity = o1 * this.moveX + o;
}
if (this.imgNewData[i].currentOpacity < 0) { // 透明度检测,在0~1范围内
this.imgNewData[i].currentOpacity = 0;
} elseif (this.imgNewData[i].currentOpacity > 1) {
this.imgNewData[i].currentOpacity = 1;
}
}
reset() {
this.transition = 0.75;
this.moveX = 0;
for (let i = 0; i < this.imgData.length; i++) {
let data = this.imgData[i];
this.imgNewData[i].currentX = data.x;
this.imgNewData[i].currentY = data.y == undefined ? 0 : data.y;
this.imgNewData[i].currentRotate = data.r == undefined ? 0 : data.r;
this.imgNewData[i].currentScale = data.s == undefined ? 0 : data.s;
this.imgNewData[i].currentOpacity = data.o == undefined ? 0 : data.o;
}
this.isReseting = true;
setTimeout(() => {
this.isReseting = false;
}, 750);
}
}
let banner = new BilibiliBannerBase({
container: document.getElementById('winter-5'),
imgData: [
{ type: 'image', file: '477fb7a2f5e2cc1b2aa00c679c8ab168b47ff1b9.png@1c.webp', width: 1728, height: 162, x: 0, y: 0, r: 0, s: 1, o: 1, newX: -1.17573, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'dd4aa5af4898a15dde074fe6b833bdfbc045dd47.png@1c.webp', width: 1632, height: 153, x: -42.5, y: 0, r: 0, s: 1, o: 1, newX: -46.2014, newY: 1.48055, newRotate: -2.17727, bench: -1.17573 },
{ type: 'image', file: 'ae64c474ba2748b4fea1a1433b9b373598d3e686.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: 0, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'd41b0292d9d1b0fce37a35f6efacac579093cdb3.png@1c.webp', width: 1728, height: 162, x: -63, y: -18, r: 0, s: 1, o: 1, newX: -68.8786, newY: -18, newRotate: -2.17727, bench: -1.17573 },
{ type: 'image', file: 'a12cbab877db2b6d3b96ec012735cfe3998de399.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: 3.70136, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '6f27fe80f495e83546921c2c58b2107c2ee89706.png@1c.webp', width: 1824, height: 171, x: 9.5, y: 0, r: 0, s: 1, o: 1, newX: -0.842045, newY: -2.06841, newRotate: 0, newScale: 0.978227, bench: -1.17573 },
{ type: 'image', file: 'ac580ac636595e27b5d5c8b1f9d802751823f02f.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: 14.8055, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '987a407da2e02a12be549ad7f011dc11f73216e9.png@1c.webp', width: 1632, height: 153, x: 0, y: 8.5, r: 0, s: 1, o: 1, newX: 5.55205, newY: 7.38959, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '843ee84b16bab6274b98b317b3adaf1351b4be76.png@1c.webp', width: 1632, height: 153, x: 8.5, y: 0, r: 0, s: 1, o: 1, newX: -2.60409, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'a5607001ac06b4780106e2a10aa835657e553f07.png@1c.webp', width: 1632, height: 153, x: 8.5, y: 0, r: 0, s: 1, o: 1, newX: 15.9027, newY: -12.9548, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'b14cad3c76e957705810c26f4c6acc236f280721.png@1c.webp', width: 1632, height: 153, x: 17, y: 0, r: 0, s: 1, o: 1, newX: 11.448, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'f569be6834a5968c038bcc0fb0403f8f77e24c18.png@1c.webp', width: 1632, height: 153, x: 8.5, y: 0, r: 0, s: 1, o: 1, newX: 1.09727, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'eb98a42561de7d45f8856407c4531d2724ac6fc6.png@1c.webp', width: 1344, height: 126, x: 21, y: 21, r: 0, s: 1, o: 1, newX: -9.48182, newY: 17.9518, newRotate: 2.17727, newScale: 1.13064, bench: -1.17573 },
{ type: 'image', file: '480a5c02dbcd3afd5f790cf621efbd1b2d39efcb.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: -18.5068, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'cc1405d4d805baf9c459f67c03f095f70ec864c6.png@1c.webp', width: 1632, height: 153, x: 0, y: 17, r: 0, s: 1, o: 1, newX: -5.55205, newY: 18.8507, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '1696ffeacb26bcce7ad50037952620ee43614a4a.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: -7.40273, newY: -2.96109, newRotate: 0, newScale: 1.08709, bench: -1.17573 },
{ type: 'image', file: 'b0747b7f64e0e07e379a4bd416a0891b3e52c7d9.png@1c.webp', width: 1651.2, height: 154.8, x: 34.4, y: 0, r: 0, s: 1, o: 1, newX: 11.9305, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'ec9f99bf71be9408a359d7cd48dfb47e48ebce2c.png@1c.webp', width: 1632, height: 153, x: 0, y: 0, r: 0, s: 1, o: 1, newX: -9.25341, newY: 6.29232, newRotate: -8.70909, newScale: 1.13064, bench: -1.17573 },
{ type: 'image', file: 'c4cef2b063a853521c7f413d8e7782ff653e4126.png@1c.webp', width: 1632, height: 153, x: 17, y: 0, r: 0, s: 1, o: 1, newX: -12.6109, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '567e0221b3bd89e34d85c604549d915c95ca17d1.png@1c.webp', width: 1920, height: 180, x: 30, y: 0, r: 0, s: 1, o: 1, newX: 73.5455, newY: 0, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: '23c05e4d9e0ffbc16671e14c406fbe785b06ff9f.png@1c.webp', width: 1632, height: 153, x: 15.3, y: 17, r: 0, s: 1, o: 1, newX: -18.0123, newY: 17, newRotate: 0, bench: -1.17573 },
{ type: 'image', file: 'fbfeb5de7e41fd1e888fca7ac76cbf2f8a42f3d3.png@1c.webp', width: 1920, height: 180, x: 0, y: 0, r: 0, s: 1, o: 1, newX: -43.5455, newY: 0, newRotate: 0, bench: -1.17573 },
],
maxMove: { left: 2000, right: 2000 },
});
</script>
</html>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
- 245.
- 246.
- 247.
- 248.
- 249.
- 250.
- 251.
- 252.
- 253.
- 254.
- 255.
- 256.
- 257.
- 258.
- 259.
- 260.
- 261.
- 262.
- 263.
- 264.
- 265.
- 266.
- 267.
- 268.
- 269.
- 270.
- 271.
- 272.
- 273.
- 274.
- 275.
- 276.
- 277.
- 278.
- 279.
- 280.
- 281.
- 282.
- 283.
- 284.
- 285.
- 286.
- 287.
- 288.
- 289.
- 290.
- 291.
- 292.
- 293.
- 294.
- 295.
- 296.
- 297.
- 298.
- 299.
- 300.
- 301.
- 302.
- 303.
- 304.
- 305.
- 306.
- 307.
- 308.
- 309.
- 310.
- 311.
- 312.
- 313.
- 314.
- 315.
- 316.
- 317.
- 318.
- 319.
- 320.
- 321.
- 322.
- 323.
- 324.
- 325.
- 326.
- 327.
- 328.
- 329.
- 330.
- 331.
- 332.
- 333.
- 334.
- 335.
- 336.
- 337.
- 338.
- 339.
- 340.
- 341.
- 342.
- 343.
- 344.
- 345.
- 346.
- 347.
- 348.
- 349.
- 350.
- 351.
- 352.
- 353.
- 354.
- 355.
- 356.
- 357.
- 358.
- 359.
- 360.
- 361.
- 362.
- 363.
- 364.
- 365.
- 366.
- 367.
- 368.
- 369.
- 370.
- 371.
- 372.
- 373.
- 374.
- 375.
- 376.
- 377.
- 378.
- 379.
- 380.
- 381.
- 382.
- 383.
- 384.
- 385.
- 386.
- 387.
- 388.
- 389.
- 390.
- 391.
- 392.
- 393.
- 394.
- 395.
- 396.
- 397.
- 398.
- 399.
- 400.
- 401.
- 402.
- 403.
- 404.

1664

被折叠的 条评论
为什么被折叠?



