순수한 CSS를 사용하여 애니메이션과 같은 흥미로운 것을 구현하는 방법은 무엇입니까? 다음 기사에서는 전환을 영리하게 사용하여 애니메이션처럼 구현하는 방법을 안내합니다. 도움이 되길 바랍니다.
다양한 짧은 비디오 인터페이스에서 다음과 같은 애니메이션을 자주 볼 수 있습니다.
매우 흥미롭고 흥미로운 상호 작용으로 인해 사용자가 더 기꺼이 상호 작용할 수 있습니다.
그렇다면 순수한 CSS를 사용하여 이렇게 재미있는 애니메이션을 구현하는 것이 가능할까요? 물론 이 글에서는 transition
을 교묘하게 사용하여 CSS만을 사용하여 이와 같은 애니메이션을 완성할 것입니다. [추천 학습: CSS 동영상 튜토리얼]transition
,仅仅使用 CSS 完成这么一个点赞动画。【推荐学习:css视频教程】
如果使用纯 CSS 实现这一整套动画的话。我们首先需要实现一段无限循环的,大量不同的表情不断向上漂浮的动画。
像是这样:
这个整体还是比较容易实现的,核心原理就是同一个动画,设置不同的 transition-duration
,transition-dalay
,和一定范围内的旋转角度。
我们首先要实现多个表情,一个 DOM 标签放入一个随机的表情。
我们可以手动一个一个的添加:
<ul class="g-wrap"> <li>?</li> <li>❤️</li> <li>?</li> // ... 随机设置不同的表情符号,共 50 个 <li>...</li> </ul>
当然,我个人觉得这样太麻烦。我习惯利用 SASS 的循环函数及随机函数,利用伪元素的 content
去随机生成不同表情。像是这样:
<ul class="g-wrap"> <li></li> <li></li> <li></li> // ... 共50个空标签 </ul>
$expression: "?", "?", "❤️", "?", "?", "?", "?", "?", "??", "?", "?", "?", "?", "?"; .g-wrap { position: relative; width: 50px; height: 50px; } @for $i from 1 to 51 { li:nth-child(#{$i}) { position: absolute; top: 0; left: 0; width: 50px; height: 50px; &::before { content: nth($expression, random(length($expression))); position: absolute; font-size: 50px; } } }
这样,我们就能得到 50 个叠加在一起的表情:
因为透明度为 1 的缘故,只能看到最上面的几个表情,实际上这里叠加了 50 个不同的表情。
这里的核心就是 content: nth($expression, random(length($expression)))
,我们利用了 SASS 的 random 和 length 和 nth 等方法,随机的将 $expression
列表中的表情,添加给了不同的 li 的 before 伪元素的 content 内。
接下来,我们需要让它们动起来。
这个简单,添加一个无限的 transform: translate()
动画即可:
@for $i from 1 to 51 { li:nth-child(#{$i}) { animation: move 3000ms infinite linear; } } @keyframes move { 100% { transform: translate(0, -250px); } }
效果如下:
OK,由于 50 个元素都叠加在一起,所以我们需要将动画区分开来,我们给它们添加随机的动画时长,并且,赋予不同的负 transition-delay
值:
@for $i from 1 to 51 { li:nth-child(#{$i}) { animation: move #{random() * 2500 + 1500}ms infinite #{random() * 4000 / -1000}s linear; } } @keyframes move { 100% { transform: translate(0, -250px); } }
效果如下:
效果已经非常接近我们想要的了!这里有一点点的跳跃,需要理解 move #{random() * 2500 + 1500}ms infinite #{random() * 4000 / -1000}s linear
这里大段代码:
#{random() * 2500 + 1500}ms
生成 1500ms ~ 4000ms 之间的随机数,表示动画的持续时长
#{random() * 4000 / -1000}s
生成 -4000ms ~ 0s 之间的随机数,表示负的动画延迟量,这样做的目的是为了让动画提前进行
如果你对负的 transition-delay
的作用还不了解,可以看看我的这篇文章 -- 深入浅出 CSS 动画
到这,还是不够随机,我们再通过随机添加一个较小的旋转角度,让整体的效果更加的随机:
@for $i from 1 to 51 { li:nth-child(#{$i}) { transform: rotate(#{random() * 80 - 40}deg); animation: move #{random() * 2500 + 1500}ms infinite #{random() * 4000 / -1000}s linear; } } @keyframes move { 100% { transform: rotate(0) translate(0, -250px); } }
这里 transform: rotate(#{random() * 80 - 40}deg)
다양한 분야의 지속적인 상승 달성 표현
순수한 CSS를 사용하여 전체 애니메이션 세트를 구현하는 경우.
먼저 위쪽으로 떠다니는 다양한 표현이 포함된 애니메이션의 무한 루프transition-duration
, transition-dalay
를 다르게 설정합니다. , 그리고 특정 범위 내의 회전 각도. 🎜🎜먼저 여러 표현식을 구현하고 임의의 표현식을 DOM 태그에 넣어야 합니다. 🎜🎜수동으로 하나씩 추가할 수도 있습니다. 🎜li { opacity: .1; transition: 1.5s opacity 0.8s; } li:active { opacity: 1; transition: .1s opacity; }
content
를 사용하여 다양한 표현식을 무작위로 생성하는 데 익숙합니다. 다음과 같습니다: 🎜@for $i from 1 to 51{ li:nth-child(#{$i}) { position: absolute; top: 0; left: 0; width: 50px; height: 50px; transform: rotate(#{random() * 80 - 40}deg); animation: move #{random() * 2500 + 1500}ms infinite #{random() * 4000 / -1000}s linear; opacity: .1; transition: 1.5s opacity .8s; &::before { content: nth($expression, random(length($expression))); position: absolute; } } li:active { opacity: 1; transition: .1s opacity; } } @keyframes move { 100% { transform: rotate(0) translate(0, -250px); } }
<ul class="g-wrap"> <li></li> <li></li> <li></li> // ... 共50个空标签 </ul>
투명도가 1이므로 상위 몇개의 표현식만 보입니다. 실제로 50가지의 다른 표현식이 있습니다. 여기에 겹쳐서.🎜여기서 핵심은
content: nth($expression, random(length($expression)))
입니다. SASS의 무작위, 길이 및 n번째 방법을 사용하여 $expression 목록은 다른 li의 이전 의사 요소 내용에 추가됩니다. 🎜🎜다음으로 그들을 🎜이동🎜하게 만들어야 합니다. 🎜🎜이것은 간단합니다. 무한 transform:translate()
애니메이션을 추가하면 됩니다. 🎜$expression: "?", "?", "❤️", "?", "?", "?", "?", "?", "??", "?", "?", "?", "?", "?"; .g-wrap { position: relative; width: 50px; height: 50px; &::before { content: "??"; position: absolute; width: 50px; height: 50px; transition: 0.1s; } &:active::before { transform: scale(1.1); } } @for $i from 1 to 51 { li:nth-child(#{$i}) { position: absolute; width: 50px; height: 50px; transform: rotate(#{random() * 80 - 40}deg); animation: move #{random() * 2500 + 1500}ms infinite #{random() * 4000 / -1000}s cubic-bezier(.46,.53,.51,.62); opacity: 0; transition: 1.5s opacity .8s; &::before { content: nth($expression, random(length($expression))); position: absolute; } } li:active { transition: .1s opacity; opacity: 1!important; } } @keyframes move { 100% { transform: rotate(0) translate(0, -250px); } }
transition-delay
값을 제공합니다. 🎜rrreee🎜효과는 다음과 같습니다: 🎜🎜move #{random() * 2500 + 1500}ms 무한 #{random() * 4000 / -1000}s 선형
을 이해해야 합니다. 다음은 큰 코드 덩어리입니다. 🎜#{random() * 2500 + 1500}ms
기간을 나타내는 1500ms ~ 4000ms 사이의 난수를 생성합니다. 🎜#{random() * 4000 / -1000}s
음의 애니메이션 지연을 나타내는 -4000ms ~ 0s 사이의 난수를 생성합니다. 이것은 애니메이션을 미리 진행시키기 위한 것입니다🎜부정적인 transition-delay
의 역할을 이해하지 못한다면 제 글을 읽어보세요-- CSS 애니메이션에 대한 심층 설명
🎜현 시점에서는 아직 충분합니다🎜random🎜, 다시 살펴보겠습니다. 무작위로 더 작은 회전 각도를 추가하여 전체 효과를 더욱 무작위로 만듭니다. 🎜rrreee🎜여기transform:rotate(#{random() * 80 - 40}deg)
무작위로 생성하는데 사용됩니다. - 40deg ~ 40deg 사이의 임의의 숫자가 임의의 각도를 생성합니다. 🎜🎜이 시점에서 다음과 같은 효과가 나타납니다. 🎜🎜🎜🎜🎜🎜전환을 사용하여 부패를 마법으로 전환 🎜🎜🎜자, 시작합니다. 많은 학생들이 아직 이해하지 못할 수도 있습니다. 좋아요는 한 번에 하나의 표현을 생성하지만 왜 끊임없이 움직이는 표현을 한 번에 그렇게 많이 생성해야 합니까? 🎜🎜CSS는 한번의 클릭만으로 이모티콘을 직접 생성할 수 없기 때문에 발상의 전환이 필요합니다. 🎜如果这些表情一直都是在运动的,只不过不点击的时候,它们的透明度都为 0,我们要做的,就是当我们点击的时候,让它们从 opacity: 0
变到 opacity: 1
。
要实现这一点,我们需要巧妙的用到 transition
。
我们以一个表情为例子:
默认它的透明度为 opacity: 0.1
点击的时候,它的透明度瞬间变成 opacity: 1
然后,通过 transition-delay
让 opacity: 1
的状态保持一段时间后
逐渐再消失,变回 opacity: 0.1
看上去有亿点点复杂,代码会更容易理解:
li { opacity: .1; transition: 1.5s opacity 0.8s; } li:active { opacity: 1; transition: .1s opacity; }
效果如下:
一定要理解上面的代码!巧妙地利用 transition
在正常状态和 active
状态下的变化,我们实现了这种巧妙的点击效果。
如果我们把初始的 opacity: 0.1
改成 opacity: 0
呢?就会是这样:
好,我们结合一下上面两个动画:
我们将所有的表情,默认的透明度改为 0.1
被点击的时候,透明度变成 1
透明度在 1
维持一段时间,逐渐消失
代码如下:
@for $i from 1 to 51{ li:nth-child(#{$i}) { position: absolute; top: 0; left: 0; width: 50px; height: 50px; transform: rotate(#{random() * 80 - 40}deg); animation: move #{random() * 2500 + 1500}ms infinite #{random() * 4000 / -1000}s linear; opacity: .1; transition: 1.5s opacity .8s; &::before { content: nth($expression, random(length($expression))); position: absolute; } } li:active { opacity: 1; transition: .1s opacity; } } @keyframes move { 100% { transform: rotate(0) translate(0, -250px); } }
效果如下:
嘿,是不是有那么点意思了!
好最后一步,我们通过一个点击按钮引导用户点击,并且给与一个点击反馈,每次点击的时候,点赞按钮放大 1.1 倍,同时,我们把默认表情的透明度从 opacity: 0.1
彻底改为 opacity: 0
。
这样,整个动画的完整的核心代码:
<ul class="g-wrap"> <li></li> <li></li> <li></li> // ... 共50个空标签 </ul>
$expression: "?", "?", "❤️", "?", "?", "?", "?", "?", "??", "?", "?", "?", "?", "?"; .g-wrap { position: relative; width: 50px; height: 50px; &::before { content: "??"; position: absolute; width: 50px; height: 50px; transition: 0.1s; } &:active::before { transform: scale(1.1); } } @for $i from 1 to 51 { li:nth-child(#{$i}) { position: absolute; width: 50px; height: 50px; transform: rotate(#{random() * 80 - 40}deg); animation: move #{random() * 2500 + 1500}ms infinite #{random() * 4000 / -1000}s cubic-bezier(.46,.53,.51,.62); opacity: 0; transition: 1.5s opacity .8s; &::before { content: nth($expression, random(length($expression))); position: absolute; } } li:active { transition: .1s opacity; opacity: 1!important; } } @keyframes move { 100% { transform: rotate(0) translate(0, -250px); } }
这里,需要注意的是:
点赞的按钮,通过了父元素 .g-wrap
的伪元素实现,这样的好处是,子元素 li 的 :active
点击事件,是可以冒泡传给父元素的,这样每次子元素被点击,我们都可以放大一次点赞按钮,用于实现点击反馈;
稍微修改一下缓动函数,让整体效果更为均衡合理。
这样,我们就得到了题图一开始的效果,利用纯 CSS 实现的点赞动画:
完整的代码,你可以戳这里:CodePen Demo -- Like Animation
当然,这个方案是有一点点问题的。
1、就是如果当点击的速率过快,是无法实现一个点击,产生一个表情的
这是由于 CSS 方案的本质是通过点击一个透明表情,让它变成不透明。而点击过快的话,会导致两次或者多次点击,点在了同一个元素上,这样,就无法实现一个点击,产生一个表情。所以上面代码中修改缓动 cubic-bezier(.46,.53,.51,.62)
的目的也是在于,让元素动画前期运动更快,这样可以有利于适配更快的点击速率。
2、不仅仅是点击按钮,点击按钮上方也能出现效果
这样也很好理解,由于本质是个障眼法,所以点击按钮上方,只要是元素运动路径的地方,也是会有元素显形的。这个硬要解决也可以,通过再叠加一层透明元素在按钮上方,通过层级关系屏蔽掉点击事件。
3、表情的随机只是伪随机
利用 SASS 随机的方案在经过编译后是不会产生随机效果的。所以,这里只能是伪随机,基于 DOM 的个数,当 DOM 数越多,整体而言,随机的效果越好。基本上 50 个 DOM 是比较足够的。
4、CSS 版本的点赞效果是单机版
无法多用户联动,可能是影响能不能实际使用最为关键的因素。
그러나 전체적으로 순수 CSS를 사용하여 구현된 솔루션의 전체적인 효과는 좋습니다.
(학습 영상 공유: 웹 프론트엔드)
위 내용은 짧은 비디오 앱과 같은 애니메이션을 구현하기 위해 전환을 사용하는 방법을 단계별로 가르칩니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!