JavaScript 運動(緩衝運動,多物體運動 ,多物體多值運動+回調機制)

来源:https://www.cnblogs.com/jiaobaba/archive/2019/03/16/10536332.html
-Advertisement-
Play Games

勻速運動 (當需要物體做勻速運動直接調用statMove函數) 緩衝運動(越接近目標,速度越慢) 緩運運動比直線運動視覺性更好,所以很常用 1 function startMove(dom, targetPosetion) { 2 clearInterval(timer); 3 var speed ...


勻速運動   (當需要物體做勻速運動直接調用statMove函數)

 

 1 function startMove(dom,targetPosetion){ //dom : 運動對象,targetPosition : 到達目標位置
 2   clearInterval(timer);                                // 防止定時器疊加,先清除定時器。
 3   var speed = targetPosetion - dom.offsetLeft > 0 ? 7 : -7;   
 4        //斷物體到移動的目標位置的左邊還是右邊,左邊速度是正的,右邊速度是負的。
 5   timer = setInterval(function(){   //設置定時器。變數timer要定義在函數外面。
 6     if(Math.abs(targetPosetion - dom.offsetLeft ) < Math.abs(speed)){  
 7       clearInterval(timer);         
 8            //當目位置減去物體偏移量小於定時器移動的位置(因為在移動就超出了目標位置),清除定時器
 9       dom.style.left = targetPosetion + "px";   
10                 //因為距離目標位置還有一小段距離,直接讓物體等於目標位置就行
11     }else{
12       dom.style.left = dom.offsetLeft + speed + "px";
13     }
14   },30);
15 }
緩衝運動(越接近目標,速度越慢 緩運運動比直線運動視覺性更好,所以很常用
 1 function startMove(dom, targetPosetion) { 
 2   clearInterval(timer);
 3   var speed = null;
 4   timer = setInterval(function () {                              //設置定時器。變數timer要定義在函數外面。
 5     speed = (targetPosetion - dom.offsetLeft) /10;    
 6     speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);     
 7     if(dom.offsetLeft == targetPosetion){
 8       clearInterval(timer);
 9     }else{
10       dom.style.left = dom.offsetLeft + speed + "px";
11     }
12   }, 30)
13 }
5: 目標位置 - 物體偏移量(因為目標位置固定的,但是物體偏移量越來越大,所以會越來越慢)第10行的dom.offsetLeft和第5行負的dom.offsetLeft互相抵消掉了,dom.style.left直接等於目標位置(速度太大),所以要除以一個小數。 6:當目標位置 - 物體偏移量小於除數時,speed就等於小數了, 但是偏移量都是整數,就會自動的取捨值,例如:dom.style.left = 35.6px 實際會轉換成dom.style.left = 36px;所以只要有小數就向上取整(Math.ceil()),加上1。當是負值的時候就下取整(Math.floor()).因為當speed是小數時,就會被取整。所以最後是一個像素一個像素加上去的,所以物體的偏移量正好等於目標位置時就清除定時器。   顏色漸變的緩衝運動 因為讓當前的顏色漸變需要讓當前的opacity增加或減少,獲取當前的透明度opacity可以用計算樣式window.getComputedStyle。 計算樣式只讀,返回的都是絕對值,沒有相對單位
1 function getStyle(dom,attr){
2   if(window.getComputedStyle){
3     return window.getComputedStyle(dom,null)[attr];
4   }
5   else{
6     return dom.currentStyle[attr]; //IE8不相容,IE獨有屬性currentStyle
7   }
8 }
讓物體透明度緩衝變化
 1 startMove(div,25);
 2 function startMove(dom, targetPosetion) {
 3   clearInterval(timer);
 4   var speed = null,current = null;
 5   timer = setInterval(function () {
 6     current = parseFloat(getStyle(div,'opacity')) * 100;
 7     console.log(current);
 8     speed = (targetPosetion - current) / 10;
 9     speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
10     if (current == targetPosetion) {
11       clearInterval(timer);
12     } else {
13     dom.style.opacity = (current + speed) / 100;
14     }
15   }, 30)
16 }

 

因為透明度的取值範圍是0-1,把緩衝範圍變大,調用函數時和獲取當前透明度值時擴大100倍,增大緩衝區間,當給opacity賦值的時候縮小100倍。   多物體運動   4個div,移入到那個div,寬度做緩衝運動移動到400;移除寬度變為100。 下麵的代碼。橙色的部分有timer變為dom自己的屬性dom.timer, 在上面定義timer的時候,定義的timer是在函數外面的,4個div共用一個timer定時器, 當移入一個div時,開啟一個定時器,移出div時,又把上一個定時器給清除了,重新開啟了一個定時器。 當從上一個div快速移入一個新的div時,還沒等回到100,開啟的那個新的div。就把上一個div給清除了。 所以解決這個問題,就是在每個div上都加一個定時器。 當清理定時器的時候也是清理自己的定時器,不會影響其他的,就在每個元素上加上timer屬性。 function startMove(dom, targetPosetion) {
clearInterval(dom.timer); var speed = null; dom.timer = setInterval(function () { current = parseFloat(getStyle(dom, 'width')); //用計算樣式獲取當前寬度值。 speed = (targetPosetion - current) / 10; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); console.log(speed, current); if (current == targetPosetion) { clearInterval(dom.timer); } else { dom.style.width = current + speed + "px"; } }, 30) } var div = document.getElementsByTagName('div'); for (var i = 0; i < div.length; i++) { div[i].onmouseenter = function () { startMove(this, 400) } div[i].onmouseleave = function(){ startMove(this,100); } } 多物體不同屬性運動
 1 function startMove(dom , attr , target){
 2   clearInterval(dom.timer);
 3   dom.timer = setInterval(function(){
 4     var current = null,speed = null;
 5     if(attr == 'opacity'){
 6       current = parseFloat(getStyle(dom,attr)) * 100;
 7      }else{
 8       current = parseFloat(getStyle(dom,attr));
 9     }
10     speed = (target - current) / 10;
11     speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
12     if(current == target){
13       clearInterval(dom.timer);
14     }
15     if(attr == 'opacity'){
16       dom.style.opacity = (current + speed) / 100;
17     }else{
18       dom.style[attr] = (current + speed) + "px";
19     }
20   },30)
21 }
22  
23 var div = document.getElementsByTagName('div');
24 div[0].onmouseenter = function(){
25   startMove(this,'width',400);
26 };
27 div[1].onmouseenter = function(){
28   startMove(this,'height',400);
29 };
30 div[2].onmouseenter = function(){
31   startMove(this,'borderWidth',20);
32 };
33 div[3].onmouseenter = function(){
34   startMove(this,'opacity',50);
35 };

多物體多值運動 + 回調機制 

 

function startMove(dom, targetObj, callback) {
            clearInterval(dom.timer);
            dom.timer = setInterval(function () {
                var stop = true;
                var speed = null, current = null;
                for (var prop in targetObj) {
                    if (prop == 'opacity') {
                        current = parseFloat(getStyle(dom, prop))*100;
                    } else {
                        current = parseFloat(getStyle(dom, prop));
                    }
                    speed = (targetObj[prop] - current) / 10;
                    speed = speed>0?Math.ceil(speed):Math.floor(speed);
                    if (prop == 'opacity') {
                        dom.style.opacity = (current + speed) / 100;
                    } else {
                        dom.style[prop] = (current + speed) + "px";
                    }
                    if (targetObj[prop] != current) {
                        stop = false;
                    }
                }
                if (stop == true) {
                    clearInterval(dom.timer);
                    typeof callback == 'function' && callback();
                }
            }, 30);
        }

//讓多物體多值運動,由於多值就可以用對象來裝。
startMove(dom, targetObj, callback)接收3個參數,運動對象,想要改變的多值屬性對象,回調函數
跟上面一樣一地步清除定時器,然後設置定時器,用for in 迴圈傳過來的對象屬性,
如果傳過來的是opacity 就要擴大100倍,不是就正常調用上面getStyle()方法,返回一個計算屬性。
設置一個鎖,每次定時器執行時定義一個變數stop = true 可以停止,
當for in 迴圈時,判斷如果有一個當前值不等於目標值的時候,就讓stop = false。不可以停止
for in 結束,stop == true 的時候就代表所有的值都到達目標值,這時候就可以清空定時器。這個運動過程結束,調用回調函數


1      var divOne = document.getElementById('one');
2         var divTwo = document.getElementById('two');
3         divOne.onclick = function () {
4             startMove(this, { width: 400,height: 400,left: 200,top: 300,opacity: 50}, function () {
5                 startMove(divTwo, { width: 400, height: 400, left: 200, top: 300, opacity: 50 }, function () {
6                     alert(555);
7                 })
8             })
9         }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • node.js的初級使用 作為一個全棧開發員怎麼能不會node.js了?至少得會用node搭載環境吧!話不多說直接開乾! 一、下載與安裝: 官網:http://nodejs.cn/ 中文文檔:http://nodejs.cn/api/ 下載好對應版本後直接雙擊安裝即可。 安裝完成後再命令行輸入:no ...
  • 效果截圖: ...
  • 1.最傳統方法 for迴圈 for… in for…of 雖然for… in 、 for… of 都能夠變曆數組,但是兩者還是有很大區別的,先說結論: 兩者的主要區別在於他們的迭代方式 推薦在迴圈對象屬性的時候,使用for in,在遍曆數組的時候推薦使用for of for…in 迴圈出來的是key ...
  • H5的新特性 1.語義化標簽 2.表單新特性 3.多媒體視頻(video)和音頻(audio) 4.web存儲 C3的新特性 1.選擇器:屬性選擇器E[attr],偽類選擇器E:nth-child(n),空偽類E:empty ,排除偽類E:not(selector) 2.顏色:新增了RGBA、HSL ...
  • 基礎知識點 1.水平垂直居中 子絕父相,子盒子設置絕對定位,設置top:50%;left:50%,margin-top:-50%;margin-left:-50%; 子絕父相,子盒子設置絕對定位,設置 left & top & right & bottom為0;margin: auto; 伸縮盒子, ...
  • 碼雲地址https://gitee.com/zenonia/gerenjianjie 截圖 代碼如下: ...
  • javaScript基礎 js中的註釋 單行註釋(格式://註釋內容) 多行註釋(格式:/* 註釋內容 */) 文本註釋(格式:/** 註釋內容 */)js語句 例如: var num = 8; 我能用var定義了一個保存數字8的變數num 語句塊:{聲明內容的區域} 註意:JS語句塊是由 { } ...
  • 最近研究了js的單元測試,分享一下心得。 說起單元測試以前還真是不太瞭解,這次索性瞭解一番,測試有很多包含單元測試,性能測試,安全測試和功能測試等幾方面,本次只介紹一下單元測試。 前端進行單元測試主要是為了提高自己的代碼質量,多組測試用例,驗證自己的代碼是否都能通過,這是在開發中很有必要的。需要倡導 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...