运动原理

运动的原理: 
    让某件物品沿着某种方向随着时间的变化改变位置
    setInterval(function(){
obox.style.left = obox.offsetLeft+10+"px";
},30)
    让页面中的obox元素的left值,每30毫秒,在自身left的基础上增加10像素
 
    为什么是30毫秒呢?
    因为电影播放每秒24帧,人眼就识别不出卡顿了,但是对于电脑来说,处理速度相对较快,需要每秒30帧以上才会显得流畅

边界处理

 当元素的offsetLeft超出一定距离或到达一个边界值后,停止计时器

    var timer;
timer = setInterval(function(){
if(obox.offsetLeft>=200){
clearInterval(timer);
}else{[
obox.style.left = obox.offsetLeft+10+"px";
}
},30)

我们先来实现一个简单的功能,当我们点击按钮之后,让一个元素动起来。并且到达500的边界之后立刻停止下来

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#d1 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top:100px;
left: 200px;
}
</style>
</head>
<body>
<button id="btn">点击运动</button>
<div id="d1"></div>
</body>
<script>
// 点击按钮,让div横向的运动起来 // 1. 获取元素
let oBtn = document.getElementById('btn');
let oDiv = document.getElementById('d1');
let iTimer = null;
// 点击按钮,让元素一直运动 ,需要使用到的知识点:定时器
oBtn.onclick = ()=>{ iTimer = setInterval(()=>{
// 点击按钮之后,让div的位置在当前的基础之上每次增加10px的距离
// oDiv.style.left = oDiv.offsetLeft + 10 + 'px'; // 虽然此代码可以让div动起来,但是我们需要div在运动之后到达某个边界就立刻停止,所以需要将此句代码改为一个判断
if (oDiv.offsetLeft === 500) {
// 清除定时器
clearInterval(iTimer);
}else { // 没有到达边界才能继续运动
oDiv.style.left = oDiv.offsetLeft + 10 + 'px';
}
},30); };
</script>
</html>

在上面的代码中,我们点击按钮之后,元素已经可以直接进行移动,但是却存在一个问题,什么问题呢?

当我们点击按钮之后,元素始终以10px的匀速进行运动,到达500的临界然后停止。 但是我们的问题是,速度可能会变,例如将速度变为7px,就不能够
准确的到达500的临界值。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#d1 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top:100px;
left: 200px;
}
</style>
</head>
<body>
<button id="btn">点击运动</button>
<div id="d1"></div>
</body>
<script>
// 点击按钮,让div横向的运动起来 // 1. 获取元素
let oBtn = document.getElementById('btn');
let oDiv = document.getElementById('d1');
let iTimer = null;
// 点击按钮,让元素一直运动 ,需要使用到的知识点:定时器
oBtn.onclick = ()=>{ iTimer = setInterval(()=>{
// 点击按钮之后,让div的位置在当前的基础之上每次增加10px的距离
// oDiv.style.left = oDiv.offsetLeft + 10 + 'px'; // 虽然此代码可以让div动起来,但是我们需要div在运动之后到达某个边界就立刻停止,所以需要将此句代码改为一个判断
if (oDiv.offsetLeft === 500) {
// 清除定时器
clearInterval(iTimer);
}else { // 没有到达边界才能继续运动
oDiv.style.left = oDiv.offsetLeft + 7 + 'px'; // 一旦将每次的移动距离变为7px ,那么将不能停的下来.元素会一直运动
}
},30); };
</script>
</html>

出现这种情况的原因是因为运动的临界值必须能够被运动的速度(也就是oDiv.offsetLeft + 7 + 'px',表示每次执行移动的距离)整除。

上面的代码当中, 因为临界值不能够被速度整除,所以,最终元素始终达到不了临界值,那么元素就没有办法在到达临界值时停止。

同时在上面的代码中的另外一个问题是,当我们每点击一次运动按钮,元素的速度就会变得更快,原因很简单,就是我们设置的定时器发生了累加。

那么该如何解决定时器累加的问题呢?

我们可以在每次开始运动之前先清除一次定时器。

oBtn.onclick = ()=>{
/*
* 为了防止定时器累加,在每次开始定时器之前,先清楚掉一个定时器
* */
clearInterval(iTimer); iTimer = setInterval(()=>{
// 点击按钮之后,让div的位置在当前的基础之上每次增加10px的距离
// oDiv.style.left = oDiv.offsetLeft + 10 + 'px'; // 虽然此代码可以让div动起来,但是我们需要div在运动之后到达某个边界就立刻停止,所以需要将此句代码改为一个判断
if (oDiv.offsetLeft === 500) {
// 清除定时器
clearInterval(iTimer);
}else { // 没有到达边界才能继续运动
oDiv.style.left = oDiv.offsetLeft + 7 + 'px'; // 一旦将每次的移动距离变为7px ,那么将不能停的下来.元素会一直运动
}
},30);
};

圆周运动demo

<!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>Document</title>
<style>
.box{width:20px;height:20px;background: red;position: absolute;lefT:0;top:0;border-radius: 50%;}
</style>
</head>
<body>
<!-- <div class="box"></div> -->
</body>
<script>
var obox = document.querySelector(".box");
var t;
var speed = 10;
var target = 360;
var iNow = 0;
var r = 200; // 圆周运动
document.onclick = function(){
clearInterval(t);
t = setInterval(() => {
if(target <= iNow){
clearInterval(t);
}else{
iNow += speed;
var div = document.createElement("div");
div.className = "box";
document.body.appendChild(div); // 利用三角函数计算left和top
div.style.left = Math.cos( Math.PI/180*iNow ) * r + 200 + "px";
div.style.top = Math.sin( Math.PI/180*iNow ) * r + 200 + "px";
}
}, 30);
} </script>
</html>

多元素缓冲运动事件委托demo

<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<title></title>
<style>
.cont {width: 1000px;height: 600px;border: 1px solid #000;box-sizing: border-box;position: relative;}
div div {width: 100px;height: 100px;position: absolute;left: 0;top: 10px;background-color: lightcoral;}
</style>
</head>
<body>
<div class="cont">
<div class="box1" >1</div>
<div class="box2">2</div>
<div class="box3">3</div>
<div class="box4">4</div>
<div class="box5">5</div>
</div>
</body>
<script>
var ocont = document.querySelector(".cont");
var abox = document.querySelectorAll("div div"); document.onclick = eventFn(abox,function(){
var a = this; move(a,{top:490},function(){
// move(a,{left:800},function(){
// move(a,{top:10},function(){
// move(a,{left:0})
// })
// })
move(a,{left:800,top:300},function(){})
})
}) // 多元素运动
function move(ele,obj,fn){
clearInterval(ele.t);
ele.t = setInterval(() => {
var onoff = true;
for(var i in obj){
var pos = parseInt(getComputedStyle(ele,false)[i]);
var speed = (obj[i]-pos)/10;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if(pos != obj[i]){
onoff = false;
}
ele.style[i] = pos + speed + "px";
if(onoff == true){
clearInterval(ele.t);
fn && fn();
}
}
}, 30);
} // 事件委托:
function eventFn(ele,cb){
return function(eve){
var e = eve || window.event;
var target = e.target || e.srcElement;
for(var j = 0;j <ele.length;j++){
if(target == ele[j]){
cb.bind(target)();
}
}
}
}
</script>
</html>

抛物线demo

<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<title></title>
<style>
html body {margin: 0;padding: 0;}
.box{width: 800px;height: 500px;position: relative;border: 1px solid #000;}
#ball{width: 50px;height: 50px;background-color: paleturquoise;border: 1px solid #000;border-radius: 50%;position: absolute;left: 0;top: 0;}
</style>
</head>
<body>
<div class="box">
<div id="ball"></div>
</div>
</body>
<script>
var obox = document.querySelector(".box");
var oball = document.querySelector("#ball");
var index = 0;
var tSpeed = 5;
var lSpeed = 20;
var t = null;
var maxTop = obox.offsetHeight - oball.offsetHeight;
var maxLeft = obox.offsetWidth - oball.offsetWidth;
var g = 1;
onload = function(){
clearInterval(t);
t = setInterval(function(){
if(index%5 == 0){
tSpeed += g;
}
if(maxTop-oball.offsetTop < tSpeed){
oball.style.top = maxTop+"px";
tSpeed = -Math.round(tSpeed*0.7);
if(Math.abs(tSpeed) <= 1){
clearInterval(t)
}
}else{
oball.style.top = oball.offsetTop + tSpeed +"px";
oball.style.left = oball.offsetLeft + lSpeed +"px";
}
if(oball.offsetLeft > maxLeft){lSpeed = -lSpeed}
if(oball.offsetLeft < 0){lSpeed = -lSpeed}
},30) }
</script>
</html>

重力运动demo

<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<title></title>
<style>
.ball {width: 50px;height: 50px;border-radius: 50%;background-color: darkorange;position: absolute;top: 0;}
.wall {width: 1000px;border: 1px solid #000;position: absolute;top: 300px;}
</style>
</head>
<body>
<div class="ball"></div>
<div class="wall"></div>
</body>
<script> onload = function(){
var oball = document.querySelector(".ball");
var owall = document.querySelector(".wall");
var speed = 6;
var index = 0;
var g = 2;
var t = null;
var maxTop = owall.offsetTop - oball.offsetHeight;
t = setInterval(function(){
index++;
if(index%6 == 0){
speed += g;
}
if(maxTop - oball.offsetTop <= speed){
oball.style.top = maxTop + "px";
speed = -Math.round(speed*0.7);
if(Math.abs(speed) <= 1){
clearInterval(t);
}
}else{
oball.style.top = oball.offsetTop + speed + "px";
}
},30)
} </script>
</html>
 

JavaScript基础12——运动的更多相关文章

  1. JavaScript基础12——js的方法重载

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. JavaScript 基础入门11 - 运动框架的封装

    目录 JavaScript 运动原理 运动基础 简单运动的封装 淡入淡出 不同属性的设置 多属性值同时运动 运动回调,链式运动 缓冲运动 加入缓冲的运动框架 案例1 多图片展开收缩 运动的留言本 Ja ...

  3. javascript 基础2第12节

    1. <html> <head> <title>javascript基础</title> </head> <body> 1.Nu ...

  4. JavaScript基础视频教程总结(091-100章)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. JavaScript基础入门06

    目录 JavaScript 基础入门06 Math 对象 Math对象的静态属性 Math对象的静态方法 指定范围的随机数 返回随机字符 三角函数 Date对象 基础知识 日期对象具体API 构造函数 ...

  6. 前端之JavaScript基础

    前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript历史 1992年Nombas开发出C ...

  7. 一步步学习javascript基础篇(3):Object、Function等引用类型

    我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...

  8. javascript基础01

    javascript基础01 Javascript能做些什么? 给予页面灵魂,让页面可以动起来,包括动态的数据,动态的标签,动态的样式等等. 如实现到轮播图.拖拽.放大镜等,而动态的数据就好比不像没有 ...

  9. 【Java EE 学习 31】【JavaScript基础增强】【Ajax基础】【Json基础】

    一.JavaScript基础增强 1.弹窗 (1)使用window对象的showModelDialog方法和showModelessDialog方法分别可以弹出模式窗口和非模式窗口,但是只能在IE中使 ...

随机推荐

  1. 洛谷P5017:摆渡车——题解

    https://www.luogu.org/problem/P5017 参考:https://www.luogu.org/blog/ztyluogucpp/solution-p5017 我想我大概是废 ...

  2. C++17 新特性之 std::optional(上)

    最近在学习 c++ 17 的一些新特性,为了加强记忆和理解,把这些内容作为笔记记录下来,有理解不对的地方请指正,欢迎大家留言交流. 引言 在介绍之前,我们从一个问题出发,C++ 的函数如何返回多个值? ...

  3. 【chromium】 cef源码下载

    至少需要17GB的磁盘空间,不光有CEF源码,还会下载chromium源码.编译master分支的话,如果编译到chromium可能会需要windows sdk,windows sdk的版本可以参考下 ...

  4. vue截取字符串

    1.vue中截取前11位字符串 <li> <span>立案时间:</span> <p>{{jsyd.TIME.substring(0,10)}}< ...

  5. MySQL面试题及答案整理,史上最全!

    原文链接:https://juejin.im/post/5d351303f265da1bd30596f9 前言 本文主要受众为开发人员,所以不涉及到MySQL的服务部署等操作,且内容较多,大家准备好耐 ...

  6. C# 填充客户端提交的值到T对象

    /// <summary>      /// 填充客户端提交的值到 T 对象  如appinfo = AppConvert.To<Appinfo>(context.Reques ...

  7. elasticsearch基础查询

    Es基础数据类型 string 字符串类型,es中最常用的类型,官方文档 比较重要的参数: index分析 analyzed(默认) not_analyzed no store存储 true 独立存储 ...

  8. openssl生成证书及签名

    第一步,生成私钥 $ openssl genrsa -out privatekey.pem 2048 查看生成的私钥内容 $ file privatekey.pem privatekey.pem: P ...

  9. Nmon监控性能分析

    一.CPU信息 1.折线图中蓝线为cpu占有率变化情况:粉线为磁盘IO的变化情况: 2.下面表各种左边的位磁盘的总体数据,包括如下几个: Avg tps during an interval 每个间隔 ...

  10. Prometheus(五):Prometheus+Alertmanager 配置企业微信报警

    此处默认已安装Prometheus服务,服务地址:192.168.56.200  一.设置企业微信 1.1.企业微信注册(已有企业微信账号请跳过) 企业微信注册地址:https://work.weix ...