ホームページ  >  記事  >  ウェブフロントエンド  >  トランジションを使用してショートビデオアプリのようなアニメーションを実装する方法を段階的に説明します。

トランジションを使用してショートビデオアプリのようなアニメーションを実装する方法を段階的に説明します。

青灯夜游
青灯夜游転載
2022-09-07 10:45:021931ブラウズ

純粋な CSS を使用してアニメーションのような興味深いものを実現するにはどうすればよいですか?以下の記事ではトランジションを上手に使ってアニメーションのような表現を実現する方法を紹介しますので、ぜひ参考にしてください。

トランジションを使用してショートビデオアプリのようなアニメーションを実装する方法を段階的に説明します。

さまざまな短いビデオ インターフェイスで、次のようなアニメーションがよく見られます。

これは非常に興味深いもので、興味深いインタラクションにより、ユーザーはより積極的にインタラクションを行うようになります。

それでは、純粋な CSS を使用して、このような興味深いアニメーションを実装することは可能でしょうか?もちろん必要ですが、今回はtransitionを上手に使って、CSSだけでこんなアニメーションを完成させてみます。 [推奨される学習: css ビデオ チュートリアル ]

さまざまな式の継続的な増加を達成する

純粋な CSS を使用してこの完全なセットを実現する場合アニメーション。 まず、多数の異なる表現が上方に浮かぶアニメーションの無限ループを実装する必要があります。

次のように:

これ全体は比較的簡単に実装できます。中心となる原則は、同じアニメーションで、異なる

transition-duration# を設定することです。 ##、transition-dalay、および特定の範囲内の回転角度。 最初に複数の式を実装し、ランダムな式を DOM タグに入れる必要があります。

手動で 1 つずつ追加することもできます:

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

もちろん、個人的にはこれは面倒だと思います。私は、SASS のループ関数とランダム関数を使用したり、疑似要素の

content

を使用してさまざまな式をランダムに生成したりすることに慣れています。次のように: <pre class="brush:php;toolbar:false">&lt;ul class=&quot;g-wrap&quot;&gt;     &lt;li&gt;&lt;/li&gt;     &lt;li&gt;&lt;/li&gt;     &lt;li&gt;&lt;/li&gt;     // ... 共50个空标签 &lt;/ul&gt;</pre> <pre class="brush:php;toolbar:false">$expression: &quot;?&quot;, &quot;?&quot;, &quot;❤️&quot;, &quot;?&quot;, &quot;?&quot;, &quot;?&quot;, &quot;?&quot;, &quot;?&quot;, &quot;??&quot;, &quot;?&quot;, &quot;?&quot;, &quot;?&quot;, &quot;?&quot;, &quot;?&quot;; .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;                  &amp;::before {             content: nth($expression, random(length($expression)));             position: absolute;             font-size: 50px;         }     } }</pre>このようにして、50 個の重ね合わせた式を取得できます:

透明度が 1 であるため、それは見えるだけです。上のいくつかの式ですが、実際には 50 個の異なる式がここに重ねられています。

ここでの核心は
content: nth($expression, random(length($expression)))

です。SA​​SS のrandom、length、nth メソッドを使用してランダムに $expression リスト内の式は、異なる li の before 疑似要素の内容に追加されます。 次に、彼らを

move

させる必要があります。 これは簡単です。無限の

transform:translate()

アニメーション: <pre class="brush:php;toolbar:false">@for $i from 1 to 51 {     li:nth-child(#{$i}) {         animation: move 3000ms infinite linear;     } } @keyframes move {     100% {         transform: translate(0, -250px);     } }</pre> 効果は次のとおりです。

OK、50 個の要素がすべて積み重ねられているため、アニメーションを区別する必要があります。ランダムなアニメーション期間をそれらに追加し、さまざまな負の

transition-delay

値を割り当てます。 <pre class="brush:php;toolbar:false">@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);     } }</pre> 効果は次のとおりです:

効果は私たちが望んでいたものに非常に近いです。ここには理解する必要がある少しジャンプがあります。

move #{random() * 2500 1500}msfinity #{random() * 4000 / -1000}s Linear

ここに大きなコードがあります。

  • #{random() * 2500 1500}ms

    アニメーションの長さを示す 1500 ミリ秒 ~ 4000 ミリ秒の乱数を生成します

  • ##{random() * 4000 / -1000}s
  • -4000ms ~ 0s の間の乱数を生成し、負のアニメーション遅延を示します。これの目的は、アニメーションを続行できるようにすることです。事前に

    負の
  • transition-delay
の役割を理解していない場合は、私の記事を読んでください --
CSS の詳細な説明アニメーション この時点では、random
だけではまだ不十分です。ランダムに小さい回転角度を追加して、全体の効果をよりランダムにしましょう:

@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);
    }
}
Heretransform: 回転 (#{random() * 80 - 40}deg) の関数は、-40deg ~ 40deg の範囲で乱数をランダムに生成し、ランダムな角度を生成します。

これまでのところ、次のようなエフェクトを実現しています:

トランジションを使用して減衰を魔法に変える

ここへ。多くの生徒はまだ理解していないかもしれませんが、「いいね」は一度に 1 つの式を生成しますが、なぜ一度にこれほど多くの絶え間なく動く式を生成する必要があるのでしょうか?

これは、CSS では直接 1 回クリックして式を生成することができないため、考え方を変える必要があります。

如果这些表情一直都是在运动的,只不过不点击的时候,它们的透明度都为 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 を使用して実装されたソリューションの全体的な効果は良好です。

(学習ビデオ共有: Web フロントエンド )

以上がトランジションを使用してショートビデオアプリのようなアニメーションを実装する方法を段階的に説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。