My plug-in finishing


In the daily work will use a lot of plug-ins, they greatly facilitate our daily development, can quickly make us achieve some beautiful effect, now the plug-ins often used in the work are sorted out


Swiper is often used to touch and slide the content of mobile websites
Swiper is a sliding effect plug-in made of pure JavaScript, which is oriented to mobile terminals such as mobile phones and tablets.
Swiper can achieve touch screen focus map, touch screen tab switching, touch screen multi map switching and other common effects.
Swiper is open source, free, stable, easy to use and powerful. It is an important choice to build a mobile terminal website!

Sliding plug-in can be said to be one of the most frequently used plug-ins. Common sliding effects can be made with this plug-in, because swiper’s usage scenarios are too wide. At present, I can only list the scenarios I have encountered; Of course, you can also click here to check the basic effect of swiper. The basic mainstream sliding effect can be found here, and other non mainstream effects are about to be removed. (o ゚ o ゚ o (laughter)

At present, swiper has two versions, swiper3 and swiper4. Both APIs can be found on the official website. The two versions have changed in some places,But its basic use is to pass in ID and optional parameters when instantiating swiper; The version used here is swiper4
Where change is taking place
My plug-in finishing;
We can see that there are not many changes, mainly in the auto play, pager and callback functions. Here is a brief introduction to some projects,
Before the explanation, first look at the swiper4 instructions to get a general understanding of the use of this thing;

There are several things that are important:
1,callback Callback function, which is usually triggered before and after the end of sliding
2,propertiesAll the properties of the swiper object
3,methodsExternal operation on swiper
4,slides gridLayout setting of swiper slide
5,scroll-barSetting of the scroll slider
What operation do you want to do with this swiper? You can find the corresponding things from the three. Next, I will introduce the use scenarios I encountered

Use scenario one external control switch

My plug-in finishing
This kind of use scenario is very common. The main reason is that the two pictures can be swiped left and right by fingers, or they can be swiped by the above two buttons;
When the picture is switched, the buttons above will also switch to activate the style;
HTML structure and code
My plug-in finishing
In fact, the structure doesn’t have to follow this completely. How do you like to write? It doesn’t have much to do with the structure;
Instantiate JS code

//Notice, this is swiper3
Var skillswiper = new swiper ('. Skill model swiper', {// instantiate sliding object)
    Pagination: 'swiper pagination skill' // pagination indicator
    Onslidechangeend: function (swiper) {// the end of the slide gets the current activation sequence number. The incoming swiper is the current swiper object. Pay attention to the callback function in the comparison chart above. This is a difference
        var curidx = swiper.activeIndex; // The key attribute of activeindex, the serial number of the current swiper activation element, is found in the API attribute
        $('.skill-lenli-btn button').eq(curidx)

//Look, this is swiper4
var skillSwiper=new Swiper('.skill-model-swiper',{
    pagination: {
        el: '.swiper-pagination-skill'
    On: {// swiper4 new binding method, similar to the on property of jQuery, is used to add callback function or event handle
        Slidechangetransitionend: function() {// this method is the same as onslidechangeend above. In addition, please note that no parameters are passed in here
            var curidex=this.activeIndex;// When you see this, she refers to the swiper object. Is it the same as the above picture?
            $('.skill-lenli-btn button').eq(curidx).addClass('skill-lenli-btn-act')

The above example introduces a usage scenario and some differences between swiper 3 and swiper 4. Let’s see the second usage scenario

Use scene 2 tab switch, swiper show hide, slide stuck

My plug-in finishingMy plug-in finishing

This use is tab switching plus swiper. In fact, this use is no different from the general use. It’s just that there are multiple Swipers in one area, and with the tab label switching, there will be some unexpected situations when the switch is displayed or hidden. In my case, only the first swipe is normal, and when I click to switch to the swiper behind, it will not slide smoothly, And the situation that you can’t slide back (of course, this is the situation I encounter, and you may encounter other strange situations);In short, if you affect some internal states of swiper through some external operations, these exceptions may occurAt this time, you need the monitor (View document observer) to help

Start the dynamic Checker (OB / viewer / viewer) and initialize the swiper automatically when you change the style of the swiper (for example, hide / show) or modify the child elements of the swiper.
The default is false. It is not turned on. You can use the update () method to update
Apply observe to the parent element of swiper. When the parent element of swiper changes, such as window. Reset, swiper updates.

HTML structure and code
My plug-in finishing
Instantiate JS code

$('.ds-sw>div').click(function(event) {
     var i = $(this).index();
//There is no big difference between the 3 and 4 versions, just the pagination writing is different
var dsItemSwiperA = new Swiper('.ds-person-swiper-a', {
    observer: true,
    observeParents: true,
    pagination : {

Use scenario 3, multi graph, interval, slide grid

My plug-in finishing
This is also a very common way to use, showing a main picture on the screen, while leaving out the preview effect of the previous one and the next one. Without pagination pager, it is a very friendly prompt for users
It’s not difficult to use, the key lies in CSS

HTML structure and code
My plug-in finishing
Instantiate JS code and CSS part

    width:296px;// The most important sentence is to give width to each swiper silde,
var dnrSwiper=new Swiper('.swiper-container-dinner',{
    Slidesperview: 'auto' // sets the number of slides that the slider container can display at the same time (carousel mode). You can set it manually, but I personally don't recommend setting it manually. Just give it to auto, especially in this similar scenario
    Centeredslides: true, // default to fasle. Set the horizontal position of the active slide, that is, to the left; This general setting is true, which is in the middle of the swiper wrapper
    Spacebetween: 10, // set the left and right margins of each swiper slide in PX
    /*Autoplay: true, it is not recommended to write it directly*/
        Disableoninteraction: false, // whether to stop the automatic carousel when the user operates swiper. The default value is true. If you directly write autoplay:true Then this value is the default true, that is, when the user manually swipes or clicks swiper, the automatic carousel will no longer take effect
        stopOnLastS lide:fasle// Automatically rotate to the last stop sliding, the default value is false;

Use scenario 4, multi graph, interval, slide grid, scroll bar, progress bar

This kind of scene is the application of scroll bar, which is similar in the official demo;
My plug-in finishingMy plug-in finishing
There are two places in this picture. The first one is that it is not welted or completely centered when loading. The second one is the scroll bar below
With this scroll bar, instead of specifying pagination, scroll bar is used
HTML structure and code
My plug-in finishing
CSS and JS code

    margin-top: 20px;
    height: 150px; // Pay attention to this height. The default height of the swiper container is the height of the swiper slide inside. You need to set it manually when there is a pager below. The default position of the pager or scroll bar is 3px from the bottom of the swiper container; So the scroll bar will coincide with the swiper slide, so you need to increase the height of the container manually, of course, according to the design;
    width: 137px;
    height: 124px;
    background-color: pink;
    line-height: 124px;
    text-align: center;
    font-size: 16px;
.swiper-container-horizontal > .swiper-scrollbar{
    width: 95%; // Manually change the width of the scroll bar
    transform: translateX(-50%); // Center scroll bar
    left: 50%;
var swiperB=new Swiper('.swiper-b',{
    slidesPerView: "auto",
    spaceBetween: 15,
    Slidesoffsetbefore: 10, // set the preset offset (unit: PX) between the slide and the left border to achieve the effect of no trimming
    Slidesoffsetafter: 10, // set the preset offset between the slide and the right border (unit: PX)
    scrollbar: {
        El: 'swiper scroll' // specify scroll
        Dragsize: 30, // manually set the width of the slider. The default value is' auto '. It will work out a suitable width by itself. Generally, it does not need to be set
        draggable:true// Set whether you can manually drag the scroll slider. The default value is false. Dragging is not allowed

Use scene 5 bidirectional control, with 3D switching effect

My plug-in finishing;
This is the details page of the introduction page of the new version of 3.3 member privileges. There are two difficulties. The first one introduces the 3D switching effect of swiper, and the second one is that the introduction below and the control button above are bidirectional control;
First of all, the first problem is the 3D switching effect, which is called 3D switching effect in swipercoverflowIn the special effects options of API, there are common configurations and the meaning of each configuration item in the introduction. The code will be provided later;
The second problem is bidirectional control; There are also cases on the basis of this example. It’s no problem to follow this example. There are two ways to write the bidirectional control in the API introduction. One is to write the control attribute when instantiating the swiper according to his way of writing. The second way is to put forward the control attribute and use the object method

However, there are two problems in the process of using it. The first is bidirectional control. The sliding direction of the upper swiper is opposite to that of the lower swiper. However, I did not add the inverse attribute in the control attribute. Later, I found that the reason for this problem is the parameter of covereffect, But the cause of the problem is unknown;
Then there is the second problem. There are 11 sliders in the swiper above, and there are 11 sliders in the swiper below. However, the swiper below can only display one slide at a time, so it can slide 10 times. However, the swiper above can display three sliders at a time, so it can only slide 9 times. Because the last slide shows the 9th, 10th and 11th sliders, there is an abnormal problem at this time; The solution is to add the centeredslides: true attribute to the first swiper;

Finally, JS code

var topSiwper=new Swiper(document.querySelector('.top-swiper-container'),{
    slidesPerView: 'auto',
    Slidetoclickedslide: true, // a useful property that allows you to write slideto () without having to write it manually
    Centeredslides: true, // in addition, although it feels a little different from the design drawing, the problem of opposite sliding on both sides is rejected
/*The following carousel components*/
var centerSwiper=new Swiper(document.querySelector('.center-swiper-conatiner'),{
    slidesPerView: 'auto',
    centeredSlides: true,
    Coverfloweffect: {// this parameter is adjusted to a 3D depth effect and solves the problem of opposite swiper sliding on both sides
        Rotate: 0, // rotation angle
        Stretch: 0, // stretch the left and right spacing and density between pictures
        Depth: 60, // depth switches the space and density between images
        Modifier: 2, // the larger the value, the more obvious the effect is
        Slideshadows: false // page shadow effect
//Two way control

Before using the official demo is not good because of the version problem, the latest is in 4.5.0 +; Download the latest version to solve this problem;

Evolutionary version of bidirectional control

In addition to the requirement that the two Swipers can be controlled in both directions, another requirement is that the previewed swiper will automatically move a slide forward when it clicks the current swiper; This has been used in previous salary raising activities, and also in the photo album

    #thumbs .swiper-slide{
        width: 1.8rem;
        height: 1.5rem;
        font-size: .24rem;
    #thumbs .swiper-slide>div{
        width: 1.5rem;
        height: 100%;
        background-color: white;
        transition: all .25s linear;
        text-align: left;
        margin: 0 auto;

<div class="swiper-container b" id="gallery"> <!-- This is the content swiper -- > < / div >
<div class="swiper-container t" id="thumbs" > <!-- This is the preview swiper -- > < / div >

jQuery(document).ready(function($) {
    //Navigation swiper
    var galleryThumbs = new Swiper('#thumbs', {
        slidesPerView: 'auto',
        freeMode: true,
        watchSlidesVisibility: true,
        watchSlidesProgress: true,
                //The number of navigation words should be unified and the width of each navigation should be consistent
                navSlideWidth = this.slides.eq(0).css('width');
                clientWidth = parseInt(this.$wrapperEl.css('width')); // The visible width of Nav
                navWidth = 0;
                for (i = 0; i < this.slides.length; i++) {
                    navWidth += parseInt(this.slides.eq(i).css('width'))

    //Content swiper
    var galleryTop = new Swiper('#gallery', {
        spaceBetween: 10,
        centeredSlides : true,
        slidesPerView: 'auto',
                activeIndex = this.activeIndex
                //Activeslide distance to the left
                navActiveSlideLeft = galleryThumbs.slides[activeIndex].offsetLeft
                if (navActiveSlideLeft < (clientWidth - parseInt(navSlideWidth)) / 2) {
                } else if (navActiveSlideLeft > navWidth - (parseInt(navSlideWidth) + clientWidth) / 2) {
                    galleryThumbs.setTranslate(clientWidth - navWidth)
                } else {
                    galleryThumbs.setTranslate((clientWidth - parseInt(navSlideWidth)) / 2 - navActiveSlideLeft)
    //Bind navigation Click to switch
        clickIndex = this.clickedIndex
        clickSlide = this.slides.eq(clickIndex);
        galleryTop.slideTo(clickIndex, 0);

The above method can meet the requirements, but there is a problem. This thing has some requirements for previewing the layout of the swiper. There can be no space in the preview swiper or swiper slide, whether it is margin or padding written in CSS or spacebetween set in JS; This can lead to miscalculation (funny, don’t ask me why); So, in this case, you can use a compromise method to widen the swiper slide, wrap the contents with a div, and then center the outer layer

Swiper slide switch internal elements with animation

It’s also a common point. Swiper.animate.js is needed to achieve this effect. This thing is usually in swiper’s compressed package. If not, you can download one by yourself;
usage method:

<div class="swiper-slide swiper-out-slide swiper-no-swiping">
    <div class="animated ani swiper-out-slide-left">
        <img width="400" height="400" class="ani" swiper-animate-effect="fadeIn" swiper-animate-duration="0.5s" swiper-animate-delay="0.3s">
    <div class="swiper-out-slide-right ani " swiper-animate-effect="fadeInUp" swiper-animate-duration="0.5s" swiper-animate-delay="0.3s">
        <h2>Baidu 3</h2>
        < div > < strong > looking for him in a thousand Baidu, looking back by default, but in the dim light < / strong > < / div >
        < div > Baidu
var swiperOut=new Swiper(document.querySelector('.swiper-out'),{
    Effect: 'fade' // the reason for using this effect is that the default slide effect will be a little strange with animation. Of course, maybe the default slide effect will be very good with other animated animations
        init: function(){
            swiperAnimateCache(this); // Hide animation elements
            swiperAnimate(this); // Initialization complete start animation
            //this.slides.eq(this.activeIndex).find('.ani').removeClass('ani'); // The animation is only shown once, and the ANI class name is removed; PS: this sentence is very strange. If you let go of this sentence, every swiper slide will not disappear and will be piled on the page;

It’s very simple to use. You just need to add ‘ani’ class to the elements that need animation. This is the class provided by her, so it can’t be changed. Then you can add the attributes of swiper animation effect = “fadein” swiper animation duration = “0.5s” swiper animation delay = “0.3s”. The animation time can be changed freely, and the animation type can also be changed freely;

Create a uniform scrolling effect, such as a text loop lantern

This effect is mostly used in text display of some lists, such as lucky draw display. The three versions found on the Internet are basically the same as the four versions
HTML structure is no different from general structure
To achieve this effect is to change the CSS effect. You can copy this code to your CSS or page;

    transition-timing-function: linear; // The former is ease in out;
    -moz-transition-timing-function: linear; /* Firefox 4 */
    -webkit-transition-timing-function: linear; /*  Safari and chrome*/
    -o-transition-timing-function: linear; /* Opera */
    margin: 0 auto;

JS code

var slideSwiper=new Swiper('.slidetext-swiper',{
    freeM ode:true , // this parameter is required for uniform rolling
    speed:3000 , // this parameter mainly configures the scrolling speed. By default, the scrolling speed is fast, and 3S is not bad
        Delay: 0, // no delay
    loop:true , //, it seems stupid to avoid rolling back the text after rolling. Note that although the official document says that loop mode will cause jitter when encountering freemode, it seems that this problem has not been found. It may be because the text is too small and the interval is small. It seems that it is not obvious;
    direction : 'vertical',
    noSwiping : true,

Sliding plug in (better scroll. JS)

Please pay attention to a very important point. Please be careful
When instantiating scroll, the selector must be uniqueIn other words, if you use jQuery’s class selector, for example, if class is wrap, you must use $(‘. Wrap’) [0] to ensure uniqueness; Or you can use the native selector method document. Queryselector (selectors [, nsresolver]);
If you hit the scroll slide area display:none;Then it is very likely that the instance will be instantiated but cannot be scrolled, because display:none There is no width and height attribute on the page for the element of. It will only get 0 or some other strange value, so the plug-in will only get the wrong width and height data, so it can’t be instantiated correctly. You can set the opacity of the scrolling area to 0, Let the plug-in at least get the correct width and height attributes for instantiation. After instantiation, you can display:none;

The best solution
Using his built-in refresh () method, you don’t need to set the style, transparency, zinde and so on. You just need to refresh () manually when you click the display mask

var bsw=cbs(); // Create BS instance
$('. Showbs'). Click (function (event) {// click to display the BS pop-up window
bsw.refresh(); // Manually refresh, computes BS instances

You don’t have to worry about anything when you hide it. Just hide it

Note the height relationship between the wrapping element of the content and the outer parent elementThe height of the instantiated DOM element must be fixed, and it must be smaller than the direct wrapping element of the content. Only in this way can the rolling drop be generated. Sometimes you can easily instantiate the wrong DOM object; Then you can’t have the height attribute for the direct package element of the content. Its height is the height of the content inside;

One more word about the above display:none At least two problems are caused by him. One is that when the PDF of the portfolio is switched, the first iframe is displayed by default, so it is displayed correctly, but the second one is hidden by default, which is written at that time display:none The result is that their framework adds the first PDF to the calculation width:0; height:0; It took a long time to solve such a damned pattern; Fortunately, in the end, they revised the version and fixed the bug;
The second problem is the better scroll plug-in found above, because display:none The problem that caused the incorrect instantiation

A good sliding plug-in, hereinafter referred to as BS plug-in, overcomes the problem of local sliding anomaly on IOS such as uiwebview (such as mobile QQ) by simulating body sliding;
Scrolling occurs when the inner height of the element is higher than that of the wrapped element. Scrolling is divided into normal body scrolling and local scrolling. The bottom layer of body scrolling is controlled by the browser kernel and will not be affected too much; Local scrolling is relatively troublesome, which will cause many problems in IOS;
Introduce the usage of better scroll directly. First, release the usage description, better scroll parameters and methods

Using the BS plug-in requires that the DOM structure must be simple, usually one layer package is the best, and all the contents are put in the inner layer package

< div class = "wrapper" > // please check the height of this object and. Content. If you can't join it, you can see their CSS
  <div class="content">

    var wrapper=$('#wrapper);
    Var myscroll = new bscroll (wrapper, {// just instantiate it directly. Parameters can be added according to the actual situation or the instructions
        useT ransition:false , // prevent iPhone wechat from sliding and jamming
        probeType: 3,

Jquery.parallax.js parallax engine

A light and powerful parallax engine plug-in, can make the background elements follow the mouse to move backward cool effect, the use is also very simple

<div id="container" class="container">
    <ul id="scene" class="scene">
        <li class="layer" data-depth="1.00"><img></li>
        <li class="layer" data-depth="0.80"><img></li>
        <li class="layer" data-depth="0.60"><img></li>
        <li class="layer" data-depth="0.40"><img></li>
        <li class="layer" data-depth="0.20"><img></li>
        <li class="layer" data-depth="0.00"><img></li>

JS part:


Note: the layer class on the element must not be discarded; Data depth determines the depth of field. It can also be written separately in X and Y directions
<li class="layer" data-depth-x="-0.60" data-depth-y="-0.20"><img></li>
<li class="layer" data-depth="0.40" data-depth-y="-0.30"><img></li>

Countdown plug in (countdown. JS)

This is a simple and practical plug-in, directly drag out a countdown effect, before the start of the activity will automatically prompt, please look forward to, after the end show the end of the activity
HTML structure

<div class="pmcount_down" style="color:#999;font-size:14px;">
    <span class="day_num">00</span>
    <span class="hour_num">00</span>:
    <span class="min_num">00</span>:
    <span class="sec_num">00</span>

JS code

    Starttimestr: '2018 / 07 / 18 10:00:00' // start time
    Endtimestr: '2018 / 09 / 20 10:10:00' // end time
    hourSelector: ".hour_num",
    minSelector: ".min_num",
    secSelector: ".sec_num"

be careful
1. When there are multiple timers on the page, don’t copy and paste all the timers carelessly. Be sure to pay attention to pmcount in each timer_ The classes of down, dayselector, hourselector, minselector and secselector cannot be repeated. Otherwise, they will be instantiated to the same place, resulting in the same countdown length for each countdown,If you see that several countdowns are the same countdown length, see if they are repeated
2. In IOS, you should pay attention to the format of the start time. On PC, the Android timestamp may be in the format of 10:00:00 on July 18, 2018, but in IOS, it is 10:00:00 on July 18, 2018;If your countdown is normal on PC or Android, but it doesn’t work on IOS, let’s see if it’s a time format problem

Waterfall flow and image loading (masonry. JS + imageloaded. JS)

Before using, jQuery should be loaded first. Imageloaded is used to facilitate masonry calculation when there are many images; Two plug-ins together can make a beautiful waterfall flow, with plug-in parameters
A simple use of plug-ins start background demo

HTML structure and CSS

.masonry {
        float: left;
        width:300px;  // Each item is limited in width, which is a waterfall flow with equal width, but not equal height
        margin-bottom: 8px;
        &:hover .pic-info{ 
            bottom:4px; opacity: 1; 
            height:auto;// In fact, in the background demo, overflow is hidden,
//The DOM structure should be as concise as possible
<div class="masonry" id="masonry">
    <div class="item">
        <i class="delete">×</i>
    <div class="item">
        <i class="delete">×</i>

JS part

$(function() {
    var $container = $('#masonry');
    $container. Imageloaded (function() {// this is the method provided by imageload. JS, and the link description also has his description
        $container. Masonry ({// for detailed parameters or to understand the function of each parameter, please refer to the link description above
            itemSelector: '.item',
            gutter: 15,
            isAnimated: true,
    $('.delete').click(function(event) {
        $container.masonry( 'remove', $(this).parent());// Plug in events, more events also see the above connection description
        $container. Masonry() // it is recommended to run this method once to recalculate the internal size of the container after the DOM changes inside the container

Contour waterfall

The above is an equal width waterfall, and the following is an equal height waterfalljquery.xgallerifyOf course, it’s better to cooperate with the aboveimagesloaded.js;

<div id="xgallerify" class="xgallerify photos">
    <div class="photo" style="display: inline-block; margin: 10px; width: 424.82px;">
    ... omit ten thousand


$(function() {
    var $container = $('#xgallerify');
    $container.imagesLoaded(function() {
            mode: 'small',
            lastRow: 'adjust',
            debounceLoad: true,
parameter Default value type describe
margin 10 int Margin value between images
width 800 int The width of the picture gallery, in pixels
model Default, bootstrap, Flickr or small string The mode parameter is used to determine how the picture gallery is displayed and how many pictures are displayed per line
lastRow Adjust or fullwidth string Set the last line full screen width or auto adjust (auto adjust recommended)
jsSetup Boor Boor Sets the default CSS style for the element.
debounceLoad Boor Boor This parameter will wait 100 milliseconds before rendering a new picture to improve performance

Drag plug in (jQuery. Dad. JS)

A simple and practical drag plug-in, can be used to drag sort
Simple demo and parameter instructions drag plug-in instructions
If you use local drag, the dragged element cannot have visibility, at least it will affect the drag at present
An official example

<div class="demo">
    <div class="item item1"><span>1</span></div>
    <div class="item item2"><span>2</span></div>
    <div class="item item3"><span>3</span></div>
    <div class="item item4"><span>4</span></div>
    <div class="item item5"><span>5</span></div>


Scrolling page triggers CSS animation plug-in (wow. JS)

(PS: it must be a plug-in written by a Warcraft player, s ([pic] ◡ [pic]))

As you can see from the title, this is a plug-in used to trigger CSS animation when you slide a page, such as many official websites that start the progressive animation of elements after rolling the mouse to a certain distance; So generally, this plug-in needs to be used with animated.css, which is very convenient to use
A simple example:

<link rel="stylesheet" type="text/css" href="../js/animate.min.css">

<div style="display:flex;justify-content:space-between;width:1200px;margin:50px auto">
    <div class="wow fadeInLeft testblock" data-wow-duration="1.5s" data-wow-delay="0.3"></div>
    <div class="wow fadeInUp testblock" data-wow-duration="1.5s" data-wow-delay="0.3"></div>
    <div class="wow fadeInDown testblock" data-wow-duration="1.5s" data-wow-delay="0.3"></div>
    <div class="wow fadeInRight testblock" data-wow-duration="1.5s" data-wow-delay="0.3"></div>


var wow = new WOW({
    boxClass: 'wow', //
    animateClass: 'animated',
    offset: 0,
    mobile: true,
    live: true
Properties / methods type Default value explain
boxClass string wow Wow needs to execute the class of the animation element, corresponding to the class on the tag
animateClass string animated Specified animation class provided by animated.css
offset num 0 How far from the visual area to start the animation
mobile bool true Do you want to perform animation on your mobile device
live bool true Does the element loaded asynchronously apply animation

In fact, configuration is generally OK. You just need to add the specified class to the element that you want to use animation. Among them, ‘wow’ means that the element needs to use wow to record the location, use the wow plug-in function, and then fadeinup. These are the preset effects provided by animated.css. If you want to use those effects to directly replace the class, it’s OK, Data wow duration refers to the duration of the animation, which can be adjusted freely. Data wow delay refers to how long the animation is delayed