با استفاده از فیزیک بهار حرکت را متحرک کنید

روش Compose را امتحان کنید
Jetpack Compose جعبه ابزار UI توصیه شده برای اندروید است. نحوه استفاده از انیمیشن ها در Compose را بیاموزید.

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

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

چرخه زندگی یک انیمیشن بهاری

در یک انیمیشن مبتنی بر فنر، کلاس SpringForce به شما امکان می‌دهد سفتی فنر، نسبت میرایی و موقعیت نهایی آن را سفارشی کنید. به محض شروع انیمیشن، نیروی فنری مقدار انیمیشن و سرعت هر فریم را به روز می کند. انیمیشن تا زمانی که نیروی فنر به تعادل برسد ادامه می یابد.

به عنوان مثال، اگر نماد برنامه را در اطراف صفحه بکشید و بعداً با برداشتن انگشت خود از روی نماد آن را رها کنید، نماد توسط نیرویی نامرئی اما آشنا به محل اصلی خود بازمی گردد.

شکل 1 یک اثر فنری مشابه را نشان می دهد. علامت مثبت (+) در وسط دایره نشان دهنده نیروی اعمال شده از طریق یک حرکت لمسی است.

انتشار بهار
شکل 1. اثر انتشار بهار

یک انیمیشن بهار بسازید

مراحل کلی ساخت انیمیشن فنری برای اپلیکیشن شما به شرح زیر است:

در بخش های بعدی مراحل کلی ساخت یک انیمیشن بهار به طور مفصل مورد بحث قرار می گیرد.

کتابخانه پشتیبانی را اضافه کنید

برای استفاده از کتابخانه پشتیبانی مبتنی بر فیزیک، باید کتابخانه پشتیبانی را به صورت زیر به پروژه خود اضافه کنید:

  1. فایل build.gradle برای ماژول برنامه خود باز کنید.
  2. کتابخانه پشتیبانی را به بخش dependencies اضافه کنید.

    شیار

            dependencies {
                def dynamicanimation_version = '1.0.0'
                implementation "androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version"
            }
            

    کاتلین

            dependencies {
                val dynamicanimation_version = "1.0.0"
                implementation("androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version")
            }
            

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

یک انیمیشن بهار بسازید

کلاس SpringAnimation به شما امکان می دهد یک انیمیشن فنری برای یک شی بسازید. برای ساخت یک انیمیشن بهار، باید یک نمونه از کلاس SpringAnimation ایجاد کنید و یک شی، یک ویژگی شی که می‌خواهید متحرک کنید، و یک موقعیت بهار نهایی اختیاری که می‌خواهید انیمیشن در آن استراحت کند، ارائه دهید.

نکته: در زمان ساخت انیمیشن فنر، موقعیت نهایی فنر اختیاری است. اگرچه، قبل از شروع انیمیشن باید تعریف شود.

کاتلین

val springAnim = findViewById<View>(R.id.imageView).let { img ->
    // Setting up a spring animation to animate the view’s translationY property with the final
    // spring position at 0.
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0f)
}

جاوا

final View img = findViewById(R.id.imageView);
// Setting up a spring animation to animate the view’s translationY property with the final
// spring position at 0.
final SpringAnimation springAnim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0);

انیمیشن مبتنی بر فنر می تواند نماهای روی صفحه را با تغییر ویژگی های واقعی در اشیاء مشاهده متحرک کند. نماهای زیر در سیستم موجود است:

  • ALPHA : نشان دهنده شفافیت آلفا در نما است. مقدار به طور پیش فرض 1 (مادر) است، با مقدار 0 نشان دهنده شفافیت کامل (قابل مشاهده نیست).
  • TRANSLATION_X ، TRANSLATION_Y ، و TRANSLATION_Z : این ویژگی‌ها کنترل می‌کنند که نما به صورت دلتا از مختصات سمت چپ، مختصات بالا و ارتفاع، که توسط محفظه طرح‌بندی آن تنظیم می‌شود، قرار گیرد.
    • TRANSLATION_X مختصات سمت چپ را توصیف می کند.
    • TRANSLATION_Y مختصات بالایی را توصیف می کند.
    • TRANSLATION_Z عمق نما را نسبت به ارتفاع آن توصیف می کند.
  • ROTATION ، ROTATION_X ، و ROTATION_Y : این ویژگی‌ها چرخش را به صورت دو بعدی (ویژگی rotation ) و سه بعدی حول نقطه محوری کنترل می‌کنند.
  • SCROLL_X و SCROLL_Y : این ویژگی‌ها نشان‌دهنده افست اسکرول منبع سمت چپ و لبه بالایی بر حسب پیکسل است. همچنین موقعیت را بر حسب میزان پیمایش صفحه نشان می دهد.
  • SCALE_X و SCALE_Y : این ویژگی‌ها مقیاس‌بندی دوبعدی یک نما را در اطراف نقطه محوری آن کنترل می‌کنند.
  • X , Y , و Z : اینها ویژگی های کاربردی اساسی برای توصیف مکان نهایی نمای در ظرف آن هستند.

ثبت شنوندگان

کلاس DynamicAnimation دو شنونده ارائه می دهد: OnAnimationUpdateListener و OnAnimationEndListener . این شنوندگان به به‌روزرسانی‌های انیمیشن گوش می‌دهند، مانند زمانی که تغییری در مقدار انیمیشن وجود دارد و زمانی که انیمیشن به پایان می‌رسد.

OnAnimationUpdateListener

وقتی می‌خواهید چندین نما را متحرک کنید تا یک انیمیشن زنجیره‌ای ایجاد کنید، می‌توانید OnAnimationUpdateListener را طوری تنظیم کنید که هر بار که تغییری در ویژگی نمای فعلی ایجاد می‌شود، یک تماس برگشتی دریافت کنید. callback به نمای دیگر اطلاع می دهد تا موقعیت فنر خود را بر اساس تغییر ایجاد شده در ویژگی نمای فعلی به روز کند. برای ثبت نام شنونده مراحل زیر را انجام دهید:

  1. متد addUpdateListener() را فراخوانی کنید و شنونده را به انیمیشن متصل کنید.

    توجه: قبل از شروع انیمیشن باید شنونده به روز رسانی را ثبت کنید. اگرچه، شنونده به‌روزرسانی فقط در صورتی باید ثبت شود که به به‌روزرسانی هر فریم در تغییرات ارزش انیمیشن نیاز دارید. شنونده به روز رسانی از اجرای بالقوه انیمیشن در یک رشته جداگانه جلوگیری می کند.

  2. روش onAnimationUpdate() را نادیده بگیرید تا تماس گیرنده را در مورد تغییر شی فعلی مطلع کنید. کد نمونه زیر کاربرد کلی OnAnimationUpdateListener را نشان می دهد.

کاتلین

// Setting up a spring animation to animate the view1 and view2 translationX and translationY properties
val (anim1X, anim1Y) = findViewById<View>(R.id.view1).let { view1 ->
    SpringAnimation(view1, DynamicAnimation.TRANSLATION_X) to
            SpringAnimation(view1, DynamicAnimation.TRANSLATION_Y)
}
val (anim2X, anim2Y) = findViewById<View>(R.id.view2).let { view2 ->
    SpringAnimation(view2, DynamicAnimation.TRANSLATION_X) to
            SpringAnimation(view2, DynamicAnimation.TRANSLATION_Y)
}

// Registering the update listener
anim1X.addUpdateListener { _, value, _ ->
    // Overriding the method to notify view2 about the change in the view1’s property.
    anim2X.animateToFinalPosition(value)
}

anim1Y.addUpdateListener { _, value, _ -> anim2Y.animateToFinalPosition(value) }

جاوا

// Creating two views to demonstrate the registration of the update listener.
final View view1 = findViewById(R.id.view1);
final View view2 = findViewById(R.id.view2);

// Setting up a spring animation to animate the view1 and view2 translationX and translationY properties
final SpringAnimation anim1X = new SpringAnimation(view1,
        DynamicAnimation.TRANSLATION_X);
final SpringAnimation anim1Y = new SpringAnimation(view1,
    DynamicAnimation.TRANSLATION_Y);
final SpringAnimation anim2X = new SpringAnimation(view2,
        DynamicAnimation.TRANSLATION_X);
final SpringAnimation anim2Y = new SpringAnimation(view2,
        DynamicAnimation.TRANSLATION_Y);

// Registering the update listener
anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

// Overriding the method to notify view2 about the change in the view1’s property.
    @Override
    public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                  float velocity) {
        anim2X.animateToFinalPosition(value);
    }
});

anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

  @Override
    public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                  float velocity) {
        anim2Y.animateToFinalPosition(value);
    }
});

OnAnimationEndListener

OnAnimationEndListener پایان یک انیمیشن را اعلام می کند. می‌توانید شنونده را طوری تنظیم کنید که هر زمان که انیمیشن به حالت تعادل رسید یا لغو شد، پاسخ تماس دریافت کند. برای ثبت نام شنونده مراحل زیر را انجام دهید:

  1. متد addEndListener() را فراخوانی کنید و شنونده را به انیمیشن متصل کنید.
  2. روش onAnimationEnd() لغو کنید تا هر زمان که انیمیشنی به تعادل رسید یا لغو شد، اعلان دریافت کنید.

شنوندگان را حذف کنید

برای توقف دریافت تماس‌های به‌روزرسانی انیمیشن و پاسخ‌های پایانی انیمیشن، به ترتیب روش‌های removeUpdateListener() و removeEndListener() را فراخوانی کنید.

مقدار شروع انیمیشن را تنظیم کنید

برای تنظیم مقدار شروع انیمیشن، متد setStartValue() را فراخوانی کرده و مقدار شروع انیمیشن را ارسال کنید. اگر مقدار شروع را تنظیم نکنید، انیمیشن از مقدار فعلی ویژگی شی به عنوان مقدار شروع استفاده می کند.

محدوده مقدار انیمیشن را تنظیم کنید

هنگامی که می خواهید مقدار ویژگی را در محدوده خاصی محدود کنید، می توانید حداقل و حداکثر مقادیر انیمیشن را تنظیم کنید. همچنین در مواردی که ویژگی‌هایی را که دارای محدوده ذاتی هستند، مانند آلفا (از 0 تا 1) متحرک کنید، به کنترل محدوده کمک می‌کند.

  • برای تنظیم حداقل مقدار، متد setMinValue() را فراخوانی کرده و مقدار حداقل ویژگی را ارسال کنید.
  • برای تنظیم حداکثر مقدار، متد setMaxValue() را فراخوانی کرده و حداکثر مقدار ویژگی را ارسال کنید.

هر دو روش انیمیشنی را که مقدار برای آن تنظیم شده است، برمی گرداند.

توجه: اگر مقدار شروع را تنظیم کرده اید و محدوده مقدار انیمیشن را تعریف کرده اید، مطمئن شوید که مقدار شروع در محدوده حداقل و حداکثر مقدار باشد.

تنظیم سرعت شروع

سرعت شروع سرعت تغییر ویژگی انیمیشن در ابتدای انیمیشن را مشخص می کند. سرعت شروع پیش فرض روی صفر پیکسل در ثانیه تنظیم شده است. می توانید سرعت را با سرعت حرکات لمسی یا با استفاده از یک مقدار ثابت به عنوان سرعت شروع تنظیم کنید. اگر یک مقدار ثابت را انتخاب می کنید، توصیه می کنیم مقدار را بر حسب dp در ثانیه تعریف کنید و سپس آن را به پیکسل در ثانیه تبدیل کنید. تعریف مقدار بر حسب dp در ثانیه اجازه می دهد تا سرعت مستقل از چگالی و عوامل شکل باشد. برای اطلاعات بیشتر در مورد تبدیل مقدار به پیکسل در ثانیه، به بخش تبدیل dp در ثانیه به پیکسل در ثانیه مراجعه کنید.

برای تنظیم سرعت، متد setStartVelocity() را فراخوانی کنید و سرعت را بر حسب پیکسل بر ثانیه ارسال کنید. این روش جسم نیروی فنری را که سرعت روی آن تنظیم شده است، برمی گرداند.

توجه: از روش‌های کلاس GestureDetector.OnGestureListener یا VelocityTracker برای بازیابی و محاسبه سرعت حرکات لمسی استفاده کنید.

کاتلین

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        
        // Compute velocity in the unit pixel/second
        vt.computeCurrentVelocity(1000)
        val velocity = vt.yVelocity
        setStartVelocity(velocity)
    }
}

جاوا

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

// Compute velocity in the unit pixel/second
vt.computeCurrentVelocity(1000);
float velocity = vt.getYVelocity();
anim.setStartVelocity(velocity);

تبدیل dp در ثانیه به پیکسل در ثانیه

سرعت فنر باید بر حسب پیکسل بر ثانیه باشد. اگر یک مقدار ثابت را به عنوان شروع سرعت انتخاب می کنید، مقدار را بر حسب dp در ثانیه ارائه دهید و سپس آن را به پیکسل در ثانیه تبدیل کنید. برای تبدیل، از متد applyDimension() از کلاس TypedValue استفاده کنید. به کد نمونه زیر مراجعه کنید:

کاتلین

val pixelPerSecond: Float =
    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, resources.displayMetrics)

جاوا

float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, getResources().getDisplayMetrics());

ویژگی های فنر را تنظیم کنید

کلاس SpringForce متدهای گیرنده و تنظیم کننده را برای هر یک از ویژگی های فنر، مانند نسبت میرایی و سختی، تعریف می کند. برای تنظیم ویژگی های فنر، مهم است که یا جسم نیروی فنری را بازیابی کنید یا یک نیروی فنری سفارشی ایجاد کنید که می توانید ویژگی ها را روی آن تنظیم کنید. برای کسب اطلاعات بیشتر در مورد ایجاد نیروی فنری سفارشی، به قسمت ایجاد نیروی فنر سفارشی مراجعه کنید.

نکته: در حین استفاده از متدهای تنظیم کننده، می توانید یک زنجیره متد ایجاد کنید زیرا تمام متدهای تنظیم کننده، شی نیروی فنری را برمی گرداند.

نسبت میرایی

نسبت میرایی کاهش تدریجی یک نوسان فنر را توصیف می کند. با استفاده از نسبت میرایی، می توانید تعیین کنید که نوسانات با چه سرعتی از یک جهش به دیگری کاهش می یابند. چهار راه مختلف برای مرطوب کردن فنر وجود دارد:

  • میرایی بیش از حد زمانی اتفاق می افتد که نسبت میرایی بیشتر از یک باشد. به جسم اجازه می دهد به آرامی به حالت استراحت بازگردد.
  • میرایی بحرانی زمانی اتفاق می افتد که نسبت میرایی برابر با یک باشد. این اجازه می دهد تا جسم در کمترین زمان به حالت استراحت بازگردد.
  • میرایی کم زمانی اتفاق می افتد که نسبت میرایی کمتر از یک باشد. با عبور از حالت استراحت، اجازه می دهد تا شی چندین بار از حالت سکون عبور کند و سپس به تدریج به حالت استراحت می رسد.
  • بدون میرا زمانی اتفاق می افتد که نسبت میرایی برابر با صفر باشد. به جسم اجازه می دهد برای همیشه در نوسان باشد.

برای افزودن نسبت میرایی به فنر مراحل زیر را انجام دهید:

  1. برای بازیابی فنر برای افزودن نسبت میرایی، متد getSpring() فراخوانی کنید.
  2. متد setDampingRatio() را فراخوانی کنید و نسبت میرایی را که می خواهید به فنر اضافه کنید ارسال کنید. این روش جسم نیروی فنری را که نسبت میرایی روی آن تنظیم شده است، برمی گرداند.

    نکته: نسبت میرایی باید یک عدد غیر منفی باشد. اگر نسبت میرایی را روی صفر قرار دهید، فنر هرگز به حالت استراحت نمی رسد. به عبارت دیگر برای همیشه در نوسان است.

ثابت های نسبت میرایی زیر در سیستم موجود است:

شکل 2: پرش بالا

شکل 3: پرش متوسط

شکل 4: پرش کم

شکل 5: بدون پرش

نسبت میرایی پیش‌فرض روی DAMPING_RATIO_MEDIUM_BOUNCY تنظیم شده است.

کاتلین

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        
        // Setting the damping ratio to create a low bouncing effect.
        spring.dampingRatio = SpringForce.DAMPING_RATIO_LOW_BOUNCY
        
    }
}

جاوا

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

// Setting the damping ratio to create a low bouncing effect.
anim.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY);

سفتی

سختی ثابت فنر را مشخص می کند که قدرت فنر را اندازه گیری می کند. یک فنر سفت نیروی بیشتری را به جسمی که به آن متصل است وارد می کند وقتی فنر در حالت استراحت نیست. برای افزودن سفتی به فنر مراحل زیر را انجام دهید:

  1. برای بازیابی فنر برای افزودن سختی، متد getSpring() فراخوانی کنید.
  2. متد setStiffness() را فراخوانی کنید و مقدار stiffness را که می خواهید به فنر اضافه کنید ارسال کنید. این روش جسم نیروی فنری را که سفتی روی آن تنظیم شده است، برمی گرداند.

    نکته: سفتی باید یک عدد مثبت باشد.

ثابت های سختی زیر در سیستم موجود است:

شکل 6: سفتی بالا

شکل 7: سفتی متوسط

شکل 8: سفتی کم

شکل 9: سفتی بسیار کم

سفتی پیش‌فرض روی STIFFNESS_MEDIUM تنظیم شده است.

کاتلین

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        
        // Setting the spring with a low stiffness.
        spring.stiffness = SpringForce.STIFFNESS_LOW
        
    }
}

جاوا

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

// Setting the spring with a low stiffness.
anim.getSpring().setStiffness(SpringForce.STIFFNESS_LOW);

یک نیروی فنری سفارشی ایجاد کنید

شما می توانید نیروی فنری سفارشی را به عنوان جایگزینی برای استفاده از نیروی پیش فرض فنر ایجاد کنید. نیروی فنری سفارشی به شما امکان می دهد نمونه نیروی فنری یکسان را در چندین انیمیشن فنری به اشتراک بگذارید. هنگامی که نیروی فنر را ایجاد کردید، می توانید ویژگی هایی مانند نسبت میرایی و سختی را تنظیم کنید.

  1. یک شی SpringForce ایجاد کنید.

    SpringForce force = new SpringForce();

  2. خصوصیات را با فراخوانی متدهای مربوطه اختصاص دهید. شما همچنین می توانید یک زنجیره روش ایجاد کنید.

    force.setDampingRatio(DAMPING_RATIO_LOW_BOUNCY).setStiffness(STIFFNESS_LOW);

  3. متد setSpring() را فراخوانی کنید تا فنر را روی انیمیشن تنظیم کنید.

    setSpring(force);

انیمیشن را شروع کنید

دو راه برای شروع یک انیمیشن بهار وجود دارد: با فراخوانی start() یا با فراخوانی متد animateToFinalPosition() . هر دو روش باید در رشته اصلی فراخوانی شوند.

متد animateToFinalPosition() دو کار را انجام می دهد:

  • موقعیت نهایی فنر را تنظیم می کند.
  • انیمیشن را شروع می کند، اگر شروع نشده باشد.

از آنجایی که این روش موقعیت نهایی فنر را به روز می کند و در صورت نیاز انیمیشن را شروع می کند، می توانید هر زمان که بخواهید این روش را برای تغییر مسیر یک انیمیشن فراخوانی کنید. به عنوان مثال در یک انیمیشن فنری زنجیری، انیمیشن یک نما به نمای دیگری بستگی دارد. برای چنین انیمیشنی، استفاده از متد animateToFinalPosition() راحت تر است. با استفاده از این روش در یک انیمیشن فنری زنجیره ای، اگر انیمیشنی که می خواهید در مرحله بعدی آپدیت کنید در حال حاضر در حال اجرا است، نیازی به نگرانی ندارید.

شکل 10 یک انیمیشن فنری زنجیری را نشان می دهد که در آن انیمیشن یک نما به نمای دیگری بستگی دارد.

دمو بهار زنجیردار
شکل 10. دمو فنر زنجیردار

برای استفاده از متد animateToFinalPosition() ، متد animateToFinalPosition() را فراخوانی کرده و موقعیت استراحت فنر را پاس کنید. همچنین می توانید با فراخوانی متد setFinalPosition() وضعیت استراحت فنر را تنظیم کنید.

متد start() مقدار خاصیت را به مقدار شروع بلافاصله تنظیم نمی کند. مقدار ویژگی در هر پالس انیمیشن تغییر می کند، که قبل از عبور از قرعه کشی اتفاق می افتد. در نتیجه، تغییرات در فریم بعدی منعکس می شود، گویی مقادیر بلافاصله تنظیم می شوند.

کاتلین

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        
        // Starting the animation
        start()
        
    }
}

جاوا

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

// Starting the animation
anim.start();

لغو انیمیشن

می توانید انیمیشن را لغو کنید یا به انتهای آن بروید. یک موقعیت ایده آل که در آن باید انیمیشن را لغو کنید یا به پایان آن بروید، زمانی است که تعامل کاربر درخواست می کند انیمیشن فوراً پایان یابد. این بیشتر زمانی است که کاربر به طور ناگهانی از یک برنامه خارج می شود یا نما نامرئی می شود.

دو روش وجود دارد که می توانید برای خاتمه دادن به انیمیشن استفاده کنید. متد cancel() انیمیشن را در مقداری که هست خاتمه می دهد. متد skipToEnd() انیمیشن را به مقدار نهایی پرش می کند و سپس آن را خاتمه می دهد.

قبل از اینکه بتوانید انیمیشن را خاتمه دهید، مهم است که ابتدا وضعیت فنر را بررسی کنید. اگر حالت غیرممکن باشد، انیمیشن هرگز نمی تواند به حالت استراحت برسد. برای بررسی وضعیت فنر، متد canSkipToEnd() فراخوانی کنید. اگر فنر میرایی داشته باشد، روش true و در غیر این صورت false را برمی گرداند.

هنگامی که از وضعیت فنر مطلع شدید، می توانید یک انیمیشن را با استفاده از متد skipToEnd() یا متد cancel() خاتمه دهید. متد cancel() باید فقط در رشته اصلی فراخوانی شود.

نکته: به طور کلی، متد skipToEnd() باعث یک پرش بصری می شود.