diff --git a/uniapp/youjiala/src/components/family-tree-chart/family-tree-chart.vue b/uniapp/youjiala/src/components/family-tree-chart/family-tree-chart.vue index bdda11d..619fa32 100644 --- a/uniapp/youjiala/src/components/family-tree-chart/family-tree-chart.vue +++ b/uniapp/youjiala/src/components/family-tree-chart/family-tree-chart.vue @@ -275,6 +275,81 @@ function toggleDirection(): void { vertical.value = !vertical.value; } +// ===== 控制条可拖拽:按住顶部握把行挪位(拖拽热区只在握把,不碰动作钮), +// ctrlOffset 为整条相对默认右上锚点的位移 ===== +const ctrlOffset = ref({ x: 0, y: 0 }); +let dragStart: { tx: number; ty: number; ox: number; oy: number } | null = null; + +function onCtrlTouchStart(e: TouchEvent): void { + const t0 = e.touches?.[0]; + if (!t0) { + return; + } + dragStart = { tx: t0.clientX, ty: t0.clientY, ox: ctrlOffset.value.x, oy: ctrlOffset.value.y }; +} + +function onCtrlTouchMove(e: TouchEvent): void { + const t0 = e.touches?.[0]; + if (!dragStart || !t0) { + return; + } + const sys = uni.getSystemInfoSync(); + const barW = uni.upx2px(88); + const barH = uni.upx2px(384); // 握把 + 4 动作钮各 76 + 分隔线 + const edge = uni.upx2px(16); + // 默认锚点(top/right 定位)换算成 left/top 基准,再按屏幕边界夹取 + const baseLeft = sys.windowWidth - uni.upx2px(24) - barW; + const baseTop = uni.upx2px(120) + (sys.safeAreaInsets?.top || 0); + const minX = edge - baseLeft; + const maxX = sys.windowWidth - edge - barW - baseLeft; + const minY = edge + uni.upx2px(110) + (sys.safeAreaInsets?.top || 0) - baseTop; + const maxY = sys.windowHeight - edge - barH - baseTop; + ctrlOffset.value = { + x: Math.min(Math.max(dragStart.ox + t0.clientX - dragStart.tx, minX), maxX), + y: Math.min(Math.max(dragStart.oy + t0.clientY - dragStart.ty, minY), maxY), + }; +} + +function onCtrlTouchEnd(): void { + dragStart = null; +} + +// ===== 双指捏合缩放:画布触摸层两指距离比换算 zoom(5% 步进,比 ± 钮细腻)===== +let pinchStartDist = 0; +let pinchStartZoom = 1; + +function touchGap(t0: Touch, t1: Touch): number { + return Math.hypot(t1.clientX - t0.clientX, t1.clientY - t0.clientY); +} + +function onChartTouchStart(e: TouchEvent): void { + if (e.touches?.length === 2) { + pinchStartDist = touchGap(e.touches[0], e.touches[1]); + pinchStartZoom = zoom.value; + } else { + pinchStartDist = 0; + } +} + +function onChartTouchMove(e: TouchEvent): void { + if (e.touches?.length !== 2 || pinchStartDist <= 0) { + return; + } + const ratio = touchGap(e.touches[0], e.touches[1]) / pinchStartDist; + const next = Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, Math.round(pinchStartZoom * ratio * 20) / 20)); + if (next !== zoom.value) { + // H5:捏合期间拦掉默认滚动,避免双指被 scroll-view 当成拖动 + e.preventDefault?.(); + zoom.value = next; + } +} + +function onChartTouchEnd(e: TouchEvent): void { + if (!e.touches || e.touches.length < 2) { + pinchStartDist = 0; + } +} + function requestLoad(personId: string): void { emit("select-child", personId); } @@ -457,15 +532,18 @@ function close(): void { {{ props.title || t('FamilyTreePage.pedigreeChart') }} - - - - {{ t("FamilyTreePage.cancel") }} - + + + - - + + + + ⠿ + + @@ -479,7 +557,9 @@ function close(): void { ⇅ - + + @@ -518,18 +598,17 @@ function close(): void { color: #1f2329; } -.ftc__cancel { - padding: 12rpx 40rpx; - border-radius: 999rpx; +.ftc__close { + display: flex; + align-items: center; + justify-content: center; + width: 64rpx; + height: 64rpx; + border-radius: 50%; background-color: #f2f3f5; } -.ftc__cancel-text { - font-size: 26rpx; - color: #5c626b; -} - -/* 悬浮控制条:右侧竖排,白底圆角轻阴影 */ +/* 悬浮控制条:右侧竖排,白底圆角轻阴影;整条可拖拽(见 ctrlOffset) */ .ftc__ctrl { position: absolute; top: calc(120rpx + env(safe-area-inset-top)); @@ -543,6 +622,24 @@ function close(): void { box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.12); } +/* 顶部握把行:拖拽热区(touch-action:none 只加在这里,动作钮手势不受影响); + 与动作钮等高,手指易按住 */ +.ftc__ctrl-grip { + display: flex; + align-items: center; + justify-content: center; + height: 76rpx; + border-bottom: 2rpx solid #f2f3f5; + cursor: move; + touch-action: none; +} + +.ftc__ctrl-grip-dot { + font-size: 22rpx; + line-height: 1; + color: #c0c4cc; +} + .ftc__ctrl-btn { display: flex; align-items: center; diff --git a/uniapp/youjiala/src/components/family-tree-home/family-tree-home.vue b/uniapp/youjiala/src/components/family-tree-home/family-tree-home.vue new file mode 100644 index 0000000..1606619 --- /dev/null +++ b/uniapp/youjiala/src/components/family-tree-home/family-tree-home.vue @@ -0,0 +1,1730 @@ + + +