make drag resizer more scalable

This commit is contained in:
David Tsay 2025-01-27 15:53:18 -08:00
parent 66e4acd3b7
commit 35feeec602
2 changed files with 34 additions and 23 deletions

View File

@ -108,9 +108,9 @@ export default {
); );
// Drag resizer - Swimlane column width // Drag resizer - Swimlane column width
const { size, mousedown } = useDragResizer('horizontal', { size: 200 }); const { x: swimLaneLabelWidth, mousedown } = useDragResizer({ initialX: 200 });
provide('swimLaneLabelWidth', size); provide('swimLaneLabelWidth', swimLaneLabelWidth);
provide('mousedown', mousedown); provide('mousedown', mousedown);
return { alignmentData, resetAlignment }; return { alignmentData, resetAlignment };

View File

@ -24,33 +24,33 @@ import { ref } from 'vue';
/** /**
* @typedef {Object} DragResizerOptions the options object * @typedef {Object} DragResizerOptions the options object
* @property {number} [size=0] the initial size of the object to track size for * @property {number} [initialX=0] the initial x of the object to track size for
* @property {number} [initialY=0] the initial y of the object to track size for
* @property {Function} [callback] the function to call when drag is complete * @property {Function} [callback] the function to call when drag is complete
*/ */
/** /**
* @typedef {Object} ReturnObject the return object * @typedef {Object} ReturnObject the return object
* @property {number} size the reactive size ref * @property {number} x the reactive horizontal size during/post drag
* @property {number} y the reactive vertical size during/post drag
* @property {function} mousedown * @property {function} mousedown
*/ */
/** /**
* Defines a drag resizer hook that tracks the size of an object * Defines a drag resizer hook that tracks the size of an object
* in vertical or horizontal direction on drag * in vertical and horizontal direction on drag
* @param {('horizontal'|'vertical')} [direction='horizontal'] the direction of drag to track
* @param {DragResizerOptions} [param={}] the options object * @param {DragResizerOptions} [param={}] the options object
* @returns {ReturnObject} * @returns {ReturnObject}
*/ */
export function useDragResizer(direction = 'horizontal', { size: initialSize = 0, callback } = {}) { export function useDragResizer({ initialX = 0, initialY = 0, callback } = {}) {
if (direction !== 'horizontal' && direction !== 'vertical') { const x = ref(initialX);
throw new Error(`Must specify 'horizontal' or 'vertical' drag direction`); const y = ref(initialY);
} const isDragging = ref(false);
const size = ref(initialSize); let dragStartX;
let dragStartY;
let dragStartLength; let dragStartClientX;
let dragStartPosition; let dragStartClientY;
const position = direction === 'horizontal' ? 'clientX' : 'clientY';
/** /**
* Begins the tracking process for the drag resizer * Begins the tracking process for the drag resizer
@ -59,8 +59,11 @@ export function useDragResizer(direction = 'horizontal', { size: initialSize = 0
* @param {*} event the mousedown event * @param {*} event the mousedown event
*/ */
function mousedown(event) { function mousedown(event) {
dragStartLength = size.value; dragStartX = x.value;
dragStartPosition = event[position]; dragStartY = y.value;
dragStartClientX = event.clientX;
dragStartClientY = event.clientY;
isDragging.value = true;
document.addEventListener('mouseup', mouseup, { document.addEventListener('mouseup', mouseup, {
once: true, once: true,
@ -71,13 +74,19 @@ export function useDragResizer(direction = 'horizontal', { size: initialSize = 0
} }
function mousemove(event) { function mousemove(event) {
const delta = event[position] - dragStartPosition; const deltaX = event.clientX - dragStartClientX;
size.value = dragStartLength + delta; const deltaY = event.clientY - dragStartClientY;
x.value = dragStartX + deltaX;
y.value = dragStartY + deltaY;
} }
function mouseup(event) { function mouseup(event) {
dragStartLength = undefined; dragStartX = undefined;
dragStartPosition = undefined; dragStartY = undefined;
dragStartClientX = undefined;
dragStartClientY = undefined;
isDragging.value = false;
document.removeEventListener('mousemove', mousemove); document.removeEventListener('mousemove', mousemove);
event.preventDefault(); event.preventDefault();
@ -87,7 +96,9 @@ export function useDragResizer(direction = 'horizontal', { size: initialSize = 0
} }
return { return {
size, mousedown,
mousedown x,
y,
isDragging
}; };
} }