Skip to content

Instantly share code, notes, and snippets.

@stephen-zhao
Last active December 24, 2021 20:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stephen-zhao/325626e98b425e3dcbceb4a14a3d53fb to your computer and use it in GitHub Desktop.
Save stephen-zhao/325626e98b425e3dcbceb4a14a3d53fb to your computer and use it in GitHub Desktop.
Library to Drag Multiple Items Touch-Friendly
var draggamil = function() {
var dragItems = document.querySelectorAll('.sticker');
var container = document.querySelector('.is---sticker_container');
var dragStates = {};
var dragMaxZ = 0;
dragItems.forEach(function (dragItem, idx) {
dragItem.setAttribute("drag-id", idx);
var initialTransform = window.getComputedStyle(dragItem).getPropertyValue('transform');
dragStates["" + idx] = {
active: false,
currentX: undefined,
currentY: undefined,
initialX: undefined,
initialY: undefined,
initialTransform: initialTransform == "none" ? "" : initialTransform,
xOffset: 0,
yOffset: 0,
};
var initialZ = window.getComputedStyle(dragItem).getPropertyValue('z-index') || 0;
if (initialZ > dragMaxZ) {
dragMaxZ = initialZ;
}
});
container.addEventListener("touchstart", dragStart, false);
container.addEventListener("touchend", dragStop, false);
container.addEventListener("touchmove", drag, false);
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragStop, false);
container.addEventListener("mouseleave", dragStopIfLeavingContainer, false);
container.addEventListener("mousemove", drag, false);
function dragStart(e) {
// Check if event target exists
if (!e || !e.target) {
// Cannot start drag if no event target, so stop all dragging.
dragStop();
return;
}
var dragItem = e.target;
var dragId = dragItem.getAttribute("drag-id");
// Check if it is actually a draggable item
if (!dragId) {
// If not, check if any of its ancestors is a draggable item
var maybeAncestorTarget = e.target.closest(".sticker");
if (!maybeAncestorTarget) {
dragStop();
return;
}
dragItem = maybeAncestorTarget;
dragId = maybeAncestorTarget.getAttribute("drag-id");
// Check if it is actually a draggable item
if (!dragId) {
// If not a draggable item, stop all dragging.
dragStop();
return;
}
}
var dragState = dragStates[dragId];
if (e.type === "touchstart") {
dragState.initialX = e.touches[0].clientX - dragState.xOffset;
dragState.initialY = e.touches[0].clientY - dragState.yOffset;
}
else {
dragState.initialX = e.clientX - dragState.xOffset;
dragState.initialY = e.clientY - dragState.yOffset;
}
++dragMaxZ;
dragItem.style['z-index'] = dragMaxZ;
dragState.active = true;
}
function dragStop(e) {
// Stop all active drag states
Object.keys(dragStates).forEach(function(dragId) {
var dragState = dragStates[dragId];
if (dragState.active) {
dragState.initialX = dragState.currentX;
dragState.initialY = dragState.currentY;
dragState.active = false;
}
});
return;
}
function dragStopIfLeavingContainer(e) {
if (e.target.id == "#container") {
dragStop();
}
}
function drag(e) {
dragItems.forEach(function(dragItem) {
var dragId = dragItem.getAttribute("drag-id");
if (!dragId) {
return;
}
var dragState = dragStates[dragId];
if (dragState.active) {
e.preventDefault();
if (e.type === "touchmove") {
dragState.currentX = e.touches[0].clientX - dragState.initialX;
dragState.currentY = e.touches[0].clientY - dragState.initialY;
} else {
dragState.currentX = e.clientX - dragState.initialX;
dragState.currentY = e.clientY - dragState.initialY;
}
dragState.xOffset = dragState.currentX;
dragState.yOffset = dragState.currentY;
dragItem.style.transform = "translate3d(" + dragState.currentX + "px, " + dragState.currentY + "px, 0) " + dragState.initialTransform;
}
});
}
}
$(document).ready(draggamil);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment