When I was on vacation at home, one of my friends in the group asked me if I had the idea of seamless rotation. After a search on Baidu, it turned out that seamless rotation refers to the traditional rotation chart in which the last one is the first one and the next one is the first one, which does not go through the middle of the rotation chart.
Let me give you an example
Also put codepen’s address
Conventional thinking
This is the native JS seamless rotation effect, to give you a brief talk about the idea, the following as an example
The process is as follows: assume that the six pictures are A, B, C, D, E, AND F respectively. Click the next button and move all the pictures left to change the width of picture A to B, C, D, E, F, ACopy the code
And then let’s describe it in code
var img0 = document.querySelector('img')[0]; var img0Width = img0.offsetWidth, var imgContainer = document.querySelector('.box'); / / loading picture of container imgContainer. The animate ({marginLeft: - img0Width}, function () {/ / end of the animation callback methods imgContainer. Style.css. MarginLeft = 0; // Revert the marginleft to 0 var newNode = img0.clonenode (true); Imgcontainer.removechild (img0); imgContainer.appendChild(img0); })Copy the code
It’s a pretty simple idea, but if you think about it, there’s a bad one, and that’s this code.
imgContainer.style.marginLeft = 0;
Copy the code
Why is this code bad? Here is the use of the computer’s powerful CPU, so that we can be invisible to the naked eye fast right, let’s simulate in detail
Next slide: Assume that the six pictures are A, B, C, D, E, F, left movement (slow motion), A, B, C, D, E, F, animation callback (instantaneous), B, C, D, E, F, ACopy the code
Did you notice that this animation is very irregular
- We moved the image container to the left, but then moved it instantly to the right, which is not consistent with the semantics of image movement.
The thinking of the react
Because we can determine the initial state of the picture
A B C D E = > B C D E A moving description of the picture (B C D E) left shift (A) right shiftCopy the code
That is to say, we can specify the state of the picture before and after the animation, and the order of the picture is the distance of the picture moving. This is very much in line with react’s design philosophy. Okay, let’s do react again. Here we use native JS to simulate React.
1. Set the initial state
const defaultState = Array(items.length).fill(0).map((item, index) => {
return {
key: `item${index}`,
style: {
left: (index + currentNum) * 100,
opacity: 1
}
}
})
Copy the code
Here items is the nodelist of the IMG tag, and currentNum is the initial offset of the image (-1 means all images move one left, 1 means all images move one right).
2. Update the state after the order is changed
const getState = (states, moveItemKey) => states.map((state, index) => {
return {
key: state.key,
style: {
left: (index + currentNum) * 100,
opacity: moveItemKey === state.key ? 0 : 1
}
}
})
const setState = (newStates, moveItemKey) => {
return getState(newStates, moveItemKey);
}
Copy the code
MoveItemKey is the image of A that needs to be in A, B, C, D, E = > B, C, D, E, A. There is A problem here. When A moves from the first picture to the last one, A will pass through B, C, D and E, which is definitely not possible. Therefore, we have obtained A’s key in advance and changed the transparency of A to 0, so that users can’t detect it even if it passes through B, C, D and E.
3. Bind key values to DOM elements
const setAttr = () => [...items].map((item, index) => { item.setAttribute('key', states[index]['key']); }); const render = () => { [...items].map((item, index) => { var key = item.getAttribute('key'); states.map((state, i) => { if (state.key === key) { item.style.left = state['style']['left'] + 'px'; item.style.opacity = state['style']['opacity']; }}); })}Copy the code
Here we bind the key to the element to the DOM property, and the render method renders the DOM based on the state data.
4. Add previous and next events
const prev = () => {
var moveItem = states.slice(states.length - 1);
newStates = [...moveItem, ...states.slice(0, states.length - 1)];
states = setState(newStates, moveItem[0].key);
render();
}
const next = () => {
var moveItem = states.slice(0, 1);
newStates = [...states.slice(1), ...moveItem];
states = setState(newStates, moveItem[0].key);
render();
}
prevButton.onclick = prev;
nextButton.onclick = next;
Copy the code
In the case of The Next page event (Next), all we need to do is move the first image in the image group to the end. It’s a bit of a shame that we didn’t implement the automatic render for state changes, but here’s how to animate react.
Let’s see how react works
Also put codepen’s address
Compared with the traditional seamless rotation, after recT rewriting, the code readability becomes higher, the idea is clearer, and the code also becomes less and easier to maintain.
The official react – motion
Of course, the final react animation solution must be React-Motion. Motion provides various animation parameters and makes animation very realistic. It also implements a version of react-Motion seamless rotation according to the REact-Motion API.
With the introduction of React-Motion, animation costs were significantly lower and less code was written. I’ll leave an address here for those of you who are interested.
Making the address
A summary
Now look at the animation, feel animation is gradual, regular, by operating elements teleport from one position to another position, personal feel is against the idea of the animation, because the instantaneous changes from one location to another, this is cannot describe (or do not conform to the animation of the semantic), can consult us before implementation of shuffling in a traditional way. Now we write the animation, we should first describe the state of the animation, and then describe the initial state and end state of the animation, such animation is regular.