Pengantar untuk animasi kompleks
Untuk animasi yang tidak dapat digerakkan dengan menambahkan dan menghapus kelas, AMP menawarkan beberapa komponen yang spesifik untuk animasi. Komponen-komponen ini menerapkan prinsip-prinsip AMP pada animasi: cepat, efisien, dan mengutamakan pengguna. AMP membatasi properti CSS apa di dalam keyframe yang diizinkan, namun memberikan keuntungan, seperti kontrol mendetail, animasi mulus, dan kompatibilitas lintas browser tanpa kerja ekstra.
Gunakan amp-animation jika Anda perlu mengontrol pemutaran secara ketat serta mempunyai penghitungan waktu yang akurat dengan beberapa elemen yang beranimasi pada saat yang sama.
Membuat animasi AMP dasar
Komponen amp-animation
memungkinkan penggunaan API Animasi Web di dalam AMP.
Sebuah amp-animation
dasar adalah objek JSON yang terbuat dari bagian-bagian penting berikut ini:
- Elemen komponen beranimasi, atau
selector
. - Properti Penghitungan Waktu
- Keyframe
- Pemicu
<amp-animation layout="nodisplay" id="exampleAnimation">
<script type="application/json">
{
"selector": "#elementID", //select the element to animate
"duration": "1s", //timing property
"iterations": 2, //timing property
"fill": "both", //timing property
"keyframes": {"opacity": 0, "transform": "scale(2)"} //keyframes
}
</script>
</amp-animation>
<!-- trigger -->
<button on="tap:exampleAnimation.start">
Pemilih
Serupa dengan CSS, komponen amp-animation
menautkan properti animasi ke elemen dengan menyatakan nama, kelas, atau ID elemen di dalam bidang "selector"
Komponen tersebut menganimasi setiap elemen dengan jenis tag atau nama kelas yang dinyatakan. Gunakan sebuah ID untuk memastikan Anda menganimasi elemen tunggal.
Properti penghitungan waktu
Properti penghitungan waktu mengontrol berapa lama animasi berlangsung, berapa kali diputar, dan keyframe arah mana yang bekerja.
Tidak diperlukan properti penghitungan waktu, namun animasi mungkin tidak berjalan jika properti yang terkait dengan waktu dan tampilan tidak ada, seperti duration
dan fill
.
Keyframe
Meskipun CSS mengizinkan Anda untuk melakukan morfing dari satu status ke yang lainnya melalui transisi, Anda harus menyatakan properti animasi sebagai keyframe untuk menerapkan amp-animation
yang dapat digunakan pada properti GPU yang dipercepat yang tidak menyebabkan pengulangan tata letak dan dapat menganimasi pada utas kompositor. Ini mencegah animasi mengganggu AMP dan merender proses browser.
amp-animation
. Pemicu
Pemicu memulai urutan animasi. Ekstensi amp-animation
dimulai baik saat <body>
menjadi terlihat di halaman atau dengan menghubungkannya ke sebuah peristiwa atau tindakan AMP
Pemicuan saat <body>
dapat dilihat berguna ketika animasi seharusnya berjalan begitu halaman memuat karena ia muncul “di atas lipatan”, atau dalam viewport pertama halaman tersebut. Pemicu animasi melalui visibilitas dengan menambahkan trigger="visibility"
sebagai atribut pada komponen.
<amp-animation layout="nodisplay"
trigger="visibility">
...
</amp-animation>
Animasi terhubung ke suatu tindakan atau peristiwa dengan memberi komponen amp-animation
sebuah id
dan menautkan id
tersebut ke pemicu peristiwa yang diinginkan, seperti mengetuk sebuah tombol.
<amp-animation layout="nodisplay" id="exampleAnimation">
...
</amp-animation>
<button on="tap:exampleAnimation.start">
Membuat animasi yang kompleks
Membuat suatu animasi dalam amp-animation
memungkinkan kontrol mendetail yang melampaui kegiatan memulai dan menghentikan animasi: ini juga dapat menjeda, membalik, dan mengarahkan ke titik yang spesifik. Anda bahkan dapat merangkai beberapa animasi bersama dan menganimasi elemen dalam suatu urutan.
Subtarget
Elemen tag atau kelas yang sama dapat mempunyai properti penghitungan waktu yang ditentukan dan menimpa nilai-nilai variabel yang telah ditentukan pada animasi tingkat atas.
<body>
<h1>Hello World!</h1>
<h1>Hello World!</h1>
<h1 id="helloMe">Hello World!</h1>
<h1>Hello World!</h1>
<amp-animation layout="nodisplay" id="animateThis">
<script type="application/json">
{
"selector": "h1",
"duration": "3s",
"fill": "both",
"keyframes": [
{"transform": "translateX(0px)"},
{"transform": "translateX(50%)"}
],
"subtargets": [
{
"index": 1,
"duration": "1s"
},
{
"selector": "#helloMe",
"direction": "reverse",
"duration": "5s"
}
]
}
</script>
</amp-animation>
<button on="tap:animateThis.start">start</button>
</body>
Animasi berantai
Beberapa animasi dapat terhubung untuk membentuk urutan yang panjang. Anda dapat membuat efek terjadwal, seperti hamparan pada video, dengan menulis animasi dalam susunan animations
dalam komponen amp-animation
.
<amp-animation id="overlaysAnim" layout="nodisplay">
<script type="application/json">
{
"duration": "3s",
"fill": "both",
"animations": [{
"selector": ".one",
"keyframes": [{
"opacity": "1",
"offset": 0
},
{
"opacity": "1",
"offset": 0.04
},
{
"opacity": "0",
"offset": 0.0401
},
{
"opacity": "0",
"offset": 1
}
]
},
]
}
</script>
</amp-animation>
Pengaturan ini memutar setiap animasi selama 3 detik dalam satu urutan.
Untuk animasi yang lebih besar, animasi di dalam susunan animations
mampu merujuk komponen amp-animation
lain.
<amp-animation id="addEnergy" layout="nodisplay">
<script type="application/json">
{
"duration": "0.3s",
"fill": "both",
"direction": "alternate",
"animations": [
{
"selector": "#energy",
"keyframes": [
{"transform": "scaleX(calc(num(width('#energy'))/10))"},
{"transform": "scaleX(calc(num(width('#energy'))/10 + 3))"}
]
},
{
"animation": "atomExcite"
}
]
}
</script>
</amp-animation>
<amp-animation id="atomExcite" layout="nodisplay" trigger="visibility">
<script type="application/json">
{
"duration": "0.3s",
"iterations": "2",
"fill": "both",
"direction": "alternate",
"animations": [
{
"selector": ".atom",
"keyframes": {
"transform": "translate(20vw)"
}
}
]
}
</script>
</amp-animation>
Menganimasi jumlah elemen yang tidak diketahui
Dengan menggunakan [ekspresi `var(/content/amp-dev/documentation/components/reference/amp-animation.md#css-extensions), Anda dapat menulis animasi yang kompleks dan terjadwal yang berfungsi dengan berapa pun jumlah elemen. Ini memungkinkan data yang dibuat pengguna dan data yang dinamis dapat dianimasi dengan mudah dan mulus.
<head>
<script
async
custom-element="amp-animation"
src="https://cdn.ampproject.org/v0/amp-animation-0.1.js"
></script>
<style amp-custom>
.parent {
perspective: 1000px;
transform-style: preserve-3d;
position: relative;
margin: 10px;
width: 239px;
height: 335px;
}
.card {
transform-origin: left;
height: 50%;
width: 50%;
}
</style>
</head>
<body>
<amp-animation layout="nodisplay" id="cardAdmin">
<script type="application/json">
{
"selector": ".card",
"--duration": "2s",
"duration": "var(--duration)",
"delay": "calc((length() - index() - 1) * var(--duration))",
"easing": "ease-in",
"iterations": "1",
"fill": "both",
"keyframes": [
{"transform": "translate3d(0px, 0px, 0px)"},
{"transform": "translate3d(50%, 0px, 100px)"},
{"transform": "translate3d(110%, 0px, 0px) rotateY(-20deg)"},
{"transform": "translate3d(50%, 0px, -100px)"},
{"transform": "translate3d(0px, 0px, -1px)"}
]
}
</script>
</amp-animation>
<div class="parent" on="tap:cardAdmin.start" tabindex="none" role="animation">
<amp-img
class="card"
src="https://upload.wikimedia.org/wikipedia/commons/7/70/3C.svg"
layout="fill"
></amp-img>
<amp-img
class="card"
src="https://upload.wikimedia.org/wikipedia/commons/3/3a/3H.svg"
layout="fill"
></amp-img>
<amp-img
class="card"
src="https://upload.wikimedia.org/wikipedia/commons/e/e1/KC.svg"
layout="fill"
></amp-img>
</div>
</body>
- Menyatakan sebuah variabel,
--duration
, dan memberinya nilai selama dua detik. - Menetapkan
duration
pada nilai--duration
variabel. - Menghitung penundaan yang diterapkan pada setiap elemen dengan yang memenuhi
.card
pemilih. 1. [Ekstensilength(/content/amp-dev/documentation/components/reference/amp-animation.md#css-length()-extension>) menghitung berapa jumlah elemen
.cardyang dipilih 2. Panjang lalu mengurangi setiap [indeks(/content/amp-dev/documentation/components/reference/amp-animation.md#css-index()-extension>)
.card3. Nilai hasil dikalikan dengan
--duration` variabel 4. Total jumlah final diterapkan dalam detik pada penundaan elemen itu - Animasi diterapkan pada setiap elemen secara terpisah sehingga kartu diacak satu demi satu, bukan sekaligus.
Buka animasi di AMP playground dan tambahkan lebih banyak elemen amp-img
untuk menguji perilaku ini.
Tampak bagus, di mana pun
Animasi dapat menyertakan conditions
.
<head>
<style amp-custom>
.drop {
width: 20px;
height: 20px;
background: blue;
margin-top: 1em;
border-radius: 50%;
}
.right {
position: absolute;
right: 0;
background: red;
}
</style>
<script
async
custom-element="amp-animation"
src="https://cdn.ampproject.org/v0/amp-animation-0.1.js"
></script>
</head>
<body>
<amp-animation id="mediaAnimation" layout="nodisplay">
<script type="application/json">
{
"duration": "1s",
"iterations": "4",
"fill": "both",
"direction": "alternate",
"animations": [
{
"media": "(min-width: 300px)",
"selector": ".drop",
"keyframes": {
"transform": "translate(100vw)"
}
},
{
"media": "(max-width: 300px)",
"selector": ".drop",
"keyframes": {
"transform": "translate(50vw)"
}
},
{
"media": "(min-width: 300px)",
"selector": ".right",
"keyframes": {
"transform": "translate(-100vw)"
}
},
{
"media": "(max-width: 300px)",
"selector": ".right",
"keyframes": {
"transform": "translate(-50vw)"
}
}
]
}
</script>
</amp-animation>
<div class="rain">
<div class="drop"></div>
<div class="drop right"></div>
<div class="drop"></div>
<div class="drop right"></div>
<div class="drop"></div>
<div class="drop right"></div>
<div class="drop"></div>
<div class="drop right"></div>
</div>
<button on="tap:mediaAnimation.start">Start</button>
</body>
-
Written by @CrystalOnScript