What do I see

When looking at taobao front – end team’s blog, inadvertently into the pointAbout usIn this page, there is an animation which I think is very interesting and universal. It feels like it can be used everywhere. The effect is as shown in the picture below:


The profile picture and the position of ‘You’ are different every time. To be honest, I thought it was quite interesting, so I tried to implement it myself.

Below, I will analyze the realization of such effect from my perspective, because I don’t know how FED achieves it

What to do

First analyze the structure of the small box, that is:



<span>
  <img />
  <I></i>
</span>Copy the code

Img is the head, SPAN controls the background color, and I is used to create the mirror effect. We get the effect that I’m nearsighted, that I’m not male or female from ten meters away, and then look at this layout and it looks familiar, and I see this structure and it looks something like this



[
  ' '.' xxxx xx xxx '.' x x x x '.' xxxx x x x '.' x x x x '.' xxxx xx xxx '.' ',]Copy the code

This is not a string array, then I as a two-dimensional array processing, is not easy to find the character to display the abscissa and ordinate, is not beautiful. Don’t roll up your sleeves just yet. After years of not thinking about rolling up your sleeves, I thought for a while that it would be better to use an array, and the DOM aspect would be easier to handle. Each square is an individual of the array.

With that in mind, I pinched my finger and figured out that I needed 126 squares in a 7-by-18 layout. I pinched my finger and figured out that I wanted to write a 126 span label, something like this:

Omnipotent editor, which I later discovered can span*126+ TAB, witty as me, delightfully.


Ah? You ask me how the top span is made, damn, I’m sure my hand slowly beat ah


Well, it feels better to use JS to generate, convenient and much less code. Ok, let’s roll up our sleeves and do it:



const faceList = (new Array(126)).map(() = > {
  const face = document.createElement("span");
  / /...
  return face;
});
document.body.append(faceList);Copy the code

We open the page:



What the hell is this?

Ok, let’s take an example. Now I want to create an array of length ten, and all the members of the array are indexed. What do I do?



const arr = (new Array(10)).map...Copy the code

Okay, here’s the correct posture:



Array.from({length: 10}, (v, i) => i);/ / the first
Array.apply(null, { length: 10 }).map(/ /...). ; / / the second
// Welcome to add moreCopy the code

Of course, you can also use recursion. Personally, I always use the first method, which feels better. Let’s implement it again:



const faceList = Array.from({ length: 126= > {}, ()const face = document.createElement("span");
  const img = document.createElement("img");
  const i = document.createElement("i");
  i.style.left = '100%';
  face.append(img);
  face.append(i);
  return face;
});Copy the code

To render the DOM to the page, it’s time to figure out where we want to render the character:



let EOITextArr = 
[
  ' '.' xxxx xx xxx '.' x x x x '.' xxxx x x x '.' x x x x '.' xxxx xx xxx '.' ',];let EOIArr = [];
EOITextArr.forEach((v, i) = > {
  for(let j = 1; j < v.length; j++) {
    if (v[j] === 'x') {
      EOIArr.push(i * 18+ j); }}})Copy the code

Remember, we have images and spans to work with, so we need two sets of arrays, shallow copy is fine:



const textArr = [].concat(EOIArr);
const imgArr = [].concat(EOIArr);Copy the code

Processing logic

Now that we’ve got the DOM and the location of the elements we need to work with, here’s how to work with the background color and the image. We have the span and IMG arrays to change respectively, we just need to change the background color first and then control the image hide. The process must be controlled by a timer, and the display position is random, so we also need the math. random method. We get the array of individuals by splice over and over again, and avoid getting duplicate individuals as follows:



const colorTimer = setInterval((a)= > {
  const length = textArr.length;
  const showNumber = textArr.splice(Math.random() * length, 1);
  spanEles[showNumber].style.backgroundColor = '#F40';
  iEles[showNumber].style.left = '100%';
  if (!textArr.length) {
    clearInterval(colorTimer);
    showImg();
  }
}, 25);Copy the code

After the background color has changed, we need to start the timer of the image. Similarly, the SRC of the image is also random:



const showImg = (a)= > {
  const imgTimer = setInterval((a)= > {
    const length = imgArr.length;
    const [showNumber] = imgArr.splice(Math.random() * length, 1);
    const [imgIndex] = imgSrc.splice(Math.random() * imgSrc.length, 1);
    
    imgEles[showNumber].src = imgList[imgIndex];
    imgEles[showNumber].style.display = 'inline';
    spanEles[showNumber].style.backgroundColor = '#fff';
    iEles[showNumber].style.left = '100%';

    if (imgArr.length === 0) {
      spanEles[showNumber].classList.add('you'); clearInterval(imgTimer); }},25);
}Copy the code

Display ‘You’ when the image goes to the last one.

Call it a day

To complete the effect



Because I really didn’t want to find that many pictures, I only made about ten copies, and then I multiplied it by three, so I had the same head repeated three times,The source code. A small try, feel very interesting, thank you for watching ~