鼠標控制CSS矩陣變換示例
鼠標控制CSS的transform matrix來實現縮放和移動:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <style> 5 #target { 6 width: 200px; 7 height: 200px; 8 background: #3498db; 9 position: absolute; 10 left: 50%; 11 top: 50%; 12 transform-origin: 0 0; 13 cursor: grab; 14 } 15 </style> 16 </head> 17 <body> 18 <div id="target"></div> 19 20 <script> 21 const target = document.getElementById('target'); 22 let isDragging = false; 23 let startX, startY; 24 let currentTX = 0, currentTY = 0; 25 let currentScale = 1; 26 27 // 鼠標按下事件(開始拖拽) 28 target.addEventListener('mousedown', (e) => { 29 isDragging = true; 30 startX = e.clientX; 31 startY = e.clientY; 32 const matrix = parseMatrix(target.style.transform); 33 currentTX = matrix.tx; 34 currentTY = matrix.ty; 35 target.style.cursor = 'grabbing'; 36 }); 37 38 // 鼠標移動事件(拖拽處理) 39 document.addEventListener('mousemove', (e) => { 40 if (!isDragging) return; 41 42 const deltaX = e.clientX - startX; 43 const deltaY = e.clientY - startY; 44 45 target.style.transform = `matrix( 46 ${currentScale}, 0, 0, ${currentScale}, 47 ${currentTX + deltaX}, ${currentTY + deltaY} 48 )`; 49 }); 50 51 // 鼠標釋放事件(結束拖拽) 52 document.addEventListener('mouseup', () => { 53 isDragging = false; 54 const matrix = parseMatrix(target.style.transform); 55 currentTX = matrix.tx; 56 currentTY = matrix.ty; 57 target.style.cursor = 'grab'; 58 }); 59 60 // 滾輪事件(縮放處理) 61 target.addEventListener('wheel', (e) => { 62 e.preventDefault(); 63 const factor = e.deltaY > 0 ? 0.9 : 1.1; 64 const rect = target.getBoundingClientRect(); 65 66 // 計算鼠標相對元素的位置 67 const x = e.clientX; 68 const y = e.clientY; 69 const localX = (x - currentTX) / currentScale; 70 const localY = (y - currentTY) / currentScale; 71 72 // 計算新的縮放比例和平移量 73 const newScale = currentScale * factor; 74 const newTX = x - localX * newScale; 75 const newTY = y - localY * newScale; 76 77 // 更新參數并應用變換 78 currentScale = newScale; 79 currentTX = newTX; 80 currentTY = newTY; 81 82 target.style.transform = `matrix( 83 ${newScale}, 0, 0, ${newScale}, 84 ${newTX}, ${newTY} 85 )`; 86 }); 87 88 // 解析 transform matrix 的輔助函數 89 function parseMatrix(transform) { 90 if (!transform || transform === 'none') { 91 return { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 }; 92 } 93 const matrix = transform.match(/matrix\(([^)]+)\)/)[1].split(/, /).map(parseFloat); 94 return { 95 a: matrix[0], 96 b: matrix[1], 97 c: matrix[2], 98 d: matrix[3], 99 tx: matrix[4], 100 ty: matrix[5] 101 }; 102 } 103 </script> 104 </body> 105 </html>
浙公網安備 33010602011771號