我来介绍几种常见的大屏适配方案

openclaw AI使用帮助 3

CSS媒体查询 + 弹性布局

/* 基准样式 - 1920x1080设计稿 */
.container {
  width: 100vw;
  height: 100vh;
}
/* 超宽屏适配 (2560x1440) */
@media screen and (min-width: 2400px) {
  html {
    font-size: 18px;
  }
  .chart-container {
    transform: scale(1.2);
    transform-origin: 0 0;
  }
}
/* 宽屏适配 (1920x1080) */
@media screen and (min-width: 1800px) and (max-width: 2399px) {
  html {
    font-size: 16px;
  }
}
/* 中等屏幕 (1600x900) */
@media screen and (min-width: 1400px) and (max-width: 1799px) {
  html {
    font-size: 14px;
  }
}
/* 小屏适配 (1366x768) */
@media screen and (max-width: 1399px) {
  html {
    font-size: 12px;
  }
}

缩放方案(推荐)

// utils/screenAdapter.js
export class ScreenAdapter {
  constructor(options = {}) {
    this.designWidth = options.designWidth || 1920
    this.designHeight = options.designHeight || 1080
    this.init()
  }
  init() {
    this.updateScale()
    window.addEventListener('resize', this.debounce(this.updateScale.bind(this), 300))
  }
  updateScale() {
    const clientWidth = document.documentElement.clientWidth
    const clientHeight = document.documentElement.clientHeight
    // 计算缩放比例
    const scaleX = clientWidth / this.designWidth
    const scaleY = clientHeight / this.designHeight
    const scale = Math.min(scaleX, scaleY)
    // 应用缩放
    const container = document.getElementById('screen-container')
    if (container) {
      container.style.transform = `scale(${scale})`
      container.style.transformOrigin = '0 0'
      container.style.width = `${this.designWidth}px`
      container.style.height = `${this.designHeight}px`
      // 居中显示
      container.style.position = 'absolute'
      container.style.left = '50%'
      container.style.top = '50%'
      container.style.marginLeft = `-${this.designWidth / 2}px`
      container.style.marginTop = `-${this.designHeight / 2}px`
    }
  }
  debounce(fn, delay) {
    let timer = null
    return function() {
      if (timer) clearTimeout(timer)
      timer = setTimeout(() => {
        fn.apply(this, arguments)
      }, delay)
    }
  }
}

Viewport + REM方案

// 动态设置视口和rem
function setViewportAndRem() {
  const baseWidth = 1920
  const baseHeight = 1080
  const clientWidth = document.documentElement.clientWidth
  const clientHeight = document.documentElement.clientHeight
  // 计算缩放比例
  const scaleX = clientWidth / baseWidth
  const scaleY = clientHeight / baseHeight
  // 设置视口缩放
  const viewportMeta = document.querySelector('meta[name="viewport"]')
  const scale = Math.min(scaleX, scaleY)
  if (viewportMeta) {
    viewportMeta.content = `width=${baseWidth}, initial-scale=${scale}, maximum-scale=${scale}, user-scalable=no`
  }
  // 设置rem基准值
  const fontSize = (clientWidth / baseWidth) * 16
  document.documentElement.style.fontSize = `${fontSize}px`
}
// 监听窗口变化
window.addEventListener('resize', setViewportAndRem)
setViewportAndRem()

CSS Transform + CSS Variables

:root {
  --scale-factor: 1;
  --screen-width: 1920px;
  --screen-height: 1080px;
}
.screen-wrapper {
  width: var(--screen-width);
  height: var(--screen-height);
  transform: scale(var(--scale-factor));
  transform-origin: 0 0;
  position: absolute;
  left: 50%;
  top: 50%;
  margin-left: calc(var(--screen-width) / -2);
  margin-top: calc(var(--screen-height) / -2);
}
/* 所有内部尺寸都使用rem或设计稿px */
.widget {
  width: 400px; /* 设计稿尺寸 */
  height: 300px;
  position: absolute;
  left: 100px;
  top: 100px;
}
// 更新缩放因子
function updateScaleFactor() {
  const designWidth = 1920
  const designHeight = 1080
  const clientWidth = window.innerWidth
  const clientHeight = window.innerHeight
  const scaleX = clientWidth / designWidth
  const scaleY = clientHeight / designHeight
  const scale = Math.min(scaleX, scaleY)
  document.documentElement.style.setProperty('--scale-factor', scale)
}

结合Flex/Grid布局

/* 使用Flex和Grid进行弹性布局 */
.dashboard {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
  padding: 20px;
}
.chart-card {
  display: flex;
  flex-direction: column;
  background: rgba(26, 35, 52, 0.8);
  border-radius: 8px;
  padding: 20px;
}
.chart-title {
  font-size: clamp(16px, 1.5vw, 24px);
  margin-bottom: 15px;
}
.chart-container {
  flex: 1;
  min-height: 300px;
}

Vue/React组件适配示例

<template>
  <div 
    class="screen-container"
    :style="containerStyle"
    ref="container"
  >
    <!-- 大屏内容 -->
    <div class="dashboard-content">
      <div 
        v-for="widget in widgets"
        :key="widget.id"
        class="widget"
        :style="getWidgetStyle(widget)"
      >
        <component :is="widget.component" />
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      scale: 1,
      widgets: [] // 组件配置
    }
  },
  computed: {
    containerStyle() {
      return {
        transform: `scale(${this.scale})`,
        transformOrigin: '0 0',
        width: '1920px',
        height: '1080px'
      }
    }
  },
  mounted() {
    this.updateScale()
    window.addEventListener('resize', this.updateScale)
  },
  methods: {
    updateScale() {
      const designWidth = 1920
      const designHeight = 1080
      const width = window.innerWidth
      const height = window.innerHeight
      const scaleX = width / designWidth
      const scaleY = height / designHeight
      this.scale = Math.min(scaleX, scaleY)
    },
    getWidgetStyle(widget) {
      return {
        position: 'absolute',
        left: `${widget.x}px`,
        top: `${widget.y}px`,
        width: `${widget.width}px`,
        height: `${widget.height}px`
      }
    }
  }
}
</script>

最佳实践建议

  1. 设计稿尺寸:建议以1920x1080为基准设计

    我来介绍几种常见的大屏适配方案-第1张图片-AI小龙虾下载官网 - openclaw下载 - openclaw小龙虾

  2. 单位选择

    • 固定尺寸使用px(设计稿尺寸)
    • 字体和间距可考虑使用rem
    • 弹性布局使用flex/grid
  3. 图表库适配

    // ECharts适配
    const chart = echarts.init(dom)
    window.addEventListener('resize', () => {
    chart.resize()
    })
  4. 性能优化

    • 使用防抖处理resize事件
    • 避免频繁重绘
    • 考虑使用CSS硬件加速

根据你的具体需求选择合适的方案,通常推荐使用缩放方案CSS Transform方案,它们在保持设计比例的同时实现较好的适配效果。

标签: 大屏适配 方案

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