缘起
前几日Boss发来这么一个视频,说很喜欢其中的广告呈现方式
参考图这种效果最早出现在谷歌日历和知乎。
Boss喜欢?盘它!
思路
广告框在list中的位置等比映射到广告框中的图片显示位置
coding
<div class="main">
<ul class="list">
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile is--ad"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
<li class="list-tile"></li>
</ul>
</div>
Give you some color to see see.
.main {
width: 350px;
height: 700px;
margin: 0 auto;
box-shadow: 0 0 5px #999;
}
.list {
margin: 0;
padding: 0;
list-style-type: none;
height: 100%;
overflow-y: auto;
}
.list-tile {
background-color: cadetblue;
height: 100px;
border-top: 1px solid #fff;
}
.list-tile.is--ad {
background: url("./background.jpg") no-repeat;
background-size: 100% auto;
background-position-y: bottom;
}
const listEl = document.querySelector(".list");
const adTileEl = document.querySelector(".list-tile.is--ad");
const listRect = document.querySelector(".main").getBoundingClientRect();
let adTileRect;
const handleScroll = e => {
requestAnimationFrame(() => {
adTileRect = adTileEl.getBoundingClientRect();
// 如果广告不在当前viewport内,不做操作
if (
listRect.bottom - adTileRect.top < 0 ||
listRect.top - adTileRect.top > 0
) {
return;
}
// 计算出当前广告在list中的位置比
let percent = (adTileRect.top / listRect.bottom).toFixed(2);
percent = Math.min(1, percent);
percent = Math.max(0, percent);
adTileEl.style.backgroundPositionY = `${percent * 100}%`;
// 图片滚动方向反转,其实也挺好的,以后封装
// adTileEl.style.backgroundPositionY = `${(1 - percent) * 100}%`;
});
};
listEl.addEventListener("scroll", handleScroll);
一时兴起搞起来的,没有封装和优化,因为暂时用不到哈哈
效果图
正向反向
反向
TODO
- 支持多广告
- 广告框更加定制化
- 测试超长图
- 封装成插件
- vue/omi/flutter/小程序版本(用到再说)
网友评论