timeline and skill dragin improvments
This commit is contained in:
parent
d0f54049e6
commit
3276e3bfb3
@ -723,6 +723,12 @@
|
|||||||
background: var(--bg1);
|
background: var(--bg1);
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
cursor: grab;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-scroll--dragging {
|
||||||
|
cursor: grabbing;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-grid {
|
.timeline-grid {
|
||||||
|
|||||||
@ -1002,7 +1002,59 @@ function initTimeline(planId) {
|
|||||||
const settings = document.getElementById('timeline-settings');
|
const settings = document.getElementById('timeline-settings');
|
||||||
if (!timeline || !settings) return;
|
if (!timeline || !settings) return;
|
||||||
|
|
||||||
|
let timelinePan = null;
|
||||||
|
let suppressNextTimelineClick = false;
|
||||||
|
|
||||||
|
timeline.addEventListener('pointerdown', e => {
|
||||||
|
if (e.button !== 0) return;
|
||||||
|
if (!e.target.closest('.timeline-scroll')) return;
|
||||||
|
if (e.target.closest('.timeline-mitigation, .timeline-boss-action, .timeline-context-menu')) return;
|
||||||
|
|
||||||
|
const scroll = e.target.closest('.timeline-scroll');
|
||||||
|
timelinePan = {
|
||||||
|
scroll,
|
||||||
|
pointerId: e.pointerId,
|
||||||
|
startX: e.clientX,
|
||||||
|
startScrollLeft: scroll.scrollLeft,
|
||||||
|
moved: false,
|
||||||
|
};
|
||||||
|
scroll.setPointerCapture?.(e.pointerId);
|
||||||
|
});
|
||||||
|
|
||||||
|
timeline.addEventListener('pointermove', e => {
|
||||||
|
if (!timelinePan || timelinePan.pointerId !== e.pointerId) return;
|
||||||
|
const dx = e.clientX - timelinePan.startX;
|
||||||
|
if (Math.abs(dx) > 3) {
|
||||||
|
timelinePan.moved = true;
|
||||||
|
timelinePan.scroll.classList.add('timeline-scroll--dragging');
|
||||||
|
timelinePan.scroll.scrollLeft = timelinePan.startScrollLeft - dx;
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
timeline.addEventListener('pointerup', e => {
|
||||||
|
if (!timelinePan || timelinePan.pointerId !== e.pointerId) return;
|
||||||
|
timelinePan.scroll.releasePointerCapture?.(e.pointerId);
|
||||||
|
timelinePan.scroll.classList.remove('timeline-scroll--dragging');
|
||||||
|
suppressNextTimelineClick = timelinePan.moved;
|
||||||
|
timelinePan = null;
|
||||||
|
if (suppressNextTimelineClick) setTimeout(() => { suppressNextTimelineClick = false; }, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
timeline.addEventListener('pointercancel', e => {
|
||||||
|
if (!timelinePan || timelinePan.pointerId !== e.pointerId) return;
|
||||||
|
timelinePan.scroll.releasePointerCapture?.(e.pointerId);
|
||||||
|
timelinePan.scroll.classList.remove('timeline-scroll--dragging');
|
||||||
|
timelinePan = null;
|
||||||
|
});
|
||||||
|
|
||||||
timeline.addEventListener('click', e => {
|
timeline.addEventListener('click', e => {
|
||||||
|
if (suppressNextTimelineClick) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
suppressNextTimelineClick = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
closeTimelineMenu();
|
closeTimelineMenu();
|
||||||
const boss = e.target.closest('.timeline-boss-action');
|
const boss = e.target.closest('.timeline-boss-action');
|
||||||
if (boss) {
|
if (boss) {
|
||||||
@ -1063,11 +1115,20 @@ function initTimeline(planId) {
|
|||||||
timeline.addEventListener('dragstart', e => {
|
timeline.addEventListener('dragstart', e => {
|
||||||
const block = e.target.closest('.timeline-mitigation');
|
const block = e.target.closest('.timeline-mitigation');
|
||||||
if (!block) return;
|
if (!block) return;
|
||||||
|
const plan = getPlan(planId);
|
||||||
|
const found = findTimelineAssignment(plan, {
|
||||||
|
mechanicId: block.dataset.mechanicId,
|
||||||
|
ability: block.dataset.ability,
|
||||||
|
job: block.dataset.job,
|
||||||
|
});
|
||||||
|
if (!plan || !found) return;
|
||||||
e.dataTransfer.effectAllowed = 'move';
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
e.dataTransfer.setData('text/plain', JSON.stringify({
|
e.dataTransfer.setData('text/plain', JSON.stringify({
|
||||||
mechanicId: block.dataset.mechanicId,
|
mechanicId: block.dataset.mechanicId,
|
||||||
ability: block.dataset.ability,
|
ability: block.dataset.ability,
|
||||||
job: block.dataset.job,
|
job: block.dataset.job,
|
||||||
|
startClientX: e.clientX,
|
||||||
|
startTimestamp: assignmentStartMs(found.mechanic, found.assignment),
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1086,8 +1147,9 @@ function initTimeline(planId) {
|
|||||||
const plan = getPlan(planId);
|
const plan = getPlan(planId);
|
||||||
if (!plan) return;
|
if (!plan) return;
|
||||||
const rect = track.getBoundingClientRect();
|
const rect = track.getBoundingClientRect();
|
||||||
const x = Math.max(0, Math.min(rect.width, e.clientX - rect.left));
|
const deltaPx = e.clientX - (Number(data.startClientX) || e.clientX);
|
||||||
const timestamp = (x / rect.width) * planDurationMs(plan);
|
const timestampDelta = (deltaPx / rect.width) * planDurationMs(plan);
|
||||||
|
const timestamp = (Number(data.startTimestamp) || 0) + timestampDelta;
|
||||||
if (row.dataset.ability && data.ability !== row.dataset.ability) return;
|
if (row.dataset.ability && data.ability !== row.dataset.ability) return;
|
||||||
updateTimelineAssignmentPosition(planId, data.mechanicId, data.ability, data.job, row.dataset.job, timestamp);
|
updateTimelineAssignmentPosition(planId, data.mechanicId, data.ability, data.job, row.dataset.job, timestamp);
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user