شروع کار با JavaScript Animation API

همان طور که می دانید اضافه کردن انیمیشنها به محیط کاربری وب ، باعث القا شدن حس تعامل بین صفحه های وب و کاربر میشود. در این مقاله با استفاده از CSS و Javascript وب انیمیشن خواهیم ساخت.

شروع کار با JavaScript Animation API

بسته شدن منوی کناری سایت با افکت انیمیشنی و روان نسبت به منویی که بدون افکت غیب میشود تجربه ی بهتری از کار با سایت را به کاربر میدهد.

برای ساخت انیمیشن ها تا اینجا، در محیط وب از CSS transition ها، CSS Keyframe ها و یا یک کتابخانه ی جداگانه مثل Animate.css یا Velocity بهره میبردیم اما حالا با استفاده از api جدید و تحت جاوا اسکریپت میتوانیم هر کدام از اجزای html که لازم داشتیم را فقط با کد جاوااسکریپت و در همان فایل js متحرک کنیم.

ساخت انیمیشن

حال برای نشان دادن ویژگی های این api جدید، یکبار با استفاده از CSS و بار دیگر بااستفاده از Javascript، انیمیشنی را خلق میکنیم.
ویرایشگر پایین دارای دو div است که در هنگام کلیک به سمت راست حرکت داده میشوند و همزمان رنگ آنها نیز عوض میشود. مربع با استفاده از CSS Keyframe متحرک شده و دایره نیز با استفاده از JS Web Animations API.

کد html

کد CSS

#square,
#circle {
    width: 100px;
    height: 100px;
    margin: 10px 10px 30px;
    background-color: #2196F3;
}

#circle {
    border-radius: 50%;
}

.animate {
    animation-name: move-and-change-color;   
    animation-duration: 0.4s;
    animation-fill-mode: forwards;
}

@keyframes move-and-change-color {
    0% {
        transform: translateX(0);
    }

    80% {
        transform: translateX(100px);
        background-color: #2196F3;
    }

    100% {
        transform: translateX(100px);
        background-color: #EF5350;
    }
}

کد JS

var square = document.getElementById('square');

square.addEventListener('click', function() {
    square.className += " animate";
});

var moveAndChangeColor = [
    { 
        transform: 'translateX(0)',
        background: '#2196F3'    // blue
    },
    { 
        offset: 0.8,
        transform: 'translateX(100px)', 
        background: '#2196F3'    // blue
    },
    {
        transform: 'translateX(100px)',
        background: '#EF5350'    // red
    }
];

var circle = document.getElementById('circle');

circle.addEventListener('click', function() {
    circle.animate(moveAndChangeColor, {
        duration: 400,
        fill: 'forwards'
    });
});

خروجی:

بیشتر برنامه نویسان، احتمالا با قسمتی که با Keyframe ساخته شده آشنایی دارند، ما این کد را در مرحله ی نخست بررسی میکنیم:

استفاده از CSS برای ساخت انیمیشن

ما کد مربوط به انیمیشن css را در قسمت keyframe تعریف کردیم که timeline از کلیه ی حرکت ها(transition) را در بر دارد. زمانی که حرکات مربوط به هر قسمت را تعریف کردیم، میتوانیم آنها را به وسیله ی پراپرتی animation و گزینه های موجود برای آن به یک سلکتور متصل کنیم.

.animate {
    animation-name: move-and-change-color;   
    animation-duration: 0.4s;
    animation-fill-mode: forwards;
}

@keyframes move-and-change-color {
    0% {
        transform: translateX(0);
    }

    80% {
        transform: translateX(100px);
        background-color: #2196F3;
    }

    100% {
        transform: translateX(100px);
        background-color: #EF5350;
    }
}


ما قصد داریم تا انیمیشن در هنگام تعامل کاربر شروع شود، پس ما از event listener هنگام کلیک کاربر استفاده میکنیم که یک کلاس را به جزء html مناسب متصل میکند.

var square = document.getElementById('square');

square.addEventListener('click', function() {
    square.className += " animate";
});


هر چند این روش به خوبی کار میکند اما تا حدودی غیر مستقیم به نظر میرسد، ما رویدادهایی که رخ میدهند را در فایل CSS تعریف کردیم، اما درواقع این فایل JS بود که کار اصلی را شروع میکرد. همچنین زمانی که کد اجرا شود ما دسترسی محدودی به انیمیشن(برای انجام تغییرات) خواهیم داشت.هر دو این مشکلات مطرح شده در api وب انیمیشن قابل حل میباشند.

استفاده از جاوااسکریپت

ما میتوانیم تقریبا با همان کد هایی که در css نوشته بودیم حرکت شی را در جاوااسکریپت تعریف کنیم:

var moveAndChangeColor = [
    { 
        transform: 'translateX(0)',
        background: '#2196F3'    // blue
    },
    { 
        offset: 0.8,
        transform: 'translateX(100px)', 
        background: '#2196F3'    // blue
    },
    {
        transform: 'translateX(100px)',
        background: '#EF5350'    // red
    }
];


هر شیء داخل آرایه یکی از حالات انیمیشن را نشان میدهد. حالت ها بصورت برابر در زمان تقسیم شده اند(سه حالتِ 0 درصد، 50 درصد و 100 درصد)، مگر اینکه ما با استفاده از گزینه ی offset زمانبندی را تغییر دهیم، همانطور که در حالت میانی این کار را انجام داده ایم.
پس از تعریف آرایه ی animation، میتوانیم آن را با تابع animate() صدا بزنیم. این تابع شی با همان مقادیر پراپرتی animation که در css داشتیم را بعنوان آرگومان دوم میگیرد(با نام هایی متفاوت از آنچه در قسمت css دیدیم، نام هایی مثل animation-fill-mode  که همان  fill است و  animation-iteration-count  که  iterationمیباشد و ....(

var circle = document.getElementById('circle');

circle.addEventListener('click', function() {
    circle.animate(moveAndChangeColor, {
        duration: 400,
        fill: 'forwards'
    });
});


همانطور که میبینید روش JS با استفاده از انیمیشن های ذخیره شده در یک متحرک و تابع animate() برای انجام دادن هر کاری که لازم باشد، بسیار سازمان دهی شده تر از روش css عمل میکند.

کنترل انیمیشن ها

Api وب انیمیشن همچنین به کاربر اجازه میدهد تا دوباره یک انیمیشن را به آسانی و با شیوه های مختلف کنترل کند. تابع animate() یک شیء animation را برمیگرداند که ما میتوانیم آن را در یک متغیر بریزیم و بعدا از آن استفاده کنیم.

var animation = elem.animate(transitions, options);


این api توابع زیر را در اختیار ما میگذارد:
Pause – انیمیشن را در حالت کنونی اش نگه میدارد
Play – انیمیشن را از حالت pause  خارج میکند و در صورتی که پایان یافته بود دوباره آن را اجرا میکند.
Reverse – حرکت انجام شده را به صورت معکوس انجام میدهد.
Finish – پایان انیمیشن را نشان میدهد (درصورتی که معکوس شده باشد آغاز را نشان میدهد)
Cancel – پخش انیمیشن را متوقف میکند و به حالت آغازین میرود

در پایین انیمیشنی از گردانه ی متحرک و بینهایت loading… را مشاهده میکنید. ما دکمه هایی را برای حالت ها و رویدادهای مختلف تنظیم کرده ایم تا بتوانید آنها را امتحان کنید:

کد JS

var spinner = document.getElementById('spinner');
var spinnerAnimation = spinner.animate([
    {
        transform: 'rotate(0)'
    },
    {
        transform: 'rotate(359deg)'
    }
], {
    duration: 1000,
    iterations: Infinity
});

document.getElementById('pause').addEventListener('click', function() { 
  spinnerAnimation.pause();
});
document.getElementById('play').addEventListener('click', function() { 
  spinnerAnimation.play(); 
});
document.getElementById('reverse').addEventListener('click', function() { 
  spinnerAnimation.reverse(); 
});
document.getElementById('cancel').addEventListener('click', function() { 
  spinnerAnimation.cancel(); 
});

کد HTML

<div id="spinner"></div>

<p>Try controlling the animation:</p>
<button id="pause">Pause</button>
<button id="play">Play</button>
<button id="reverse">Reverse</button>
<button id="cancel">Cancel</button>

کد CSS

#spinner {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 3px solid #e2e2e2;
    border-top-color: #186aab;
    margin: 50px;
}

پراپرتی ها و event listener ها

شیء انیمیشن که از تابع ()animate بازگردانده می شود پراپرتی های مفید زیادی را در خود نگه میدارد که دسترسی به گزینه هایی مانند زمان فعلی، نرخ پلی بک و چیزهای دیگری را به ما می دهد. با وجود اینکه برخی از آنها فقط قابلیت خواندن(read-only) دارد ولی بیشتر آنها هم قابلیت تنظیم و هم قابلیت برگرداندن مقادیر(set & get) را دارند.
شما میتوانید کد جاوا اسکریپت زیر را مشاهده کنید تا ببینید این پراپرتی ها چگونه کار می کنند برای مشاهده لیست کامل این پراپرتی ها به سایت MDN مراجعه کنید.

کد JS

var spinner = document.getElementById('spinner');
var spinnerAnimation = spinner.animate([
    {
        transform: 'rotate(0)'
    },
    {
        transform: 'rotate(359deg)'
    }
], {
    duration: 1000,
    iterations: Infinity
});

document.getElementById('half').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 0.5; 
});
document.getElementById('normal').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 1; 
});
document.getElementById('double').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 2; 
});
document.getElementById('triple').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 3; 
});

کد HTML

<div id="spinner"></div>

<p>Set Playback Speed:</p>
<button id="half">0.5</button>
<button id="normal">Normal</button>
<button id="double">2</button>
<button id="triple">3</button>

کد CSS

#spinner {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 3px solid #e2e2e2;
    border-top-color: #186aab;
    margin: 50px;
}

علاوه بر اینها، این api دو event handler کاربردی را در مواقعی که انیمیشن تمام شده یا کنسل شده نیز برای ما فراهم می آورد:

spinnerAnimation.addEventListener('finish', function() {
    // Animation has completed or .finish() has been called.
    doSomething();
});

spinnerAnimation.addEventListener('cancel', function() {
    // Animation has been canceled.    
    doSomething();
});


 پشتیبانی و کارکرد

بیشتر ویژگی های api آزادانه در کروم و فایرفاکس قابل دسترسی هستند اما در مورد مرورگرهایEdge و Safari پیاده سازی ها ادامه دارد، همچنین یک open-source polyfill دارای پشتیبانی خوب نیز در این زمینه موجود است که توسعه دهندگان می‌توانند از آن تا زمانی که پشتیبانی کامل api برای تمام مرورگرها ارائه شود استفاده کرد.
زمانی که حرف کارایی به میان می آید نباید فرقی بین css و جاوا اسکریپت باشد چون مرورگرها از یک موتور مشابه برای اجرای هر دو استفاده می کند. اگر شما فقط از انیمیشن هایی که نیاز به دوباره اجرا شدن ندارند استفاده میکنید، مثل transform یا opacity، نرخ به روز رسانی تصویر آن باید ۶۰ فریم ثانیه بماند.

جمع بندی

این api به توسعه‌دهندگان راه جدیدی برای ساخت و کنترل انیمیشن های تحت وب را با استفاده از جاوا اسکریپت اصل نشان می دهد. برای انیمیشن های که به تعامل کاربر و یا بقیه رخدادهای پویا لازم دارند، این خبر خوبی است که کل انیمیشن ‌میتواند توسط کد جاوااسکریپت و بدون استفاده از یک فایل css برای جابجایی ها انجام گیرد.