Flex中的字幕div

时间:2019-06-14 09:23:08

标签: javascript css scroll marquee

我正在尝试创建一个像字幕效果(例如like this one这样的无限水平“滚动”。

这是我的代码:

.parent {
  border: 1px solid black;
  width: 100%;
  height: 2rem;
}

.container {
  height: 100%;
  display: flex;
  padding-left: 10%;
  border: 1px solid tomato;
  animation: marquee 5s linear infinite;
}

@keyframes marquee {
  0% {
    transform: translate(0%, 0);
  }
  100% {
    transform: translate(-100%, 0);
  }
}

.child1 {
  width: 10rem;
  height: 100%;
  background-color: #84B7DF;
}
.child2 {
  width: 18rem;
  height: 100%;
  background-color: #f58db6;
}
.child3 {
  width: 13rem;
  height: 100%;
  background-color: #ffc410;
}
.child4 {
  width: 21rem;
  height: 100%;
  background-color: #C8E7C1;
}
<div class="parent">
  <div class="container">
    <div class="child1"></div>
    <div class="child2"></div>
    <div class="child3"></div>
    <div class="child4"></div>
  </div>
</div>

如您所见,它可以工作,但并不完美。 我希望绿色矩形一旦移动,蓝色(略有间隔)就会立即出现,我不希望整个屏幕都白屏。

我希望我的意思很清楚...

非常感谢!

1 个答案:

答案 0 :(得分:1)

您可以再添加一个具有相同子元素的容器元素,然后在父元素上使用display: flexoverflow: hidden。同样,您可以使用.container单位和vw属性将flex元素的宽度设置为大于窗口宽度。

根据需要调整width上的paddingcontainer属性。

.parent {
  border: 1px solid black;
  width: 100%;
  height: 2rem;
  display: flex;
  overflow: hidden;
}

.container {
  height: 100%;
  flex: 0 0 120vw;
  display: flex;
  padding-right: 10%;
  border: 1px solid tomato;
  animation: marquee 5s linear infinite;
}

@keyframes marquee {
  0% {
    transform: translate(0%, 0);
  }
  100% {
    transform: translate(-100%, 0);
  }
}

.child1 {
  width: 10rem;
  height: 100%;
  background-color: #84B7DF;
}

.child2 {
  width: 18rem;
  height: 100%;
  background-color: #f58db6;
}

.child3 {
  width: 13rem;
  height: 100%;
  background-color: #ffc410;
}

.child4 {
  width: 21rem;
  height: 100%;
  background-color: #C8E7C1;
}
<div class="parent">
  <div class="container">
    <div class="child1"></div>
    <div class="child2"></div>
    <div class="child3"></div>
    <div class="child4"></div>
  </div>

  <div class="container other">
    <div class="child1"></div>
    <div class="child2"></div>
    <div class="child3"></div>
    <div class="child4"></div>
  </div>
</div>

另一种解决方案是在padding-right上添加vwcontainer单位。

.parent {
  border: 1px solid black;
  width: 100%;
  height: 2rem;
  display: flex;
  overflow: hidden;
}

.container {
  height: 100%;
  display: flex;
  padding-right: 50vw;
  border: 1px solid tomato;
  animation: marquee 5s linear infinite;
}

@keyframes marquee {
  0% {
    transform: translate(0%, 0);
  }
  100% {
    transform: translate(-100%, 0);
  }
}

.child1 {
  width: 10rem;
  height: 100%;
  background-color: #84B7DF;
}

.child2 {
  width: 18rem;
  height: 100%;
  background-color: #f58db6;
}

.child3 {
  width: 13rem;
  height: 100%;
  background-color: #ffc410;
}

.child4 {
  width: 21rem;
  height: 100%;
  background-color: #C8E7C1;
}
<div class="parent">
  <div class="container">
    <div class="child1"></div>
    <div class="child2"></div>
    <div class="child3"></div>
    <div class="child4"></div>
  </div>

  <div class="container other">
    <div class="child1"></div>
    <div class="child2"></div>
    <div class="child3"></div>
    <div class="child4"></div>
  </div>
</div>

Javascript / jQuery解决方案,您可以首先创建原始元素的克隆并将其附加到父元素。使用setInterval函数创建一个减少元素左侧位置的函数。如果偏移量小于同一元素的-width,则表示该元素不在屏幕上。在这种情况下,您应该将元素移动到窗口的末尾或其他元素的末尾,并具有一定的偏移量。

const parent = $(".parent");
const container = $(".container");
const offset = 250;

const clone = cloner(container, parent, offset);

function cloner(element, parent, offset) {
  const clone = element.clone();
  const width = element.width();

  clone.css({left: width + offset})
  parent.append(clone)
  return clone;
}

function move(element, size = 1) {
  const position = element.position().left;
  const width = element.width();

  if (position < -width) {
    const next = element.siblings().first();
    const nPosition = next.position().left;
    const nWidth = next.width();
    const wWidth = $(window).width();

    if (nPosition + nWidth < wWidth) {
      element.css({left: wWidth})
    } else {
      element.css({left: nPosition + nWidth + offset})
    }

  } else {
    element.css({left: position - size})
  }
}

window.mover = setInterval(() => {
  move(container)
  move(clone)
}, 5)
.parent {
  border: 1px solid black;
  width: 100%;
  height: 2rem;
  display: flex;
  overflow: hidden;
  position: relative;
}

.parent>div {
  position: absolute;
  left: 0;
}

.container {
  height: 100%;
  display: flex;
  border: 1px solid tomato;
}

.child1 {
  width: 10rem;
  height: 100%;
  background-color: #84B7DF;
}

.child2 {
  width: 18rem;
  height: 100%;
  background-color: #f58db6;
}

.child3 {
  width: 13rem;
  height: 100%;
  background-color: #ffc410;
}

.child4 {
  width: 21rem;
  height: 100%;
  background-color: #C8E7C1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
  <div class="container">
    <div class="child1"></div>
    <div class="child2"></div>
    <div class="child3"></div>
    <div class="child4"></div>
  </div>
</div>