1. 先看成品

codepen体验

(因为图片大小问题,只截取了一部分。实际效果是始终滚动,不会有动画复位的割裂感。)

2. 问题拆分

首先看到这个需要的时候,感觉比拟难做,次要是上面的起因:须要斜着滚动,且须要有限,再就是icon错位排列的问题。

起初思考了下,对这个问题进行了拆分:

  1. 编写容器及icon等的 css
  2. 排列好icon并且丢到一个wrapper中
  3. 将整个wrapper歪斜30度
  4. 为wrapper增加有限的横向滚动动画

话不多说,开始写代码

3. 开始口头

为了不便看边界,对于一些dom增加了边框~

3.1 创立容器

容器是一个固定大小的比拟好写

.box {    height: 666px;    width: 1182px;    border-radius: 36px;    border: 1px solid;    overflow: hidden;    text-align: center;    font-size: 30px;}

3.2 而后撸个icon进去

这里就不应用图片来做了,对立用这个mock 一下~

.icon {    width: 267px;    height: 267px;    border-radius: calc(267px * 0.23);    background-image: conic-gradient(        hsl(360, 100%, 50%),        hsl(315, 100%, 50%),        hsl(270, 100%, 50%),        hsl(225, 100%, 50%),        hsl(180, 100%, 50%),        hsl(135, 100%, 50%),        hsl(90, 100%, 50%),        hsl(45, 100%, 50%),        hsl(0, 100%, 50%)    );}

3.3 排列icon到wrapper中

咱们把脖子沿逆时针方向旋转30度发现,实际上就是错落有致的摆放着两排icon。

咱们依照图示动态的摆放一下:

<div class="box">    <div class="lean-box">        <div class="wrapper">            <div class="icon-pair">                <div class="icon">1</div>                <div class="icon">2</div>            </div>            <div class="icon-pair">                <div class="icon">3</div>                <div class="icon">4</div>            </div>            <div class="icon-pair">                <div class="icon">5</div>                <div class="icon">6</div>            </div>            <div class="icon-pair">                <div class="icon">7</div>                <div class="icon">8</div>            </div>        </div>    </div></div>
.lean-box {    display: flex;    transform: rotate(-30deg);}.wrapper {    margin-top: 180px;    display: flex;    flex-wrap: nowrap;}.wrapper .icon:nth-child(even) {    margin-top: 45px;    transform: translate(155px);}.icon-pair {    margin-left: 45px;}.icon {    display: flex;    align-items: center;    justify-content: center;    color: white;    font-size: 66px;    font-weight: bold;}

这样看起来就很有精力了,接下来咱们须要让它动起来

3.4 增加动画

这里动起来应用的是animation,于是,编写下列代码并且增加到wrapper上:

@keyframes rowup {    from {        transform: translateX(0%);    }    to {        transform: translateX(-500px);    }}.wrapper {    margin-top: 180px;    display: flex;    flex-wrap: nowrap;    animation: rowup 5s linear infinite;}

这时候动是动起来了,接下来的问题是,怎么有限的进行滚动呢?

有限到是动静增加dom,销毁dom,就是在这一组wrapper后创立一组截然不同的wrapper,等本组齐全隐没后销毁。

可是,这个老本会很高不是吗,而且这种实现形式势必须要随工夫去更新icon的地位,肯定有更好的办法

3.5 无缝滚动

animation动画完结后会回归第一帧,假如咱们让第一帧的动画和最初一帧重合,那么是不是就看起来是无缝的了?

于是我将wrapper外面的元素从新拷贝一份放在前面(以后组称为A,拷贝组称为B),当动画完结时,B刚好挪动到A的初始地位。

咱们来计算一下:

这里一组8个icon排两排状况,挪动的宽度应该为4个 icon宽度+ 4个margin,(267 4) + (45 4) = 1248px,这样 B 就能够刚好挪动到 A 了

更新下动画:

@keyframes rowup {    from {        transform: translateX(0%);    }    to {        transform: translateX(-1248px);    }}

html 也相应更新下:

<div class="box">    <div class="lean-box">        <div class="wrapper">            <div class="icon-pair">                <div class="icon">1</div>                <div class="icon">2</div>            </div>            <div class="icon-pair">                <div class="icon">3</div>                <div class="icon">4</div>            </div>            <div class="icon-pair">                <div class="icon">5</div>                <div class="icon">6</div>            </div>            <div class="icon-pair">                <div class="icon">7</div>                <div class="icon">8</div>            </div>            <div class="icon-pair">                <div class="icon">1</div>                <div class="icon">2</div>            </div>            <div class="icon-pair">                <div class="icon">3</div>                <div class="icon">4</div>            </div>            <div class="icon-pair">                <div class="icon">5</div>                <div class="icon">6</div>            </div>            <div class="icon-pair">                <div class="icon">7</div>                <div class="icon">8</div>            </div>        </div>    </div></div>

3.6 欠缺一下

如果每次都要依据组件个数去计算的话,的确有点low了,其实会搁置两个截然不同的icons,所以translateX的间隔不须要计算,设置为-50%就好了,最终代码如下(能够在codepen上体验):

<div class="box">    <div class="lean-box">        <div class="wrapper">            <div class="icon-pair">                <div class="icon">1</div>                <div class="icon">2</div>            </div>            <div class="icon-pair">                <div class="icon">3</div>                <div class="icon">4</div>            </div>            <div class="icon-pair">                <div class="icon">5</div>                <div class="icon">6</div>            </div>            <div class="icon-pair">                <div class="icon">7</div>                <div class="icon">8</div>            </div>            <div class="icon-pair">                <div class="icon">1</div>                <div class="icon">2</div>            </div>            <div class="icon-pair">                <div class="icon">3</div>                <div class="icon">4</div>            </div>            <div class="icon-pair">                <div class="icon">5</div>                <div class="icon">6</div>            </div>            <div class="icon-pair">                <div class="icon">7</div>                <div class="icon">8</div>            </div>        </div>    </div></div>
@keyframes rowup {    from {        transform: translateX(0%);    }    to {        transform: translateX(-50%);    }}.box {    height: 666px;    width: 1182px;    border-radius: 36px;    border: 1px solid;    overflow: hidden;    text-align: center;    font-size: 30px;}.icon {    width: 267px;    height: 267px;    border-radius: calc(267px * 0.23);    background-image: conic-gradient(        hsl(360, 100%, 50%),        hsl(315, 100%, 50%),        hsl(270, 100%, 50%),        hsl(225, 100%, 50%),        hsl(180, 100%, 50%),        hsl(135, 100%, 50%),        hsl(90, 100%, 50%),        hsl(45, 100%, 50%),        hsl(0, 100%, 50%)    );}.lean-box {    display: flex;    transform: rotate(-30deg);}.wrapper {    margin-top: 180px;    display: flex;    flex-wrap: nowrap;    animation: rowup 5s linear infinite;}.wrapper .icon:nth-child(even) {    margin-top: 45px;    transform: translate(155px);}.icon-pair {    margin-left: 45px;}.icon {    display: flex;    align-items: center;    justify-content: center;    color: white;    font-size: 66px;    font-weight: bold;}