짧은 비디오 앱과 같은 애니메이션을 구현하기 위해 전환을 사용하는 방법을 단계별로 가르칩니다.

青灯夜游
풀어 주다: 2022-09-07 10:45:02
앞으로
2043명이 탐색했습니다.

순수한 CSS를 사용하여 애니메이션과 같은 흥미로운 것을 구현하는 방법은 무엇입니까? 다음 기사에서는 전환을 영리하게 사용하여 애니메이션처럼 구현하는 방법을 안내합니다. 도움이 되길 바랍니다.

짧은 비디오 앱과 같은 애니메이션을 구현하기 위해 전환을 사용하는 방법을 단계별로 가르칩니다.

다양한 짧은 비디오 인터페이스에서 다음과 같은 애니메이션을 자주 볼 수 있습니다.

매우 흥미롭고 흥미로운 상호 작용으로 인해 사용자가 더 기꺼이 상호 작용할 수 있습니다.

그렇다면 순수한 CSS를 사용하여 이렇게 재미있는 애니메이션을 구현하는 것이 가능할까요? 물론 이 글에서는 transition을 교묘하게 사용하여 CSS만을 사용하여 이와 같은 애니메이션을 완성할 것입니다. [추천 학습: CSS 동영상 튜토리얼]transition,仅仅使用 CSS 完成这么一个点赞动画。【推荐学习:css视频教程

实现不同表情的不断上升

如果使用纯 CSS 实现这一整套动画的话。我们首先需要实现一段无限循环的,大量不同的表情不断向上漂浮的动画

像是这样:

这个整体还是比较容易实现的,核心原理就是同一个动画,设置不同的 transition-durationtransition-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;
}
로그인 후 복사
로그인 후 복사
🎜물론 개인적으로는 이것이 너무 번거롭다고 생각합니다. 저는 SASS의 루프 함수와 랜덤 함수를 사용하고 의사 요소의 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>
로그인 후 복사
로그인 후 복사
로그인 후 복사
🎜이런 방법으로 50개의 이모티콘을 쌓을 수 있습니다: 🎜🎜🎜
투명도가 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);
    }
}
로그인 후 복사
로그인 후 복사
🎜효과는 다음과 같습니다: 🎜🎜🎜🎜좋아, 50개의 요소가 겹쳐졌으므로 우리는 애니메이션을 구별해야 하고, 애니메이션에 임의의 애니메이션 지속 시간을 추가하고 서로 다른 음수 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-delayopacity: 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:segmentfault.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿