UNPKG

svelte-gantt

Version:

Interactive JavaScript Gantt chart/resource booking component

140 lines (139 loc) 4.75 kB
import { getRelativePos, getRelativePosition } from '../utils/dom'; import { getContext } from 'svelte'; export function useCreateTask() { const { columnService, utils } = getContext('services'); return function createTaskActionBound(node, options) { return createTaskAction(node, { columnService, utils, ...options, }); }; } const MIN_DRAG_X = 2; const MIN_DRAG_Y = 2; function createTaskAction(node, options) { let startX; let startFrom; let mouseStartRight; let direction; let initialX; let initialY; let triggered = false; /** dragging will not activate around the edges */ let deadZone = 10; const container = () => options.container; function isNearEdge(x, y) { const rect = options.boundsContainer.getBoundingClientRect(); const nearBottomEdge = y - rect.top >= rect.height - deadZone; const nearRightEdge = x - rect.left >= rect.width - deadZone; return nearBottomEdge || nearRightEdge; } function onMousedown(event) { if (!options.enabled) { return; } event.stopPropagation(); event.preventDefault(); if (isNearEdge(event.clientX, event.clientY)) { return; } const [mousePosX, _] = getRelativePosition(container(), event); const from = startFrom = options.utils.roundTo(options.columnService.getDateByPosition(mousePosX)); const x = startX = options.columnService.getPositionByDate(from) | 0; const width = 0; initialX = event.clientX; initialY = event.clientY; mouseStartRight = x + width; window.addEventListener('pointermove', onMousemove, false); window.addEventListener('pointerup', onMouseup); } ; function onMousemove(event) { if (!triggered) { if (Math.abs(event.clientX - initialX) > MIN_DRAG_X || Math.abs(event.clientY - initialY) > MIN_DRAG_Y) { triggered = true; } else { return; } } event.preventDefault(); const { x, width, y } = getValues(event); options.onMove({ from: startFrom, to: startFrom, x, width, y, }); } ; function getValues(event) { const mousePos = getRelativePos(container(), event); const x = startX; const width = 0; let resultX; let resultWidth; if (direction === 'left') { if (mouseStartRight - mousePos.x <= 0) { direction = 'right'; resultX = mouseStartRight; resultWidth = mouseStartRight - mousePos.x; mouseStartRight = mouseStartRight + width; } else { resultX = mousePos.x; resultWidth = mouseStartRight - mousePos.x; } } else { // if (direction === 'right') //resize right if (mousePos.x - x <= 0) { direction = 'left'; resultX = mousePos.x; resultWidth = mousePos.x - x; mouseStartRight = x; } else { resultX = x; resultWidth = mousePos.x - x; } } return { x: resultX, width: resultWidth, y: mousePos.y }; } function onMouseup(event) { window.removeEventListener('pointerup', onMouseup); window.removeEventListener('pointermove', onMousemove, false); if (triggered) { const { x, width, y } = getValues(event); const newFrom = options.utils.roundTo(options.columnService.getDateByPosition(x)); const newTo = options.utils.roundTo(options.columnService.getDateByPosition(x + width)); const newLeft = options.columnService.getPositionByDate(newFrom) | 0; const newRight = options.columnService.getPositionByDate(newTo) | 0; options.onEnd({ from: newFrom, to: newTo, x: newLeft, width: newRight - newLeft, y, }); } mouseStartRight = null; initialX = null; initialY = null; triggered = false; } ; node.addEventListener('pointerdown', onMousedown); return { destroy() { node.removeEventListener('pointerdown', onMousedown); window.removeEventListener('pointermove', onMousemove); window.removeEventListener('pointerup', onMouseup); }, update(opts) { Object.assign(options, opts); }, }; }