這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 說在前面 滑鼠控制元素旋轉在現在也是一個很常見的功能,讓我們從實現div元素的旋轉控制開始來瞭解元素旋轉的具體原理和實現方法吧。 效果展示 體驗地址 code.juejin.cn/pen/7290719… 實現步驟 畫一個div 首先我們 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
說在前面
滑鼠控制元素旋轉在現在也是一個很常見的功能,讓我們從實現div元素的旋轉控制開始來瞭解元素旋轉的具體原理和實現方法吧。
效果展示
體驗地址
實現步驟
畫一個div
首先我們需要先畫一個div,併在它上方加上旋轉圖標,我們可以通過這個圖標來對div進行旋轉,具體代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <link rel="stylesheet" href="./index.css" /> </head> <body> <div class="container"> <div class="rotate-div"> <div class="rotate-icon">↻</div> </div> </div> </body> <script src="./index.js"></script> </html>
加點css
將div設置為紅色背景的方塊,調整旋轉圖標的位置,具體代碼如下:
.container { display: flex; justify-content: center; align-items: center; height: 100vh; } .rotate-div { position: relative; width: 200px; height: 200px; background-color: red; transform-origin: center center; } .rotate-icon { position: absolute; top: -50px; /* 調整圖標的位置 */ left: 50%; transform: translateX(-50%); font-size: 20px; cursor: pointer; }
效果如下:
完成滑鼠拖拽旋轉功能
滑鼠在旋轉圖標按下的時候,我們需要監聽滑鼠移動事件,根據滑鼠移動位置和初始點擊位置的相對角度來計算方塊旋轉的角度。
1、獲取方塊和旋轉圖標元素對象
首先我們要先獲取方塊和旋轉圖標元素對象,便於後續事件監聽和元素操作。
const rotateDiv = document.querySelector(".rotate-div"); const rotateIcon = document.querySelector(".rotate-icon");
返回值類型:TextRectangle對象,每個矩形具有四個整數性質( 上, 右 , 下,和左 )表示的坐標的矩形,以像素為單位。
rectObject.top:元素上邊到視窗上邊的距離;
rectObject.right:元素右邊到視窗左邊的距離;
rectObject.bottom:元素下邊到視窗上邊的距離;
rectObject.left:元素左邊到視窗左邊的距離;
我們記錄下方塊的初始中心點:
const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2;
(2)計算旋轉角度
Math.atan2()
Math.atan2()
返回從原點 (0,0) 到 (x,y) 點的線段與 x 軸正方向之間的平面角度 (弧度值),也就是 Math.atan2(y,x)
Math.atan2(y, x)
atan2
方法返回一個 -pi 到 pi 之間的數值,表示點 (x, y) 對應的偏移角度。這是一個逆時針角度,以弧度為單位,正 X 軸和點 (x, y) 與原點連線 之間。註意此函數接受的參數:先傳遞 y 坐標,然後是 x 坐標。
atan2
接受單獨的 x 和 y 參數,而 atan
接受兩個參數的比值。
由於 atan2
是 Math
的靜態方法,所以應該像這樣使用:Math.atan2()
,而不是作為你創建的 Math
實例的方法。
function getAngle(centerX, centerY, mouseX, mouseY) { return Math.atan2(mouseY - centerY, mouseX - centerX) * (180 / Math.PI); }
使用當前滑鼠位置相對角度減去滑鼠初始點擊點的相對角度即可得到滑鼠旋轉的角度。
startingMouseAngle = getAngle(centerX, centerY, event.clientX, event.clientY); const deltaMouseAngle = currentMouseAngle - startingMouseAngle;
(3)旋轉角度簡化
方塊的最大旋轉角度為360度,所以我們對角度進行取模,保持旋轉角度在360度以內即可。
function normalizeRotation(rotation) { if (rotation >= 0) { return rotation % 360; } else { return (rotation % 360) + 360; } }
(4)給方塊設置旋轉角度
rotateDiv.style.transform = `rotate(${newRotation}deg)`;
3、移除旋轉邏輯
滑鼠抬起的時候我們應該將旋轉邏輯給移除,及將滑鼠移動和抬起事件移除。
function stopSpin() { window.removeEventListener("mousemove", spin); window.removeEventListener("mouseup", stopSpin); }
4、完整代碼
完整的JavaScrip代碼如下:
const rotateDiv = document.querySelector(".rotate-div"); const rotateIcon = document.querySelector(".rotate-icon"); let startingMouseAngle = 0; let startingRotation = 0; rotateIcon.addEventListener("selectstart", function (event) { event.preventDefault(); }); rotateIcon.addEventListener("mousedown", function (event) { const rect = rotateDiv.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; startingMouseAngle = getAngle(centerX, centerY, event.clientX, event.clientY); startingRotation = getCurrentRotation(); window.addEventListener("mousemove", spin); window.addEventListener("mouseup", stopSpin); }); function stopSpin() { window.removeEventListener("mousemove", spin); window.removeEventListener("mouseup", stopSpin); } function spin(event) { const rect = rotateDiv.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const currentMouseAngle = getAngle( centerX, centerY, event.clientX, event.clientY ); const deltaMouseAngle = currentMouseAngle - startingMouseAngle; let newRotation = startingRotation + deltaMouseAngle; newRotation = normalizeRotation(newRotation); rotateDiv.style.transform = `rotate(${newRotation}deg)`; } function normalizeRotation(rotation) { if (rotation >= 0) { return rotation % 360; } else { return (rotation % 360) + 360; } } function getAngle(centerX, centerY, mouseX, mouseY) { return Math.atan2(mouseY - centerY, mouseX - centerX) * (180 / Math.PI); } function getCurrentRotation() { const transformStyle = window .getComputedStyle(rotateDiv) .getPropertyValue("transform"); const matrix = new DOMMatrixReadOnly(transformStyle); const angle = Math.acos(matrix.a) * (180 / Math.PI); return matrix.b < 0 ? -angle : angle; }