You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

父容器设置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 16:57:01