텍스트 회전판과 그림 회전판을 만드는 방법은 무엇입니까? 누구나 가장 먼저 생각하는 것은 js를 사용할지 여부입니다. 실제로 순수 CSS를 사용하여 구현하는 방법도 모두에게 도움이 되기를 바랍니다.
오늘은 실제 비즈니스에서 활용할 수 있는 애니메이션 기법을 공유해보겠습니다. [추천 학습:css 비디오 튜토리얼]
프레임별 애니메이션과 트윈 애니메이션을 스마트하게 사용하여 무한 루프 캐러셀 효과를 구현합니다. 다음과 같습니다.
위 다이어그램을 보면 거기에 학생들이 묻지 않을 수 없군요. 아주 단순한 변위 애니메이션 아닌가요?
간단히 분석해 보겠습니다. 표면적으로는 요소의transform:translate()
만 대체되는 것 같습니다.transform: translate()
在位移,但是注意,这里有两个难点:
这是个无限轮播的效果,我们的动画需要支持任意多个元素的无限轮播切换
因为是轮播,所以,运行到最后一个的时候,需要动画切到第一个元素
到这里,你可以暂停思考一下,如果有 20 个元素,需要进行类似的无限轮播播报,使用 CSS 实现,你会怎么去做呢?
首先,我需要利用到逐帧动画效果,也被称为步骤缓动函数,利用的是animation-timing-function
中,的 steps,语法如下:
{ /* Keyword values */ animation-timing-function: step-start; animation-timing-function: step-end; /* Function values */ animation-timing-function: steps(6, start) animation-timing-function: steps(4, end); }
如果你对steps
的语法还不是特别了解,强烈建议你先看看我的这篇文章 -- 深入浅出 CSS 动画,它对理解本文起着至关重要的作用。
好的,还是文章以开头的例子,假设我们存在这样 HTML 结构:
- Lorem ipsum 1111111
- Lorem ipsum 2222222
- Lorem ipsum 3333333
- Lorem ipsum 4444444
- Lorem ipsum 5555555
- Lorem ipsum 6666666
首先,我们实现这样一个简单的布局:
在这里,要实现轮播效果,并且是任意个数,我们可以借助animation-timing-function: steps()
:
:root { // 轮播的个数 --s: 6; // 单个 li 容器的高度 --h: 36; // 单次动画的时长 --speed: 1.5s; } .g-container { width: 300px; height: calc(var(--h) * 1px); } ul { display: flex; flex-direction: column; animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite; } ul li { width: 100%; } @keyframes move { 0% { transform: translate(0, 0); } 100% { transform: translate(0, calc(var(--s) * var(--h) * -1px)); } }
别看到上述有几个 CSS 变量就慌了,其实很好理解:
calc(var(--speed) * var(--s))
:单次动画的耗时 * 轮播的个数,也就是总动画时长
steps(var(--s))
就是逐帧动画的帧数,这里也就是steps(6)
,很好理解
calc(var(--s) * var(--h) * -1px))
单个 li 容器的高度 * 轮播的个数,其实就是 ul 的总体高度,用于设置逐帧动画的终点值
上述的效果,实际如下:
如果给容器添加上overflow: hidden
,就是这样的效果:
这样,我们就得到了整体的结构,至少,整个效果是循环的。
但是由于只是逐帧动画,所以只能看到切换,但是每一帧之间,没有过渡动画效果。所以,接下来,我们还得引入补间动画。
我们需要利用补间动画,实现动态的切换效果。
这一步,其实也非常简单,我们要做的,就是将一组数据,利用transform
하지만 주의하세요
를 사용하여 단계 이징 기능으로도 알려진 프레임별 애니메이션 효과를 사용해야 합니다. animation-timing-function code>, 단계, 구문은 다음과 같습니다. <div class="g-container"> <ul style="--s: 6"> <li>Lorem ipsum 1111111</li> <li>Lorem ipsum 2222222</li> <li>Lorem ipsum 3333333</li> <li>Lorem ipsum 4444444</li> <li>Lorem ipsum 5555555</li> <li>Lorem ipsum 6666666</li> </ul> </div>
로그인 후 복사 단계
구문에 특별히 익숙하지 않은 경우 먼저 내 기사를 읽어 보시기 바랍니다. - CSS 애니메이션에 대한 간단한 설명은 이 글을 이해하는 데 매우 유용합니다.
글의 시작 부분에 있는 예제를 사용하겠습니다. 다음과 같은 HTML 구조가 있다고 가정합니다.
:root { --h: 36; --speed: 1.2s; } ul li { height: 36px; animation: liMove calc(var(--speed)) infinite; } @keyframes liMove { 0% { transform: translate(0, 0); } 80%, 100% { transform: translate(0, -36px); } }
로그인 후 복사
먼저 다음과 같은 간단한 레이아웃을 구현합니다.
![](https://img.php.cn/upload/article/000/000/024/c34b75c6e1124174fd23f5fa98b69af7-3.png)
![](https://img.php.cn/upload/article/000/000/024/e27aa96b32b052ccec9384dfb834de87-7.gif)
여기서 캐러셀 효과를 얻으려면 , 숫자에 관계없이
animation-timing-function: steps()
를 사용할 수 있습니다.
:root { // 轮播的个数 --s: 6; // 单个 li 容器的高度 --h: 36; // 单次动画的时长 --speed: 1.5s; } .g-container { width: 300px; height: calc(var(--h) * 1px); } ul { display: flex; flex-direction: column; animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite; } ul li { width: 100%; animation: liMove calc(var(--speed)) infinite; } @keyframes move { 0% { transform: translate(0, 0); } 100% { transform: translate(0, calc(var(--s) * var(--h) * -1px)); } } @keyframes liMove { 0% { transform: translate(0, 0); } 80%, 100% { transform: translate(0, calc(var(--h) * -1px)); } }
로그인 후 복사
위의 여러 CSS 변수를 보면 당황하지 마세요. 실제로 이해하기 쉽습니다.< ul style="list-style-type: disc;">
calc(var(--speed) * var(--s))
: 단일 애니메이션의 시간 소비* Carousel 숫자, 즉 총 애니메이션 기간
steps(var(--s))
은 프레임별 애니메이션의 프레임 수입니다. 여기서는단계( 6)
이며 이해하기 쉽습니다
calc(var(--s) * var(--h) * -1px)) code> 단일 li 컨테이너 높이 * 캐러셀 수는 실제로 프레임별 애니메이션의 끝점 값을 설정하는 데 사용되는 ul의 전체 높이입니다
위 효과 실제로는 다음과 같습니다.
컨테이너에 overflow:hidden
을 추가하면 다음과 같은 효과가 나타납니다.
이런 방식으로 우리는 전체적인 구조를 얻으려면 적어도 전체 효과는 순환적입니다. 하지만 프레임별 애니메이션이기 때문에 전환만 볼 수 있을 뿐 각 프레임 간 전환 애니메이션 효과는 없습니다. 그럼 다음으로 트위닝 애니메이션을 소개하겠습니다.트위닝 애니메이션을 사용하여 두 데이터 세트 간 전환
동적인 전환 효과를 얻으려면 트위닝 애니메이션을 사용해야 합니다. 이 단계는 실제로 매우 간단합니다. 우리가 해야 할 일은transform
을 사용하여 데이터 세트를 A 상태에서 B 상태로 이동하는 것입니다. 시연용으로 하나만 꺼내면 대략적인 코드는 다음과 같습니다.
- Lorem ipsum 1111111
- Lorem ipsum 2222222
- Lorem ipsum 3333333
- Lorem ipsum 4444444
- Lorem ipsum 5555555
- Lorem ipsum 6666666
- Lorem ipsum 1111111
로그인 후 복사
로그인 후 복사
- Lorem ipsum 1111111
- Lorem ipsum 2222222
- Lorem ipsum 3333333
- Lorem ipsum 4444444
- Lorem ipsum 5555555
- Lorem ipsum 6666666
- Lorem ipsum 1111111
로그인 후 복사
로그인 후 복사
아주 간단한 애니메이션: 위 효과를 바탕으로 프레임별 애니메이션을 결합하면 처음과 여기에서 언급한 이 트윈 애니메이션을 결합하면 ul의 전체 움직임이 li의 단일 움직임에 겹쳐집니다.
:root { --w: 300; --speed: 1.5s; } .g-container { width: calc(--w * 1px); overflow: hidden; } ul { display: flex; flex-wrap: nowrap; animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite; } ul li { flex-shrink: 0; width: 100%; height: 100%; animation: liMove calc(var(--speed)) infinite; } @keyframes move { 0% { transform: translate(0, 0); } 100% { transform: translate(calc(var(--s) * var(--w) * -1px), 0); } } @keyframes liMove { 0% { transform: translate(0, 0); } 80%, 100% { transform: translate(calc(var(--w) * -1px), 0); } }
로그인 후 복사
로그인 후 복사
는 다음과 같은 효과를 얻을 수 있습니다. 와우, 마법의 화학 반응 발생했습니다! 프레임별 애니메이션과 트위닝된 애니메이션을 결합하여 거의 캐러셀 효과를 구현했습니다.当然,有一点瑕疵,可以看到,最后一组数据,是从第六组数据 transform 移动向了一组空数据:
![](https://img.php.cn/upload/article/000/000/024/e27aa96b32b052ccec9384dfb834de87-8.png)
末尾填充头部第一组数据
实际开发过轮播的同学肯定知道,这里,其实也很好处理,我们只需要在末尾,补一组头部的第一个数据即可:
改造下我们的 HTML:
- Lorem ipsum 1111111
- Lorem ipsum 2222222
- Lorem ipsum 3333333
- Lorem ipsum 4444444
- Lorem ipsum 5555555
- Lorem ipsum 6666666
- Lorem ipsum 1111111
로그인 후 복사
로그인 후 복사
这样,我们再看看效果:
![](https://img.php.cn/upload/article/000/000/024/6590228ce450f1514641f4145b70c351-9.gif)
Beautiful!如果你还有所疑惑,我们给容器加上overflow: hidden
,实际效果如下,通过额外添加的最后一组数据,我们的整个动画刚好完美的衔接上,一个完美的轮播效果:
![](https://img.php.cn/upload/article/000/000/024/029f5f7ed65279be7e0a08f5abadad09-2.gif)
完整的代码,你可以戳这里:CodePen Demo -- Vertical Infinity Loop
https://codepen.io/Chokcoco/pen/RwQVByx
横向无限轮播
当然,实现了竖直方向的轮播,横向的效果也是一样的。
并且,我们可以通过在 HTML 结构中,通过 style 内填写 CSS 变量值,传入实际的 li 个数,以达到根据不同 li 个数适配不同动画:
- Lorem ipsum 1111111
- Lorem ipsum 2222222
- Lorem ipsum 3333333
- Lorem ipsum 4444444
- Lorem ipsum 5555555
- Lorem ipsum 6666666
- Lorem ipsum 1111111
로그인 후 복사
로그인 후 복사
整个动画的 CSS 代码基本是一致的,我们只需要改变两个动画的transform
值,从竖直位移,改成水平位移即可:
:root { --w: 300; --speed: 1.5s; } .g-container { width: calc(--w * 1px); overflow: hidden; } ul { display: flex; flex-wrap: nowrap; animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite; } ul li { flex-shrink: 0; width: 100%; height: 100%; animation: liMove calc(var(--speed)) infinite; } @keyframes move { 0% { transform: translate(0, 0); } 100% { transform: translate(calc(var(--s) * var(--w) * -1px), 0); } } @keyframes liMove { 0% { transform: translate(0, 0); } 80%, 100% { transform: translate(calc(var(--w) * -1px), 0); } }
로그인 후 복사
로그인 후 복사
这样,我们就轻松的转化为了横向的效果:
![](https://img.php.cn/upload/article/000/000/024/b864f2195b18884e8bc0a1830ee55acc-11.gif)
完整的代码,你可以戳这里:CodePen Demo -- Horizontal Infinity Loop
https://codepen.io/Chokcoco/pen/JjpNBXY
轮播图?不在话下
OK,上面的只是文字版的轮播,那如果是图片呢?
没问题,方法都是一样的。基于上述的代码,我们可以轻松地将它修改一下后得到图片版的轮播效果。
代码都是一样的,就不再列出来,直接看看效果:
![](https://img.php.cn/upload/article/000/000/024/b864f2195b18884e8bc0a1830ee55acc-12.gif)
完整的代码,你可以戳这里:CodePen Demo -- Horizontal Image Infinity Loop
https://codepen.io/Chokcoco/pen/GRQvqgq
掌握了这个技巧之后,你可以将它运用在非常多只需要简化版的轮播效果之上。
再简单总结一下,非常有意思的技巧:
利用逐帧动画,实现整体的轮播的循环效果
利用补间动画,实现具体的状态A向状态B* 的动画效果
逐帧动画配合补间动画构成整体轮播的效果
通过向 HTML 结构末尾补充一组头部数据,实现整体动画的衔接
通过 HTML 元素的 style 标签,利用 CSS 变量,填入实际的参与循环的 DOM 个数,可以实现 JavaScript 与 CSS 的打通
(学习视频分享:web前端)
위 내용은 텍스트 캐러셀과 이미지 캐러셀도 순수 CSS를 사용하여 구현할 수 있다는 것이 밝혀졌습니다!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!