水平无限循环弹幕
by Mike Lin
HTML
<div id="app"></div>
<div id="app1"></div>
SCSS
.scroll-list{
display: flex;
&.horizon {
flex-direction: row;
}
&.vertical{
flex-direction: column;
}
}
#app, #app1{
overflow: hidden;
width: 100%;
position: absolute;
top:0px;
.bullet-screen{
padding-top: 0.7567567567567568rem;
height: 1.3783783783783783rem;
transform: translateX(calc(100vw));
.item{
margin-left: 1.0810810810810811rem;
}
}
.item{
height: 0.6216216216216216rem;
display: flex;
padding: 0.16216216216216217rem 0.2702702702702703rem 0.13513513513513514rem 0.2702702702702703rem;
align-items: center;
justify-content: center;
flex-shrink: 0;
background: rgba(255,255,255,0.8);
border-radius: 12px;
}
}
#app1{
top: 30px;
}
React
class InfiniteScroll extends React.Component {
componentDidMount() {
const { animationName, scrollDirection } = this.props
setTimeout(() => {
if (this.scrollInstance) {
const appendElementWidth = []
const appendElement = []
const visibleWidth = this.scrollInstance.clientWidth
// 滚动的初始位置从视口的最右边开始,后面支持更多方向
const initPosition = visibleWidth
let scrollContainerWidth = 0
let isCoverViewPort = false
// 遍历滚动的所有元素
for (let i = 0; i < this.scrollInstance.children.length; i += 1) {
const style = this.scrollInstance.children[i].currentStyle || window.getComputedStyle(this.scrollInstance.children[i])
// width 已经包含了border和padding,如果box-sizing变化了呢?
const width = this.scrollInstance.children[i].offsetWidth// or use style.width
const margin = parseFloat(style.marginLeft) + parseFloat(style.marginRight)
const clientWidth = (width + margin)
scrollContainerWidth += clientWidth
// 保存需要追加到原有滚动元素的列表后面
if (scrollContainerWidth < visibleWidth * 2 && !isCoverViewPort) {
appendElementWidth.push(clientWidth)
appendElement.push(this.scrollInstance.children[i].cloneNode(true))
if (scrollContainerWidth >= visibleWidth && !isCoverViewPort) {
isCoverViewPort = true
}
}
}
const isScrollWidthLargeViewPort = scrollContainerWidth > visibleWidth
// const styleSheet = document.styleSheets[0]
const keyframes = `
@keyframes ${animationName}{
from{
transform: ${scrollDirection === 'horizon' ? `translateX(${isScrollWidthLargeViewPort ? 0 : initPosition}px)` : 'translateY(0px)'};
}
to {
transform: ${scrollDirection === 'horizon' ? `translateX(-${scrollContainerWidth}px)` : `translateX(-${scrollContainerWidth}px)`};
}
}
@-webkit-keyframes...