如何将一条线变成两条线并用 css 旋转

How can I transform a line into two and rotate with css

我想在我的 header 中有一条直线,然后在页面加载几秒钟后,我希望这些线慢慢向下移动,直到它们看起来像下图中的那样:

我想过用css变换属性旋转两个旋转两个div,但是这似乎不是一个解决方案,你可以在我的笔中看到结果here

HTML:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<div id="big">
  <div class="arrow-box">
    <div class="line line-1"></div>    
    <div class="line line-2"></div>

  </div>
</div>

CSS:

#big{
  background: red;
  height: 200px;
}
.arrow-box{
  max-width: 200px;
  margin: 0 auto;
  padding-top: 10px;

}
.line{
  background: white;
  width: 60px;
  height: 1px;
}

.line-1{
  transform: rotate(20deg);
}

.line-2{
  transform: rotate(-20deg);
}

如何使 a/the 行在页面加载后看起来像图像上的图标?

您可以使用 css 动画来做到这一点。您可以使用 rotateZ 变换来创建箭头形状,也可以使用 scale 来随着动画的进行不断增加线条的宽度。

您还需要使用 transform-origin 让两个部分在正确的点进行变换。

.line {
  position: relative;
  width: 100px;
}

.line:after,
.line:before {
  background: black;
  position: absolute;
  content: "";
  height: 2px;
  width: 50%;
  bottom: 0;
}

.line:before {
  left: 0;
  animation: moveBefore 1s linear forwards;
  transform-origin: center left;
}

.line:after {
  right: 0;
  animation: moveAfter 1s linear forwards;
  transform-origin: center right;
}

@keyframes moveBefore {
  0% {
    transform: rotateZ(0) scale(1, 1);
  }
  50% {
    transform: rotateZ(15deg) scale(1.05, 1);
  }
  
  100% {
    transform: rotateZ(30deg) scale(1.16, 1);
  }
}

@keyframes moveAfter {
  0% {
    transform: rotateZ(0) scale(1, 1);
  }
  50% {
    transform: rotateZ(-15deg) scale(1.05, 1);
  }
  
  100% {
    transform: rotateZ(-30deg) scale(1.16, 1);
  }
}
<div class="line"></div>

您也可以通过 svg 使用 line 元素和一些 javascript 来移动 y 左右线部分。要逐渐增加角度,您可以使用 setInterval 方法。

let step = 0;
const left = document.querySelector('.left-line');
const right = document.querySelector('.right-line');

function move(el, prop, size) {
  el.setAttribute(prop, +el.getAttribute(prop) + size);
}

setInterval(() => {
  if (step <= 40) {
    move(left, 'y2', 0.8);
    move(right, 'y1', 0.8)
    step += 1;
  }
}, 30)
<svg xmlns="http://www.w3.org/2000/svg">
  <line class="left-line" x1="0" y1="20" x2="40" y2="20" stroke="black" />
  <line class="right-line" x1="40" y1="20" x2="80" y2="20" stroke="black" />
</svg>

虽然接受的答案工作得很好,但由于缩放比例,我的艺术家无法在中心处理线条的重叠。这里有几个替代选项:

选项 1 - clip-path

使用 clip-path,为矩形的 mid-points 设置动画,将多边形转换为人字形。这通过屏蔽动画形状外部元素的背景颜色来实现。

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.line {
  display: inline-block;
  width: 200px;
  height: 50px;
  background-color: black;
  clip-path: polygon(0 0, 100% 0, 100% 2px, 0 2px);
  animation: 2s infinite linear;
}

.line.down {
  animation-name: chevron-down;
}

.line.up {
  animation-name: chevron-up;
}

@keyframes chevron-down {
  from {
    clip-path: polygon(0 0, 50% 0, 100% 0, 100% 2px, 50% 2px, 0 2px);
  }
  to {
    clip-path: polygon(0 0, 50% 48px, 100% 0, 100% 2px, 50% 50px, 0 2px);
  }
}

@keyframes chevron-up {
  from {
    clip-path: polygon(0 48px, 50% 48px, 100% 48px, 100% 50px, 50% 50px, 0 50px);
  }
  to {
    clip-path: polygon(0 0, 50% 48px, 100% 0, 100% 2px, 50% 50px, 0 2px);
  }
}
<div class="line down"></div>
<div class="line up"></div>

然而,对 clip-path 的支持参差不齐。


选项 2 - pseudo-elements

如果您不能使用 clip-path 或更喜欢使用伪元素,请将它们的位置和转换原点更改为来自中心(而不是上角):

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.line {
  position: relative;
  width: 200px;
  height: 50px;
  overflow: hidden;
}

.line::before,
.line::after {
  position: absolute;
  content: '';
  display: block;
  bottom: 0;
  height: 2px;
  width: 50%;
  background-color: black;
  animation: 2s linear infinite;
}

.line::before {
  transform-origin: bottom right;
  left: 0;
  animation-name: before;
}
.line::after {
  transform-origin: bottom left;
  right: 0;
  animation-name: after;
}

@keyframes before {
  to { transform: rotateZ(30deg); }
}

@keyframes after {
  to { transform: rotateZ(-30deg); }
}
<div class="line"></div>