父容器设置scale缩放后Svelte可拖拽组件位置偏移如何修复?
Svelte拖拽组件父级缩放偏移修复方案
问题根源
当拖拽元素的父级设置transform: scale()属性后,元素的CSS坐标单位和页面实际渲染像素会产生比例差。原有逻辑直接使用页面鼠标坐标计算元素位置,没有适配缩放比例,因此出现位置偏移。
修复后的完整Draggable.svelte代码
<script> export let posX = 0 export let posY = 0 let moving = false let offsetX let offsetY let scaleX = 1 let scaleY = 1 function dragStart(e) { const target = e.currentTarget const rect = target.getBoundingClientRect() // 计算当前元素的累积水平、垂直缩放比例 scaleX = rect.width / target.offsetWidth scaleY = rect.height / target.offsetHeight // 适配缩放比例计算鼠标在元素内的偏移量(CSS单位) offsetX = (e.pageX - rect.left) / scaleX offsetY = (e.pageY - rect.top) / scaleY moving = true } function dragStop() { moving = false } function dragMove(e) { if (moving) { // 适配缩放比例计算元素最终位置 posX = (e.pageX - offsetX * scaleX) / scaleX posY = (e.pageY - offsetY * scaleY) / scaleY } } </script> <style> .draggable { user-select: none; position: absolute; cursor: grab; } .draggable:active { cursor: grabbing; } </style> <svelte:window on:mouseup={dragStop} on:mousemove={dragMove} /> <div on:mousedown={dragStart} style="top: {posY}px; left: {posX}px;" class="draggable" > <slot/> </div>
关键修改说明
- 新增
scaleX、scaleY变量存储元素的累积缩放比例,支持非等比例缩放场景 - 拖拽初始化时通过
getBoundingClientRect()返回的实际渲染尺寸和元素原生offsetWidth/offsetHeight的比值计算缩放系数,不需要递归遍历父元素,兼容性更强 - 偏移量计算、位置更新逻辑都适配缩放系数,彻底消除比例差带来的位置偏移
修改后不管父级设置任意缩放比例,拖拽都可以正常对齐鼠标位置。
内容的提问来源于stack exchange,提问作者joe
相关产品推荐
相关产品推荐

