鼠标控制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>

 

posted @ 2025-03-27 10:12  地yu荒冢  阅读(26)  评论(0)    收藏  举报