Now.js Framework Documentation
AnimationManager
AnimationManager
ภาพรวม
AnimationManager คือระบบจัดการ animations ใน Now.js Framework รองรับ predefined animations, custom keyframes, chaining และ stagger effects
ใช้เมื่อ:
- ต้องการ animate elements
- ต้องการ chain animations
- ต้องการ stagger animations สำหรับ lists
- ต้องการ custom keyframe animations
ทำไมต้องใช้:
- ✅ Predefined animations (fade, slide, scale, bounce)
- ✅ Custom keyframe support
- ✅ Animation chaining
- ✅ Parallel animations
- ✅ Stagger effects
- ✅ Pause/Resume support
- ✅ Promise-based API
การใช้งานพื้นฐาน
Declarative Template Directives
AnimationManager ยังเป็นแกนให้กับ animation directives ฝั่ง TemplateManager ด้วย นี่คือ API ฝั่ง template ที่ใช้อยู่ในปัจจุบัน
| Directive | หน้าที่ | attributes เพิ่มเติม |
|---|---|---|
data-show |
แสดง/ซ่อน element จาก expression แบบ boolean | data-show-animation, data-show-duration |
data-enter |
เล่น animation เมื่อตัว element เข้าสู่ viewport | data-enter-duration, data-enter-threshold, data-enter-repeat |
data-leave |
เล่น animation เมื่อตัว element ออกจาก viewport | data-leave-duration, data-leave-threshold |
data-transition |
เล่น animation ใหม่เมื่อค่า expression เปลี่ยน | data-transition-animation, data-transition-duration |
<section data-show="panelOpen"
data-show-animation="fade"
data-show-duration="200">
...
</section>
<article data-enter="slideUp"
data-enter-duration="350"
data-enter-threshold="0.2">
...
</article>
<div data-transition="activeTab"
data-transition-animation="fade"
data-transition-duration="180">
...
</div>ข้อสำคัญ:
data-showต้องเป็น expression ที่ให้ค่าแนว boolean เช่นisOpenหรือitem.visibleไม่ใช่ชื่อ animation- ปัจจุบัน TemplateManager ไม่มี directive ชื่อ
data-hideแล้ว ให้ใช้data-showคู่กับdata-show-animationแทน - การ cleanup ของ reactive update และ observer จะถูกจัดการอัตโนมัติเมื่อ TemplateManager reprocess หรือลบ element
- ถ้าต้องการคู่มือแบบเน้นฝั่ง template ดูที่ template/data-animation.md
Simple Animation
// Fade in
await AnimationManager.animate(element, 'fade', {
direction: 'in',
duration: 300
});
// Fade out
await AnimationManager.animate(element, 'fade', {
direction: 'out',
duration: 300
});Slide Animation
// Slide up
await AnimationManager.animate(element, 'slideUp', {
direction: 'in',
duration: 400
});
// Slide from right
await AnimationManager.animate(element, 'slideRight', {
direction: 'in',
duration: 400
});Predefined Animations
| Name | Description |
|---|---|
fade |
Fade in/out |
slideUp |
Slide from bottom |
slideDown |
Slide from top |
slideLeft |
Slide from left |
slideRight |
Slide from right |
scale |
Scale in/out |
rotate |
Rotate in/out |
bounce |
Bounce effect |
shake |
Shake effect |
pulse |
Pulse effect |
flip |
3D flip effect |
zoomIn |
Zoom in/out |
swing |
Swing effect |
Animation Options
AnimationManager.animate(element, 'fade', {
// Direction: 'in' or 'out'
direction: 'in',
// Duration in ms
duration: 300,
// Easing function
easing: 'easeOutQuart',
// Animation delay
delay: 0,
// Iterations (Infinity for loop)
iterations: 1,
// Fill mode
fill: 'forwards',
// Callback on complete
onComplete: () => console.log('Done!')
});Easing Functions
| Easing | Description |
|---|---|
linear |
Constant speed |
ease |
CSS default |
easeIn |
Slow start |
easeOut |
Slow end |
easeInOut |
Slow start and end |
easeOutQuart |
Smooth ending |
easeOutBack |
Overshoot then settle |
easeOutBounce |
Bounce at end |
spring |
Spring physics |
API อ้างอิง
AnimationManager.animate(element, animation, options)
Animate element
| Parameter | Type | Description |
|---|---|---|
element |
HTMLElement | Element to animate |
animation |
string/Object | Animation name หรือ custom keyframes |
options |
object | Animation options |
Returns: Promise<void>
await AnimationManager.animate(element, 'bounce', {
direction: 'in',
duration: 500
});AnimationManager.chain(element, animations)
Chain animations ตามลำดับ
| Parameter | Type | Description |
|---|---|---|
element |
HTMLElement | Element |
animations |
array | Array of animation configs |
Returns: Promise<void>
await AnimationManager.chain(element, [
{ name: 'fadeIn', duration: 200 },
{ name: 'pulse', duration: 300 },
{ name: 'scale', direction: 'out', duration: 200 }
]);AnimationManager.parallel(element, animations, options)
Run animations พร้อมกัน
| Parameter | Type | Description |
|---|---|---|
element |
HTMLElement | Element |
animations |
array | Array of animations |
options |
object | Shared options |
Returns: Promise<void>
await AnimationManager.parallel(element, [
'fade',
'scale'
], {
direction: 'in',
duration: 300
});AnimationManager.stagger(elements, animation, options)
Stagger animation สำหรับ multiple elements
| Parameter | Type | Description |
|---|---|---|
elements |
NodeList/Array | Elements |
animation |
string | Animation name |
options.stagger |
number | Delay between each element (ms) |
Returns: Promise<void>
const items = document.querySelectorAll('.list-item');
await AnimationManager.stagger(items, 'slideUp', {
direction: 'in',
duration: 300,
stagger: 50 // 50ms between each
});Custom Keyframes
// Custom animation
await AnimationManager.animate(element, {
from: { opacity: 0, transform: 'translateY(-50px)' },
to: { opacity: 1, transform: 'translateY(0)' }
}, {
duration: 400,
easing: 'easeOutBack'
});
// With steps
await AnimationManager.animate(element, {
from: { transform: 'scale(1)' },
steps: [
{ transform: 'scale(1.2)', offset: 0.5 }
],
to: { transform: 'scale(1)' }
}, { duration: 300 });ตัวอย่างการใช้งานจริง
Modal Animation
async function showModal(modal) {
modal.style.display = 'block';
await AnimationManager.animate(modal, 'scale', {
direction: 'in',
duration: 200,
easing: 'easeOutBack'
});
}
async function hideModal(modal) {
await AnimationManager.animate(modal, 'fade', {
direction: 'out',
duration: 150
});
modal.style.display = 'none';
}List Items Animation
async function animateListItems() {
const items = document.querySelectorAll('.list-item');
await AnimationManager.stagger(items, 'slideUp', {
direction: 'in',
duration: 300,
stagger: 30
});
}Page Transition
async function pageTransition(oldContent, newContent) {
// Fade out old
await AnimationManager.animate(oldContent, 'fade', {
direction: 'out',
duration: 200
});
// Replace content
oldContent.replaceWith(newContent);
// Fade in new
await AnimationManager.animate(newContent, 'fade', {
direction: 'in',
duration: 200
});
}ข้อควรระวัง
⚠️ 1. รอ Animation เสร็จ
// ❌ ไม่รอ animation
AnimationManager.animate(el, 'fade', { direction: 'out' });
el.remove(); // Element ถูกลบก่อน animation เสร็จ
// ✅ รอ animation
await AnimationManager.animate(el, 'fade', { direction: 'out' });
el.remove();⚠️ 2. Display Property
// ❌ Element hidden ไม่สามารถ animate
element.style.display = 'block';
await AnimationManager.animate(element, 'fade', { direction: 'in' });
// ✅ Set display ก่อน แล้ว opacity 0
element.style.display = 'block';
element.style.opacity = '0';
await AnimationManager.animate(element, 'fade', { direction: 'in' });เอกสารที่เกี่ยวข้อง
- FilterManager - Filter with animations
- DialogManager - Dialog animations