Skip to content

移动端与横屏

Yotsuba Gantt 把“组件交互”和“设备方向”分开处理:组件负责时间轴、任务与手势,是否进入全屏或锁定横屏由宿主应用在用户操作后决定。这样不会在页面加载时打断系统方向设置,也能在不支持方向锁定的浏览器中安全回退。

Web 横屏入口

演示应用的横屏按钮采用渐进增强:

  1. 用户点击后请求 requestFullscreen()
  2. 浏览器支持时调用 screen.orientation.lock('landscape')
  3. 任一步不支持时保留 CSS 沉浸布局,扩大甘特图工作区,但不会宣称系统已完成旋转。
  4. 用户退出、按 Esc 或应用卸载时恢复原布局并解除方向锁定。

方向 API 需要安全上下文和用户手势。组件包不会自动调用这些 API,宿主可以复制演示应用的入口,也可以接入现有的全屏管理器。

Web 双指缩放

YgGantt 默认只在时间轴区域识别双指缩放。单指横向滚动、纵向滚动、任务拖动和分栏调整保持原有行为。

vue
<YgGantt
  :tasks="tasks"
  :enable-pinch-zoom="true"
  :pinch-zoom-threshold="0.16"
  :pinch-zoom-cooldown="420"
  :auto-focus="{ enabled: true, strategy: 'dense', onViewChange: true }"
/>

达到阈值后只切换一个相邻维度,并进入冷却期。维度变化继续使用 autoFocus,因此 10K 数据模式不会回到空白日期段。关闭 enablePinchZoom 后,浏览器恢复自己的默认触控处理。

Flutter 与 Android

Flutter Widget 同样不主动改变设备方向。示例应用在 AppBar 中调用 SystemChrome.setPreferredOrientations,横屏时进入 immersiveSticky,退出页面时恢复全部方向和 edgeToEdge

dart
YotsubaGantt(
  tasks: tasks,
  viewMode: viewMode,
  autoFocus: YgAutoFocus.dense,
  enableScaleGesture: true,
  scaleGestureThreshold: 0.16,
  scaleGestureCooldown: const Duration(milliseconds: 420),
  onViewModeChanged: (next) => setState(() => viewMode = next),
)

组件使用原始触控指针识别双指距离,不加入单指手势竞争,因此 ScrollView 和任务条拖动仍由 Flutter 的手势系统处理。横屏下示例展示完整维度控制;窄竖屏改用下拉选择,避免六段控件溢出。

触控验收清单

  • 所有主要按钮在窄屏下至少保留 40px 触控区域。
  • 双指缩放不会连续跨越多档,也不会触发任务移动提交。
  • 任务拖动被系统中断时清理预览状态,不产生一次错误的 task-change
  • 刘海屏与系统栏由宿主的 SafeArea、全屏模式和方向策略共同管理。
  • Android 返回键、浏览器 Esc 和横屏退出按钮都能恢复非沉浸布局。

MIT License · Vue / React / Flutter