OpenClaw 的横竖屏适配主要针对移动端应用,以下是完整的适配方案

openclaw 中文openclaw 2

HTML Viewport 设置

<meta name="viewport" 
      content="width=device-width, 
               initial-scale=1.0, 
               minimum-scale=1.0, 
               maximum-scale=1.0, 
               user-scalable=no,
               viewport-fit=cover">

CSS 媒体查询适配

基于方向检测

/* 竖屏样式 */
@media screen and (orientation: portrait) {
  .openclaw-container {
    flex-direction: column;
  }
  .toolbar {
    height: 50px;
    width: 100%;
  }
  .content-area {
    height: calc(100vh - 50px);
  }
}
/* 横屏样式 */
@media screen and (orientation: landscape) {
  .openclaw-container {
    flex-direction: row;
  }
  .toolbar {
    width: 60px;
    height: 100%;
  }
  .content-area {
    width: calc(100vw - 60px);
  }
  /* 横屏时可能需要调整字体大小 */
  body {
    font-size: 14px;
  }
}

JavaScript 方向检测与处理

// 检测屏幕方向
function detectOrientation() {
  const isPortrait = window.innerHeight > window.innerWidth;
  const orientation = screen.orientation || {};
  return {
    isPortrait,
    isLandscape: !isPortrait,
    angle: orientation.angle || 0,
    type: orientation.type || (isPortrait ? 'portrait' : 'landscape')
  };
}
// 监听方向变化
function setupOrientationListeners() {
  // 标准方式
  if (screen.orientation) {
    screen.orientation.addEventListener('change', handleOrientationChange);
  } 
  // 回退方案
  else {
    window.addEventListener('resize', handleOrientationChange);
    window.addEventListener('orientationchange', handleOrientationChange);
  }
}
// 方向变化处理
function handleOrientationChange() {
  const orientation = detectOrientation();
  // 添加/移除 CSS 类
  document.body.classList.toggle('portrait', orientation.isPortrait);
  document.body.classList.toggle('landscape', orientation.isLandscape);
  // 触发自定义事件
  const event = new CustomEvent('orientationchange', {
    detail: { orientation }
  });
  window.dispatchEvent(event);
  // 更新 UI 布局
  updateLayoutForOrientation(orientation);
}
// 初始化
window.addEventListener('DOMContentLoaded', () => {
  setupOrientationListeners();
  handleOrientationChange(); // 初始检测
});

React/Vue 适配方案

React 示例

import { useState, useEffect } from 'react';
function useOrientation() {
  const [orientation, setOrientation] = useState({
    isPortrait: window.innerHeight > window.innerWidth,
    isLandscape: window.innerWidth > window.innerHeight
  });
  useEffect(() => {
    const handleResize = () => {
      setOrientation({
        isPortrait: window.innerHeight > window.innerWidth,
        isLandscape: window.innerWidth > window.innerHeight
      });
    };
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  return orientation;
}
// 使用组件
function OpenClawApp() {
  const { isPortrait } = useOrientation();
  return (
    <div className={`openclaw-app ${isPortrait ? 'portrait' : 'landscape'}`}>
      {isPortrait ? (
        <MobileLayout />
      ) : (
        <DesktopLayout />
      )}
    </div>
  );
}

响应式布局策略

Flexbox 布局适配

.openclaw-wrapper {
  display: flex;
  min-height: 100vh;
}
/* 竖屏:垂直排列 */
@media (orientation: portrait) {
  .openclaw-wrapper {
    flex-direction: column;
  }
  .sidebar {
    width: 100%;
    height: 60px;
    order: 1;
  }
  .main-content {
    flex: 1;
    order: 2;
  }
}
/* 横屏:水平排列 */
@media (orientation: landscape) {
  .openclaw-wrapper {
    flex-direction: row;
  }
  .sidebar {
    width: 200px;
    height: 100vh;
    order: 1;
  }
  .main-content {
    flex: 1;
    order: 2;
  }
}

特殊场景处理

键盘弹出处理(移动端)

// 检测虚拟键盘状态
function handleKeyboard() {
  const originalHeight = window.innerHeight;
  window.addEventListener('resize', () => {
    const currentHeight = window.innerHeight;
    const keyboardVisible = currentHeight < originalHeight;
    if (keyboardVisible) {
      // 键盘弹出时调整布局
      document.body.classList.add('keyboard-open');
    } else {
      document.body.classList.remove('keyboard-open');
    }
  });
}

安全区域适配(全面屏)

/* 适配刘海屏、圆角等 */
.safe-area {
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}
/* 横屏时的安全区域 */
@media (orientation: landscape) {
  .toolbar {
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }
}

性能优化建议

  1. 防抖处理

    OpenClaw 的横竖屏适配主要针对移动端应用,以下是完整的适配方案-第1张图片-OpenClaw下载中文-AI中文智能体

    const debouncedOrientationChange = debounce(handleOrientationChange, 200);
    window.addEventListener('resize', debouncedOrientationChange);
  2. CSS 硬件加速

    .transform-element {
    will-change: transform;
    transform: translateZ(0);
    }
  3. 懒加载资源

    // 根据方向加载不同资源
    function loadOrientationAssets(orientation) {
    if (orientation.isLandscape) {
     // 加载横屏专用资源
     import('./landscape-components.js');
    }
    }

测试工具

// 开发调试工具
function orientationDebug() {
  console.log({
    width: window.innerWidth,
    height: window.innerHeight,
    orientation: detectOrientation(),
    devicePixelRatio: window.devicePixelRatio
  });
}
// 模拟不同设备
function simulateDevice(deviceType) {
  const devices = {
    iphone: { width: 375, height: 812 },
    ipad: { width: 1024, height: 1366 }
  };
  // 在开发环境中模拟
  if (process.env.NODE_ENV === 'development') {
    Object.assign(window, {
      innerWidth: devices[deviceType].width,
      innerHeight: devices[deviceType].height
    });
    handleOrientationChange();
  }
}

注意事项

  1. 保持功能一致性:横竖屏下核心功能应保持一致
  2. 状态保持:切换方向时应保持用户操作状态
  3. 动画过渡:方向切换时添加合适的过渡动画
  4. 测试覆盖:在所有目标设备上测试横竖屏表现
  5. 后备方案:提供用户手动锁定方向的选项
// 锁定方向(如果应用支持)
function lockOrientation(mode) {
  if (screen.orientation && screen.orientation.lock) {
    screen.orientation.lock(mode)
      .catch(err => console.log('Orientation lock failed:', err));
  }
}

这个方案覆盖了 OpenClaw 横竖屏适配的主要方面,可根据具体需求进行调整和扩展。

标签: OpenClaw 横竖屏适配

抱歉,评论功能暂时关闭!