daybrush / moveable

Moveable! Draggable! Resizable! Scalable! Rotatable! Warpable! Pinchable! Groupable! Snappable!
https://daybrush.com/moveable/
MIT License
10.1k stars 617 forks source link

moveable position is wrong #531

Open ChenWeihua123 opened 3 years ago

ChenWeihua123 commented 3 years ago

Environments

Description

image

<div ref="panelContainerRef" class="panel-container"  style="position: relative; left: 0; top: 0">
            <div
              ref="panelCanvasRef"
              style="position: relative"
            >
              <div class="custom-target" style="width: 200px; height: 200px; background-color: red"></div>
              <moveable :target="target"></moveable>
            </div>
</div>
target = document.querySelector('.custom-target')

When I set position: relative , the moveable position did not match the element

is there any vue3 demo? thanks

ChenWeihua123 commented 3 years ago

i set rootContainer ,it not worked, but container is worked,

This is my first time using it, i am sorry .Maybe I should take a closer look at the documentation

glancel commented 3 years ago

@ChenWeihua123 How do you set container? Could you please give us a snippet so that other people can solve this too? Thank you for your help!

glancel commented 3 years ago

Have you set "draggable: true"? Because my problem is that when I drag the position where the script think I released the rectangle is wrong...

ChenWeihua123 commented 3 years ago

image just like this and it's amazing

<template>
  <v-moveable
    ref="moveableRef"
    v-bind="moveableState"
    @dragStart="onDragStart"
    @drag="onDrag"
    @resize="onResize"
    @resizeEnd="onResizeEnd"
    :container="container"
    :rootContainer="rootContainer"
  ></v-moveable>
</template>
<script lang="ts">
import { useStore } from '@/store';
import { computed, defineComponent, onMounted, PropType, reactive, ref } from 'vue';
import VMoveable, { MoveableProps, OnDrag, OnResize } from 'vue3-moveable';

export default defineComponent({
  components: { VMoveable },
  props: {
    selectedTargets: {
      type: Array as PropType<HTMLElement[]>,
      default: () => [],
    },
    zoom: {
      type: Number,
      default: 1,
    },
  },
  setup(props) {
    const store = useStore();
    const moveableRef = ref<VMoveable>();

    const zoom = computed(() => 1 / store.state.editor.scale);
    const select = computed(() => store.state.editor.select);
    const moduleTargets = computed(() => store.state.editor.moduleTargets);
    const selectedTargets = computed(() =>
      select.value
        .map(id => {
          return moduleTargets.value.get(id);
        })
        .filter(Boolean),
    );
    const target = ref<HTMLElement[]>([]);
    const moveableState = reactive<MoveableProps>({
      className: 'svt-moveable',
      draggable: true,
      resizable: true,
      // dragArea: true,
      origin: false,
      pinchable: true,
      zoom: zoom as unknown as number,
      throttleResize: 1,
      throttleDrag: 1,
      target: selectedTargets as unknown as HTMLElement[],
      // target: target as unknown as HTMLElement[],
    });
    const container = ref<HTMLElement | null>(document.querySelector('.panel-container'));
    const rootContainer = ref<HTMLElement | null>(document.body);

    setTimeout(() => {
      target.value = [document.querySelector('.custom-target') as HTMLElement];
    }, 2000);

    const onDragStart = () => {
      console.log('dragStart');
    }
    const onDrag = ({ transform, target, translate }: OnDrag) => {
      target.style.transform = transform;
    };
    const onResize = ({ target, width, height, drag }: OnResize) => {
      target.style.width = `${width}px`;
      target.style.height = `${height}px`;
      target.style.transform = drag.transform;
    };
    const onResizeEnd = () => {
      store.commit('editor/setRefresh');
    };

    onMounted(() => {
      console.log('moveableRef: ', moveableRef.value);
      console.log('moveableRef: ', moveableRef.value!.$_moveable.dragStart);
    });

    const getMoveable = () => {
      return moveableRef.value!.$_moveable;
    };

    return {
      moveableRef,
      onDrag,
      onResize,
      moveableState,
      container,
      rootContainer,
      zoom,
      onResizeEnd,
      getMoveable,
      onDragStart
    };
  },
});
</script>
<style lang="scss" scoped></style>
daybrush commented 3 years ago

I'm not sure why this is happening. It is not good to set container prop. Here's my example:

<template>
  <div class="root">
    <div class="container" style="position: relative">
      <div class="target">Target</div>
      <button @click="toggleDraggable">Toggle {{draggable}}</button>
      <moveable
        v-bind:target="['.target']"
        v-bind:draggable="draggable"
        v-bind:throttleDrag="1"
        v-bind:edgeDraggable="false"
        v-bind:startDragRotate="0"
        v-bind:throttleDragRotate="0"
        @drag="onDrag"
      />
    </div>
  </div>
</template>
<script>
import { defineComponent } from "vue";
import Moveable from "../src/Moveable.vue";

export default defineComponent({
    components: {
        Moveable,
    },
    data(){
        return {
            draggable: true,
        };
    },
    methods: {
        onDrag(e) {
            e.target.style.transform = e.transform;
        },
        toggleDraggable() {
            console.log(this.draggable);
            this.draggable = !this.draggable;
        }
    }
});
</script>
<style>
html,
body {
  position: relative;
  height: 100%;
  margin: 0;
  padding: 0;
}
.description {
  padding: 10px;
}
.root {
  position: relative;
}
.container {
  position: relative;
  margin-top: 50px;
}
.target {
  position: absolute;
  width: 100px;
  height: 100px;
  top: 150px;
  left: 100px;
  line-height: 100px;
  text-align: center;
  background: #ee8;
  color: #333;
  font-weight: bold;
  border: 1px solid #333;
  box-sizing: border-box;
}

.target1 {
  left: 120px;
  top: 120px;
}

.target2 {
  left: 300px;
  top: 140px;
}

.target3 {
  left: 180px;
  top: 250px;
}
</style>
ChenWeihua123 commented 3 years ago

I see, I have time to try again