JS单物体运动
文章目录
- JS单物体运动
- JS物体运动基础
- 分享侧边栏
- 图片透明度改变
- 缓冲运动
- timer与重复点击按钮
- 多物体运动
JS单物体运动
在JavaScript定时器 的基础上,定时修改物体的位置属性,物体便能移动。
当物体移动到指定位置的时候,关闭定时器,物体移动结束。
代码来源视频:代码来源视频
代码详细:github
JS物体运动基础
代码实现:点击按钮,方框匀速抵达指定位置。见下方gif。
这个代码还有很多可以改进的地方(见下方),后面实例中会不断改进。
- 目标位置300应当抽出来作为参数。
- speed为正,预先定为正(负),无法动态指定方法。
当speed=5不是300的整数的时候,无法精确定位到300px位置停下。
<!DOCTYPE html>
分享侧边栏
代码实现:鼠标悬浮,代码侧边栏移动出;鼠标离开,代码侧边栏回去。过程见下方gif。
下面代码在上面基础版本的基础上作出一些改动。
- 目标位置作为target参数,可以传递进入函数。
- 可以根据target的位置与当前位置,判断使用speed速度的正负。
使用绝对值进行判断,解决了最后一次移动无法精确定为的问题。
<!DOCTYPE html>
qq
微信
微博
分享到
图片透明度改变
物体运动的思路,也可以应用到图片透明度的动态改变。
下面使用了CSS和JS两种方法实现。
<!DOCTYPE html>
<html>
<head>
<style> #div1 { width: 250px;height: 150px;background-image: url('./images/1.jpg'); float:left; margin: 10px; opacity: 0.4; } #div1:hover{ opacity: 1.0;} #div2 { width: 250px;height: 150px;background-image: url('./images/2.jpg'); float:left;margin: 10px; opacity: 0.4; } </style>
<script> window.onload = function(){ var odiv2 = document.getElementById('div2'); odiv2.onmouseover = function(){ opacity_target(1.0); } odiv2.onmouseout = function(){ opacity_target(0.4); } } var timer = null; function opacity_target(target){ var odiv2 = document.getElementById('div2'); var opacity = parseFloat(getComputedStyle(odiv2,null).opacity); var speed = 0.1; if(target < opacity) speed = -speed; // alert(typeof(getComputedStyle(odiv2,null).opacity)); // alert(getComputedStyle(odiv2,null).opacity); clearInterval(timer); timer = setInterval(function() { //浮点数不好比较,都将其转换成整数 // if(parseInt(opacity*10) == parseInt(target*10)) if(Math.abs(opacity - target) < Math.abs(speed)){ clearInterval(timer); odiv2.style.opacity = target; }else{ opacity = opacity + speed; odiv2.style.opacity = opacity; } }, 30); } </script>
</head>
<body>
<span style="text-align: left;font-size: 35px;">分别用css和js控制图片透明度的变化</span>
<br>
<div id='div1'></div>
<div id='div2'></div>
</body>
</html>
缓冲运动
上面物体运动的speed为常量,即物体匀速运动。
根据target的距离,动态改变speed大小,即为变速运动。
缓冲运动:target的距离越大,speed越大;target的距离越小,speed越小;
控制速度最小也有1px/间隔,所以最后必然精确到达。
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style> #div1 { width:100px; height:100px; background:red; position:absolute; left:0; top:50px;} #div2 { width:1px; height:300px; position:absolute; left:300px; top:0; background:black;} </style>
<script> var timer = null; function startMove(target) { var target = parseFloat(target) var oDiv=document.getElementById('div1'); // oDiv.timer = null //给对象添加一个属性,用自己对象的timer // clearInterval(this.timer); //避免多次点击?不能 clearInterval(timer); timer = setInterval(function (){ var speed=(target-oDiv.offsetLeft)/10; //speed=Math.floor(speed); speed=speed>0?Math.ceil(speed):Math.floor(speed); if(speed == 0) clearInterval(this.timer) else oDiv.style.left=oDiv.offsetLeft+speed+'px'; // document.title=oDiv.offsetLeft+','+speed; }, 30); } </script>
</head>
<body>
<input type="button" value="开始运动" onclick="startMove('200px')" />
<div id="div1"></div>
<div id="div2"></div>
</body>
</html>
timer与重复点击按钮
- 上面缓冲运动中,var为全局变量。所以再次点击按钮的时候,重新触发函数,在再次设置定时器前,将timer对应的计时器关闭。所以重复点击不会出问题。即,同一个“事件”,使用同一个timer(var为全局变量),不会出问题。
- 上面缓冲运动中,注释部分,不行。因为再次点击按钮的时候,获得新的oDiv对象。该对象中有新的oDiv.timer。所以clearInterval(this.timer),没啥用。对上一个oDiv对象,没有影响。timer属性应当和startMove方法等级相同,不应当在里面。
多物体运动
下面是一个简单的运动框架。可以设置将对象(obj)的属性(property),修改成指定值(target)。但是还有不足。
- 无法完成链式运动。即,它只能修改物体的一个属性,无法修改属性后保持,继续修改下一个属性。
- 无法同时修改两个值。因为参数的设定,使得其一次只能修改一个属性。
要修复上述两个缺点,可以参考:JS运动事件中级
// base_move.js
function startMove(obj,property,target){/** * 将对象(obj)的属性(property),修改成指定值(target) */
target = parseFloat(target);
//透明度属性设置
if(property == 'opacity'){
var opacity = parseFloat(getComputedStyle(obj,null).opacity);
var speed = 0.1;
if(target < opacity)
speed = -speed;
clearInterval(obj.timer);
obj.timer = setInterval(function() {
//浮点数不好比较,都将其转换成整数
// if(parseInt(opacity*10) == parseInt(target*10))
if(Math.abs(opacity - target) < Math.abs(speed)){
clearInterval(timer);
obj.style.opacity = target;
}else{
opacity = opacity + speed;
obj.style.opacity = opacity;
}
}, 30);
}
//非透明度属性设置
if(property != 'opacity'){
var step_speed = 8;
clearInterval(obj.timer);
obj.timer = setInterval(function(){
var speed = (target - parseFloat(getComputedStyle(obj,null)[property]))/step_speed;
speed = speed>0? Math.ceil(speed):Math.floor(speed);
if(speed == 0){
clearInterval(obj.timer);
}else{
obj.style[property] = parseFloat(getComputedStyle(obj,null)[property]) + speed + 'px';
}
},30)
}
}
<!DOCTYPE html>
变高
变宽
透明度变高
字体变大
还没有评论,来说两句吧...