He creado un componente esbelto para permitir elementos Dom arrastrables:
<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> Cuando agrego la propiedad CSS transform: scale(0.5); a un div que contiene componentes arrastrables, los componentes arrastrables dejan de funcionar como se esperaba. Sus posiciones se compensan con la posición del mouse.
<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>Aquí hay un enlace al esbelto REPL: https://svelte.dev/repl/679692b94afc48b48a2a3ebd39875ea0?version=3.42.5
¿Cómo haría para arreglar esto?
¡Gracias por adelantado!
Cuando reduce la escala del contenedor, suceden dos cosas:
top / left ahora son la mitad de grandes, lo que tampoco se corrige. Para solucionar esto, tenemos que calcular el desplazamiento del contenedor principal en relación con la ventana gráfica y pasar ese valor a su componente <Draggable> . También necesitamos pasar el valor de escala que estamos usando.
<!-- 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>Nuevo REPL: https://svelte.dev/repl/9ec1a1598e8f407e8ec807dbb8a4d92b?version=3.42.5