如何将一条线变成两条线并用 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>
我想在我的 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>