我一直在努力构建这个(如图所示)。我想制作一个弯曲的选框或无限滚动轮播,其中每个项目(在本例中为标志)将从左向右移动。当标志进入视口中心时,在这种情况下进入窗口区域 - 窗口背景将被更改。我该如何构建这个?如有任何疑问,请告诉我。
注意:任何第三方库(如 gsap)都可以使用,我没有问题。
这是一个基本想法。 每个标志都位于 div 的“末尾”作为背景图像。
每个 div 都按照您决定的宽度居中放置,并与下一个标志围绕您定义的圆弧放置一定距离。
然后计算 div 的高度,以使该距离在它们从中心点旋转放置时发生。
然后整体无限旋转。
顶部矩形的颜色变化是单独完成的,但动画持续时间相同。
此关键帧将 CSS 变量 --bg 设置为与第一个、第二个等标志相关的背景颜色。
此设置仅在 CSS 中作为演示。在现实生活中,我会实现一些 JS 来减少设置的繁琐,因此可以从 DOM 中获取标志数量并相应地设置关键帧。
我担心 CPU 使用率,但即使在没有高级 GPU 的简单笔记本电脑上,它似乎也只有百分之几。
body {
margin: 0;
display: flex;
flex-direction: column;
width: 100vw;
justify-content: center;
position: relative;
align-items: center;
overflow: hidden;
}
.flags-container {
overflow: hidden;
clip-path: polygon(0 0, 100% 0, 100% 25%, 0 25%);
position: relative;
--num: 20;
/* number of flags */
--a: 10vmin;
/* set this to the distance along the arc between two flags that you want */
--r: calc(2 * var(--a) * var(--num) / pi);
--w: calc(2 * var(--r));
width: var(--w);
aspect-ratio: 1;
top: 15vmin;
display: block;
}
.flags-container::before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 10%;
aspect-ratio: 2 / 1;
animation: color 60s infinite linear;
z-index: -1;
background-color: var(--bg);
}
@keyframes color {
0% {
--bg: red;
}
5% {
--bg: green;
}
10% {
--bg: blue;
}
15% {
--bg: black;
}
20% {
--bg: cyan;
}
25% {
--bg: magenta;
}
30% {
--bg: yellow;
}
35% {
--bg: red;
}
40% {
--bg: green;
}
45% {
--bg: blue;
}
50% {
--bg: black;
}
55% {
--bg: cyan;
}
60% {
--bg: magenta;
}
65% {
--bg: yellow;
}
70% {
--bg: red;
}
75% {
--bg: green;
}
80% {
--bg: blue;
}
85% {
--bg: black;
}
90% {
--bg: cyan;
}
95% {
--bg: magenta;
}
100% {
--bg: red;
}
}
.flags {
width: 100%;
height: 100%;
position: relative;
animation: rotate 60s infinite linear;
top: 1vmin;
}
@keyframes rotate {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
.flags>* {
width: 5%;
height: var(--r);
position: absolute;
top: 0;
left: 50%;
transform-origin: center bottom;
transform: translateX(-50%) rotate(calc((var(--n) - 1) * 360deg / var(--num)));
--bgi: url(https://i.sstatic.net/Yjh0wFnx.webp);
background-image: var(--bgi);
background-size: 100% auto;
background-position: center top;
background-repeat: no-repeat;
}
.flags>*:nth-child(1) {
--n: 1;
--bgi: url(https://i.sstatic.net/Yjh0wFnx.webp);
/* REMEMBER to set --bgi for each flag */
}
.flags>*:nth-child(2) {
--n: 2;
}
.flags>*:nth-child(3) {
--n: 3;
}
.flags>*:nth-child(4) {
--n: 4;
}
.flags>*:nth-child(5) {
--n: 5;
}
.flags>*:nth-child(6) {
--n: 6;
}
.flags>*:nth-child(7) {
--n: 7;
}
.flags>*:nth-child(8) {
--n: 8;
}
.flags>*:nth-child(9) {
--n: 9;
}
.flags>*:nth-child(10) {
--n: 10;
}
.flags>*:nth-child(11) {
--n: 11;
}
.flags>*:nth-child(12) {
--n: 12;
}
.flags>*:nth-child(13) {
--n: 13;
}
.flags>*:nth-child(14) {
--n: 14;
}
.flags>*:nth-child(15) {
--n: 15;
}
.flags>*:nth-child(16) {
--n: 16;
}
.flags>*:nth-child(17) {
--n: 17;
}
.flags>*:nth-child(18) {
--n: 18;
}
.flags>*:nth-child(19) {
--n: 19;
}
.flags>*:nth-child(20) {
--n: 20;
}
<div class="flags-container">
<div class="bg"></div>
<div class="flags">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<style>
.mask1 {
mask-image: linear-gradient(black 0 100px, transparent 100px 100%);
mask-size: 100px 100px;
mask-repeat: no-repeat;
mask-position: 50% 10%;
background-image: conic-gradient(red, yellow, blue, green);
width: 600px;
height: 300px;
}