fix(calendar): zoom selected block first, then commit level

This commit is contained in:
Ruslan Bakiev
2026-02-23 14:56:11 +07:00
parent 40a225783d
commit ec94dd6e2a

View File

@@ -2695,6 +2695,70 @@ async function animateCalendarFlipTransition(
}
}
async function animateCalendarZoomIntoSource(
sourceElement: HTMLElement | null,
apply: () => void,
) {
clearCalendarZoomPrime();
calendarZoomBusy.value = true;
let restoreSiblings = () => {};
let snapshot: {
transform: string;
transition: string;
transformOrigin: string;
willChange: string;
zIndex: string;
} | null = null;
try {
const viewportRect = calendarContentScrollRef.value?.getBoundingClientRect() ?? null;
const sourceRect = sourceElement?.getBoundingClientRect() ?? null;
if (!sourceElement || !isRenderableRect(viewportRect) || !isRenderableRect(sourceRect)) {
apply();
return;
}
restoreSiblings = fadeOutCalendarSiblings(sourceElement);
snapshot = {
transform: sourceElement.style.transform,
transition: sourceElement.style.transition,
transformOrigin: sourceElement.style.transformOrigin,
willChange: sourceElement.style.willChange,
zIndex: sourceElement.style.zIndex,
};
const dx = viewportRect.left - sourceRect.left;
const dy = viewportRect.top - sourceRect.top;
const sx = Math.max(0.01, viewportRect.width / sourceRect.width);
const sy = Math.max(0.01, viewportRect.height / sourceRect.height);
sourceElement.style.transformOrigin = "top left";
sourceElement.style.willChange = "transform";
sourceElement.style.zIndex = "24";
sourceElement.style.transition = "none";
sourceElement.style.transform = "translate3d(0px, 0px, 0px) scale(1, 1)";
sourceElement.getBoundingClientRect();
await nextAnimationFrame();
sourceElement.style.transition = `transform ${CALENDAR_ZOOM_DURATION_MS}ms cubic-bezier(0.16, 0.86, 0.18, 1)`;
sourceElement.style.transform = `translate3d(${dx}px, ${dy}px, 0px) scale(${sx}, ${sy})`;
await waitForTransformTransition(sourceElement);
apply();
await nextTick();
await nextAnimationFrame();
} finally {
if (sourceElement && snapshot) {
sourceElement.style.transform = snapshot.transform;
sourceElement.style.transition = snapshot.transition;
sourceElement.style.transformOrigin = snapshot.transformOrigin;
sourceElement.style.willChange = snapshot.willChange;
sourceElement.style.zIndex = snapshot.zIndex;
}
restoreSiblings();
calendarZoomBusy.value = false;
}
}
function resolveMonthAnchor(event?: WheelEvent) {
const target = event?.target as HTMLElement | null;
const monthAttr = target?.closest<HTMLElement>("[data-calendar-month-index]")?.dataset.calendarMonthIndex;
@@ -2738,13 +2802,9 @@ async function zoomInCalendar(event?: Event) {
queryCalendarElement(`[data-calendar-month-index="${monthIndex}"]`) ??
queryCalendarElement("[data-calendar-month-index]");
if (maybePrimeWheelZoom(wheelEvent, calendarPrimeMonthToken(monthIndex))) return;
await animateCalendarFlipTransition(
sourceElement,
() => {
openYearMonth(monthIndex);
},
() => queryCalendarElement(`[data-calendar-month-index="${monthIndex}"]`),
);
await animateCalendarZoomIntoSource(sourceElement, () => {
openYearMonth(monthIndex);
});
return;
}
@@ -2757,14 +2817,9 @@ async function zoomInCalendar(event?: Event) {
queryCalendarElement("[data-calendar-week-start-key]") ??
queryCalendarElement("[data-calendar-day-key]");
if (maybePrimeWheelZoom(wheelEvent, calendarPrimeWeekToken(rowStartKey))) return;
const monthIndex = new Date(`${anchorDayKey}T00:00:00`).getMonth();
await animateCalendarFlipTransition(
sourceElement,
() => {
openWeekView(anchorDayKey);
},
() => queryCalendarElement(`[data-calendar-month-index="${monthIndex}"]`),
);
await animateCalendarZoomIntoSource(sourceElement, () => {
openWeekView(anchorDayKey);
});
return;
}
@@ -2772,25 +2827,16 @@ async function zoomInCalendar(event?: Event) {
const dayAnchor = resolveDayAnchor(wheelEvent);
const sourceElement = queryCalendarElement(`[data-calendar-day-key="${dayAnchor}"]`) ?? queryCalendarElement("[data-calendar-day-key]");
if (maybePrimeWheelZoom(wheelEvent, calendarPrimeDayToken(dayAnchor))) return;
const monthIndex = new Date(`${dayAnchor}T00:00:00`).getMonth();
await animateCalendarFlipTransition(
sourceElement,
() => {
openDayView(dayAnchor);
},
() => queryCalendarElement(`[data-calendar-month-index="${monthIndex}"]`),
);
await animateCalendarZoomIntoSource(sourceElement, () => {
openDayView(dayAnchor);
});
}
}
async function zoomToMonth(monthIndex: number) {
await animateCalendarFlipTransition(
queryCalendarElement(`[data-calendar-month-index="${monthIndex}"]`),
() => {
openYearMonth(monthIndex);
},
() => queryCalendarElement(`[data-calendar-month-index="${monthIndex}"]`),
);
await animateCalendarZoomIntoSource(queryCalendarElement(`[data-calendar-month-index="${monthIndex}"]`), () => {
openYearMonth(monthIndex);
});
}
async function zoomOutCalendar() {