JavaScript -- the encapsulation of WEBAPIS UU deep animation function, common webpage special effects

Deep encapsulation of animation functions

1. Encapsulation of animation function

1.1 realization of slow motion effect

Here are some core algorithms, (target value - current position) / 10 = step size of each move

Take a specific effect, for example, slowing down an element,
Implementation idea: let the moving distance of the element change, and the step size of each time becomes smaller. Core algorithm: * * (target value - current position) / 10 as the distance step size of each movement * *, the stop condition is to stop the timer when the box reaches the target position

Implemented Code:

<body>
    <button>After clicking, old Li can fly!</button>
    <span>BM Lao Li</span>
    <script>
        // Slow motion animation function encapsulates the target position of obj target object
        // Train of thought:
        // 1. Let the box move a smaller distance each time, and the speed will slowly fall down.
        // 2. Core algorithm: (target value - current position) / 10 as the distance step of each movement
        // 3. Stop the timer if the current box position is equal to the target position
        function animate(obj, target) {
            // Clear the previous timer first, and only keep the current timer execution
            clearInterval(obj.timer);
            obj.timer = setInterval(function() {
                // The step value is written into the timer
                var step = (target - obj.offsetLeft) / 10;
                if (obj.offsetLeft == target) {
                    // The essence of stop animation is stop timer
                    clearInterval(obj.timer);
                }
                // Change the step value of adding 1 each time to a gradually smaller value step formula: (target value - current position) / 10
                obj.style.left = obj.offsetLeft + step + 'px';

            }, 15);
        }
        var span = document.querySelector('span');
        var btn = document.querySelector('button');

        btn.addEventListener('click', function() {
                // Calling function
                animate(span, 500);
            })
            // Uniform animation is that the box is the current position + fixed value of 10 
            // Jog animation is the current position of the box + changed value (target value - current position) / 10)
    </script>
</body>

1.2 multi value movement

For example, I have such a demand now: Click to go to 800 and then click to go to 500, which is equivalent to going back. We can add a condition to judge the step length

  1. If it is a positive value, the step size will be rounded up
  2. If it is a negative value, the step size is rounded to a smaller value

Core code

+++
 var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
// To explain, here, the Math.celi(step) function returns a minimum integer greater than or equal to a given number. For example, if I give a 0.95, it gives me 1, which is better than if I give a 4, which is 4. If it is - 7.44, it returns - 7
// Math.floor(step); returns the largest integer less than or equal to a given number. Pay attention to the downward rounding of this thing

+++

1.3 about callback function

As for callback function, it's actually relatively simple. To be clear, it's what to do next after the end of action (function). Notice in the animation function where the callback function writes: where the timer ends.

2. Common examples of web effects

2.1 rotation chart

Attention ha, every time we encounter a problem, we must think clearly before typing the code. It is very important to think clearly. Don't knock code as soon as you come up!!! In the end, you don't know what you're writing.

  1. requirement analysis
1. The mouse passes through the carousel module, left and right buttons are displayed, left and right buttons are hidden.

2. Click the right button once, and the picture will play to the left, and so on. The left button is the same.

3. while the picture is playing, the small circle module below changes with it.

4. Click the small circle to play the corresponding picture.

5. If the mouse does not pass through the carousel, the carousel will automatically play the picture.

6. After the mouse passes, the carousel chart module will automatically stop playing.

Implementation code:

window.addEventListener('load', function() {
    // 1. Get element
    var arrow_l = document.querySelector('.arrow-l');
    var arrow_r = document.querySelector('.arrow-r');
    var focus = document.querySelector('.focus');
    var focusWidth = focus.offsetWidth;
    // 2. The left and right buttons are hidden when the mouse passes through focus
    focus.addEventListener('mouseenter', function() {
        arrow_l.style.display = 'block';
        arrow_r.style.display = 'block';
        clearInterval(timer);
        timer = null; // Clear timer variable
    });
    focus.addEventListener('mouseleave', function() {
        arrow_l.style.display = 'none';
        arrow_r.style.display = 'none';
        timer = setInterval(function() {
            //Call click event manually
            arrow_r.click();
        }, 2000);
    });
    // 3. Dynamically generate small circles. If there are several pictures, I will generate several small circles
    var ul = focus.querySelector('ul');
    var ol = focus.querySelector('.circle');
    // console.log(ul.children.length);
    for (var i = 0; i < ul.children.length; i++) {
        // Create a small li 
        var li = document.createElement('li');
        // The index number of the current small circle is recorded by the custom attribute 
        li.setAttribute('index', i);
        // Insert little li into ol
        ol.appendChild(li);
        // 4. Exclusive thought of small circle we can directly bind click event while generating small circle
        li.addEventListener('click', function() {
            // Kill everyone. Clear all the current class names
            for (var i = 0; i < ol.children.length; i++) {
                ol.children[i].className = '';
            }
            // Leave my current little li to set the current class name
            this.className = 'current';
            // 5. Click the small circle to move the picture, of course, ul 
            // ul's moving distance the index number of the small circle times the width of the picture notice that it's a negative value
            // When we click a small li, we get the index number of the current small li
            var index = this.getAttribute('index');
            // When we click on a small li, we will give the index number of li to num  
            num = index;
            // When we click on a small li, we will give the index number of li to circle  
            circle = index;
            // num = circle = index;
            console.log(focusWidth);
            console.log(index);

            animate(ul, -index * focusWidth);
        })
    }
    // Set the first small li in ol to the class name current
    ol.children[0].className = 'current';
    // 6. Clone the first picture (li) and put it at the back of ul
    var first = ul.children[0].cloneNode(true);
    ul.appendChild(first);
    // 7. Click the right button to scroll one picture
    var num = 0;
    // circle controls the playback of small circles
    var circle = 0;
    // flag throttle valve
    var flag = true;
    arrow_r.addEventListener('click', function() {
        if (flag) {
            flag = false; // Close the throttle valve
            // If we go to the last copied image, our ul will quickly restore left to 0
            if (num == ul.children.length - 1) {
                ul.style.left = 0;
                num = 0;
            }
            num++;
            animate(ul, -num * focusWidth, function() {
                flag = true; // Open throttle valve
            });
            // 8. Click the button on the right, and the small circle can be changed together to declare another variable to control the play of the small circle
            circle++;
            // If circle == 4, we will restore the image we cloned at the end
            if (circle == ol.children.length) {
                circle = 0;
            }
            // Calling function
            circleChange();
        }
    });

    // 9. Left button method
    arrow_l.addEventListener('click', function() {
        if (flag) {
            flag = false;
            if (num == 0) {
                num = ul.children.length - 1;
                ul.style.left = -num * focusWidth + 'px';

            }
            num--;
            animate(ul, -num * focusWidth, function() {
                flag = true;
            });
            // Click the button on the left, and the small circle can be changed together to declare another variable to control the play of the small circle
            circle--;
            // If circle < 0 indicates the first picture, the small circle should be changed to the fourth small circle (3)
            // if (circle < 0) {
            //     circle = ol.children.length - 1;
            // }
            circle = circle < 0 ? ol.children.length - 1 : circle;
            // Calling function
            circleChange();
        }
    });

    function circleChange() {
        // Clear the current class names of the rest of the small circles first
        for (var i = 0; i < ol.children.length; i++) {
            ol.children[i].className = '';
        }
        // Leave the current class name of the current small circle
        ol.children[circle].className = 'current';
    }
    // 10. Automatically play the carousel chart
    var timer = setInterval(function() {
        //Call click event manually
        arrow_r.click();
    }, 2000);

})

2.2 off diagram call, closure gate

When we execute the above code, we will find some small bug s. For example, if I click the next page crazily, there will be a problem! At this time, the closure gate was born

Core principles:

Purpose of throttle valve: when the animation content of the previous function is completed, execute the animation of the next function, so that the event cannot be triggered continuously.

Core implementation idea: using callback function, add a variable to control, lock function and unlock function.

Start setting a variable var flag= true;

If(flag){flag = false; do something} turn off the tap

Use callback function animation to finish execution, flag = true to turn on the tap

Instance code block:


2.3 back to top

Say the important thing again! Be sure to analyze the needs before starting!

  1. Demand analysis:
1. Animated back to top
 2. At this time, we can continue to use our encapsulated animation functions
 3. Just change all the left related values to the vertical scrolling distance of the page
 4. How many pages have been scrolled can be obtained through window.pageYOffset
 5. Finally, page scrolling, using window.scroll(x,y) 

code implementation

  //1. Get element
        var sliderbar = document.querySelector('.slider-bar');
        var banner = document.querySelector('.banner');
        // banner.offestTop is the size of the head to be rolled out, which must be written outside the scroll
        var bannerTop = banner.offsetTop
            // The value that should change when our sidebar is fixed
        var sliderbarTop = sliderbar.offsetTop - bannerTop;
        // Get main body element
        var main = document.querySelector('.main');
        var goBack = document.querySelector('.goBack');
        var mainTop = main.offsetTop;
        // 2. Page scrolling event scroll
        document.addEventListener('scroll', function() {
                // console.log(11);
                // The head of the window.pageYOffset page
                // console.log(window.pageYOffset);
                // 3. When the head of our page is more than or equal to 172, the sidebar will be fixed
                if (window.pageYOffset >= bannerTop) {
                    sliderbar.style.position = 'fixed';
                    sliderbar.style.top = sliderbarTop + 'px';
                } else {
                    sliderbar.style.position = 'absolute';
                    sliderbar.style.top = '300px';
                }
                // 4. When we scroll to the main box, the goback module will be displayed
                if (window.pageYOffset >= mainTop) {
                    goBack.style.display = 'block';
                } else {
                    goBack.style.display = 'none';
                }

            })
            // 3. When we click to return to the top module, let the window scroll to the top of the page
        goBack.addEventListener('click', function() {
            // If the x and y in it are not the same as the unit, just write the number directly
            // window.scroll(0, 0);
            // Because it's window scrolling, the object is window
            animate(window, 0);
        });

3. Touch screen events of mobile terminal

3.1 touch screen events

Generally speaking, js of mobile terminal is quite compatible.

  1. touch event list

3.1 touch screen event object

TouchEvent is a kind of event that describes the state change of fingers in the touch plane (touch screen, touchpad, etc.). These events are used to describe one or more contacts, enabling developers to detect the movement of contacts, the increase and decrease of contacts, and so on

touchstart, touchmove and touchend all have event objects.

Touch event objects focus on three common object lists:

Note that in the actual development, the most commonly used is targetTocuhes, because we usually register touch events for elements

3.1 implement drag elements

  1. touchstart, touchmove and touchend can implement dragging elements

  2. But dragging the element requires the coordinate value of the current finger. We can use pageX and pageY in targetTouches[0]

  3. The principle of drag at the moving end: in the process of finger moving, calculate the distance of finger moving. Then use the box's original position + the distance the finger moves

  4. Finger moving distance: the position in finger sliding minus the position where the finger just started to touch

    Drag the element three step:

    (1) Touch element touchstart: get the initial coordinates of the finger and the original position of the box at the same time

    (2) Move finger touchmove: calculates the sliding distance of the finger and moves the box

    (3) Leave the finger touch end:

    Note: finger movement will also trigger scrolling of the screen, so the default screen scrolling should be prevented here;

Example code:

<body>
    <div></div>
    <script>
        // (1) Touch element touchstart: get the initial coordinates of the finger and the original position of the box at the same time
        // (2) Move finger touchmove: calculates the sliding distance of the finger and moves the box
        // (3) Leave the finger touch end:
        var div = document.querySelector('div');
        var startX = 0; //Get initial finger coordinates
        var startY = 0;
        var x = 0; //Get the original position of the box
        var y = 0;
        div.addEventListener('touchstart', function(e) {
            //  Get initial finger coordinates
            startX = e.targetTouches[0].pageX;
            startY = e.targetTouches[0].pageY;
            x = this.offsetLeft;
            y = this.offsetTop;
        });

        div.addEventListener('touchmove', function(e) {
            //  Calculate the moving distance of the finger: subtract the initial coordinates of the finger from the coordinates after the finger moves
            var moveX = e.targetTouches[0].pageX - startX;
            var moveY = e.targetTouches[0].pageY - startY;
            // Move the original position of our box box + the distance of finger movement
            this.style.left = x + moveX + 'px';
            this.style.top = y + moveY + 'px';
            e.preventDefault(); // Default behavior to prevent screen scrolling
        });
    </script>
</body>

Tags: Javascript Mobile less Attribute REST

Posted on Sat, 14 Mar 2020 23:13:55 -0700 by lovelf