I want to make a list of draggable objects like the one on the left side of this image:
To do so I have modified Vue2InteractDraggable.vue to work with VueJs3
as you can see in this codesandbox, but I get a draggable list of one repeated component as you can see here:
Can you please tell me how can I solve this problem and parse this list of draggable objects properly? thanks in advance.
The solution in my case was to adapt the Vue2InteractDraggable.vue
component to work with Vue 3
:
<template>
<div
ref="interactElement"
:class="{ 'vue-interact-animated': interactIsAnimating }"
:style="{
transform: interactTransformString,
transition: interactTransitionString,
}"
>
<slot />
</div>
</template>
<script>
import interact from "interactjs";
export default {
name: "VueInteractDraggable",
props: {
interactBlockDragDown: {
type: Boolean,
default: false,
},
interactBlockDragLeft: {
type: Boolean,
default: false,
},
interactBlockDragRight: {
type: Boolean,
default: false,
},
interactBlockDragUp: {
type: Boolean,
default: false,
},
interactEventBusEvents: {
type: Object,
default: () => {},
},
interactMaxRotation: {
type: Number,
default: 0,
},
interactLockXAxis: {
type: Boolean,
default: false,
},
interactLockYAxis: {
type: Boolean,
default: false,
},
interactLockSwipeDown: {
type: Boolean,
default: false,
},
interactLockSwipeLeft: {
type: Boolean,
default: false,
},
interactLockSwipeRight: {
type: Boolean,
default: false,
},
interactLockSwipeUp: {
type: Boolean,
default: false,
},
interactOutOfSightXCoordinate: {
type: Number,
default: 500,
},
interactOutOfSightYCoordinate: {
type: Number,
default: 1000,
},
interactXThreshold: {
type: Number,
default: 200,
},
interactYThreshold: {
type: Number,
default: 300,
},
},
data() {
return {
interactIsAnimating: true,
interactDragged: null,
interactPosition: {
x: 0,
y: 0,
rotation: 0,
},
};
},
computed: {
interactTransformString() {
if (!this.interactIsAnimating || this.interactDragged) {
const { x, y, rotation } = this.interactPosition;
return `translate3D(${x}px, ${y}px, 0) rotate(${rotation}deg)`;
}
return null;
},
interactTransitionString() {
if (this.interactIsAnimating)
return "transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)";
return null;
},
},
watch: {
interactEventBusEvents(val) {
this.interactSetEventBusEvents();
},
},
mounted() {
this.interactSetEventBusEvents();
const element = this.$refs.interactElement;
interact(element).draggable({
onstart: () => {
this.interactIsAnimating = false;
},
onmove: (event) => {
let x = 0;
let y = 0;
if (this.interactLockSwipeLeft && event.dx < 0) x = 0;
else if (this.interactLockSwipeRight && event.dx > 0) x = 0;
else
x = this.interactLockXAxis
? 0
: (this.interactPosition.x || 0) + event.dx;
if (this.interactLockSwipeUp && event.dy < 0) y = 0;
else if (this.interactLockSwipeDown && event.dy > 0) y = 0;
else
y = this.interactLockYAxis
? 0
: (this.interactPosition.y || 0) + event.dy;
let rotation = this.interactMaxRotation * (x / this.interactXThreshold);
if (rotation > this.interactMaxRotation)
rotation = this.interactMaxRotation;
else if (rotation < -this.interactMaxRotation)
rotation = -this.interactMaxRotation;
this.interactSetPosition({ x, y, rotation });
},
onend: () => {
const { x: cardPositionX, y: cardPositionY } = this.interactPosition;
const { interactXThreshold, interactYThreshold } = this;
this.interactIsAnimating = true;
if (cardPositionX > interactXThreshold) this.interactDraggedRight();
else if (cardPositionX < -interactXThreshold)
this.interactDraggedLeft();
else if (cardPositionY > interactYThreshold) this.interactDraggedDown();
else if (cardPositionY < -interactYThreshold) this.interactDraggedUp();
else this.interactResetCardPosition();
},
});
},
beforeUnmount() {
interact(this.$refs.interactElement).unset();
this.interactUnsetEventBusEvents();
},
methods: {
interactDraggedDown() {
if (this.interactBlockDragDown) {
this.interactResetCardPosition();
return;
}
this.interactUnsetElement();
this.interactSetPosition({ y: this.interactOutOfSightYCoordinate });
this.$emit("draggedDown");
},
interactDraggedLeft() {
if (this.interactBlockDragLeft) {
this.interactResetCardPosition();
return;
}
this.interactUnsetElement();
this.interactSetPosition({
x: -this.interactOutOfSightXCoordinate,
rotation: -this.interactMaxRotation,
});
this.$emit("draggedLeft");
},
interactDraggedRight() {
if (this.interactBlockDragRight) {
this.interactResetCardPosition();
return;
}
this.interactUnsetElement();
this.interactSetPosition({
x: this.interactOutOfSightXCoordinate,
rotation: this.interactMaxRotation,
});
this.$emit("draggedRight");
},
interactDraggedUp() {
if (this.interactBlockDragUp) {
this.interactResetCardPosition();
return;
}
this.interactUnsetElement();
this.interactSetPosition({ y: -this.interactOutOfSightYCoordinate });
this.$emit("draggedUp");
},
interactSetEventBusEvents() {
if (this.interactEventBusEvents) {
if (this.interactEventBusEvents.draggedDown) {
this.emitter.$on(
this.interactEventBusEvents.draggedDown,
this.interactDraggedDown
);
}
if (this.interactEventBusEvents.draggedLeft) {
this.emitter.$on(
this.interactEventBusEvents.draggedLeft,
this.interactDraggedLeft
);
}
if (this.interactEventBusEvents.draggedRight) {
this.emitter.$on(
this.interactEventBusEvents.draggedRight,
this.interactDraggedRight
);
}
if (this.interactEventBusEvents.draggedUp) {
this.emitter.$on(
this.interactEventBusEvents.draggedUp,
this.interactDraggedUp
);
}
}
},
interactSetPosition(coordinates) {
const { x = 0, y = 0, rotation = 0 } = coordinates;
this.interactPosition = { x, y, rotation };
},
interactUnsetElement() {
interact(this.$refs.interactElement).unset();
this.interactDragged = true;
},
interactUnsetEventBusEvents() {
if (this.interactEventBusEvents) {
if (this.interactEventBusEvents.draggedDown) {
this.emitter.$off(
this.interactEventBusEvents.draggedDown,
this.draggedDown
);
}
if (this.interactEventBusEvents.draggedLeft) {
this.emitter.$off(
this.interactEventBusEvents.draggedLeft,
this.draggedLeft
);
}
if (this.interactEventBusEvents.draggedRight) {
this.emitter.$off(
this.interactEventBusEvents.draggedRight,
this.draggedRight
);
}
if (this.interactEventBusEvents.draggedUp) {
this.emitter.$off(
this.interactEventBusEvents.draggedUp,
this.draggedUp
);
}
}
},
interactResetCardPosition() {
this.interactSetPosition({ x: 0, y: 0, rotation: 0 });
},
},
emits: ['draggedUp', 'draggedDown', 'draggedLeft', 'draggedRight'],
};
</script>