Flip动画的实现示例demo
- 文章说明
- 核心代码
- 效果展示
- Flip动画工具类的封装
文章说明
文章主要为了学习flip动画的实现思路,并且采用此示例效果来理解该实现思路的含义
参考渡一前端袁老师的讲解视频
核心代码
采用简单的y轴变化的动画效果为示例
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
margin: auto;
margin-top: 100px;
width: 100px;
div {
height: 30px;
line-height: 30px;
margin: 10px 0;
background-color: chocolate;
border-radius: 10px;
color: #ffffff;
text-align: center;
}
}
</style>
</head>
<body>
<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
<button onclick="randomFlip()">点击flip</button>
<script>
function getElemConfig(container, children, first, last) {
const elemFirst = container.children[first];
const elemLast = container.children[last];
const destElem = children[last];
destElem.style.transform = `translateY(${elemLast.getBoundingClientRect().y - elemFirst.getBoundingClientRect().y}px)`;
return destElem;
}
function play(destElem) {
setTimeout(() => {
for (let i = 0; i < destElem.length; i++) {
destElem[i].style.transition = "transform 1s";
destElem[i].style.removeProperty("transform");
}
}, 100);
}
function randomFlip() {
const numbers = [];
const container = document.getElementsByClassName("container")[0];
const children = [];
for (let i = 0; i < container.children.length; i++) {
numbers.push(i);
children.push(container.children[i].cloneNode(true));
}
const result = derange(numbers);
const destElem = [];
for (let i = 0; i < result.length; i++) {
destElem.push(getElemConfig(container, children, i, result[i]));
}
container.innerHTML = "";
for (let i = 0; i < destElem.length; i++) {
container.appendChild(destElem[i]);
}
play(destElem);
}
function derange(array) {
let derangedArray = array.slice();
let i = derangedArray.length;
while (i > 0) {
let j = Math.floor(Math.random() * i);
while (j === i || derangedArray[i] === derangedArray[j]) {
j = Math.floor(Math.random() * i);
}
[derangedArray[i - 1], derangedArray[j]] = [derangedArray[j], derangedArray[i - 1]];
i--;
}
return derangedArray;
}
</script>
</body>
</html>
效果展示
采用translateY进行 transform 动画
Gif展示
Flip动画工具类的封装
在实现拖拽排序示例时,我在参考的学习视频中看到有关于Flip动画功能进行了封装,我于是自己研究了一下,封装了该工具,工具类如下
class Flip {
children = null;
delay = 0;
constructor(children, delay = 1) {
this.children = children;
this.calculatePos();
this.delay = delay;
}
calculatePos(name = "first") {
const children = this.children;
for (let i = 0; i < children.length; i++) {
children[i][name] = children[i].getBoundingClientRect();
}
}
play() {
this.calculatePos("last");
const children = this.children;
for (let i = 0; i < children.length; i++) {
const first = children[i]["first"];
const last = children[i]["last"];
if (first.x !== last.x || first.y !== last.y) {
children[i].style.transform = `translateY(${first.y - last.y}px) translateX(${first.x - last.x}px)`;
setTimeout(() => {
children[i].style.transition = `transform ${this.delay}s`;
children[i].style.removeProperty("transform");
setTimeout(() => {
children[i].style.removeProperty("transition");
this.calculatePos();
}, this.delay * 1000);
}, 0);
}
}
}
}
关于拖拽排序和该工具类的使用,可参考这篇文章–拖拽排序