为什么我的可拖动 svelte 在缩放后不能正常工作?
Why doesn't my draggable svelte work properly after scaling it?
我创建了一个允许拖动 Dom 元素的 svelte 组件:
<script>
export let posX = 0
export let posY = 0
let moving = false
let offsetX
let offsetY
function dragStart(e) {
const rect = e.currentTarget.getBoundingClientRect()
offsetX = e.pageX - rect.left
offsetY = e.pageY - rect.top
moving = true
}
function dragStop() {
moving = false
}
function dragMove(e) {
if (moving) {
posX = e.pageX - offsetX
posY = e.pageY - offsetY
}
}
</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>
当我将 CSS 属性 transform: scale(0.5);
添加到包含可拖动组件的 div 时,可拖动组件按预期停止工作。他们的位置偏离鼠标位置。
<script>
import Draggable from "./Draggable.svelte"
</script>
<style>
.box {
background: red;
width: 150px;
height: 150px;
}
.container {
transform: scale(0.5);
}
</style>
<div class="container">
<Draggable>
<div class="box"/>
</Draggable>
<Draggable posY={250}>
<div class="box"/>
</Draggable>
</div>
这是一个 link 到精巧的 REPL:https://svelte.dev/repl/679692b94afc48b48a2a3ebd39875ea0?version=3.42.5
我该如何解决这个问题?
提前致谢!
缩小容器时,会发生两件事:
- 容器大小变得小于视口,导致鼠标位置偏移未更正。
top
/left
CSS 属性的单位现在是原来的一半大,也没有更正。
要解决此问题,我们必须计算父容器相对于视口的偏移量,并将该值传递到您的 <Draggable>
组件中。我们还需要传入我们正在使用的比例值。
<!-- App.svelte -->
<script>
import {onMount} from "svelte"
import Draggable from "./Draggable.svelte"
let parent;
let parentOffset = {x: 0, y:0}
onMount(() => {
let rect = parent.getBoundingClientRect()
parentOffset = {x: rect.x, y: rect.y}
})
</script>
<style>
.box {
background: red;
width: 150px;
height: 150px;
}
.container {
transform: scale(0.5);
}
</style>
<div class="container" bind:this={parent}>
<Draggable {parentOffset} scale={0.5}>
<div class="box"/>
</Draggable>
<Draggable posY={250} {parentOffset} scale={0.5}>
<div class="box"/>
</Draggable>
</div>
<!-- Draggable.svelte -->
<script>
export let posX = 0
export let posY = 0
export let parentOffset;
export let scale;
let moving = false
let offsetX
let offsetY
function dragStart(e) {
const rect = e.currentTarget.getBoundingClientRect()
offsetX = e.pageX - rect.left
offsetY = e.pageY - rect.top
moving = true
}
function dragStop() {
moving = false
}
function dragMove(e) {
if (moving) {
// new math! we subtract the parent offset to correct the parent shift
// and also divide by the scale to correct the scale multiplication
posX = ((e.pageX - offsetX)-parentOffset.x)/scale
posY = ((e.pageY - offsetY)-parentOffset.y)/scale
}
}
</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>
新 REPL:https://svelte.dev/repl/9ec1a1598e8f407e8ec807dbb8a4d92b?version=3.42.5
我创建了一个允许拖动 Dom 元素的 svelte 组件:
<script>
export let posX = 0
export let posY = 0
let moving = false
let offsetX
let offsetY
function dragStart(e) {
const rect = e.currentTarget.getBoundingClientRect()
offsetX = e.pageX - rect.left
offsetY = e.pageY - rect.top
moving = true
}
function dragStop() {
moving = false
}
function dragMove(e) {
if (moving) {
posX = e.pageX - offsetX
posY = e.pageY - offsetY
}
}
</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>
当我将 CSS 属性 transform: scale(0.5);
添加到包含可拖动组件的 div 时,可拖动组件按预期停止工作。他们的位置偏离鼠标位置。
<script>
import Draggable from "./Draggable.svelte"
</script>
<style>
.box {
background: red;
width: 150px;
height: 150px;
}
.container {
transform: scale(0.5);
}
</style>
<div class="container">
<Draggable>
<div class="box"/>
</Draggable>
<Draggable posY={250}>
<div class="box"/>
</Draggable>
</div>
这是一个 link 到精巧的 REPL:https://svelte.dev/repl/679692b94afc48b48a2a3ebd39875ea0?version=3.42.5
我该如何解决这个问题?
提前致谢!
缩小容器时,会发生两件事:
- 容器大小变得小于视口,导致鼠标位置偏移未更正。
top
/left
CSS 属性的单位现在是原来的一半大,也没有更正。
要解决此问题,我们必须计算父容器相对于视口的偏移量,并将该值传递到您的 <Draggable>
组件中。我们还需要传入我们正在使用的比例值。
<!-- App.svelte -->
<script>
import {onMount} from "svelte"
import Draggable from "./Draggable.svelte"
let parent;
let parentOffset = {x: 0, y:0}
onMount(() => {
let rect = parent.getBoundingClientRect()
parentOffset = {x: rect.x, y: rect.y}
})
</script>
<style>
.box {
background: red;
width: 150px;
height: 150px;
}
.container {
transform: scale(0.5);
}
</style>
<div class="container" bind:this={parent}>
<Draggable {parentOffset} scale={0.5}>
<div class="box"/>
</Draggable>
<Draggable posY={250} {parentOffset} scale={0.5}>
<div class="box"/>
</Draggable>
</div>
<!-- Draggable.svelte -->
<script>
export let posX = 0
export let posY = 0
export let parentOffset;
export let scale;
let moving = false
let offsetX
let offsetY
function dragStart(e) {
const rect = e.currentTarget.getBoundingClientRect()
offsetX = e.pageX - rect.left
offsetY = e.pageY - rect.top
moving = true
}
function dragStop() {
moving = false
}
function dragMove(e) {
if (moving) {
// new math! we subtract the parent offset to correct the parent shift
// and also divide by the scale to correct the scale multiplication
posX = ((e.pageX - offsetX)-parentOffset.x)/scale
posY = ((e.pageY - offsetY)-parentOffset.y)/scale
}
}
</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>
新 REPL:https://svelte.dev/repl/9ec1a1598e8f407e8ec807dbb8a4d92b?version=3.42.5