當今的生活質量越來越高,人們對于自身的身體素質也更加重視,對于運動的熱情,逐漸高漲起來,

人類的體育鍛煉運動中,看見最多的就是籃球了吧,本人不會打籃球,因為籃球看著太嚇人, 我的小身板也不允許我去打籃球,打籃球的程序中總會有磕磕撞撞,導致受傷,
籃球運動的規則不就是,把球扔進籃球籃子嘛,so eazy ,再換句話說不就是大家都知道的拋物運動嘛,

提到拋物運動,回想起高中物理,是不是大家對于打籃球就充滿了‘自信’,手抬高,一扔,進了!!!
今天介紹的也是拋物運動的實作,不過不是在生活中實作它,而是在頁面中實作它,而實際上在也頁面上投籃的就是JavaScript,它才是本場比賽的籃球運動員,

在講拋物線運動之前,要明白拋物線運動的實質,或者將其分解為兩個方向的運動,
1.首先是豎直方向上的運動,就是單純的高度逐漸減小的程序
2.其次就是水平方向上的運動,也就是單純的往一個方向位移程序,
將這兩個分支運動合起來就是我們的打籃球了,
讓我們的JavaScript上場表演吧!!!
垂直方向:
垂直方向的運動,在頁面中就是高度的減小,
下面是一個簡單的例子:籃球的重力回彈的效果,

第一階段的程序就是球的下落程序,也就是球的高度top的不斷增大,
在top值增大的程序中也就需要,不斷地給top增加一個speed步進值,
先是基本的css和html樣式和結構
<style type="text/css">
.cont {
width: 1000px;
height: 600px;
background: #eee;
margin: 20px auto;
position: relative;
}
.box {
width: 100px;
height: 100px;
background: red;
position: absolute;
left: 0;
border-radius: 50%;
}
</style>
<body>
<div class="cont">
<div class="box"></div>
</div>
</body>
接下來就是我們今天的主角:JavaScript登場啦!!!
第一步是獲取html當中的節點物件,才能進行操作,
<script>
// 1 獲取節點
let contObj = document.querySelector('.cont');//籃球可以活動的范圍,節點物件
let boxObj = document.querySelector('.box');//籃球節點物件
</script>
第二步進行我們所需要的變數的宣告準備,
其中重要的變數有:
1. 因為地球的原因,有重力,所以在步進值speed的基礎上,應該還要增加重力帶來的加速度,
2.target目標,就是籃球在范圍內最大的可運動的高度(要減去球自身的高度),
3.要想讓球的高度減少,就應該讓球在反向的時候,讓它的speed比原來小就可以了,所以給speed乘以一個小于1的數,就可以讓反向高度變小,
// 2 設定變數
let speed = 10; //步進值
let g = 2; //重力的影響
let times = ''; //清除定時器的識別符號
let target = contObj.offsetHeight - boxObj.offsetHeight; // 小球的最大目標值
第三步就是具體的實作方法 :
//球系結點擊事件
ball.addEventListener('click', function() {
clearInterval(timer) //防止定時器累加
timer = setInterval(function() { //設定定時器
speed += g; //步長增加
if (speed < target - ball.offsetTop) { //高度小于目標高度時
ball.style.top = ball.offsetTop + speed + 'px'; //設定球的高度樣式
} else if (speed >= target - ball.offsetTop) { //當到盒子目標高度時
ball.style.top = target + 'px'; //讓球直接到達底部
speed = -parseInt(speed) * 0.8; //讓步長變負,高度減小,球往上走
if (Math.abs(speed) < 1) { //當步長小于1
clearInterval(timer); //停止
}
}
}, 30)
})
完成上述的垂直方向的運動之后,就可以往其加上水平方向的代碼了,
垂直方向和水平方向的結合:
水平方向的原理其實和垂直方向差不多,你也可以想象將頁面順時針旋轉90度,
實作方法:
第一步獲取節點物件,同上,
第二步準備需要的變數,因為要在水平方向上變化,肯定也需要一個水平的步進值,leftSpeed,也同樣需要往左的最大范圍值leftTarget,也是 籃球在范圍內最大的可運動的寬度再減去球本身的寬度,增加了一個count值用來,累積運動次數,每5次增加一個重力,讓它能跳更久,到底部的時間增加,
// 設定left的步進值和最大值
var leftSpeed = 20;
var leftTarget = 1000 - ballObj.offsetWidth;
var count = 0; // 累計運動次數
第三步,只需要給球在高度樣式的位置添加水平位移樣式即可
ballObj.style.left = leftSpeed + ballObj.offsetLeft + 'px'; //給球位移樣式
在這里需要注意:
球可能會從水平方向滾出去,所以還需要給球設定邊界:
思路其實很簡單:只需要等球到達可運動范圍的最大值的時候,讓它的步進值反向,
if (ballObj.offsetLeft >= leftTarget) { //當球到達最右邊屆
leftSpeed = -leftSpeed; //步進值反向
}
if (ballObj.offsetLeft <= 0) { //當球到達最右邊屆
leftSpeed = -leftSpeed; //步進值反向
}
綜上實作得到的代碼 :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.box {
width: 1000px;
height: 400px;
margin: 50px auto;
position: relative
}
#ball {
width: 50px;
height: 50px;
background: red;
border-radius: 50%;
position: absolute;
left: 0px;
top: 0;
}
.line {
width: 1000px;
height: 1px;
background: black;
position: absolute;
top: 300px;
left: 0px;
}
</style>
</head>
<body>
<div class="box">
<div id="ball"></div>
<div class="line"></div>
</div>
</body>
<script type="text/javascript">
// 1 獲取節點
var ballObj = document.getElementById('ball');
var lineObj = document.querySelector('.line')
// 2 設定top的步進值,和最大值.
// 定時器的計數器
var topSpeed = 5;
var topTarget = 300 - ballObj.offsetHeight; // top的臨界值
var count = 0; // 累計運動次數
var g = 1; // 重力值的設定
// 設定left的步進值和最大值
var leftSpeed = 20;
var leftTarget = 1000 - ballObj.offsetWidth;
//定時器標識
var times = '';
ballObj.onclick = function() {
clearInterval(times); //清除定時器累加
times = setInterval(function() {
count++;
if (count % 5 == 0) { //運動5次增加一個重力
topSpeed += g; //高度步進增加
}
if (topSpeed + ballObj.offsetTop > topTarget) { //當大于目標值
topSpeed = -topSpeed * 0.8; //步進變負,上升
ballObj.style.top = topTarget; //強制到最下面
if (Math.abs(topSpeed) < 1) clearInterval(times); //步進值小于1,清除定時器
} else {
ballObj.style.top = topSpeed + ballObj.offsetTop + 'px'; //給球下降的樣式
ballObj.style.left = leftSpeed + ballObj.offsetLeft + 'px'; //給球位移樣式
}
if (ballObj.offsetLeft >= leftTarget) { //當球到達最右邊屆
leftSpeed = -leftSpeed; //步進值反向
}
if (ballObj.offsetLeft <= 0) { //當球到達最右邊屆
leftSpeed = -leftSpeed; //步進值反向
}
}, 30)
}
</script>
</html>
前兩個例子大同小異,方法基本相同,所以可以想辦法封裝一個運動函式,
運動函式的目的就是,只要輸入運動的三要素{誰運動,運動方向,目標值},我們就能實作運動效果,
其中獲取元素的實時屬性的時候,需要考慮是否是行內樣式,如果不是行內樣式,要添加兼容性獲取樣式的封裝函式,
// 獲取元素的非行內樣式的封裝函式
function getPos(obj, attr) {//引數為物件,和屬性
if (obj.currentStyle) { // 獲取css的樣式
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj)[attr]
}
}
得到元素的實時位置之后就可以進行下一步封裝運動函式了,
var times = '';
function move(ele, obj, back) { //運動函式
clearInterval(times); //清除定時器,以免累加
times = setInterval(function() { //定時器
var onOff = true;
for (let index in obj) { //遍歷物件中的所有屬性,index代表屬性
var value = parseInt(getPos(ele, index)); //獲取元素屬性對應的樣式的實時值
var speed = (obj[index] - value) / 10; //設定步進值
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //取整,方便計算
if (value == obj[index]) onOff = true; // 當一個屬性運動到位置,設定開關狀態
ele.style[index] = value + speed + 'px'; //設定元素的樣式
}
for (var i in obj) { //再次遍歷物件中的所有屬性
if (obj[i] !== parseInt(getPos(ele, i))) { //如果存在實時值和目標值不相等,
onOff = false; //開關狀態為假
break;
}
}
if (onOff) { //開關為真,則清除定時器
clearInterval(times);
back && back(); //呼叫回呼函式
}
}, 30)
}
// 獲取元素的非行內樣式的封裝函式
function getPos(obj, attr) {
if (obj.currentStyle) { // 獲取css的樣式
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj)[attr]
}
}
呼叫封裝運動函式的方法:
首先應該得到一個目標值(可以是任何資料),target
再比如給一個按鈕系結點擊事件,開始運動,同樣需要運動三要素,
ele為要運動元素名,第二個引數為物件,物件中是需要運動的屬性和屬性值,最后是回呼函式,回呼函式可以根據情況添加或者不加,
btn.onclick = function() {
move(ele, {
left: target,
height: 300
}, function() {})
}
有了運動函式就可以隨意添加變化的屬性值了,再也不用擔心要添加的變數多了!
舉一個使用封裝運動函式實作的例子:

第一個要求:讓紅色方塊移動到黑色豎線,
第二個要求:在移動的程序中方塊的高度要變化到300px,
實作步驟:
1.首先是移動的元素是:方塊,
2.變化的屬性:方塊的height,方塊距離螢屏的left值,
3.目標值:height的目標值就是300px,left的目標值設為target就應該是方塊的offsetLeft值減去豎線的offsetLeft值,
// 1 獲取節點
let btnObj = document.getElementById('btn'); //獲取按鈕節點物件
let divObj = document.querySelector('div'); //獲取方塊節點物件
// 目標值
let target = divObj.offsetLeft - divObj.nextElementSibling.offsetLeft;
//給按鈕系結點擊事件
btnObj.onclick = () => {
//呼叫移動函式
move(divObj, {
left: target,
height: 300
}, function() {
console.log('移到目標啦!!!');
})
}
再將上面封裝好的運動函式,加到點擊事件后面即可完成,
運動函式的封裝就完成了!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/298390.html
標籤:其他
下一篇:如使用原生js自定義右鍵選單
