CSS Animation

رفته رفته با پیش رفت دنیای وب و بوجود آمدن نیازهای جدید، زبان ها و ابزارها نیز امکانات جدیدی را برای برنامه نویسان و کاربران فراهم می سازند، CSS یکی از جذاب ترین زبان تحت وب است، با وجود اینکه این زبان بخودی خود زبان برنامه نویسی نیست و بسیاری از ساختار های یک زبان برنامه نویسی را ندارد (هر چند با بوجود آمدن ابزار هایی مانند LESS یا SCSS این ساختارها نیز تا حدودی بوجود آمده است) ولی ویژگی های قدرتمندی درون خود دارد که با شما این امکان را می دهد که کارهایی فوق العاده انجام دهید. یکی از این ویژگی ها انیمیشن سازی است که تقریبا ویژگی جوانی درون CSS است و تنها مرورگر های بروز بطور کامل آن را پشتیبانی می کنند.

در اینجا با ساخت یک مثال ساده و نسبتا پیچیده به توضیح ساختار اصلی انیمیشین ( تصویر متحرک :) ) در سی اس اس می پردازیم، و با تعاریفی همچون `keyframes` ، `transform` ، `scale` و .. آشنا می شویم.

به خاطر داشته باشید که بدلیل جدید بودن این ویژگی پشتیبانی نکردن همه ی نسخه های مرورگرها برای استفاده از این انیمیشن می بایست پیشوند موتور اصلی مرورگر را نیز قبل از هر دستور بنویسید، پیشوند های `-o-` ،`-moz-` ، `-webkit-` و همچنین فرم اصلی کدها. در اینجا از پیشوند `-webkit-` که برای مرور گرهای سافاری، کروم و نسخه های جدید اپرا است استفاده می کنیم ولی در مثال نهایی تمامی مرورگر ها لحاظ خواهند شد. نخست اجازه دهید آشنایی ای اولیه با دستورات و کلید واژهای بکار رفته در یک انیمیشن داشته باشیم.

`keyframes`

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

```

@-webkit-keyframes NAME1 {
0% { }
50% { }
100% { }
}
@-webkit-keyframes NAME2 {
from { }
to { }
}

<h2>`transform`</h2>
<p>ترنسفورم ها یکی از مهمترین تغییرات در یک انیمیشن هستند، تغییر موقعیت عمودی یا افقی یک شی، فشردگی به کش آمدگی یک شی نمونه های از ترنسفورم ها هستند.</p>

@-webkit-keyframes NAME1 {
0% { }
50% { -webkit-transform: translateY(-300px); }
100% { }
}

<h2>`animation`</h2>
<p>دستور اصلی ایجاد یک انیمیشن در <em>CSS</em>، این دستور مشخص می کند که کدام کی فریم در مدت چه زمانی به چه تاخیری و با چه ویژگی هایی می بایست اجرا شود.</p>

.box {
-webkit-animation: 1s 2s 3 alternate;
}

<p>خب اولین کار برای ساخت یک انیمیشن ساخت یه سناریو است، اصلا قرار است چه اتفاقی در انیمیشن ما بیافتد؟ نقش اول انیمیشن ما یک توپ نارنجی رنگ پرتاب شده است، قهرمان داستان ما توسط فردی ناشناس پرتاب می شود و از سمت چپ وارد می شود و در نهایت در سمت چپ پایین صفحه آرام می گیرد.
</p>
<q>بعد چهار روز درگیری الان ساعت ۳:۱۳ بامداد ۱۱ دی میریم که ادامه مطلب رو داشته باشیم :)</q>
<p data-height="350" data-theme-id="1094" data-slug-hash="cbKGn" data-user="farnabaz" data-default-tab="result" class='codepen'>See the Pen <a href='http://codepen.io/farnabaz/pen/cbKGn'>cbKGn</a> by Ahad Birang (<a href='http://codepen.io/farnabaz'>@farnabaz</a>) on <a href='http://codepen.io'>CodePen</a></p>
<script async src="//codepen.io/content/images/hexo/embed/ei.js"></script>
<p>بخش <em>HTML</em> بسیار ساده است. تنها چند تگ ساده با کلاس های تعریف شده.</p>
Click on page to restart animation
```

خب اجازه دهید رنگ و لعابی به فضای انیمیشن خود بدهیم و آن را کمی رنگی کنیم، نمایش ما درون کادری کوچک از صفحه انجام می شود، که `scene` نامیده می شود.لایه های انیمیشن ما نیز باید هم اندازه صحفه نمایش و دقیقا درون آن قرار داشته باشند.

```

body {
background: #444;
}
.scene {
width: 500px;
height: 300px;
border: 1px solid #333;
background: #666;
margin: 0 auto;
position: relative;
overflow: hidden;
}
.layer {
position:absolute;
top: 0;
left: 0;
width: 500px;
bottom: 0;
}

<p>نارنجی، این رنگی بود که برای قهرمان داستان خود انتخاب کرده بودیم.</p>

.ball {
position: absolute;
right: 0;
bottom: 23px;
width: 35px;
height: 35px;
background: #fc0;
border-radius: 35px;
}

<p>اوه نکته مهم دیگر در مورد داستان ما این که، ساعت ۱۲ ظهر است و آفتاب مستقیم از بالا می تابد، پس توپ ما نیازمند یک سایه در زمین نیز هست.
همانطور که در کد <em>HTML` مشاهده می کنید سایه توپ ما هم از کلاس `ball` است، یعنی تمام خصوصیات توپ را دارد، فقط می بایست در کف زمین باشد ، مشکی رنگ باشد و مهمتر از همه، بجای دایره بودن بیضی شکل باشد.
برای ساختن یک بیضی افقی کافی است دایره را بصورت عمودی بفشاریم، تعریفی که ما در اینجا از فشرده شدن یا کشیده شدن دارین `scale` است، پس کافی است `scaleY` سایه را کمتر از ۱ قرار دهیم.</p>

.ball.shadow {
background: #222;
bottom: 0px;
-webkit-transform: scaleY(0.3);
}

<p>همه چیز آماده است تا به توپ جان ببخشید و از بالا پایین پریدن آن لذت ببریم. همانطور که در سناریو گفته بودیم توپ ما از سمت چپ وارد می شود و با در سمت راست آرام می گیرد، برای دستیابی به این حرکت افقی لایه ای که توپ در آن قرار دارد را حرکت می دهیم. این لایه را از سمت چپ تصویر به جای اصلی خود در طی هفت ثانیه منتقل می کنیم.</p>

@-webkit-keyframes layer2-animate {
from {
left: -500px;
}
to {
left: 0;
}
}
.layer2 {
-webkit-animation: layer2-animate 7s ;
}

تنها باید به این نکته توجه داشته باشیم سرعت توپ در ابتدا باید زیاد بوده و رفته رفته کمتر شود، پس باید از یک تابع زمان بندی نیز استفاده کنید، توابع زمانبندی در انیمیشن مشخص کننده نموداری هستن که سرعت حرکت بر حسب آن تغییر می کند.
ما در اینجا می خواهیم سرعت در ابتدا زیاد و در پایان آرام شود، برای این کار از تابع `cubic-bezier` استفاده می کنیم، و نموداری شبیه تصویر زیر می سازیم، شیب بیشتر در ابتدا و شیب کمتر در انتها نشان دهنده سرعت تغییر بیشتر در آغاز و سرعت کمتر در پایان است.
<img src="/files/css-animation-curve.png" alt="cubic bezier" class="center" /></p>

.layer2 {
-webkit-animation: layer2-animate 7s cubic-bezier(0, 0, 0.35, 1);
}

<p>تا اینجای کار قهرمان ما بسیار با وقار از سمت چپ وارد شده و در سمت راست می ایستد ولی این تمامی کاری نیست که قرار است انجام دهد، وی قرار است بالا و پایین بپرد و شادی خود را نشان دهد. درست مثل توپی رو پرتاپ می شود، به زمین بخورد، دوباره از زمین فاصله بگیرد و دوباره زمین بخورد و تا ایست کامل نوسان کند.</p>
<p>اوضاع کمی پیچیده از حالت افقی است، دیگر از `from` و `to` استفاده نمی کنیم، چون در اینجا حرکت ما یک حرکت ساده نیست، توپ باید ارتفاع خود را در زمام های مختلف تغییر دهد، گاهی پایین بیاید و گاه بالا رود، به همین جهت با درصد ها سرو کار داریم.
توپ ما قرار است ۴ نوسان داشته باشد، برای این کار به ۵ اوج و ۴ حضیض احتیاج داریم، اوج ها در مکان مختلق از نظر ارتفاع اتفاق می افتند و رفته رفته ارتفاع آنها کم می شود ولی تمامی حضیض ها در سطح زمین اتفاق می افتند.</p>
<p>برای تغییر ارتفاع توپ در زمان های مختلف آن را `transform` داده و با تغییر `translateY` آن را در راستای عمودی تغییر مکان می دهیم.</p>

.ball.self {
-webkit-animation: ball-y 7s;
}
@-webkit-keyframes ball-y {
0% {
-webkit-transform: translateY(-200px);
}
30% {
-webkit-transform: translateY(-100px);
}
55% {
-webkit-transform: translateY(-50px);
}
75% {
-webkit-transform: translateY(-20px);
}
90% {
-webkit-transform: translateY(-7px);
}
21%, 48%, 66%, 88% {
-webkit-transform: translateY(0px);
}
}

<p>اجازه دهید قبل پرداختن به ادامه ماجرا با دوتابع زمانبندی دیگر نیز آشنا شویم، `ease-in` و `ease-out`. این دو تابع در حقیقت تنها یک حالت ممکن از تابع `cubic-bezier` هستند. که `ease-in` در ابتدا آرام و در پایان سریع تر می شود و `ease-out` در ابتدا سریع و در پایان آرام می شود.
<img class="half" src="/files/css-animation-ease-in.png" alt="ease-in" /><img class="half" src="/files/css-animation-ease-out.png" alt="ease-out" /></p>
<p>حرکت یک توپ را در نظر بگیرید، توپ وقتی در یک نوسان به اوج خود نزدیک می شود سرعت حرکتش آرامتر می شود، و در مقابل هنگامی که با زمین برخورد می کند و بر می گردد سرعتش بیشتر است. با توجه یه توابع معرفی شده فوق می توان براحتی این حرکت را پیاده سازی کرد، تنها کافی است در اوج زمانبند را `ease-in` و در حضیض زمانبند را `ease-out` قرار می دهیم.</p>

@-webkit-keyframes ball-y {
0% {
-webkit-transform: translateY(-200px);
-webkit-animation-timing-function: ease-in;
}
30% {
-webkit-transform: translateY(-100px);
-webkit-animation-timing-function: ease-in;
}
55% {
-webkit-transform: translateY(-50px);
-webkit-animation-timing-function: ease-in;
}
75% {
-webkit-transform: translateY(-20px);
-webkit-animation-timing-function: ease-in;
}
90% {
-webkit-transform: translateY(-7px);
-webkit-animation-timing-function: ease-in;
}
21%, 48%, 66%, 88% {
-webkit-transform: translateY(4px);
-webkit-animation-timing-function: ease-out;
}
}

<p>تنها یک کار مانده تا انیمیشن ما کامل شود، هنگامی که توپ با زمین بر خورد میکند قرار است کمی فشرده شود و دوباره به حالت اول بر گردد. حرف از فشردگی شد، پس حتما پای `scale` در میان است.</p>

@-webkit-keyframes ball-y {
0% {
-webkit-transform: translateY(-200px);
-webkit-animation-timing-function: ease-in;
}
30% {
-webkit-transform: translateY(-100px);
-webkit-animation-timing-function: ease-in;
}
55% {
-webkit-transform: translateY(-50px);
-webkit-animation-timing-function: ease-in;
}
75% {
-webkit-transform: translateY(-20px);
-webkit-animation-timing-function: ease-in;
}
90% {
-webkit-transform: translateY(-7px);
-webkit-animation-timing-function: ease-in;
}
20%, 47%, 65%, 87%, 100%{
-webkit-transform: scaleY(1);
}
21%, 48%, 66%, 88% {
-webkit-transform: scaleY(0.8) translateY(4px);
-webkit-animation-timing-function: ease-out;
}
}

<p>چقدر با شکوه :)</p>