分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

JS运动

发布时间:2023-09-06 02:12责任编辑:郭大石关键词:暂无标签

新学的JS运动,和各位分享一下。

提到运动,肯定要对元素进行定位,通过更改它的left,top值来实现定位的目的,运动过程用定时器来实现。

基本步骤:

  1.关闭上一个定时器(多次触发事件会开启多个定时器,会累加)

  2.开启一个定时器

  3.定义一个值作为运动的速度

  4.判断定时器什么时候关闭,也就是终止条件

  5.让元素怎样动

下面开始说几种常见的运动

1.匀速运动

速度是不变的。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{margin:0;padding:0;}
#box{
width: 100px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div ></div>
</body>
</html>
<script>
var oBox = document.getElementById("box");
var speed = 10;

var timer=null;
document.onclick = function () {
timer= setInterval(function(){

  if(oBox.offsetLeft>=400){

    clearInterval(timer);

  }else{

     oBox.style.left = oBox.offsetLeft+speed+"px";

  }

},30)
}
</script>

oBox会匀速向右运动400px后停止,建议终止条件写oBox.offsetLeft>=400,而不是oBox.offsetLeft==400,因为定时器每次加一个speed,不一定正好加到所给的终止值。

以下案例的布局是一样的,所以只写JS代码

2.减速运动

<script>
var oBox = document.getElementById("box");
var speed = 40;
var timer=null;
document.onclick = function () {
timer= setInterval(function(){
speed--;
if(speed<0){
speed=0;
}
console.log();
  if(oBox.offsetLeft>=800){

    clearInterval(timer);

  }else{

     oBox.style.left = oBox.offsetLeft+speed+"px";

  }

},30)
}
</script>

速度每次减减,加速度相同,所以是匀减速运动

3.匀加速运动(同理)

<script>
var oBox = document.getElementById("box");
var speed = 5;
var timer=null;
document.onclick = function () {
timer= setInterval(function(){
speed++;
if(speed>=40){
speed=40;
}
  if(oBox.offsetLeft>=800){

    clearInterval(timer);

  }else{

     oBox.style.left = oBox.offsetLeft+speed+"px";

  }

},30)
}
</script>

4.缓冲运动 (样式改变)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{margin:0;padding:0;}
#box{
width: 100px;
height: 100px;
background: red;
position: absolute;
left: 800px;
}

#border{
width: 1px;
height: 300px;
background: #000;
position: absolute;
left: 400px;
top: 0;
}
</style>
</head>
<body>
<div ></div>
<div ></div>
</body>
</html>

<script>

var oBox = document.getElementById("box");
var timer = null;

document.onclick=function(){
clearInterval(timer);
timer=setInterval(function(){
var speed=(400-oBox.offsetLeft)/8;
speed=speed>0?Math.ceil(speed):Math.floor(speed);
console.log(speed);
if(oBox.offsetLeft==400){
clearInterval(timer);
}else{
oBox.style.left=oBox.offsetLeft+speed+"px";
}
},30);
}

</script>

每次都把速度的值变小,但不是均匀的改变(跟减速运动最大不同),取整是为了让浏览器更好的计算,避免计算小数,以免出现误差。

封装一下。

function move(obj,iTarget){
clearInterval(timer);
timer = setInterval(function(){
//速度
var speed = (iTarget - obj.offsetLeft)/8;
speed = speed>0?Math.ceil(speed):Math.floor(speed);

if(obj.offsetLeft==iTarget){
clearInterval(timer)
}else{
obj.style.left = obj.offsetLeft+speed+"px";
}

},30)
}

obj,是对象,iTarget是目标值。例如:move(div,400)

5.上面的封装不完善,想改变一个元素的透明度就做不到。透明度是小数且没单位,还得做IE的兼容,下面是怎样更改透明度

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{margin:0;padding:0;}
#box{
width: 100px;
height: 100px;
background: red;
opacity: 1;
filter: alpha(opacity: 100);

}
</style>
</head>
<body>
<div ></div>
</body>
</html>
<script>
var oBox = document.getElementById("box");
var timer =null;
var alpha = 100;

document.onclick=function(){
clearInterval(timer);
timer=setInterval(function(){
var speed=(30-alpha)/8;
speed=speed>0?Math.ceil(speed):Math.floor(speed);
if(alpha==30){
clearInterval(timer);
}else{
alpha+=speed;
oBox.style.opacity=alpha/100;
oBox.style.filter="alpha(opacity:"+alpha+")";
}
},30);
}
</script>

6.考虑到透明度,于是再次封装。

这次先封装一个获取非行内元素

function getStyle(obj,attr){

return obj.currentStyle?obj.currentStyle[attr]:getComputedStyle(obj,false)[attr];

}

function move(obj,target,attr){
clearInterval(timer);
timer=setInterval(function(){
var icur=0;
if(attr=="opacity"){
//避免opacity的值是0.5555555这样,所以取整
icur=parseInt(getStyle(obj,attr)*100);
}else{
icur=parseInt(getStyle(obj,attr));
}

var speed=(target-icur)/8;
speed=speed>0?Math.ceil(speed):Math.floor(speed);

if(icur==target){
clearInterval(timer);
}else{
if(attr=="opacity"){
obj.style.opacity=(icur+speed)/100;
obj.style.filter="alpha(opacity:"+(icur+speed)+")";
}else{
obj.style[attr]=icur+speed+"px";
}
}
},30);
}

oBox.onmouseover = function(){
move(this,100,"opacity");
}

调用一下,没问题

7.多物体运动框架

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{margin:0;padding:0;}
div{
width: 100px;
height: 100px;
background: red;
opacity: 0.3;
filter: alpha(opacity: 30);
margin: 10px;
}
</style>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
</html>
<script>
function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}


function move(obj,iTarget,attr){
//obj.timer,定时器之间不影响
clearInterval(obj.timer);
obj.timer = setInterval(function(){
//第一步 判断attr是否为透明度
var iCur = 0;
if(attr == "opacity"){
iCur =parseInt(getStyle(obj,attr)*100);
}else{
iCur = parseInt(getStyle(obj,attr));
}

//第二步算速度
var speed = (iTarget - iCur )/8;
speed = speed>0?Math.ceil(speed):Math.floor(speed);


//第三步
if(iCur == iTarget){
clearInterval(obj.timer);
}else{
if(attr == "opacity"){
obj.style.opacity = (iCur+speed)/100;
obj.style.filter = "alpha(opacity:"+(iCur+speed)+")";
}else{
obj.style[attr] = iCur+speed+"px";
}

}


},30)
}

var aDiv = document.getElementsByTagName("div");

aDiv[0].onmouseover = function(){
move(this,300,"width")

}

aDiv[1].onmouseover = function(){
move(this,300,"height")
}

aDiv[2].onmouseover = function(){
move(this,100,"opacity")
}
</script>

当多物体的时候,只用一个timer定义定时器时,会影响下一个物体的运动,所以要用obj.timer,关闭的时候关闭自己的定时器,不影响其他定时器的执行

8.链式运动

function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}


function move(obj,iTarget,attr,fn){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
//第一步 判断attr是否为透明度
var iCur = 0;
if(attr == "opacity"){
iCur =parseInt(getStyle(obj,attr)*100);
}else{
iCur = parseInt(getStyle(obj,attr));
}

//第二步算速度
var speed = (iTarget - iCur )/8;
speed = speed>0?Math.ceil(speed):Math.floor(speed);


//第三步
if(iCur == iTarget){
clearInterval(obj.timer);
fn&&fn();
}else{
if(attr == "opacity"){
obj.style.opacity = (iCur+speed)/100;
obj.style.filter = "alpha(opacity:"+(iCur+speed)+")";

}else{
obj.style[attr] = iCur+speed+"px";
}

}


},30)
}

var aDiv = document.getElementsByTagName("div");

aDiv[0].onmouseover = function(){
move(this,100,"opacity",function(){
move(aDiv[0],300,"height");
})

}
//给2个move(),下面会覆盖上面的函数,再写一个事件,也不行
aDiv[1].onmouseover = function(){
move(this,300,"height")
}

aDiv[2].onmouseover = function(){
move(this,100,"opacity")
}

给原来封装的函数加一个回调函数,解决

9.完美运动(让元素2个属性同时运动,链式运动只能一个执行完,再执行另一个)

<script>
function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}
//obj={width:100,height:200}

function move(obj,json,fn){
//防止多次点击 关闭掉上一个定时器
clearInterval(obj.timer);
//开启定时器 obj.timer:防止多个对象抢定时器
obj.timer = setInterval(function(){
//开关门
var bStop = true;
//传入的是一个对象 需要将对象中所有的值进行遍历
for(var attr in json){
/*
因为offset的局限性太大,如果想要这个方法灵活多用只能用获取非行间样式

考虑2点
1、透明度是小数 不能够直接取整需要先*100在取整

2、因为getStyle()获取出来的是字符串 我们需要将它转换为数字
*/
var iCur = 0;
if(attr == "opacity"){
iCur = parseInt(getStyle(obj,attr)*100);
}else{
iCur = parseInt(getStyle(obj,attr));
}



/*
因为要做缓存运动,因此需要计算速度 速度是一个不定值
公式: (目标值 - 当前对象的位置) /系数 建议是8

考虑的问题:
计算机处理小数有问题因此需要将小数干掉,我们要进行向上取整和向下取整
*/
//算速度
var speed = (json[attr] - iCur)/8;
speed = speed>0?Math.ceil(speed):Math.floor(speed);

/*判断是否都已经到达终点 只要有一个没有到达终点就将bStop为false 循环完毕以后判断bstop来决定关闭定时器*/
if(json[attr] !=iCur){
bStop = false;
}


/*
考虑2部分
1、透明度是不需要加px的因此需要单独判断
2、普通的属性是需要加px的因此需要再次判断

*/
if(attr == "opacity"){
//透明度的兼容性
obj.style.opacity = (iCur+speed)/100;
obj.style.filter = "alpha(opacity:"+(iCur+speed)+")";
}else{
obj.style[attr] = (iCur+speed)+"px";
}


}

//当循环完毕以后 判断bStop的状态来决定是否关闭定时器
if(bStop){
clearInterval(obj.timer);
//链式操作
fn&&fn();
}

},30)
}

var aDiv = document.getElementsByTagName("div");

aDiv[0].onmouseover = function(){
move(this,{width:300,height:150},function(){
move(aDiv[0],{opacity:100});
});
}

JS运动

原文地址:https://www.cnblogs.com/lzn0330/p/9538903.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved