Rumah  >  Artikel  >  hujung hadapan web  >  Ajar anda langkah demi langkah cara menggunakan peralihan untuk melaksanakan animasi seperti APP video pendek

Ajar anda langkah demi langkah cara menggunakan peralihan untuk melaksanakan animasi seperti APP video pendek

青灯夜游
青灯夜游ke hadapan
2022-09-07 10:45:022016semak imbas

Bagaimana untuk menggunakan CSS tulen untuk mencapai animasi yang menarik? Artikel berikut akan membawa anda melalui cara bijak menggunakan peralihan untuk merealisasikan seperti animasi. Saya harap ia akan membantu anda!

Ajar anda langkah demi langkah cara menggunakan peralihan untuk melaksanakan animasi seperti APP video pendek

Pada pelbagai antara muka video pendek, kita sering melihat animasi seperti ini:

Ia sangat menarik, dan interaksi yang menarik akan membuatkan pengguna lebih bersedia untuk berinteraksi.

Jadi, adakah mungkin untuk melaksanakan animasi yang menarik seperti menggunakan CSS tulen? Sudah tentu ia perlu Dalam artikel ini, kami akan menggunakan transition dengan bijak untuk melengkapkan animasi seperti itu hanya menggunakan CSS. [Pembelajaran yang disyorkan: tutorial video css]

Mencapai peningkatan berterusan ekspresi berbeza

Jika anda menggunakan CSS tulen untuk merealisasikan set lengkap ini animasi. Kami mula-mula perlu melaksanakan gelung animasi tak terhingga dengan sejumlah besar ekspresi berbeza terapung ke atas.

Seperti ini:

Keseluruhan ini agak mudah untuk dilaksanakan Prinsip teras adalah animasi yang sama, menetapkan transition-duration yang berbeza, transition-dalay , dan sudut putaran dalam julat tertentu.

Kita perlu melaksanakan berbilang ungkapan terlebih dahulu dan meletakkan ungkapan rawak ke dalam teg DOM.

Kita boleh menambahnya satu demi satu secara manual:

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

Sudah tentu, saya secara peribadi berpendapat ini terlalu menyusahkan. Saya biasa menggunakan fungsi gelung dan fungsi rawak SASS, dan menggunakan elemen pseudo content untuk menjana ekspresi berbeza secara rawak. Seperti ini:

<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;
        }
    }
}

Dengan cara ini, kita boleh mendapatkan 50 ekspresi bertindih antara satu sama lain:

Kerana ketelusan adalah 1 Kerana daripada ini, anda hanya boleh melihat beberapa ungkapan teratas Malah, terdapat 50 ungkapan berbeza yang ditindih di sini.

Inti di sini ialah content: nth($expression, random(length($expression))) Kami menggunakan kaedah rawak, panjang dan ke-n SASS untuk menambah secara rawak ungkapan dalam senarai $expression kepada kandungan unsur pseudo sebelum li Inside yang berbeza.

Seterusnya, kita perlu membuatkan mereka bergerak.

Ini mudah, cuma tambahkan animasi transform: translate() tanpa had:

@for $i from 1 to 51 {
    li:nth-child(#{$i}) {
        animation: move 3000ms infinite linear;
    }
}
@keyframes move {
    100% {
        transform: translate(0, -250px);
    }
}

Kesannya adalah seperti berikut:

OK , kerana 50 elemen semuanya disusun bersama, jadi kita perlu membezakan animasi tersebut Kami menambah tempoh animasi rawak kepada mereka, dan memberi mereka nilai negatif transition-delay yang berbeza:

@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);
    }
}

Kesannya adalah seperti berikut. :

Kesannya sangat dekat dengan apa yang kita nak! Terdapat sedikit lompatan di sini, anda perlu faham move #{random() * 2500 1500}ms infinite #{random() * 4000 / -1000}s linear Berikut adalah sekeping kod yang besar:

  • #{random() * 2500 1500}ms Hasilkan nombor rawak antara 1500ms ~ 4000ms, menunjukkan tempoh animasi

  • #{random() * 4000 / -1000}s Hasilkan nombor rawak antara -4000ms ~ 0s, mewakili kelewatan animasi negatif Tujuannya adalah untuk membuat animasi diteruskan lebih awal

Jika anda tidak memahami peranan negatif transition-delay, anda boleh membaca artikel saya ini - Penjelasan ringkas tentang animasi CSS

Sehingga ini titik, ia masih tidak mencukupiRawak , kami kemudian secara rawak menambah sudut putaran yang lebih kecil untuk menjadikan kesan keseluruhan lebih rawak:

@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);
    }
}

Fungsi transform: rotate(#{random() * 80 - 40}deg) di sini adalah untuk menjana secara rawak nombor rawak -40deg ~ 40deg, Hasilkan sudut rawak.

Setakat ini, kami telah mencapai kesan sedemikian:

Gunakan peralihan untuk menukar pereputan menjadi sihir

Ke sini. Ramai pelajar mungkin belum faham Walaupun suka menjana satu ungkapan pada satu masa, mengapa anda perlu menjana begitu banyak ungkapan yang sentiasa bergerak serentak?

Ini kerana CSS tidak boleh menjana secara langsung emotikon dengan satu klik, jadi kita perlu mengubah cara berfikir.

如果这些表情一直都是在运动的,只不过不点击的时候,它们的透明度都为 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 版本的点赞效果是单机版

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

Walau bagaimanapun, secara keseluruhannya, kesan keseluruhan penyelesaian yang dilaksanakan menggunakan CSS tulen adalah baik.

(Belajar perkongsian video: bahagian hadapan web)

Atas ialah kandungan terperinci Ajar anda langkah demi langkah cara menggunakan peralihan untuk melaksanakan animasi seperti APP video pendek. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:segmentfault.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam