You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中不使用Stack实现自适应足球场地及球员布局?

自适应足球场地与球员布局实现方案

核心思路

放弃固定图片方案,改用矢量SVG绘制场地+CSS Grid/Flexbox动态排列球员,从根源解决不同阵型导致的两侧高度不一致问题,同时保证全尺寸自适应。

具体实现步骤

1. 用SVG绘制自适应足球场地

SVG是矢量格式,天生支持自适应缩放,不会像位图那样变形。定义好viewBox属性后,场地会自动填充容器空间:

<svg viewBox="0 0 100 60" class="football-pitch">
  <!-- 场地边线 -->
  <rect x="1" y="1" width="98" height="58" fill="#2ecc71" stroke="#fff" stroke-width="0.5"/>
  <!-- 中线 & 中圈 -->
  <line x1="50" y1="1" x2="50" y2="59" stroke="#fff" stroke-width="0.5"/>
  <circle cx="50" cy="30" r="5" stroke="#fff" stroke-width="0.5" fill="none"/>
  <!-- 双方禁区 -->
  <rect x="1" y="15" width="12" height="30" fill="none" stroke="#fff" stroke-width="0.5"/>
  <rect x="87" y="15" width="12" height="30" fill="none" stroke="#fff" stroke-width="0.5"/>
  <!-- 其他元素(点球点、球门等)可按需添加 -->
</svg>

给SVG加基础样式,让它自适应父容器:

.football-pitch {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
}

2. 用CSS Grid实现球员自适应排列

把场地两侧的球员区域设为Grid容器,根据阵型的行数动态分配行高,确保两侧高度完全对齐:

<div class="pitch-container">
  <div class="team team-home" data-formation="4-3-3"></div>
  <svg class="football-pitch">...</svg>
  <div class="team team-away" data-formation="3-4-2-1"></div>
</div>
.pitch-container {
  display: flex;
  align-items: stretch; /* 强制两侧球队容器高度一致 */
  gap: 10px;
  padding: 20px;
}

.team {
  display: grid;
  gap: 8px;
  align-items: center;
}

/* 动态生成的阵型样式,比如4-3-3对应3行 */
.team[data-formation="4-3-3"] {
  grid-template-rows: repeat(3, 1fr);
}

.team[data-formation="3-4-2-1"] {
  grid-template-rows: repeat(4, 1fr);
}

3. JS动态渲染球员

根据阵型数据生成对应数量的球员卡片,自动填充到Grid容器中:

// 阵型数据:键是阵型标识,值是每行球员数量
const formations = {
  "4-3-3": [4, 3, 3],
  "3-4-2-1": [3, 4, 2, 1]
};

function renderTeam(teamEl, formationKey) {
  const playerCounts = formations[formationKey];
  teamEl.innerHTML = "";
  
  playerCounts.forEach(count => {
    const row = document.createElement("div");
    row.style.display = "flex";
    row.style.justifyContent = "center";
    row.style.gap = "6px";
    
    for(let i=0; i<count; i++) {
      const player = document.createElement("div");
      player.className = "player";
      player.textContent = "10"; // 替换为球员号码/姓名
      row.appendChild(player);
    }
    
    teamEl.appendChild(row);
  });
}

// 渲染两支球队
renderTeam(document.querySelector(".team-home"), "4-3-3");
renderTeam(document.querySelector(".team-away"), "3-4-2-1");

给球员卡片加基础样式:

.player {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: bold;
}

关键优势

  • 完全自适应:不管是桌面端还是移动端,场地和球员布局都会自动适配容器尺寸
  • 阵型兼容:支持任意阵型,只需在formations对象中添加对应数据即可
  • 高度对齐:通过align-items: stretch和Grid的等分行高,强制两侧球队区域高度一致

内容的提问来源于stack exchange,提问作者Alifarhad Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:31:02