如何在Blazor Web App WASM客户端项目中添加鼠标平移与缩放功能
实现Blazor布局的鼠标平移与Ctrl+滚轮缩放功能
1. 创建JavaScript工具文件
在客户端项目的wwwroot目录下新建js文件夹,创建zoomPan.js文件并写入以下代码:
let zoomPanState = { isDragging: false, startX: 0, startY: 0, currentTranslateX: 0, currentTranslateY: 0, currentScale: 1, targetElement: null }; export function initZoomPan(element) { zoomPanState.targetElement = element; // 绑定平移相关事件 element.addEventListener('mousedown', handleMouseDown); document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); // 绑定缩放事件 element.addEventListener('wheel', handleWheel); } export function destroyZoomPan() { if (!zoomPanState.targetElement) return; // 移除事件监听,避免内存泄漏 zoomPanState.targetElement.removeEventListener('mousedown', handleMouseDown); document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); zoomPanState.targetElement.removeEventListener('wheel', handleWheel); zoomPanState.targetElement = null; } function handleMouseDown(e) { e.preventDefault(); zoomPanState.isDragging = true; // 记录鼠标初始位置与元素当前偏移的差值 zoomPanState.startX = e.clientX - zoomPanState.currentTranslateX; zoomPanState.startY = e.clientY - zoomPanState.currentTranslateY; zoomPanState.targetElement.style.cursor = 'grabbing'; } function handleMouseMove(e) { if (!zoomPanState.isDragging) return; e.preventDefault(); // 计算新的偏移量 zoomPanState.currentTranslateX = e.clientX - zoomPanState.startX; zoomPanState.currentTranslateY = e.clientY - zoomPanState.startY; updateElementTransform(); } function handleMouseUp() { zoomPanState.isDragging = false; zoomPanState.targetElement.style.cursor = 'grab'; } function handleWheel(e) { if (!e.ctrlKey) return; e.preventDefault(); // 控制缩放比例,每次滚轮调整10%,限制缩放范围在0.1-5倍 const scaleFactor = e.deltaY > 0 ? 0.9 : 1.1; zoomPanState.currentScale = Math.max(0.1, Math.min(5, zoomPanState.currentScale * scaleFactor)); // 基于鼠标位置计算缩放后的偏移,保证缩放围绕鼠标点 const rect = zoomPanState.targetElement.getBoundingClientRect(); const mouseX = e.clientX - rect.left; const mouseY = e.clientY - rect.top; zoomPanState.currentTranslateX = mouseX - (mouseX - zoomPanState.currentTranslateX) * scaleFactor; zoomPanState.currentTranslateY = mouseY - (mouseY - zoomPanState.currentTranslateY) * scaleFactor; updateElementTransform(); } function updateElementTransform() { zoomPanState.targetElement.style.transform = `translate(${zoomPanState.currentTranslateX}px, ${zoomPanState.currentTranslateY}px) scale(${zoomPanState.currentScale})`; zoomPanState.targetElement.style.transformOrigin = '0 0'; zoomPanState.targetElement.style.willChange = 'transform'; }
2. 在自定义布局中集成功能
修改你的布局组件代码,添加JS互操作与元素引用:
@inherits LayoutComponentBase @inject IJSRuntime JSRuntime @implements IAsyncDisposable <main @ref="mainElement" style="cursor: grab; overflow: hidden; touch-action: none;"> <article> @Body </article> </main> @code { private ElementReference mainElement; private IJSObjectReference? _zoomPanModule; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { // 加载JS模块并初始化功能 _zoomPanModule = await JSRuntime.InvokeAsync<IJSObjectReference>( "import", "./js/zoomPan.js"); await _zoomPanModule.InvokeVoidAsync("initZoomPan", mainElement); } } public async ValueTask DisposeAsync() { // 组件销毁时清理资源 if (_zoomPanModule is not null) { await _zoomPanModule.InvokeVoidAsync("destroyZoomPan"); await _zoomPanModule.DisposeAsync(); } } }
3. 功能说明
- 平移操作:按住鼠标左键拖动
main区域即可平移页面内容,松开鼠标结束平移。 - 缩放操作:按住
Ctrl键滚动鼠标滚轮,将围绕当前鼠标位置进行缩放,缩放范围限制在0.1-5倍(可自行修改JS代码中的Math.max和Math.min参数调整范围)。 - 体验优化:添加了拖拽状态的光标样式,禁用触摸设备默认手势避免干扰,开启硬件加速提升动画流畅度。
内容的提问来源于stack exchange,提问作者user27339040
相关产品推荐
相关产品推荐

