This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

preface

I’m sure you’ve used the transition-group component in Vue. You can see this sentence below the component

This looks like a magic, internal implementation. Vue uses a simple animation queue called FLIP that uses transforms to smooth elements from their previous positions into new ones. We combined our previous implementation examples with this technique to animate all changes to our list.

And a really, really cool animation effect

Follow me into the wonderful world of Flip animation

Front knowledge

getBoundingClientRect

Through the dom. GetBoundingClientRect (), can be an element in a rectangular area on the screen

const rect = dom.getBoundingClientRect(); // Get the rectangle area
rect.left; // Get the left value of the rectangle
rect.top; // Get the top value of the rectangle
Copy the code

transform

Transform is a property provided by CSS3 that means transform or transform

Css3 provides a variety of transformation methods, including translation, rotation, tilt, scale, and more versatile matrix transformation

All transformations will not affect the actual layout position, only the final visual effect

animate api

The Animate () method of the Element interface is a convenient way to create a new Animation, apply it to an Element, and then run the Animation. It will return a newly created Animation instance

Implementing an animation using the Animate API is very simple and requires only the following code

dom.animate(
  [
    { /* Start CSS property */ },
    { /* End CSS properties */{},],duration: 800.// The time to complete the animation});Copy the code

See the MDN documentation for other apis

Flip thought

Flip is an animation idea, specifically for that scenario

It consists of four words, which are:

  • First
  • Last
  • Invert
  • Play

The specific process is as follows

In code implementation, you can follow the following structure to achieve animation effects

/ / (1) the Frist
record(container); // Record the starting coordinates of each child element in the container
// Change the element order
change();
// ② Last + ③ Invert + ④ Play
move(container); // Make the element really move
Copy the code

implementation

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
    }

    .btns {
        text-align: center;
    }

    .btns button {
        margin: 0 1em;
        outline: none;
        border: none;
        background: #579ef8;
        color: #fff;
        padding: 7px 10px;
        border-radius: 5px;
        cursor: pointer;
    }

    .btns button:hover {
        opacity: 0.8;
    }

    .container {
        width: 500px;
        overflow: hidden;
        margin: 20px auto;
        display: flex;
        flex-wrap: wrap;
    }

    .item {
        width: 50px;
        height: 50px;
        box-sizing: border-box;
        text-align: center;
        background: #eef5fe;
        border: 1px solid #ddebfd;
        line-height: 50px;
        margin: 5px;
    }
</style>

<body>
    <div class="btns">
        <button id="sort">Random sequence</button>
    </div>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
        <div class="item">5</div>
        <div class="item">6</div>
        <div class="item">7</div>
        <div class="item">8</div>
        <div class="item">9</div>
        <div class="item">10</div>
        <div class="item">11</div>
        <div class="item">12</div>
        <div class="item">13</div>
        <div class="item">14</div>
        <div class="item">15</div>
        <div class="item">16</div>
        <div class="item">17</div>
        <div class="item">18</div>
        <div class="item">19</div>
        <div class="item">20</div>
        <div class="item">21</div>
        <div class="item">22</div>
        <div class="item">23</div>
        <div class="item">24</div>
        <div class="item">25</div>
        <div class="item">26</div>
        <div class="item">27</div>
        <div class="item">28</div>
        <div class="item">29</div>
        <div class="item">30</div>
        <div class="item">31</div>
        <div class="item">32</div>
        <div class="item">33</div>
        <div class="item">34</div>
        <div class="item">35</div>
        <div class="item">36</div>
        <div class="item">37</div>
        <div class="item">38</div>
        <div class="item">39</div>
        <div class="item">40</div>
        <div class="item">41</div>
        <div class="item">42</div>
        <div class="item">43</div>
        <div class="item">44</div>
        <div class="item">45</div>
        <div class="item">46</div>
        <div class="item">47</div>
        <div class="item">48</div>
        <div class="item">49</div>
        <div class="item">50</div>
    </div>

<script>
    const container = document.querySelector('.container')
    function change() {
        const childrens = [...container.children]
        for(let i = 0, l = childrens.length; i < l; i ++) {
            const children = childrens[i]
            const j = Math.floor(Math.random() * l)
            if(i ! == j) {// Get the next element of the current DOM
                const inextDom = children.nextElementSibling
                // insert I before j
                container.insertBefore(children, childrens[j])
                // Insert the element subscript j before the element I
                container.insertBefore(childrens[j], inextDom)
            }
        }
    }
    sort.onclick = () = > {
        record(container)
        change()
        move(container)
    }

    function record(container) {
        for(let i = 0, len = container.children.length; i < len; i ++) {
            const dom = container.children[i]
            const rect = dom.getBoundingClientRect()
            dom.startX = rect.left
            dom.startY = rect.top
        }
    }

    function move(container) {
        for(let i = 0, len = container.children.length; i < len; i ++) {
            const dom = container.children[i]
            const rect = dom.getBoundingClientRect()
            const curX = rect.left, curY = rect.top
            dom.animate([
                { transform: `translate(${dom.startX - curX}px, ${dom.startY - curY}px)` },
                { transform: `translate(0px, 0px)`}, {duration: 600}}})</script>
</body>

</html>
Copy the code

That’s all of the code, and you can see it on the console without the style tag, which is amazing.

conclusion

FLIP can animate not only position changes, but also transparency, size, and so on.

Flip is very useful and can be implemented wherever animation is needed

I hope this article will be helpful to you. Thank you!