沉浸式视频体验,大致内容是一个页面里有几十个视频,用户点击其中一个视频时,该视频自动滑动到屏幕可视区域的顶部开始播放,并暂停其他视频,该视频滑出屏幕可视区域之后要自动暂停。
沉浸式视频体验
-
如何将视频滑动到屏幕可视区域的顶部
-
如何判断视频滑出了屏幕可视区域
1.递归
const getElementLeft = element => {
let actualLeft = element.offsetLeft;
let current = element.offsetParent;
while (current !== null){
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return actualLeft;
}
const getElementTop = element => {
let actualTop = element.offsetTop;
let current = element.offsetParent;
while (current !== null){
actualTop += current.offsetTop;
current = current.offsetParent;
}
return actualTop;
}
2. 你听说过getBoundingClientRect吗?
如何将视频滑动到屏幕可视区域的顶部?
const autoScroll = (offsetTop, needScrollTop, hasScrollTop) => {
let _needScrollTop = needScrollTop; // 本次递归时,离终点的距离
let _hasScrollTop = hasScrollTop; // 本次递归时,已经移动的距离总和
const speed = 10;
setTimeout(() => {
const dist = needScrollTop > 0
? Math.max(Math.ceil(needScrollTop / speed), 5)
: Math.min(Math.ceil(needScrollTop / speed), -5);
_needScrollTop -= dist;
_hasScrollTop += dist;
window.scroll(0, offsetTop + _hasScrollTop);
// 如果移动幅度小于十个像素,直接移动,否则递归调用,实现动画效果
if (_needScrollTop > speed || _needScrollTop < -speed) {
this.__onScroll(offsetTop, _needScrollTop, _hasScrollTop);
} else {
window.scroll(0, offsetTop + _hasScrollTop + _needScrollTop);
}
}, 1);
}
const rect = element.getBoundingClientRect();
const offsetTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || window.screenY;
autoScroll(offsetTop, rect.top, 0);
如何判断视频滑出了屏幕可视区域?
// 检测滑出可视区域
checkLeave() {
const element = document.querySelector(`[data-action-id="${this.__domId}"]`);
if (!element) {
console.error(`Action: element [data-action-id="${this.__domId}"] not found`);
return;
}
const { top, bottom, left, right } = element.getBoundingClientRect();
if ((top > getWindowHeight() || bottom < 0
|| left > getWindowWidth() || right < 0)) {
this.onLeave(); //onLeave函数中实现具体业务逻辑
}
}
// 检测真实曝光
checkExpose() {
const element = document.querySelector(`[data-action-id="${this.__domId}"]`);
if (!element) {
console.error(`Action: element [data-action-id="${this.__domId}"] not found`);
return;
}
const { top, bottom, left, right } = element.getBoundingClientRect();
if (Math.max(0, top) <= Math.min(getWindowHeight(), bottom)
&& Math.max(0, left) <= Math.min(getWindowWidth(), right)) {
this.onExpose(); //onExpose函数中实现具体业务逻辑
}
}
render() {
const { children } = this.props;
return cloneElement(Children.only(children), {
'data-action-id': this.__domId,
});
}