思路:
效果:
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
.button {
width: 30px;
height: 30px;
border-radius: 100%;
background: blue;
margin-left: 300px;
margin-top: 50px;
line-height: 30px;
font-size: 1em;
text-align: center;
color: white;
cursor: pointer;
}
.box {
width: 100px;
height: 100px;
position: fixed;
left: 0px;
bottom: 0px;
}
/* openBox.png:一张打开的盒子图片 */
.boxOpen {
background: url('./openBox.png') no-repeat center;
background-size: 100% 100%;
}
/* closeBox.png:一张关闭的盒子图片 */
.boxClose {
background: url('./closeBox.png') no-repeat center;
background-size: 100% 100%;
}
</style>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
</head>
<body>
<!-- 放在左下角的盒子 -->
<div class=" box boxClose" id="box"></div>
<!-- 模拟菜单 -->
<div id="buttonCon">
<div class="button">
1
</div>
<div class="button">
2
</div>
<div class="button">
3
</div>
<div class="button">
4
</div>
<div class="button">
5
</div>
<div class="button">
6
</div>
<div class="button">
7
</div>
<div class="button">
8
</div>
</div>
<script>
// 获取按钮的容器
var buttonCon = document.getElementById("buttonCon");
// 获取盒子
var box = document.getElementById("box");
// 定义小球的个数
var index = 0;
// 委托代理事件
buttonCon.addEventListener("click", function(e) {
// 获取当前对象
var target = e.target;
// 判断当前对象样式列表中有没有button类
if (target.classList.contains("button")) {
// 判断盒子是否是关闭的盒子
if (box.classList.contains("boxClose")) {
// 移除关闭盒子样式
box.classList.remove("boxClose");
// 增加打开盒子样式
box.classList.add("boxOpen");
}
// 创建动画小球的容器--运动时让小球容器朝下方运动,让里面的小球向左运动,这样就会使小球成弧形运动
var ball = document.createElement("div");
// 定义样式
ball.style.position = "fixed"
// 定义在目标元素的上方
ball.style.top = (target.offsetTop - target.offsetHeight) + "px";
ball.style.left = target.offsetLeft;
// 定义小球容器的大小
ball.style.width = target.offsetWidth + "px"
ball.style.height = target.offsetHeight + "px"
ball.style.borderRadius = "100%"
// 设置为点击穿透
ball.style.pointerEvents = "none"
// 设置过度动画--贝塞尔曲线
ball.style.transition = "3s cubic-bezier(0.49,-0.3,0.75,0.41)"
// 定义小球
var ballIn = document.createElement("div");
// 定义小球大小
ballIn.style.width = target.offsetWidth + "px"
ballIn.style.height = target.offsetHeight + "px"
ballIn.style.borderRadius = "100%"
ballIn.style.background = "red"
ballIn.style.backgroundSize = "100% 100%"
// 定义过度效果
ballIn.style.transition = " 3s linear"
ballIn.innerHTML = ""
// 添加到dom中
ball.appendChild(ballIn);
document.body.appendChild(ball)
// 小球个数增加
index++
// 指定小球的落点
setTimeout(function() {
// 指定小球容器的落点在y轴的底部
ball.style.transform = "translateY(" + (window.innerHeight - target.offsetTop - 30) + "px)"
// 指定小球的落点在x轴的左侧 同时旋转360度
ballIn.style.transform = "translateX(" + (-300 + 20) + "px) rotate(360deg)"
// 小球容器的过度动画结束时
ball.addEventListener('transitionend', function(ev) {
// 事件结束,小球容器删除
ball.remove();
// 因为执行两次 每次减去0.5 两次正好减去1 代表小球少一个
index -= 0.5
// 当没有小球的时候,只要有小球盒子应该一直保持打开的状态
if (index === 0) {
// 删掉打开的盒子样式
box.classList.remove("boxOpen")
// 增加关闭的盒子
box.classList.add("boxClose")
}
})
});
}
}, false)
</script>
</body>
</html>