Maison > interface Web > tutoriel CSS > le corps du texte

Apprenez-vous étape par étape comment utiliser la transition pour mettre en œuvre l'animation similaire à une courte application vidéo.

青灯夜游
Libérer: 2022-09-07 10:45:02
avant
2025 Les gens l'ont consulté

Comment utiliser du CSS pur pour réaliser une animation intéressante ? L'article suivant vous expliquera comment utiliser intelligemment les transitions pour réaliser des animations similaires. J'espère qu'il vous sera utile !

Apprenez-vous étape par étape comment utiliser la transition pour mettre en œuvre l'animation similaire à une courte application vidéo.

Sur diverses interfaces vidéo courtes, nous voyons souvent des animations comme celle-ci :

C'est très intéressant, et des interactions intéressantes rendront les utilisateurs plus disposés à interagir.

Alors, est-il possible d'implémenter une animation aussi intéressante en utilisant du CSS pur ? Bien sûr, c'est nécessaire. Dans cet article, nous utiliserons intelligemment transition pour réaliser une telle animation en utilisant uniquement du CSS. [Apprentissage recommandé : tutoriel vidéo CSS]transition,仅仅使用 CSS 完成这么一个点赞动画。【推荐学习:css视频教程

实现不同表情的不断上升

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

像是这样:

这个整体还是比较容易实现的,核心原理就是同一个动画,设置不同的 transition-durationtransition-dalay,和一定范围内的旋转角度。

我们首先要实现多个表情,一个 DOM 标签放入一个随机的表情。

我们可以手动一个一个的添加:

<ul class="g-wrap">
    <li>?</li>
    <li>❤️</li>
    <li>?</li>
    // ... 随机设置不同的表情符号,共 50 个
    <li>...</li>
</ul>
Copier après la connexion

当然,我个人觉得这样太麻烦。我习惯利用 SASS 的循环函数及随机函数,利用伪元素的 content 去随机生成不同表情。像是这样:

<ul class="g-wrap">
    <li></li>
    <li></li>
    <li></li>
    // ... 共50个空标签
</ul>
Copier après la connexion
Copier après la connexion
Copier après la connexion
$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;
        }
    }
}
Copier après la connexion

这样,我们就能得到 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);
    }
}
Copier après la connexion

效果如下:

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);
    }
}
Copier après la connexion

效果如下:

效果已经非常接近我们想要的了!这里有一点点的跳跃,需要理解 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);
    }
}
Copier après la connexion

这里 transform: rotate(#{random() * 80 - 40}deg)

Réaliser l'essor continu des différents expressions

Si vous utilisez du CSS pur pour implémenter tout cet ensemble d'animations. Nous

devons d'abord implémenter une boucle infinie d'animation

avec un grand nombre d'expressions différentes flottant vers le haut. Comme ceci :

Tout cela est relativement facile à mettre en œuvre. Le principe de base est la même animation, en définissant différents transition-duration, transition-dalay. , et un angle de rotation dans une certaine plage. 🎜🎜Nous devons d'abord implémenter plusieurs expressions et mettre une expression aléatoire dans une balise DOM. 🎜🎜Nous pouvons les ajouter un par un manuellement : 🎜
li {
    opacity: .1;
    transition: 1.5s opacity 0.8s;
}
li:active {
    opacity: 1;
    transition: .1s opacity;
}
Copier après la connexion
Copier après la connexion
🎜Bien sûr, je pense personnellement que c'est trop gênant. J'ai l'habitude d'utiliser la fonction de boucle et la fonction aléatoire de SASS, ainsi que d'utiliser le content des pseudo-éléments pour générer de manière aléatoire différentes expressions. Comme ceci : 🎜
@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);
    }
}
Copier après la connexion
Copier après la connexion
<ul class="g-wrap">
    <li></li>
    <li></li>
    <li></li>
    // ... 共50个空标签
</ul>
Copier après la connexion
Copier après la connexion
Copier après la connexion
🎜De cette façon, on peut obtenir 50 émoticônes superposées les unes aux autres : 🎜🎜🎜
Comme la transparence est de 1, seules les quelques expressions du haut peuvent être vues. En fait, il y en a 50 différentes expressions superposées ici.
🎜Le noyau ici est content: nth($expression, random(length($expression))) Nous utilisons les méthodes random, length et nth de SASS pour modifier aléatoirement $expression sont ajoutés au contenu du pseudo-élément before des différents li. 🎜🎜Ensuite, nous devons les faire 🎜bouger🎜. 🎜🎜C'est simple, il suffit d'ajouter une animation transform: translate() infinie : 🎜
$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);
    }
}
Copier après la connexion
Copier après la connexion
🎜L'effet est le suivant : 🎜🎜🎜🎜OK, puisque 50 éléments sont superposés, donc nous devons distinguer les animations, nous leur ajoutons des durées d'animation aléatoires, et leur donnons différentes valeurs négatives de transition-delay : 🎜rrreee🎜L'effet est le suivant : 🎜🎜🎜🎜L'effet a été très proche de ce que nous voulions ! Il y a un petit saut ici, vous devez comprendre move #{random() * 2500 + 1500}ms infini #{random() * 4000 / -1000}s linéaire Voici un gros morceau de code : 🎜
  • 🎜#{random() * 2500 + 1500}ms Génère un nombre aléatoire entre 1500 ms et 4000 ms, indiquant la durée de l'animation 🎜
  • 🎜#{random() * 4000 / -1000}s Génère un nombre aléatoire entre -4000ms ~ 0s, représentant un délai d'animation négatif. le but de ceci est de faire en sorte que l'animation se déroule à l'avance🎜
Si vous ne comprenez pas le rôle du délai de transition négatif, vous pouvez lire mon article -- Explication détaillée de l'animation CSS
🎜À ce stade, c'est ce n'est toujours pas assez🎜aléatoire🎜, revoyons-le. Ajoutez au hasard un angle de rotation plus petit pour rendre l'effet global plus aléatoire : 🎜rrreee🎜Icitransform: rotate(#{random() * 80 - 40}deg) consiste à générer de manière aléatoire - Un nombre aléatoire compris entre 40 et 40 degrés génère un angle aléatoire. 🎜🎜À ce stade, nous avons un tel effet : 🎜🎜🎜🎜🎜🎜Utilisez la transition pour transformer la décomposition en magie 🎜🎜🎜C'est parti. De nombreux étudiants ne comprennent peut-être pas encore. Même si les likes génèrent une expression à la fois, pourquoi avez-vous besoin de générer autant d'expressions en mouvement constant à la fois ? 🎜🎜C'est parce que CSS ne peut pas générer directement une émoticône en un seul clic, nous devons donc changer notre façon de penser. 🎜<p>如果这些表情一直都是在运动的,只不过不点击的时候,它们的透明度都为 0,我们要做的,就是当我们点击的时候,让它们从 <code>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;
}
Copier après la connexion
Copier après la connexion

效果如下:

一定要理解上面的代码!巧妙地利用 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);
    }
}
Copier après la connexion
Copier après la connexion

效果如下:

嘿,是不是有那么点意思了!

好最后一步,我们通过一个点击按钮引导用户点击,并且给与一个点击反馈,每次点击的时候,点赞按钮放大 1.1 倍,同时,我们把默认表情的透明度从 opacity: 0.1 彻底改为 opacity: 0

这样,整个动画的完整的核心代码:

<ul class="g-wrap">
    <li></li>
    <li></li>
    <li></li>
    // ... 共50个空标签
</ul>
Copier après la connexion
Copier après la connexion
Copier après la connexion
$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);
    }
}
Copier après la connexion
Copier après la connexion

这里,需要注意的是:

  • 点赞的按钮,通过了父元素 .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 版本的点赞效果是单机版

无法多用户联动,可能是影响能不能实际使用最为关键的因素。

Cependant, dans l’ensemble, l’effet global de la solution mise en œuvre en utilisant du CSS pur est bon.

(Partage de vidéos d'apprentissage : front-end web)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!