1. 伸缩框:鼠标移到指定区域,框缓冲伸展出,移出指定区域,框收回。
核心思想:给两个目标值,缩回时嵌入页面左边,伸出时整个wrapper向右移出。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Motion2</title>
<style type = "text/css">
*{
margin:0;
padding: 0;
}
.wrapper{
position: relative;
width: 400px;
height: 100px;
top: 300px;
left: -400px;
background: #f40;
}
.wrapper .show{
position: absolute;
width:50px;
height: 100px;
top: 0px;
right: -50px;
background: green;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="show"> </div>
</div>
<script type = "text/javascript">
// 鼠标移入,框缓冲弹出,移出框缓冲收回
var wrapper = document.getElementsByClassName('wrapper')[0],
show = document.getElementsByClassName('show')[0],
timer = null;
wrapper.onmouseenter = function(){
startMove(this,0);
}
wrapper.onmouseleave = function(){
startMove(this,-400);
}
function startMove(obj,target){
clearInterval(timer);
var speed;
timer = setInterval(function(){
speed = (target-obj.offsetLeft)/7;
speed = speed>0? Math.ceil(speed):Math.floor(speed);
if(obj.offsetLeft === target){
clearInterval(timer);
}else{
obj.style.left = obj.offsetLeft + speed + 'px';
}
},30)
}
</script>
</body>
</html>
2. 多物体多值链式运动框架:点击指定区域,同时改变div的宽、高、位置和透明度。
核心思想:透明度0-1之间变化,转化成0-100,否则透明度会在-1和1之间闪烁,无法缓冲改变透明度;透明度没有’px‘,其他有’px‘;注意判断停止的时间点;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Motion4</title>
<style type = "text/css">
*{
margin: 0;
padding:0;
}
div{
position: absolute;
width: 100px;
height:100px;
background:#f00;
border:1px solid black;
opacity: 1;
top:0;
left: 0;
margin-top:60px;
}
.bottom{
top:200px;
left:0;
}
</style>
</head>
<body>
<div class = "top"></div>
<div class = "bottom"></div>
<script type = "text/javascript">
// 多物体多值链式运动框架
var odiv1 = document.getElementsByTagName('div')[0],
odiv2 = document.getElementsByTagName('div')[1];
var timer = null;
var target = {
height:400,
width:400,
top:200,
left:300,
opacity:50
}
odiv1.onclick = function(){
startMove(this,target,function(){
startMove(odiv2,target);
});
}
function getStyle(elem,prop){
if(window.getComputedStyle){
return window.getComputedStyle(elem,null)[prop];
}else{
return elem.currentStyle[prop];
}
}
function startMove(obj,json,callback){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
var speed,cur;
var bstop = true;
for(var prop in json){
if(prop == 'opacity'){
cur = parseFloat(getStyle(obj,prop))*100;
}else{
cur = parseInt(getStyle(obj,prop));
}
speed = (json[prop]-cur)/7;
speed = speed>0? Math.ceil(speed):Math.floor(speed);
if(prop == 'opacity'){
obj.style[prop] = (cur+speed)/100;
}else{
obj.style[prop] = cur + speed + 'px';
}
if(cur != json[prop])
{
bstop = false;
}
}
if(bstop){
clearInterval(obj.timer);
typeof callback =='function'? callback():'';
}
},30)
}
</script>
</body>
</html>
3. 导航栏选中样式:当鼠标移入导航栏某一选项时,该选项的背景颜色发生改变,其他选项恢复正常。
核心思想:创建n+1个li,最后一个li作为背景颜色,当鼠标移入其他li时,最后一个li移动到目标li。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>elastic1</title>
<style type = "text/css">
*{
margin: 0;
padding:0;
list-style: none;
}
ul{
position: relative;
width: 400px;
height: 80px;
top:100px;
left: 200px;
}
ul .nav{
/* position: absolute; */
width: 98px;
height: 78px;
text-align: center;
line-height: 78px;
border:1px solid #000;
float: left;
}
ul .bg{
position: absolute;
width: 98px;
height: 78px;
background: #f40;
opacity: 0.5;
border:1px solid #000;
}
</style>
</head>
<body>
<ul>
<li class = "nav">liu</li>
<li class = "nav">hai</li>
<li class = "nav">ping</li>
<li class = "nav">hu</li>
<li class = "bg"></li>
</ul>
<script type = "text/javascript">
var liArray = document.getElementsByClassName('nav'),
// liArray = Array.prototype.slice.call(document.getElementsByClassName('nav'),0),
libg = document.getElementsByClassName('bg')[0];
for(var i = 0; i< liArray.length;i++){
liArray[i].onmouseenter = function(){
var target = this.offsetLeft;
startMove(libg,target);
}
}
// liArray.forEach(function(ele,index){
// ele.onmouseenter = function(){
// var target = this.offsetLeft;
// startMove(libg,target);
// }
// })
function startMove(obj,target){
clearInterval(obj.timer); //必不可少
var speed = 40,a,u = 0.8;
obj.timer = setInterval(function (){
a = (target-obj.offsetLeft)/7;
speed = (speed + a)*u;
if(Math.abs(speed)<=1 && Math.abs(target-obj.offsetLeft)<1){
clearInterval(obj.timer);
obj.style.left = target + 'px';
}else{
obj.style.left = obj.offsetLeft + speed + 'px';
}
},30)
}
</script>
</body>
</html>
4.弹性碰撞
核心思想:碰到页面边缘时速度反向,注意碰到边缘的条件:
碰到下边缘:div.style.height = document.documentElement.Height - div.offsetTop
碰到上边缘:0 = document.documentElement.Height - div.offsetTop
碰到右边缘:div.style.width = document.documentElement.Width - div.offsetLeft
碰到左边缘:0 = document.documentElement.Width- div.offsetLeft
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>elastic2</title>
<style type = "text/css">
*{
margin: 0;
padding:0;
list-style: none;
}
div{
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
background: #f00;
}
</style>
</head>
<body>
<div></div>
<script type = "text/javascript">
//弹性碰撞
var div = document.getElementsByTagName('div')[0];
div.onclick = function(){
startMove(div);
}
function startMove(obj){
clearInterval(obj.timer);
var speedX = 60,
speedY = 400,
g = 8,
u = 0.8;
obj.timer = setInterval(function(){
speedY += g;
var newLeft = obj.offsetLeft + speedX,
newTop = obj.offsetTop + speedY;
if(newTop >= document.documentElement.clientHeight-obj.offsetHeight){
speedY = speedY*(-1);
speedY *= u;
speedX *= u;
newTop = document.documentElement.clientHeight-obj.offsetHeight;
}
if(newTop<=0){
speedY = speedY*(-1);
speedY *= u;
speedX *= u;
newTop = 0;
}
if(newLeft>=document.documentElement.clientWidth-obj.offsetWidth){
speedX = speedX*(-1);
speedY *= u;
speedX *= u;
newLeft = document.documentElement.clientWidth-obj.offsetWidth;
}
if(newLeft<=0){
speedX = speedX*(-1);
speedY *= u;
speedX *= u;
newLeft = 0;
}
obj.style.left = newLeft + 'px';
obj.style.top = newTop + 'px';
},30)
}
</script>
</body>
</html>
5. 点击拖拽div,松开时div弹性碰撞
核心思想:点击时获取鼠标当前位置,计算距离div左边缘和上边缘距离,固定住这个距离,鼠标移动时事件绑定为document.onmousemove而非div.onmousemove;
注意:当div速度不为零时再次点击拖拽需要清空上次弹性碰撞的定时器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>elastic3</title>
<style type = "text/css">
*{
margin: 0;
padding:0;
list-style: none;
}
div{
position: absolute;
width: 100px;
height: 100px;
background: #f00;
}
</style>
</head>
<body>
<div></div>
<script type = "text/javascript">
//拖拽松开后进行弹性碰撞
var div = document.getElementsByTagName('div')[0];
var timer = null,
lastX = this.offsetLeft,
lastY = this.offsetTop;
div.onmousedown = function(e){
clearInterval(this.timer);
var e = e||window.event,
disX = e.clientX - this.offsetLeft,
disY = e.clientY - this.offsetTop,
that = this,
speedX = 0,
speedY = 0;
document.onmousemove = function(e){
var newLeft = e.clientX - disX,
newTop = e.clientY - disY;
speedX = newLeft - lastX;
speedY = newTop - lastY;
lastX = newLeft;
lastY = newTop;
that.style.left = newLeft + 'px';
that.style.top = newTop + 'px';
}
document.onmouseup = function(){
document.onmousemove = null;
document.onmouseup = null;
startMove(that,speedX,speedY);
}
}
function startMove(obj,speedX,speedY){
clearInterval(obj.timer);
var u = 0.8,
g = 8;
obj.timer = setInterval(function(){
speedY += g;
var newTop = obj.offsetTop + speedY,
newLeft = obj.offsetLeft + speedX;
if(newTop >= document.documentElement.clientHeight-obj.offsetHeight){
speedY = speedY*(-1);
speedY *= u;
speedX *= u;
newTop = document.documentElement.clientHeight-obj.offsetHeight;
}
if(newTop<=0){
speedY = speedY*(-1);
speedY *= u;
speedX *= u;
newTop = 0;
}
if(newLeft>=document.documentElement.clientWidth-obj.offsetWidth){
speedX = speedX*(-1);
speedY *= u;
speedX *= u;
newLeft = document.documentElement.clientWidth-obj.offsetWidth;
}
if(newLeft<=0){
speedX = speedX*(-1);
speedY *= u;
speedX *= u;
newLeft = 0;
}
obj.style.left = newLeft + 'px';
obj.style.top = newTop + 'px';
if(Math.abs(speedX) <= 1){speedX = 0;}
if(Math.abs(speedY) <= 1){speedY = 0;}
if(speedX ==0 && speedY ==0 && newTop == document.documentElement.clientHeight - obj.offsetHeight){
clearInterval(obj.timer);
console.log('over');
}
},30)
}
</script>
</body>
</html>