اÙÛÙ ÛØ´ÙâÙØ§Û Ø¬Ø§ÙØ§ اسکرÛپت Ù ÛâØªÙØ§ÙÙØ¯ ÚÛØ²ÙاÛÛ Ø±Ø§ Ú©Ù CSS ÙØ§Ø¯Ø± Ø¨Ù Ø§ÙØ¬Ø§Ù Ø¢Ù ÙÛØ³ØªØ Ù Ø¯ÛØ±Ûت Ú©ÙÙØ¯.
ب٠عÙÙØ§Ù Ù Ø«Ø§ÙØ ØØ±Ú©Øª در ا٠تداد ÛÚ© Ù Ø³ÛØ± Ù¾ÛÚÛØ¯ÙØ Ø¨Ø§ ÛÚ© تابع Ø²Ù Ø§Ù Ø¨ÙØ¯Û Ù ØªÙØ§Ùت از Ù ÙØÙÛ ÙØ§Û BezierØ ÛØ§ ÛÚ© اÙÛÙ ÛØ´Ù رÙÛ Ø¨ÙÙ .
بکار برد٠setInterval
ÛÚ© اÙÛÙ ÛØ´Ù را Ù Û ØªÙØ§Ù ب٠عÙÙØ§Ù Ø¯ÙØ¨Ø§ÙÙ Ø§Û Ø§Ø² ÙØ±ÛÙ ÙØ§ Ù¾ÛØ§Ø¯Ù Ø³Ø§Ø²Û Ú©Ø±Ø¯ â ٠ع٠ÙÙØ§Ù تغÛÛØ±Ø§Øª Ú©ÙÚÚ©Û Ø¯Ø± ÙÛÚÚ¯Û ÙØ§Û HTML/CSS.
Ø¨Ø±Ø§Û Ù
Ø«Ø§ÙØ تغÛÛØ± «style.left» از 0px ب٠100px Ø¹ÙØµØ± را جابÙâØ¬Ø§ Ù
ÛâÚ©ÙØ¯. ٠اگر آ٠را در setInterval Ø§ÙØ²Ø§ÛØ´ دÙÛÙ
Ø Ø¨Ø§ ÛÚ© ØªØ§Ø®ÛØ± Ú©ÙÚÚ©Ø Ù
اÙÙØ¯ 50 بار در ثاÙÛÙØ 2px تغÛÛØ± Ú©ÙØ¯Ø Ø¢ÙÚ¯Ø§Ù ØµØ§Ù Ø¨Ù ÙØ¸Ø± Ù
Û Ø±Ø³Ø¯. اÛÙ ÙÙ
ا٠اص٠در سÛÙÙ
ا است: 24 ÙØ±ÛÙ
ÛØ§ Ø¨ÛØ´ØªØ± در ثاÙÛÙ Ø¨Ø±Ø§Û ØµØ§Ù Ø¨Ù ÙØ¸Ø± Ø±Ø³ÛØ¯Ù کاÙÛ Ø§Ø³Øª.
شب٠کد Ù Û ØªÙØ§Ùد Ø¨Ù Ø´Ú©Ù Ø²ÛØ± باشد:
let timer = setInterval(function() {
if (animation complete) clearInterval(timer);
else increase style.left by 2px
}, 20); // change by 2px every 20ms, about 50 frames per second
ÙÙ ÙÙÙ Ú©Ø§Ù ÙØªØ± اÙÛÙ ÛØ´Ù:
let start = Date.now(); // remember start time
let timer = setInterval(function() {
// how much time passed from the start?
let timePassed = Date.now() - start;
if (timePassed >= 2000) {
clearInterval(timer); // finish the animation after 2 seconds
return;
}
// draw the animation at the moment timePassed
draw(timePassed);
}, 20);
// as timePassed goes from 0 to 2000
// left gets values from 0px to 400px
function draw(timePassed) {
train.style.left = timePassed / 5 + 'px';
}
Ø¨Ø±Ø§Û Ø¯Ù Ù Ú©ÙÛÚ© Ú©ÙÛØ¯:
<!DOCTYPE HTML>
<html>
<head>
<style>
#train {
position: relative;
cursor: pointer;
}
</style>
</head>
<body>
<img id="train" src="https://js.cx/clipart/train.gif">
<script>
train.onclick = function() {
let start = Date.now();
let timer = setInterval(function() {
let timePassed = Date.now() - start;
train.style.left = timePassed / 5 + 'px';
if (timePassed > 2000) clearInterval(timer);
}, 20);
}
</script>
</body>
</html>بکار برد٠requestAnimationFrame
Ø¨ÛØ§ÛÛØ¯ ØªØµÙØ± Ú©ÙÛÙ ÚÙØ¯Û٠اÙÛÙ ÛØ´Ù Ø¨Ù Ø·ÙØ± Ù٠ز٠ا٠اجرا Ù Û Ø´ÙÙØ¯.
اگر Ø¢ÙâÙØ§ را جداگاÙ٠اجرا Ú©ÙÛÙ
Ø ØØªÛ اگر ÙØ± کداÙ
Ø¯Ø§Ø±Ø§Û setInterval(...Ø 20) Ø¨Ø§Ø´ÙØ¯Ø Ù
Ø±ÙØ±Ú¯Ø± Ø¨Ø§ÛØ¯ Ø¨ÛØ´ØªØ± از ÙØ± 20 Ù
ÛÙÛâØ«Ø§ÙÛÙ Ø¯ÙØ¨Ø§Ø±Ù رÙÚ¯âØ¢Ù
ÛØ²Û Ú©ÙØ¯.
اÛ٠ب٠اÛ٠دÙÛ٠است ک٠آÙÙØ§ زÙ
Ø§Ù Ø´Ø±ÙØ¹ Ù
ØªÙØ§ÙØªÛ Ø¯Ø§Ø±ÙØ¯Ø Ø¨ÙØ§Ø¨Ø±Ø§ÛÙ âÙØ± 20 Ù
ÛÙÛ Ø«Ø§ÙÛÙâ Ø¨Û٠اÙÛÙ
ÛØ´Ù ÙØ§Û Ù
ختÙÙ Ù
ØªÙØ§Ùت است. ÙÙØ§ØµÙ ÙÙ
تراز ÙÛØ³ØªÙد. Ø¨ÙØ§Ø¨Ø±Ø§ÛÙ Ù
ا ÚÙØ¯Û٠اجرا Ù
ستÙ٠در عرض 20 Ù
ÛÙÛ Ø«Ø§ÙÛÙ Ø®ÙØ§ÙÛÙ
داشت.
ب٠عبارت دÛÚ¯Ø±Ø Ø§ÛÙ:
setInterval(function() {
animate1();
animate2();
animate3();
}, 20)
⦠سبکتر از س٠ت٠اس ٠ستÙ٠است:
setInterval(animate1, 20); // independent animations
setInterval(animate2, 20); // in different places of the script
setInterval(animate3, 20);
اÛÙ ÚÙØ¯Û٠تصÙÛØ± ٠جدد ٠ستÙÙ Ø¨Ø§ÛØ¯ با Ù٠گرÙÙ Ø¨ÙØ¯Û Ø´ÙÙØ¯ تا ترسÛ٠٠جدد Ø¨Ø±Ø§Û Ù Ø±ÙØ±Ú¯Ø± آسا٠تر Ø´ÙØ¯ ٠در ÙØªÛج٠بار CPU Ú©Ù ØªØ±Û Ø¨Ø§Ø±Ú¯ÛØ±Û Ø´ÙØ¯ Ù Ø±ÙØ§Ù تر Ø¨Ù ÙØ¸Ø± برسد.
ÛÚ© ÚÛØ² دÛگر را Ø¨Ø§ÛØ¯ در ÙØ¸Ø± داشت. گاÙÛ Ø§ÙÙØ§Øª CPU Ø¨ÛØ´ از ØØ¯ Ø¨Ø§Ø±Ú¯ÛØ±Û Ù Û Ø´ÙØ¯Ø ÛØ§ Ø¯ÙØ§Û٠دÛÚ¯Ø±Û Ø¨Ø±Ø§Û ØªØ±Ø³Û٠٠جدد ک٠تر ÙØ¬Ùد دارد (٠اÙÙØ¯ ز٠اÙÛ Ú©Ù Ø¨Ø±Ú¯Ù Ù Ø±ÙØ±Ú¯Ø± Ù¾ÙÙØ§Ù است)Ø Ø¨ÙØ§Ø¨Ø±Ø§Û٠٠ا ÙØ§ÙØ¹Ø§Ù ÙØ¨Ø§Ûد آ٠را ÙØ± 20 Ù ÛÙÛ Ø«Ø§ÙÛ٠اجرا Ú©ÙÛÙ .
ا٠ا ÚÚ¯ÙÙ٠در Ù ÙØ±Ø¯ آ٠در Ø¬Ø§ÙØ§ اسکرÛپت بداÙÛÙ Ø ÛÚ© ٠شخصات Animation timeing ÙØ¬Ùد دارد ک٠تابع ârequestAnimationFrameâ Ø±Ø§ Ø§Ø±Ø§Ø¦Ù Ù Û Ø¯ÙØ¯. ب٠Ù٠٠اÛÙ Ù Ø³Ø§Ø¦Ù Ù ØØªÛ Ø¨ÛØ´ØªØ± Ù Û Ù¾Ø±Ø¯Ø§Ø²Ø¯.
ÙØÙ:
let requestId = requestAnimationFrame(callback)
زÙ
اÙÛ Ú©Ù Ù
Ø±ÙØ±Ú¯Ø± Ù
ÛâØ®ÙØ§Ùد اÙÛÙ
ÛØ´Ù Ø§ÙØ¬Ø§Ù
Ø¯ÙØ¯Ø عÙ
Ùکرد callback را Ø¨Ø±ÙØ§Ù
ÙâØ±ÛØ²Û Ù
ÛâÚ©ÙØ¯ تا در ÙØ²Ø¯ÛÚ©âØªØ±Û٠زÙ
ا٠اجرا Ø´ÙØ¯.
اگر تغÛÛØ±Ø§ØªÛ را در Ø¹ÙØ§ØµØ± در بازگشت ب٠تÙ
اس Ø§ÙØ¬Ø§Ù
دÙÛÙ
Ø Ø¢ÙâÙØ§ با دÛگر تÙ
اسâÙØ§Û requestAnimationFrame ٠با اÙÛÙ
ÛØ´ÙâÙØ§Û CSS گرÙÙâØ¨ÙØ¯Û Ù
ÛâØ´ÙÙØ¯. Ø¨ÙØ§Ø¨Ø±Ø§ÛÙ ÛÚ© Ù
ØØ§Ø³Ø¨Ù Ù
جدد ÙÙØ¯Ø³Û ٠رÙÚ¯ Ø¢Ù
ÛØ²Û Ù
جدد Ø¨Ù Ø¬Ø§Û ØªØ¹Ø¯Ø§Ø¯ Ø²ÛØ§Ø¯Û ÙØ¬Ùد Ø®ÙØ§Ùد داشت.
Ù ÙØ¯Ø§Ø± Ø¨Ø§Ø²Ú¯Ø´ØªÛ Ø¯Ø±Ø®ÙØ§Ø³Øª Id Ù Û ØªÙØ§Ùد Ø¨Ø±Ø§Û ÙØºÙ ت٠اس Ø§Ø³ØªÙØ§Ø¯Ù Ø´ÙØ¯:
// cancel the scheduled execution of callback
cancelAnimationFrame(requestId);
بازگشت ب٠تÙ
اس ÛÚ© آرگÙÙ
Ø§Ù Ø¯Ø±ÛØ§Ùت Ù
Û Ú©ÙØ¯ â Ø²Ù
Ø§Ù Ø³Ù¾Ø±Û Ø´Ø¯Ù Ø§Ø² آغاز Ø¨Ø§Ø±Ú¯ÛØ±Û ØµÙØÙ Ø¨Ø± ØØ³Ø¨ Ù
ÛÙÛ Ø«Ø§ÙÛÙ. اÛ٠زÙ
ا٠را ÙÛØ² Ù
Û ØªÙØ§Ù از طرÛ٠تÙ
اس Ø¯Ø±ÛØ§Ùت کردperformance.now().
Ù
عÙ
ÙÙØ§Ù callback Ø®ÛÙÛ Ø²ÙØ¯ اجرا Ù
ÛâØ´ÙØ¯Ø Ù
گر اÛÙÚ©Ù CPU Ø¨ÛØ´ از ØØ¯ Ø¨Ø§Ø±Ú¯ÛØ±Û شد٠باشد ÛØ§ Ø¨Ø§ØªØ±Û ÙÙ¾âØªØ§Ù¾ ØªÙØ±Ûبا٠خاÙÛ Ø´Ø¯Ù Ø¨Ø§Ø´Ø¯ ÛØ§ دÙÛ٠دÛÚ¯Ø±Û ÙØ¬Ùد داشت٠باشد.
کد Ø²ÛØ± ز٠ا٠بÛÙ 10 Ø§Ø¬Ø±Ø§Û Ø§ÙÙ Ø¯Ø±Ø®ÙØ§Ø³Øª AnimationFrame را ÙØ´Ø§Ù Ù Û Ø¯ÙØ¯. ٠ع٠ÙÙØ§Ù 10-20 Ù ÛÙÛ Ø«Ø§ÙÛ٠است:
<script>
let prev = performance.now();
let times = 0;
requestAnimationFrame(function measure(time) {
document.body.insertAdjacentHTML("beforeEnd", Math.floor(time - prev) + " ");
prev = time;
if (times++ < 10) requestAnimationFrame(measure);
})
</script>
اÙÛÙ ÛØ´Ù ساخت ÛØ§ÙتÙ
اکÙÙÙ Ù
ÛâØªÙØ§ÙÛÙ
ÛÚ© تابع اÙÛÙ
ÛØ´Ù Ø¬ÙØ§ÙÛâØªØ± بر اساس requestAnimationFrame Ø§ÛØ¬Ø§Ø¯ Ú©ÙÛÙ
:
function animate({timing, draw, duration}) {
let start = performance.now();
requestAnimationFrame(function animate(time) {
// timeFraction goes from 0 to 1
let timeFraction = (time - start) / duration;
if (timeFraction > 1) timeFraction = 1;
// calculate the current animation state
let progress = timing(timeFraction)
draw(progress); // draw it
if (timeFraction < 1) {
requestAnimationFrame(animate);
}
});
}
تابع animate3 پاراÙ
تر را Ù
Û Ù¾Ø°ÛØ±Ø¯ ک٠اساسا٠اÙÛÙ
ÛØ´Ù را ØªÙØµÛÙ Ù
Û Ú©ÙØ¯:
duration-
ز٠ا٠ک٠اÙÛÙ ÛØ´Ù. ٠اÙÙØ¯
1000. Ø²Ù Ø§Ù Ø¨ÙØ¯Û (ز٠ا٠کسر).-
تابع Ø²Ù Ø§Ù Ø¨ÙØ¯ÛØ Ù Ø§ÙÙØ¯ ÙÛÚÚ¯Û
CSStransition-timing-function Ú©Ù Ú©Ø³Ø±Û Ø§Ø² Ø²Ù Ø§Ù Ø³Ù¾Ø±Û Ø´Ø¯Ù Ø±Ø§ Ø¯Ø±ÛØ§Ùت Ù Û Ú©ÙØ¯ (â0â Ø¯Ø± Ø´Ø±ÙØ¹Ø â1â Ø¯Ø± Ù¾Ø§ÛØ§Ù) ٠تک٠Û٠اÙÛÙ ÛØ´Ù را Ø¨Ø±Ù Û Ú¯Ø±Ø¯Ø§ÙØ¯ (٠اÙÙØ¯yدر Bezier Ù ÙØÙÛ).ب٠عÙÙØ§Ù Ù Ø«Ø§ÙØ ÛÚ© تابع Ø®Ø·Û Ø¨Ù Ø§Û٠٠عÙÛ Ø§Ø³Øª ک٠اÙÛÙ ÛØ´Ù Ø¨Ù Ø·ÙØ± ÛÚ©ÙÙØ§Ø®Øª با Ù٠ا٠سرعت Ø§Ø¯Ø§Ù Ù Ù Û ÛØ§Ø¨Ø¯:
function linear(timeFraction) { return timeFraction; }Its graph:
اÛ٠دÙÛÙØ§Ù ٠اÙÙØ¯ تابع
Transition-timing-function: Ø®Ø·ÛØ§Ø³Øª. اÙÙØ§Ø¹ Ø¬Ø§ÙØ¨ ØªØ±Û ÙØ¬Ùد دارد ک٠در Ø²ÛØ± ÙØ´Ø§Ù داد٠شد٠است. draw(progress)-
ØªØ§Ø¨Ø¹Û Ú©Ù ØØ§Ùت تک٠Û٠اÙÛÙ ÛØ´Ù را Ù Û Ú¯ÛØ±Ø¯ ٠آ٠را ترسÛÙ Ù Û Ú©ÙØ¯. Ù ÙØ¯Ø§Ø±
Ù¾ÛØ´Ø±Ùت=0ÙØ´Ø§ÙâØ¯ÙÙØ¯Ù ÙØ¶Ø¹Ûت Ø´Ø±ÙØ¹ اÙÛÙ ÛØ´ÙØ ÙÙ¾ÛØ´Ø±Ùت=1â ØØ§ÙØª Ù¾Ø§ÛØ§Ù است.اÛÙ ÙÙ Ø§Ù ØªØ§Ø¨Ø¹Û Ø§Ø³Øª ک٠در ÙØ§Ùع اÙÛÙ ÛØ´Ù را Ø¨ÛØ±ÙÙ Ù Û Ú©Ø´Ø¯.
Ù Û ØªÙØ§Ùد Ø¹ÙØµØ± را جابجا Ú©ÙØ¯:
function draw(progress) { train.style.left = progress + 'px'; }â¦ ÛØ§ ÙØ± کار دÛÚ¯Ø±Û Ø§ÙØ¬Ø§Ù دÙÛÙ Ø Ù Ø§ Ù Û ØªÙØ§ÙÛÙ ÙØ± ÚÛØ²Û را Ø¨Ù ÙØ± Ø´Ú©ÙÛ Ù ØªØØ±Ú© Ú©ÙÛÙ .
Ø¨ÛØ§ÛÛØ¯ با Ø§Ø³ØªÙØ§Ø¯Ù از تابع Ø®ÙØ¯ Ø¹ÙØµØ± width را از 0 ب٠100Ùª Ù
ØªØØ±Ú© Ú©ÙÛÙ
.
رÙÛ Ø¹ÙØµØ± Ø¨Ø±Ø§Û Ø¯Ù Ù Ú©ÙÛÚ© Ú©ÙÛØ¯:
function animate({duration, draw, timing}) {
let start = performance.now();
requestAnimationFrame(function animate(time) {
let timeFraction = (time - start) / duration;
if (timeFraction > 1) timeFraction = 1;
let progress = timing(timeFraction)
draw(progress);
if (timeFraction < 1) {
requestAnimationFrame(animate);
}
});
}<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
progress {
width: 5%;
}
</style>
<script src="animate.js"></script>
</head>
<body>
<progress id="elem"></progress>
<script>
elem.onclick = function() {
animate({
duration: 1000,
timing: function(timeFraction) {
return timeFraction;
},
draw: function(progress) {
elem.style.width = progress * 100 + '%';
}
});
};
</script>
</body>
</html>کد ÙÙ ÙÙÙ:
animate({
duration: 1000,
timing(timeFraction) {
return timeFraction;
},
draw(progress) {
elem.style.width = progress * 100 + '%';
}
});
Ø¨Ø±Ø®ÙØ§Ù اÙÛÙ
ÛØ´Ù CSSØ Ù
ا Ù
Û ØªÙØ§ÙÛÙ
ÙØ± تابع زÙ
Ø§Ù Ø¨ÙØ¯Û Ù ÙØ± تابع ترسÛÙ
Û Ø±Ø§ در اÛÙØ¬Ø§ Ø§ÛØ¬Ø§Ø¯ Ú©ÙÛÙ
. عÙ
Ùکرد زÙ
Ø§Ù Ø¨ÙØ¯Û ØªÙØ³Ø· Ù
ÙØÙÛ ÙØ§Û Bezier Ù
ØØ¯Ùد ÙÙ
Û Ø´ÙØ¯. Ù draw Ù
ÛâØªÙØ§Ùد ÙØ±Ø§ØªØ± از ÙÛÚÚ¯ÛâÙØ§ Ø¨Ø§Ø´Ø¯Ø Ø¹ÙØ§ØµØ± Ø¬Ø¯ÛØ¯Û Ù
اÙÙØ¯ اÙÛÙ
ÛØ´Ù Ø¢ØªØ´âØ¨Ø§Ø²Û ÛØ§ ÚÛØ² دÛÚ¯Ø±Û Ø§ÛØ¬Ø§Ø¯ Ú©ÙØ¯.
Timing تابع
٠ا ساد٠ترÛ٠تابع Ø²Ù Ø§Ù Ø¨ÙØ¯Û Ø®Ø·Û Ø±Ø§ در Ø¨Ø§ÙØ§ Ø¯ÛØ¯ÛÙ .
Ø¨ÛØ§ÛÛØ¯ Ø¨ÛØ´ØªØ± Ø¢ÙÙØ§ را ببÛÙÛÙ . ٠ا اÙÛÙ ÛØ´Ù ÙØ§Û ØØ±Ú©ØªÛ را با ع٠ÙÚ©Ø±Ø¯ÙØ§Û Ø²Ù Ø§Ù Ø¨ÙØ¯Û ٠ختÙÙ Ø§Ù ØªØØ§Ù Ù Û Ú©ÙÛ٠تا ببÛÙÛÙ ÚÚ¯ÙÙ٠کار Ù Û Ú©ÙÙØ¯.
ØªÙØ§Ù Ø¨Ø±Ø§Û n
اگر Ø¨Ø®ÙØ§ÙÛÙ
سرعت اÙÛÙ
ÛØ´Ù را Ø§ÙØ²Ø§ÛØ´ دÙÛÙ
Ø Ù
ÛâØªÙØ§ÙÛÙ
از Ù¾ÛØ´Ø±Ùت در ÙØ¯Ø±Øª n Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛÙ
.
ب٠عÙÙØ§Ù Ù Ø«Ø§ÙØ Ù ÙØÙÛ Ø³ÙÙ ÙÛ:
function quad(timeFraction) {
return Math.pow(timeFraction, 2)
}
گراÙ:
Ø¨Ø±Ø§Û Ø¯ÛØ¯Ù Ú©ÙÛÚ© Ú©ÙÛØ¯:
â¦ ÛØ§ Ù
ÙØÙÛ Ù
کعب ÛØ§ ØØªÛ n بزرگتر. Ø§ÙØ²Ø§ÛØ´ ÙØ¯Ø±Øª باعث Ø§ÙØ²Ø§ÛØ´ سرعت Ø¢Ù Ù
Û Ø´ÙØ¯.
در اÛÙØ¬Ø§ ÙÙ
ÙØ¯Ø§Ø± Ù¾ÛØ´Ø±Ùت در ØªÙØ§Ù 5 Ø¢Ù
د٠است:
در ع٠Ù:
ÙÙØ³ ÛØ§ The arc
تابع:
function circ(timeFraction) {
return 1 - Math.sin(Math.acos(timeFraction));
}
گراÙ:
Back: ØªÛØ± Ø§ÙØ¯Ø§Ø²Û با ک٠اÙ
اÛ٠تابع ØªÛØ±Ø§ÙØ¯Ø§Ø²Û Ø¨Ø§ Ú©Ù
ا٠را Ø§ÙØ¬Ø§Ù
Ù
Û Ø¯ÙØ¯. ابتدا سÛÙ
Ú©Ù
ا٠را Ù
Û Ú©Ø´ÛÙ
٠سپس Ø´ÙÛÚ© Ù
Û Ú©ÙÛÙ
.
Ø¨Ø±Ø®ÙØ§Ù ØªÙØ§Ø¨Ø¹ ÙØ¨ÙÛØ ب٠ÛÚ© پاراÙ
تر اضاÙÛ xØ Ø¶Ø±ÛØ¨ Ø§ÙØ§Ø³ØªÛØ³ÛØªÙ Ø¨Ø³ØªÚ¯Û Ø¯Ø§Ø±Ø¯. ÙØ§ØµÙÙ Ú©Ø´ÛØ¯Ù Ø±ÛØ³Ù
ا٠کÙ
ا٠با Ø¢Ù Ù
شخص Ù
Û Ø´ÙØ¯.
کد:
function back(x, timeFraction) {
return Math.pow(timeFraction, 2) * ((x + 1) * timeFraction - x)
}
Ú¯Ø±Ø§Ù Ø¨Ø±Ø§Û x = 1.5:
Ø¨Ø±Ø§Û Ø§ÙÛÙ
ÛØ´Ù از آ٠با Ù
ÙØ¯Ø§Ø± Ø®Ø§ØµÛ Ø§Ø² x Ø§Ø³ØªÙØ§Ø¯Ù Ù
Û Ú©ÙÛÙ
. Ù
Ø«Ø§Ù Ø¨Ø±Ø§Û x = 1.5:
پرش ÛØ§ Bounce
ØªØµÙØ± Ú©ÙÛØ¯ در ØØ§Ù Ø±ÙØ§ کرد٠ÛÚ© تÙÙ¾ ÙØ³ØªÛÙ . سÙÙØ· Ù Û Ú©ÙØ¯Ø سپس ÚÙØ¯ بار Ø¨Ù Ø¹ÙØ¨ Ø¨Ø±Ú¯Ø´ØªÙ Ù Ù Û Ø§ÛØ³ØªØ¯.
تابع Ø¬ÙØ´ ÙÙ
Û٠کار را Ù
Û Ú©ÙØ¯Ø اÙ
ا Ø¨Ù ØªØ±ØªÛØ¨ Ù
Ø¹Ú©ÙØ³: Ø¬ÙØ´ Ø¨ÙØ§ÙاصÙÙ Ø´Ø±ÙØ¹ Ù
Û Ø´ÙØ¯. از ÚÙØ¯ Ø¶Ø±Ø§ÛØ¨ خاص Ø¨Ø±Ø§Û Ø¢Ù Ø§Ø³ØªÙØ§Ø¯Ù Ù
Û Ú©ÙØ¯:
function bounce(timeFraction) {
for (let a = 0, b = 1; 1; a += b, b /= 2) {
if (timeFraction >= (7 - 4 * a) / 11) {
return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
}
}
}
در ع٠Ù:
Elastic اÙÛÙ ÛØ´Ù
ÛÚ© تابع Ø§ÙØ§Ø³ØªÛÚ© دÛگر Ú©Ù ÛÚ© پاراÙ
تر اضاÙÛ x را Ø¨Ø±Ø§Û Ù
ØØ¯Ùد٠اÙÙÛÙ Ù
Û Ù¾Ø°ÛØ±Ø¯.
function elastic(x, timeFraction) {
return Math.pow(2, 10 * (timeFraction - 1)) * Math.cos(20 * Math.PI * x / 3 * timeFraction)
}
Ú¯Ø±Ø§Ù Ø¨Ø±Ø§Û x=1.5:
در عÙ
Ù Ø¨Ø±Ø§Û x=1.5:
Ù Ø¹Ú©ÙØ³: ease*
Ø¨ÙØ§Ø¨Ø±Ø§ÛÙ Ù
ا Ù
جÙ
ÙØ¹Ù Ø§Û Ø§Ø² ØªÙØ§Ø¨Ø¹ زÙ
Ø§Ù Ø¨ÙØ¯Û دارÛÙ
. کاربرد Ù
ستÙÛÙ
Ø¢ÙÙØ§ easeIn ÙØ§Ù
ÛØ¯Ù Ù
Û Ø´ÙØ¯.
گاÙÛ Ø§ÙÙØ§Øª ÙØ§Ø²Ù
است اÙÛÙ
ÛØ´Ù را Ø¨Ù ØªØ±ØªÛØ¨ Ù
Ø¹Ú©ÙØ³ ÙØ´Ø§Ù دÙÛÙ
. اÛ٠کار با تبدÛÙ easeOut Ø§ÙØ¬Ø§Ù
Ù
Û Ø´ÙØ¯.
easeOut
در ØØ§Ùت easeOut تابع timing در ÙÙØ§Ù timingEaseOut ÙØ±Ø§Ø± Ù
Û Ú¯ÛØ±Ø¯:
timingEaseOut(timeFraction) = 1 - timing(1 - timeFraction)
ب٠عبارت دÛÚ¯Ø±Ø Ù
ا ÛÚ© تابع تغÛÛØ± makeEaseOut دارÛÙ
Ú©Ù ÛÚ© تابع زÙ
Ø§Ù Ø¨ÙØ¯Û âØ¹Ø§Ø¯Ûâ Ø±Ø§ Ù
Û Ú¯ÛØ±Ø¯ Ù Ù¾ÙØ´Ø´ Ø¯ÙØ± آ٠را برÙ
Û Ú¯Ø±Ø¯Ø§ÙØ¯:
// accepts a timing function, returns the transformed variant
function makeEaseOut(timing) {
return function(timeFraction) {
return 1 - timing(1 - timeFraction);
}
}
Ø¨Ø±Ø§Û Ù
Ø«Ø§ÙØ Ù
ÛâØªÙØ§ÙÛÙ
تابع Ø¬ÙØ´ ک٠در Ø¨Ø§ÙØ§ ØªÙØ¶ÛØ Ø¯Ø§Ø¯Ù Ø´Ø¯ را Ú¯Ø±ÙØªÙ ٠آ٠را اعÙ
ا٠کÙÛÙ
:
let bounceEaseOut = makeEaseOut(bounce);
سپس پرش Ù٠در Ø§Ø¨ØªØ¯Ø§Ø Ø¨Ùک٠در Ø§ÙØªÙØ§Û Ø§ÙÛÙ ÛØ´Ù Ø®ÙØ§Ùد Ø¨ÙØ¯. ØØªÛ Ø¨ÙØªØ± Ø¨Ù ÙØ¸Ø± Ù Û Ø±Ø³Ø¯:
#brick {
width: 40px;
height: 20px;
background: #EE6B47;
position: relative;
cursor: pointer;
}
#path {
outline: 1px solid #E8C48E;
width: 540px;
height: 20px;
}<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<script src="https://js.cx/libs/animate.js"></script>
</head>
<body>
<div id="path">
<div id="brick"></div>
</div>
<script>
function makeEaseOut(timing) {
return function(timeFraction) {
return 1 - timing(1 - timeFraction);
}
}
function bounce(timeFraction) {
for (let a = 0, b = 1; 1; a += b, b /= 2) {
if (timeFraction >= (7 - 4 * a) / 11) {
return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
}
}
}
let bounceEaseOut = makeEaseOut(bounce);
brick.onclick = function() {
animate({
duration: 3000,
timing: bounceEaseOut,
draw: function(progress) {
brick.style.left = progress * 500 + 'px';
}
});
};
</script>
</body>
</html>در اÛÙØ¬Ø§ Ù Û ØªÙØ§ÙÛ٠ببÛÙÛÙ Ú©Ù ÚÚ¯ÙÙ٠تبدÛÙ Ø±ÙØªØ§Ø± تابع را تغÛÛØ± Ù Û Ø¯ÙØ¯:
اگر در ابتدا ÛÚ© اÙکت اÙÛÙ ÛØ´Ù ÙØ¬Ùد Ø¯Ø§Ø´ØªÙ Ø¨Ø§Ø´Ø¯Ø Ù Ø§ÙÙØ¯ پرش â Ø¯Ø± Ø§ÙØªÙا ÙØ´Ø§Ù Ø¯Ø§Ø¯Ù Ù Û Ø´ÙØ¯.
در ÙÙ ÙØ¯Ø§Ø± Ø¨Ø§ÙØ§Ø پرش Ù ÙØ¸Ù رÙÚ¯ ÙØ±Ù ز دارد Ù easeOut bounce Ø¢Ø¨Û Ø§Ø³Øª.
- پرش Ù ÙØ¸Ù â Ø¬Ø³Ù در پاÛÛÙ Ù Û Ù¾Ø±Ø¯Ø Ø³Ù¾Ø³ در Ø§ÙØªÙا ب٠شدت Ø¨Ù Ø¨Ø§ÙØ§ Ù Û Ù¾Ø±Ø¯.
- بعد از
easeOutâ Ø§Ø¨ØªØ¯Ø§ Ø¨Ù Ø¨Ø§ÙØ§ Ù Û Ù¾Ø±Ø¯Ø Ø³Ù¾Ø³ Ø¨Ù Ø¢ÙØ¬Ø§ Ù Û Ù¾Ø±Ø¯.
easeInOut
Ù
ا ÙÙ
ÚÙÛÙ Ù
Û ØªÙØ§ÙÛÙ
اثر را ÙÙ
در ابتدا Ù ÙÙ
در Ø§ÙØªÙØ§Û Ø§ÙÛÙ
ÛØ´Ù ÙØ´Ø§Ù دÙÛÙ
. تبدÛÙ easeInOut ÙØ§Ù
ÛØ¯Ù Ù
Û Ø´ÙØ¯.
با ØªÙØ¬Ù ب٠تابع Ø²Ù Ø§Ù Ø¨ÙØ¯ÛØ ØØ§Ùت اÙÛÙ ÛØ´Ù را Ø¨Ù ØµÙØ±Øª Ø²ÛØ± Ù ØØ§Ø³Ø¨Ù Ù Û Ú©ÙÛÙ :
if (timeFraction <= 0.5) { // first half of the animation
return timing(2 * timeFraction) / 2;
} else { // second half of the animation
return (2 - timing(2 * (1 - timeFraction))) / 2;
}
کد wrraper:
function makeEaseInOut(timing) {
return function(timeFraction) {
if (timeFraction < .5)
return timing(2 * timeFraction) / 2;
else
return (2 - timing(2 * (1 - timeFraction))) / 2;
}
}
bounceEaseInOut = makeEaseInOut(bounce);
در عÙ
Ù, bounceEaseInOut:
#brick {
width: 40px;
height: 20px;
background: #EE6B47;
position: relative;
cursor: pointer;
}
#path {
outline: 1px solid #E8C48E;
width: 540px;
height: 20px;
}<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<script src="https://js.cx/libs/animate.js"></script>
</head>
<body>
<div id="path">
<div id="brick"></div>
</div>
<script>
function makeEaseInOut(timing) {
return function(timeFraction) {
if (timeFraction < .5)
return timing(2 * timeFraction) / 2;
else
return (2 - timing(2 * (1 - timeFraction))) / 2;
}
}
function bounce(timeFraction) {
for (let a = 0, b = 1; 1; a += b, b /= 2) {
if (timeFraction >= (7 - 4 * a) / 11) {
return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
}
}
}
let bounceEaseInOut = makeEaseInOut(bounce);
brick.onclick = function() {
animate({
duration: 3000,
timing: bounceEaseInOut,
draw: function(progress) {
brick.style.left = progress * 500 + 'px';
}
});
};
</script>
</body>
</html>تبدÛÙ easeInOut د٠ÙÙ
ÙØ¯Ø§Ø± را ب٠ÛÚ© ÙÙ
ÙØ¯Ø§Ø± Ù
Û Ù¾ÛÙÙØ¯Ø¯: easeIn (عادÛ) Ø¨Ø±Ø§Û ÙÛÙ
٠اÙ٠اÙÛÙ
ÛØ´Ù Ù easeOut (Ù
Ø¹Ú©ÙØ³) â Ø¨Ø±Ø§Û ÙØ³Ù
ت دÙÙ
.
اگر ÙÙ
ÙØ¯Ø§Ø±ÙØ§Û easeInØ easeOut Ù easeInOut تابع زÙ
Ø§ÙØ¨ÙØ¯Û circ را با ÙÙ
Ù
ÙØ§Ûس٠کÙÛÙ
Ø Ø§Û٠اثر Ø¨Ù ÙØ¶ÙØ Ù
Ø´Ø§ÙØ¯Ù Ù
Û Ø´ÙØ¯:
- Red ÙÙØ¹ Ù
عÙ
ÙÙÛ Ø§Ø³Øª
circ(easeIn). - Green â
easeOut. - Blue â
easeInOut.
ÙÙ
Ø§ÙØ·Ùر Ú©Ù Ù
Û Ø¨ÛÙÛÙ
Ø ÙÙ
ÙØ¯Ø§Ø± ÙÛÙ
٠اÙ٠اÙÛÙ
ÛØ´Ù easeIn Ú©ÙÚÚ© شد٠٠ÙÛÙ
٠دÙÙ
easeOut Ú©ÙÚÚ© شد٠است. در ÙØªÛج٠اÙÛÙ
ÛØ´Ù با ÙÙ
ا٠اÙکت Ø´Ø±ÙØ¹ Ù Ø¨Ù Ù¾Ø§ÛØ§Ù Ù
Û Ø±Ø³Ø¯.
ÙÚ©ØªÙ Ø¬Ø§ÙØ¨ تر âdrawâ
Ø¨Ù Ø¬Ø§Û Ø¬Ø§Ø¨Ø¬Ø§ÛÛ Ø¹ÙØµØ± Ù
Û ØªÙØ§ÙÛÙ
کار دÛÚ¯Ø±Û Ø§ÙØ¬Ø§Ù
دÙÛÙ
. تÙÙØ§ ÚÛØ²Û Ú©Ù ÙÛØ§Ø² دارÛÙ
اÛ٠است Ú©Ù draw Ù
ÙØ§Ø³Ø¨ را بÙÙÛØ³ÛÙ
.
در اÛÙØ¬Ø§ تاÛÙ¾ Ù
ت٠Ù
ØªØØ±Ú© bouncing Ø¢Ù
د٠است:
textarea {
display: block;
border: 1px solid #BBB;
color: #444;
font-size: 110%;
}
button {
margin-top: 10px;
}<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<script src="https://js.cx/libs/animate.js"></script>
</head>
<body>
<textarea id="textExample" rows="5" cols="60">He took his vorpal sword in hand:
Long time the manxome foe he soughtâ
So rested he by the Tumtum tree,
And stood awhile in thought.
</textarea>
<button onclick="animateText(textExample)">Run the animated typing!</button>
<script>
function animateText(textArea) {
let text = textArea.value;
let to = text.length,
from = 0;
animate({
duration: 5000,
timing: bounce,
draw: function(progress) {
let result = (to - from) * progress + from;
textArea.value = text.slice(0, Math.ceil(result))
}
});
}
function bounce(timeFraction) {
for (let a = 0, b = 1; 1; a += b, b /= 2) {
if (timeFraction >= (7 - 4 * a) / 11) {
return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
}
}
}
</script>
</body>
</html>Ø®ÙØ§ØµÙ
Ø¨Ø±Ø§Û Ø§ÙÛÙ
ÛØ´Ù ÙØ§ÛÛ Ú©Ù CSS ÙÙ
Û ØªÙØ§Ùد Ø¨Ù Ø®ÙØ¨Û از Ø¹ÙØ¯Ù Ø¢ÙÙØ§ Ø¨Ø±Ø¢ÛØ¯Ø ÛØ§ Ø¢ÙÙØ§ÛÛ Ú©Ù ÙÛØ§Ø² Ø¨Ù Ú©ÙØªØ±Ù دÙÛÙ Ø¯Ø§Ø±ÙØ¯Ø Ø¬Ø§ÙØ§ اسکرÛپت Ù
Û ØªÙØ§Ùد Ú©Ù
Ú© Ú©ÙØ¯. اÙÛÙ
ÛØ´Ù ÙØ§Û Ø¬Ø§ÙØ§ اسکرÛپت Ø¨Ø§ÛØ¯ از طرÛÙ requestAnimationFrame Ù¾ÛØ§Ø¯Ù Ø³Ø§Ø²Û Ø´ÙÙØ¯. اÛÙ Ø±ÙØ´ داخÙÛ Ø¨Ù Ø´Ù
ا اÙ
کا٠Ù
ÛâØ¯ÙØ¯ تا زÙ
اÙÛ Ú©Ù Ù
Ø±ÙØ±Ú¯Ø± در ØØ§Ù Ø¢Ù
ادÙâØ³Ø§Ø²Û Ø±ÙÚ¯âØ¢Ù
ÛØ²Û Ù
جدد Ø§Ø³ØªØ ÛÚ© تابع پاسخ ب٠تÙ
اس را ØªÙØ¸ÛÙ
Ú©ÙÛØ¯. Ù
عÙ
ÙÙØ§Ù Ø®ÛÙÛ Ø²ÙØ¯ Ø§Ø³ØªØ Ø§Ù
ا زÙ
ا٠دÙÛ٠ب٠Ù
Ø±ÙØ±Ú¯Ø± Ø¨Ø³ØªÚ¯Û Ø¯Ø§Ø±Ø¯.
ÙÙØªÛ ÛÚ© ØµÙØÙ Ø¯Ø± Ù¾Ø³âØ²Ù ÛÙÙ Ø§Ø³ØªØ ÙÛÚ Ø±ÙÚ¯âØ¢Ù ÛØ²Û ٠جدد ÙØ¬Ùد ÙØ¯Ø§Ø±Ø¯Ø Ø¨ÙØ§Ø¨Ø±Ø§Û٠ت٠اس Ø¨Ø±Ú¯Ø´ØªÛ Ø§Ø¬Ø±Ø§ ÙÙ ÛâØ´ÙØ¯: اÙÛÙ ÛØ´Ù Ø¨Ù ØØ§Ùت تعÙÛ٠در Ù ÛâØ¢ÛØ¯ Ù Ù ÙØ§Ø¨Ø¹ را ٠صر٠ÙÙ ÛâÚ©ÙØ¯. عاÙÛÙ.
در اÛÙØ¬Ø§ تابع Ú©Ù
Ú©Û animate Ø¨Ø±Ø§Û ØªÙØ¸ÛÙ
Ø¨ÛØ´ØªØ± اÙÛÙ
ÛØ´Ù ÙØ§ است:
function animate({timing, draw, duration}) {
let start = performance.now();
requestAnimationFrame(function animate(time) {
// timeFraction goes from 0 to 1
let timeFraction = (time - start) / duration;
if (timeFraction > 1) timeFraction = 1;
// calculate the current animation state
let progress = timing(timeFraction);
draw(progress); // draw it
if (timeFraction < 1) {
requestAnimationFrame(animate);
}
});
}
گزÛÙÙ ÙØ§:
٠دتâ ک٠ز٠ا٠اÙÛÙ ÛØ´Ù بر ØØ³Ø¨ ms.Ø²Ù Ø§Ù Ø¨ÙØ¯Ûâ ØªØ§Ø¨Ø¹Û Ø¨Ø±Ø§Û Ù ØØ§Ø³Ø¨Ù Ù¾ÛØ´Ø±Ùت اÙÛÙ ÛØ´Ù. کسر ز٠اÙÛ Ø±Ø§ از 0 تا 1 Ø¯Ø±ÛØ§Ùت Ù Û Ú©ÙØ¯Ø Ù¾ÛØ´Ø±Ùت اÙÛÙ ÛØ´Ù را ٠ع٠ÙÙØ§Ù از 0 ب٠1 Ø¨Ø±Ù Û Ú¯Ø±Ø¯Ø§ÙØ¯.drawâ ØªØ§Ø¨Ø¹Û Ø¨Ø±Ø§Û ØªØ±Ø³Û٠اÙÛÙ ÛØ´Ù.
Ù Ø·Ù Ø¦ÙØ§Ù Ù ÛâØªÙØ§ÙÛ٠آ٠را Ø¨ÙØ¨Ùد بخشÛÙ Ø Ø²ÙÚ¯âÙØ§ Ù Ø³ÙØªâÙØ§Û Ø¨ÛØ´ØªØ±Û اضاÙÙ Ú©ÙÛÙ Ø Ø§Ù Ø§ اÙÛÙ ÛØ´ÙâÙØ§Û Ø¬Ø§ÙØ§ اسکرÛپت Ø¨Ù ØµÙØ±Øª Ø±ÙØ²Ø§Ù٠اع٠ا٠ÙÙ ÛâØ´ÙÙØ¯. از Ø¢ÙÙØ§ Ø¨Ø±Ø§Û Ø§ÙØ¬Ø§Ù Ú©Ø§Ø±ÙØ§Û Ø¬Ø§ÙØ¨ Ù ØºÛØ± Ø§Ø³ØªØ§ÙØ¯Ø§Ø±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù Ù Û Ø´ÙØ¯. Ø¨ÙØ§Ø¨Ø±Ø§Û٠ش٠ا Ù Û Ø®ÙØ§ÙÛØ¯ ÙÛÚÚ¯Û ÙØ§Û Ù ÙØ±Ø¯ ÙÛØ§Ø² Ø®ÙØ¯ را در ØµÙØ±Øª ÙÛØ§Ø² اضاÙÙ Ú©ÙÛØ¯.
اÙÛÙ ÛØ´Ù ÙØ§Û Ø¬Ø§ÙØ§ اسکرÛپت Ù Û ØªÙØ§ÙÙØ¯ از ÙØ± تابع Ø²Ù Ø§Ù Ø¨ÙØ¯Û Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÙØ¯. ٠ا ÙÙ ÙÙÙ ÙØ§ ٠دگرگÙÙÛ ÙØ§Û Ø²ÛØ§Ø¯Û را Ù¾ÙØ´Ø´ دادÛ٠تا Ù٠٠کار٠تر Ø´ÙÙØ¯. Ø¨Ø±Ø®ÙØ§Ù CSSØ Ù Ø§ در اÛÙØ¬Ø§ Ø¨Ù Ù ÙØÙÛ ÙØ§Û Bezier Ù ØØ¯Ùد ÙÙ Û Ø´ÙÛÙ .
در Ù
ÙØ±Ø¯ draw ÙÙ
ÙÙ
ÛÙØ·Ùر است: Ù
ا Ù
Û ØªÙØ§ÙÛÙ
ÙØ± ÚÛØ²Û را Ù
ØªØØ±Ú© Ú©ÙÛÙ
Ø ÙÙ ÙÙØ· ÙÛÚÚ¯Û ÙØ§Û CSS.
ÙØ¸Ø±Ø§Øª
<code>Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯Ø Ø¨Ø±Ø§Û ÚÙØ¯Û٠خط â کد را درÙ٠تگ<pre>ÙØ±Ø§Ø± دÙÛØ¯Ø Ø¨Ø±Ø§Û Ø¨ÛØ´ از د٠خط کد â Ø§Ø² ÛÚ© جعبÙÙ Ø´ÙÛ Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯. (plnkrØ jsbinØ codepenâ¦)