
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FLIP 动画</title>
<style>
* {
padding: 0;
margin: 0;
}
ul,li {
list-style: none;
}
ul {
border: 1px solid gold;
padding: 20px;
width: 300px;
}
li {
height: 40px;
background: goldenrod;
border-radius: 20px;
margin-bottom: 5px;
text-align: center;
line-height: 40px;
}
li:last-child {
background: red;
}
</style>
</head>
<body>
<button id="btn">run</button>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
<script>
const list = document.querySelector('ul')
const btn = document.getElementById('btn')
btn.onclick = () => {
const firstItem = document.querySelector('li')
const dis = getDistance(firstItem)
addTransition(firstItem, dis)
raf(() => {
firstItem.style.transition = 'transform 5s'
firstItem.style.removeProperty('transform')
})
}
function getDistance(firstItem) {
const start = getLocation(firstItem)
list.insertBefore(firstItem, null)
const end = getLocation(firstItem)
const dis = start - end
return dis
}
function addTransition(firstItem, dis) {
firstItem.style.removeProperty('transition')
firstItem.style.transform = `translateY(${dis}px)`
}
function raf(cb) {
requestAnimationFrame(() => {
requestAnimationFrame(cb)
})
}
function getLocation(firstItem) {
const react = firstItem.getBoundingClientRect()
return react.top
}
</script>
</body>
</html>