OpenClaw 是一个用于多指触摸手势识别的库,横竖屏适配主要涉及布局和交互的调整。以下是完整的横竖屏适配方案

openclaw openclaw解答 1

CSS 媒体查询适配

/* 竖屏样式 */
@media (orientation: portrait) {
  .openclaw-container {
    width: 100vw;
    height: 60vh;
    /* 竖屏下的手势区域布局 */
  }
  .gesture-panel {
    grid-template-columns: repeat(2, 1fr);
  }
}
/* 横屏样式 */
@media (orientation: landscape) {
  .openclaw-container {
    width: 80vw;
    height: 80vh;
    margin: 0 auto;
  }
  .gesture-panel {
    grid-template-columns: repeat(4, 1fr);
  }
}
/* 响应式基础样式 */
.openclaw-container {
  touch-action: none; /* 防止浏览器默认手势 */
  user-select: none;
  position: relative;
}

JavaScript 方向监听与适配

class OpenClawOrientationAdapter {
  constructor(options = {}) {
    this.options = {
      onOrientationChange: null,
      portraitConfig: {
        maxFingers: 4,
        gestureThreshold: 30,
        // 竖屏特定配置
      },
      landscapeConfig: {
        maxFingers: 5,
        gestureThreshold: 40,
        // 横屏特定配置
      },
      ...options
    };
    this.currentOrientation = this.getOrientation();
    this.init();
  }
  // 获取当前方向
  getOrientation() {
    return window.innerWidth > window.innerHeight ? 'landscape' : 'portrait';
  }
  // 初始化 OpenClaw 实例
  init() {
    const config = this.currentOrientation === 'portrait' 
      ? this.options.portraitConfig 
      : this.options.landscapeConfig;
    this.openclaw = new OpenClaw({
      element: document.getElementById('touch-area'),
      maxFingers: config.maxFingers,
      threshold: config.gestureThreshold,
      onGesture: this.handleGesture.bind(this),
      // 其他配置...
    });
    this.setupOrientationListeners();
  }
  // 设置方向监听
  setupOrientationListeners() {
    // 监听窗口大小变化(包含方向变化)
    let resizeTimer;
    window.addEventListener('resize', () => {
      clearTimeout(resizeTimer);
      resizeTimer = setTimeout(() => {
        this.handleOrientationChange();
      }, 150);
    });
    // 监听设备方向变化(移动设备)
    if (window.screen.orientation) {
      window.screen.orientation.addEventListener('change', () => {
        this.handleOrientationChange();
      });
    }
    // 监听 orientationchange 事件
    window.addEventListener('orientationchange', () => {
      setTimeout(() => this.handleOrientationChange(), 100);
    });
  }
  // 处理方向变化
  handleOrientationChange() {
    const newOrientation = this.getOrientation();
    if (newOrientation !== this.currentOrientation) {
      this.currentOrientation = newOrientation;
      this.updateOpenClawConfig();
      // 触发回调
      if (this.options.onOrientationChange) {
        this.options.onOrientationChange(newOrientation);
      }
    }
  }
  // 更新 OpenClaw 配置
  updateOpenClawConfig() {
    const config = this.currentOrientation === 'portrait' 
      ? this.options.portraitConfig 
      : this.options.landscapeConfig;
    // 重新配置 OpenClaw
    this.openclaw.updateConfig(config);
    // 更新 UI 布局
    this.updateUILayout();
  }
  // 更新 UI 布局
  updateUILayout() {
    const container = document.querySelector('.openclaw-container');
    const isPortrait = this.currentOrientation === 'portrait';
    // 调整布局
    if (isPortrait) {
      container.classList.add('portrait-mode');
      container.classList.remove('landscape-mode');
    } else {
      container.classList.add('landscape-mode');
      container.classList.remove('portrait-mode');
    }
    // 调整手势区域大小
    this.adjustTouchArea();
  }
  // 调整触摸区域
  adjustTouchArea() {
    const touchArea = document.getElementById('touch-area');
    const rect = touchArea.getBoundingClientRect();
    // 通知 OpenClaw 区域变化
    this.openclaw.setBounds(rect);
  }
  // 手势处理
  handleGesture(gesture) {
    // 根据方向调整手势处理逻辑
    const adjustedGesture = this.adjustGestureForOrientation(gesture);
    // 执行手势动作
    this.executeGesture(adjustedGesture);
  }
  // 根据方向调整手势数据
  adjustGestureForOrientation(gesture) {
    const isPortrait = this.currentOrientation === 'portrait';
    if (isPortrait) {
      // 竖屏下的手势调整
      return {
        ...gesture,
        // 调整坐标或阈值
      };
    } else {
      // 横屏下的手势调整
      return {
        ...gesture,
        // 调整坐标或阈值
      };
    }
  }
}

React/Vue 组件适配示例

React 示例:

import React, { useEffect, useState } from 'react';
import OpenClaw from 'openclaw';
const OpenClawComponent = () => {
  const [orientation, setOrientation] = useState(
    window.innerWidth > window.innerHeight ? 'landscape' : 'portrait'
  );
  const [openclaw, setOpenclaw] = useState(null);
  useEffect(() => {
    // 初始化 OpenClaw
    const claw = new OpenClaw({
      element: document.getElementById('touch-area'),
      ...getConfigByOrientation(orientation)
    });
    setOpenclaw(claw);
    // 监听方向变化
    const handleResize = () => {
      const newOrientation = window.innerWidth > window.innerHeight 
        ? 'landscape' 
        : 'portrait';
      if (newOrientation !== orientation) {
        setOrientation(newOrientation);
        claw.updateConfig(getConfigByOrientation(newOrientation));
      }
    };
    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
      claw.destroy();
    };
  }, [orientation]);
  const getConfigByOrientation = (orient) => {
    return orient === 'portrait' 
      ? { maxFingers: 4, threshold: 30 }
      : { maxFingers: 5, threshold: 40 };
  };
  return (
    <div className={`openclaw-wrapper ${orientation}`}>
      <div 
        id="touch-area"
        className={`touch-area ${orientation}`}
        style={orientation === 'portrait' 
          ? { height: '60vh' }
          : { height: '80vh' }
        }
      />
      <div className="gesture-hints">
        {orientation === 'portrait' 
          ? '竖屏手势提示' 
          : '横屏手势提示'
        }
      </div>
    </div>
  );
};

移动端特定适配

// 移动端横竖屏适配增强
class MobileOpenClawAdapter extends OpenClawOrientationAdapter {
  constructor(options) {
    super(options);
    // 处理 iOS 和 Android 的差异
    this.isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
    this.isAndroid = /Android/.test(navigator.userAgent);
    this.setupMobileSpecifics();
  }
  setupMobileSpecifics() {
    // 防止双击缩放
    document.addEventListener('touchstart', (e) => {
      if (e.touches.length > 1) {
        e.preventDefault();
      }
    }, { passive: false });
    // 处理移动端键盘弹出
    if (this.isIOS) {
      this.handleIOSKeyboard();
    }
  }
  handleIOSKeyboard() {
    // iOS 键盘弹出时调整布局
    window.addEventListener('focusin', () => {
      this.pauseGestures();
    });
    window.addEventListener('focusout', () => {
      this.resumeGestures();
    });
  }
  pauseGestures() {
    if (this.openclaw) {
      this.openclaw.disable();
    }
  }
  resumeGestures() {
    if (this.openclaw) {
      this.openclaw.enable();
      this.adjustTouchArea();
    }
  }
}

最佳实践建议

  1. 测试策略

    OpenClaw 是一个用于多指触摸手势识别的库,横竖屏适配主要涉及布局和交互的调整。以下是完整的横竖屏适配方案-第1张图片-OpenClaw下载官网 - OpenClaw电脑版 | ai小龙虾

    // 在开发和测试阶段添加方向切换测试
    function addOrientationTestButtons() {
      const testDiv = document.createElement('div');
      testDiv.innerHTML = `
        <button onclick="switchToPortrait()">模拟竖屏</button>
        <button onclick="switchToLandscape()">模拟横屏</button>
      `;
      document.body.appendChild(testDiv);
    }
    function switchToPortrait() {
      window.innerWidth = 375;
      window.innerHeight = 667;
      window.dispatchEvent(new Event('resize'));
    }
    function switchToLandscape() {
      window.innerWidth = 667;
      window.innerHeight = 375;
      window.dispatchEvent(new Event('resize'));
    }
  2. 性能优化

    // 防抖处理方向变化
    const debouncedOrientationChange = debounce(() => {
      // 更新逻辑
    }, 250);
  3. CSS 变量动态调整

    :root {
      --openclaw-max-fingers: 4;
      --openclaw-threshold: 30px;
    }
    @media (orientation: landscape) {
      :root {
        --openclaw-max-fingers: 5;
        --openclaw-threshold: 40px;
      }
    }

这样适配后,OpenClaw 可以在不同屏幕方向上提供一致的手势体验,同时确保布局和交互的合理性。

标签: OpenClaw 横竖屏适配

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