Anda bisa mempertimbangkannya border-radius
. Ini adalah contoh dasar yang bisa Anda tingkatkan
.box {
height:100px;
margin-top:50px;
border:10px solid transparent;
border-bottom:10px solid red;
width:100px;
animation:
loop 5s infinite alternate linear,
radius 5s infinite alternate linear;
}
@keyframes loop{
0% {
transform:translateX(0);
}
40% {
transform:translateX(100px) rotate(0deg);
}
60% {
transform:translateX(100px) rotate(-360deg);
}
100% {
transform:translateX(200px) rotate(-360deg);
}
}
@keyframes radius{
0%,28% {
border-radius:0%
}
35%,38% {
border-bottom-right-radius:50%;
border-bottom-left-radius:0%;
}
45%,55% {
border-radius:50%
}
62%,65% {
border-bottom-right-radius:0%;
border-bottom-left-radius:50%;
}
70%,100% {
border-radius:0%
}
}
<div class="box"></div>
Gagasan gila lain di mana Anda dapat menghidupkan bentuk persegi panjang di belakang jalur melengkung transparan:
.box {
height: 165px;
width: 315px;
position: relative;
border-radius: 0 100px 100px 0;
animation: hide 3s infinite linear alternate;
overflow:hidden;
}
.box:after {
content: "";
display:block;
height: 100%;
background: white padding-box;
border-radius: inherit;
border: 15px solid transparent;
border-left:0;
box-sizing: border-box;
}
.alt {
margin-top: -165px;
transform: scaleX(-1);
transform-origin: 170px 0;
animation-direction: alternate-reverse;
}
.box:before {
content: "";
position: absolute;
z-index: -1;
width: 90px;
height: 90px;
background: blue;
bottom: -40px;
animation: loop 3s infinite linear alternate;
transform-origin: 50% -20px;
}
.alt:before {
animation-direction: alternate-reverse;
}
@keyframes loop {
15% {
transform: translateX(180px) rotate(0deg);
}
40% {
transform: translateX(180px) rotate(-180deg);
}
50%,100% {
transform: translateX(125px) rotate(-180deg);
}
}
@keyframes hide {
0%,50% {
visibility: visible;
}
50.2%,100% {
visibility: hidden;
}
}
<div class="box"></div>
<div class="box alt"></div>
Versi yang dioptimalkan dengan lebih sedikit kode dan dengan transparansi (akan mempertimbangkan mask
ini)
.box {
height: 165px;
width: 315px;
position: relative;
border-radius: 0 100px 100px 0;
animation: hide 3s infinite linear alternate;
overflow:hidden;
-webkit-mask:
linear-gradient(#fff,#fff) top left /235px 15px,
linear-gradient(#fff,#fff) bottom left/235px 15px,
radial-gradient(farthest-side at left,transparent calc(100% - 15px),#fff 0) right/100px 100%;
-webkit-mask-repeat:no-repeat;
mask:
linear-gradient(#fff,#fff) top left/235px 15px,
linear-gradient(#fff,#fff) bottom left/235px 15px,
radial-gradient(farthest-side at left,transparent calc(100% - 15px),#fff 0) right/100px 100%;
mask-repeat:no-repeat;
}
.alt {
margin-top: -165px;
transform: scaleX(-1);
transform-origin: 170px 0;
animation-direction: alternate-reverse;
}
.box:before {
content: "";
position: absolute;
width: 90px;
height: 90px;
background: blue;
bottom: -40px;
animation: loop 3s infinite linear alternate;
transform-origin: 50% -20px;
}
.alt:before {
animation-direction: alternate-reverse;
}
@keyframes loop {
15% {
transform: translateX(180px) rotate(0deg);
}
40% {
transform: translateX(180px) rotate(-180deg);
}
50%,100% {
transform: translateX(125px) rotate(-180deg);
}
}
@keyframes hide {
0%,50% {
visibility: visible;
}
50.2%,100% {
visibility: hidden;
}
}
body {
background:linear-gradient(to right,yellow,gray);
}
<div class="box"></div>
<div class="box alt"></div>
Versi lain dengan nilai piksel dan variabel CSS yang lebih sedikit di mana Anda dapat dengan mudah mengatur semuanya.
Jalankan cuplikan di halaman penuh dan bersenang-senang dengan semua coaster!
.box {
--w:400px; /* Total width of the coaster */
--h:180px; /* Height of the coaster */
--b:90px; /* width of the small bar */
--t:15px; /* height of the small bar */
--c:blue; /* Color of the small bar */
width:var(--w);
height:var(--h);
}
.box > div {
height: 100%;
position:relative;
width: calc(50% + var(--h)/2 + var(--b)/2);
border-radius: 0 1000px 1000px 0;
animation: hide 3s infinite linear alternate;
-webkit-mask:
linear-gradient(#fff,#fff) top left /calc(100% - var(--h)/2) var(--t),
linear-gradient(#fff,#fff) bottom left/calc(100% - var(--h)/2) var(--t),
radial-gradient(farthest-side at left,transparent calc(100% - var(--t)),#fff 0) right/calc(var(--h)/2) 100%;
-webkit-mask-repeat:no-repeat;
mask:
linear-gradient(#fff,#fff) top left /calc(100% - var(--h)/2) var(--t),
linear-gradient(#fff,#fff) bottom left/calc(100% - var(--h)/2) var(--t),
radial-gradient(farthest-side at left,transparent calc(100% - var(--t)),#fff 0) right/calc(var(--h)/2) 100%;
mask-repeat:no-repeat;
}
.box > div:last-child {
margin-top:calc(-1*var(--h));
margin-left:auto;
transform: scaleX(-1);
animation-direction: alternate-reverse;
}
.box > div:before {
content: "";
position: absolute;
width: var(--b);
height: 50%;
background: var(--c);
bottom: -25%;
animation: loop 3s infinite linear alternate;
transform-origin: 50% -50%;
}
.box > div:last-child:before {
animation-direction: alternate-reverse;
}
@keyframes loop {
15% {
transform: translateX(calc(var(--w)/2)) rotate(0deg);
}
40% {
transform: translateX(calc(var(--w)/2)) rotate(-180deg);
}
50%,100% {
transform: translateX(calc(var(--w)/2 - var(--b)/2)) rotate(-180deg);
}
}
@keyframes hide {
50% {
visibility: visible;
}
50.1%,100% {
visibility: hidden;
}
}
body {
background:linear-gradient(to right,yellow,gray);
}
<div class="box">
<div></div><div></div>
</div>
<div class="box" style="--w:500px;--h:80px;--b:50px;--c:red;--t:5px">
<div></div><div></div>
</div>
<div class="box" style="--w:90vw;--h:200px;--b:100px;--c:purple;--t:20px">
<div></div><div></div>
</div>
Untuk memahami triknya, mari kita hapus topeng dan ganti dengan gradien sederhana dan hapus animasi sembunyikan:
.box {
--w:400px; /* Total width of the coaster */
--h:180px; /* Height of the coaster */
--b:90px; /* width of the small bar */
--t:15px; /* height of the small bar */
--c:blue; /* Color of the small bar */
width:var(--w);
height:var(--h);
}
.box > div {
height: 100%;
position:relative;
width: calc(50% + var(--h)/2 + var(--b)/2);
border-radius: 0 1000px 1000px 0;
/*animation: hide 3s infinite linear alternate;*/
background:
linear-gradient(red,red) top left /calc(100% - var(--h)/2) var(--t),
linear-gradient(green,green) bottom left/calc(100% - var(--h)/2) var(--t),
radial-gradient(farthest-side at left,transparent calc(100% - var(--t)),black 0) right/calc(var(--h)/2) 100%;
background-repeat:no-repeat;
}
.box > div:last-child {
margin-top:calc(-1*var(--h));
margin-left:auto;
transform: scaleX(-1);
animation-direction: alternate-reverse;
}
.box > div:before {
content: "";
position: absolute;
width: var(--b);
height: 50%;
background: var(--c);
bottom: -25%;
animation: loop 3s infinite linear alternate;
transform-origin: 50% -50%;
}
.box > div:last-child:before {
animation-direction: alternate-reverse;
background:purple;
}
@keyframes loop {
15% {
transform: translateX(calc(var(--w)/2)) rotate(0deg);
}
40% {
transform: translateX(calc(var(--w)/2)) rotate(-180deg);
}
50%,100% {
transform: translateX(calc(var(--w)/2 - var(--b)/2)) rotate(-180deg);
}
}
@keyframes hide {
0%,50% {
visibility: visible;
}
50.2%,100% {
visibility: hidden;
}
}
body {
background:linear-gradient(to right,yellow,gray);
}
<div class="box">
<div></div><div></div>
</div>
Path yang dibuat oleh gradient adalah mask kita dan kita hanya akan melihat bagian itu. Kemudian kita membuat persegi panjang kita untuk mengikuti jalan dan triknya adalah memiliki dua elemen simetris untuk membuat efek loop. The menyembunyikan animasi akan memungkinkan kita untuk melihat hanya salah satu dari mereka dan tumpang tindih yang sempurna akan membuat animasi terus menerus.
Ini adalah versi jika Anda ingin lingkaran untuk coaster
.box {
--w:400px; /* Total width of the coaster */
--h:180px; /* Height of the coaster */
--b:90px; /* width of the small bar */
--t:15px; /* height of the small bar */
--c:blue; /* Color of the small bar */
width:var(--w);
height:var(--h);
}
.box > div {
height: 100%;
position:relative;
width: calc(50% + var(--h)/2);
border-radius: 0 1000px 1000px 0;
animation: hide 3s infinite linear alternate;
-webkit-mask:
radial-gradient(farthest-side at bottom right,transparent calc(100% - var(--t)),#fff 0 100%,transparent 100%) top 0 right calc(var(--h)/2)/calc(var(--h)/2) 50%,
linear-gradient(#fff,#fff) bottom left/calc(100% - var(--h)/2) var(--t),
radial-gradient(farthest-side at left,transparent calc(100% - var(--t)),#fff 0) right/calc(var(--h)/2) 100%;
-webkit-mask-repeat:no-repeat;
mask:
radial-gradient(farthest-side at bottom right,transparent calc(100% - var(--t)),#fff 0 100%,transparent 100%) top 0 right calc(var(--h)/2)/calc(var(--h)/2) 50%,
linear-gradient(#fff,#fff) bottom left/calc(100% - var(--h)/2) var(--t),
radial-gradient(farthest-side at left,transparent calc(100% - var(--t)),#fff 0) right/calc(var(--h)/2) 100%;
mask-repeat:no-repeat;
}
.box > div:last-child {
margin-top:calc(-1*var(--h));
margin-left:auto;
transform: scaleX(-1);
animation-direction: alternate-reverse;
}
.box > div:before {
content: "";
position: absolute;
width: var(--b);
height: 50%;
background: var(--c);
bottom: -25%;
animation: loop 3s infinite linear alternate;
transform-origin: 50% -50%;
}
.box > div:last-child:before {
animation-direction: alternate-reverse;
}
@keyframes loop {
15% {
transform: translateX(calc(var(--w)/2 - var(--b)/2)) rotate(0deg);
}
50%,100% {
transform: translateX(calc(var(--w)/2 - var(--b)/2)) rotate(-180deg);
}
}
@keyframes hide {
50% {
visibility: visible;
}
50.1%,100% {
visibility: hidden;
}
}
body {
background:linear-gradient(to right,yellow,gray);
}
<div class="box">
<div></div><div></div>
</div>
<div class="box" style="--w:500px;--h:80px;--b:50px;--c:red;--t:5px">
<div></div><div></div>
</div>
<div class="box" style="--w:90vw;--h:200px;--b:100px;--c:purple;--t:20px">
<div></div><div></div>
</div>