feat: 氧化铝数字孪生系统监控大屏完成

This commit is contained in:
2026-04-08 21:44:08 +08:00
commit a48babc68d
67606 changed files with 3337335 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
const threshold = 50;
const maxSpeed = 25;
const overflowStyles = new Set(["auto", "scroll"]);
// Track initial scroll limits per scrollable element (Bug 1 fix)
const initialScrollLimits = new WeakMap();
const activeScrollEdge = new WeakMap();
// Track which group element is currently dragging to clear state on end
let currentGroupElement = null;
function resetAutoScrollState() {
if (currentGroupElement) {
const scrollableAncestor = findScrollableAncestor(currentGroupElement, "y");
if (scrollableAncestor) {
activeScrollEdge.delete(scrollableAncestor);
initialScrollLimits.delete(scrollableAncestor);
}
// Also try x axis
const scrollableAncestorX = findScrollableAncestor(currentGroupElement, "x");
if (scrollableAncestorX && scrollableAncestorX !== scrollableAncestor) {
activeScrollEdge.delete(scrollableAncestorX);
initialScrollLimits.delete(scrollableAncestorX);
}
currentGroupElement = null;
}
}
function isScrollableElement(element, axis) {
const style = getComputedStyle(element);
const overflow = axis === "x" ? style.overflowX : style.overflowY;
const isDocumentScroll = element === document.body ||
element === document.documentElement;
return overflowStyles.has(overflow) || isDocumentScroll;
}
function findScrollableAncestor(element, axis) {
let current = element?.parentElement;
while (current) {
if (isScrollableElement(current, axis)) {
return current;
}
current = current.parentElement;
}
return null;
}
function getScrollAmount(pointerPosition, scrollElement, axis) {
const rect = scrollElement.getBoundingClientRect();
const start = axis === "x" ? Math.max(0, rect.left) : Math.max(0, rect.top);
const end = axis === "x" ? Math.min(window.innerWidth, rect.right) : Math.min(window.innerHeight, rect.bottom);
const distanceFromStart = pointerPosition - start;
const distanceFromEnd = end - pointerPosition;
if (distanceFromStart < threshold) {
const intensity = 1 - distanceFromStart / threshold;
return { amount: -maxSpeed * intensity * intensity, edge: "start" };
}
else if (distanceFromEnd < threshold) {
const intensity = 1 - distanceFromEnd / threshold;
return { amount: maxSpeed * intensity * intensity, edge: "end" };
}
return { amount: 0, edge: null };
}
function autoScrollIfNeeded(groupElement, pointerPosition, axis, velocity) {
if (!groupElement)
return;
// Track the group element for cleanup
currentGroupElement = groupElement;
const scrollableAncestor = findScrollableAncestor(groupElement, axis);
if (!scrollableAncestor)
return;
// Convert pointer position from page coordinates to viewport coordinates.
// The gesture system uses pageX/pageY but getBoundingClientRect() returns
// viewport-relative coordinates, so we need to account for page scroll.
const viewportPointerPosition = pointerPosition - (axis === "x" ? window.scrollX : window.scrollY);
const { amount: scrollAmount, edge } = getScrollAmount(viewportPointerPosition, scrollableAncestor, axis);
// If not in any threshold zone, clear all state
if (edge === null) {
activeScrollEdge.delete(scrollableAncestor);
initialScrollLimits.delete(scrollableAncestor);
return;
}
const currentActiveEdge = activeScrollEdge.get(scrollableAncestor);
const isDocumentScroll = scrollableAncestor === document.body ||
scrollableAncestor === document.documentElement;
// If not currently scrolling this edge, check velocity to see if we should start
if (currentActiveEdge !== edge) {
// Only start scrolling if velocity is towards the edge
const shouldStart = (edge === "start" && velocity < 0) ||
(edge === "end" && velocity > 0);
if (!shouldStart)
return;
// Activate this edge
activeScrollEdge.set(scrollableAncestor, edge);
// Record initial scroll limit (prevents infinite scroll)
const maxScroll = axis === "x"
? scrollableAncestor.scrollWidth - (isDocumentScroll ? window.innerWidth : scrollableAncestor.clientWidth)
: scrollableAncestor.scrollHeight - (isDocumentScroll ? window.innerHeight : scrollableAncestor.clientHeight);
initialScrollLimits.set(scrollableAncestor, maxScroll);
}
// Cap scrolling at initial limit (prevents infinite scroll)
if (scrollAmount > 0) {
const initialLimit = initialScrollLimits.get(scrollableAncestor);
const currentScroll = axis === "x"
? (isDocumentScroll ? window.scrollX : scrollableAncestor.scrollLeft)
: (isDocumentScroll ? window.scrollY : scrollableAncestor.scrollTop);
if (currentScroll >= initialLimit)
return;
}
// Apply scroll
if (axis === "x") {
if (isDocumentScroll) {
window.scrollBy({ left: scrollAmount });
}
else {
scrollableAncestor.scrollLeft += scrollAmount;
}
}
else {
if (isDocumentScroll) {
window.scrollBy({ top: scrollAmount });
}
else {
scrollableAncestor.scrollTop += scrollAmount;
}
}
}
export { autoScrollIfNeeded, resetAutoScrollState };
//# sourceMappingURL=auto-scroll.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,25 @@
import { mixNumber } from 'motion-dom';
import { moveItem } from 'motion-utils';
function checkReorder(order, value, offset, velocity) {
if (!velocity)
return order;
const index = order.findIndex((item) => item.value === value);
if (index === -1)
return order;
const nextOffset = velocity > 0 ? 1 : -1;
const nextItem = order[index + nextOffset];
if (!nextItem)
return order;
const item = order[index];
const nextLayout = nextItem.layout;
const nextItemCenter = mixNumber(nextLayout.min, nextLayout.max, 0.5);
if ((nextOffset === 1 && item.layout.max + offset > nextItemCenter) ||
(nextOffset === -1 && item.layout.min + offset < nextItemCenter)) {
return moveItem(order, index, index + nextOffset);
}
return order;
}
export { checkReorder };
//# sourceMappingURL=check-reorder.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"check-reorder.mjs","sources":["../../../../../src/components/Reorder/utils/check-reorder.ts"],"sourcesContent":["import { mixNumber } from \"motion-dom\"\nimport { moveItem } from \"motion-utils\"\nimport { ItemData } from \"../types\"\n\nexport function checkReorder<T>(\n order: ItemData<T>[],\n value: T,\n offset: number,\n velocity: number\n): ItemData<T>[] {\n if (!velocity) return order\n\n const index = order.findIndex((item) => item.value === value)\n\n if (index === -1) return order\n\n const nextOffset = velocity > 0 ? 1 : -1\n const nextItem = order[index + nextOffset]\n\n if (!nextItem) return order\n\n const item = order[index]\n const nextLayout = nextItem.layout\n const nextItemCenter = mixNumber(nextLayout.min, nextLayout.max, 0.5)\n\n if (\n (nextOffset === 1 && item.layout.max + offset > nextItemCenter) ||\n (nextOffset === -1 && item.layout.min + offset < nextItemCenter)\n ) {\n return moveItem(order, index, index + nextOffset)\n }\n\n return order\n}\n"],"names":[],"mappings":";;;AAIM,SAAU,YAAY,CACxB,KAAoB,EACpB,KAAQ,EACR,MAAc,EACd,QAAgB,EAAA;AAEhB,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,KAAK;AAE3B,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;IAE7D,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,KAAK;AAE9B,IAAA,MAAM,UAAU,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE;IACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC;AAE1C,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,KAAK;AAE3B,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;AACzB,IAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM;AAClC,IAAA,MAAM,cAAc,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;AAErE,IAAA,IACI,CAAC,UAAU,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,GAAG,cAAc;AAC9D,SAAC,UAAU,KAAK,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,GAAG,cAAc,CAAC,EAClE;QACE,OAAO,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU,CAAC;IACrD;AAEA,IAAA,OAAO,KAAK;AAChB;;;;"}