문서 목차
이 페이지에서목차

live-preview-match

같은 CoUI 부품의 Jaspr 웹 화면과 내장된 Flutter Web 화면을 비교할 때 사용합니다. 두 렌더링 결과를 픽셀 단위로 대조해 플랫폼 간 모양 차이를 찾습니다.

한마디로#

두 렌더링 결과를 픽셀 단위로 대조해 플랫폼 간 모양 차이를 찾습니다.

무엇을·언제#

  • 무엇을 해 주나요: 한 페이지에 나란히 놓인 두 개의 미리보기 화면(Web 쪽과 Flutter 쪽)을 화면 캡처해서, 색·글자·간격 같은 차이를 찾아내고 카드별로 합격/문제 판정을 내려 줍니다.
  • 언제 작동하나요: coui.cocode.im/live-preview-poc 같은, 같은 디자인을 두 방식으로 동시에 보여 주는 페이지를 점검할 때 켜집니다.
  • 어디서 되나요: 개발용 특수 도구 없이도 실제로 배포된(운영 중인) 사이트에서 그대로 동작합니다.
  • 어떤 점이 좋나요: 차이가 발견되면 그 종류(글자체 문제·색 문제·배치 문제)를 구분해 주고, 원본·비교본·차이 표시를 한눈에 보여 주는 이미지를 만들어 줍니다.

핵심 용어#

용어쉬운 설명
Jaspr Web / Flutter Web같은 화면을 그려 내는 서로 다른 두 가지 기술. 이 둘이 똑같이 보이는지가 비교 대상입니다.
CoUI두 기술이 공통으로 쓰는 디자인 묶음(버튼·카드 같은 화면 부품 모음).
pixel diff (픽셀 비교)두 그림을 점 단위로 맞대어 보며 다른 곳을 찾아내는 작업.
tolerance (허용 오차) "이 정도 미세한 차이는 같은 것으로 본다"고 정해 두는 기준. 엄격하게(strict)·보통(default)·느슨하게(loose) 조절할 수 있습니다.
screenshot (스크린샷)화면을 그대로 사진처럼 찍어 둔 이미지. 비교의 재료가 됩니다.
verdict (판정)차이를 분석한 뒤 내리는 결론(합격인지, 문제가 있는지).
regression (회귀 점검)시점이 다른 두 캡처를 비교해 "예전과 달라졌는지" 확인하는 것. 이 도구의 비교와는 다른 작업입니다.
selector (선택자)페이지에서 비교할 두 패널이 어디인지 콕 집어 주는 표식.

CoUI's promise is "Flutter and Jaspr Web render the same design". The live-preview-poc page already shows them side-by-side; this skill turns that page into an automated proof.

Why this needs a dedicated skill#

The native pixel-loop (Marionette + Figma over VM Service) doesn't help because both sides run in a browser. The Jaspr audit (/jaspr-web audit) doesn't help because it counts elements but doesn't compare two renders to each other. This skill is the missing piece: same-page, two-panel pixel diff with awareness of Flutter Web's canvas quirks.

Page Topology Assumption#

┌─ Variant Card ─────────────────────────────────────────────┐
│  ┌──── Web panel ────┐   ┌──── Flutter panel ────┐        │
│  │ Jaspr-rendered    │   │ Flutter Web canvas    │        │
│  │ <button>          │   │ <flutter-view>        │        │
│  │   Primary         │   │   ...                 │        │
│  │ </button>         │   │ </flutter-view>       │        │
│  └───────────────────┘   └───────────────────────┘        │
└────────────────────────────────────────────────────────────┘
                    ↑                       ↑
        clip rect derived from           clip rect derived from
        [data-co="preview-web"]           [data-co="preview-flutter"]

The skill assumes each variant card has two clearly marked panels reachable via two stable container selectors. cocode's live-preview emits exactly this structure based on the page's HTML — see commands/match.md for the assumed catalogue.

How matching works#

  1. Navigate to the page (Playwright).
  2. Find all variant cards: [data-co="preview-card"].
  3. For each card:
    • getBoundingClientRect() for the Web panel container → clip screenshot → A.png.
    • getBoundingClientRect() for the Flutter panel container → clip screenshot → B.png.
    • Wait for the Flutter panel to finish loading (no "Loading Flutter..." text, canvas mounted, first frame painted via flutter-view data-flt-renderer ready).
    • Diff A.png vs B.png with anti-aliasing tolerance and font-rendering tolerance turned up.
  4. Emit per-variant verdict + 3-up image (A | B | diff).

Tolerance presets#

Flutter Web font-rendering and Jaspr DOM font-rendering will never be byte-identical. Defaults are tuned for "same design language" rather than "same bytes":

default:
  pixel: 2
  color_delta_e: 3.0       # CIEDE2000
  ignore_aa: true          # ignore anti-alias edge differences
  mask_outside_intersection: true   # only compare the overlapping rect

strict:
  pixel: 1
  color_delta_e: 2.0
  ignore_aa: false

loose:
  pixel: 4
  color_delta_e: 5.0
  ignore_aa: true

Pass with --tolerance-preset=strict (default default).

What counts as a real divergence#

The skill classifies diffs into:

ClassTriggerAction
typography Glyph centroids shift > 1px or font weight differs Open issue; this is usually a CSS variable miss on one side
color color_delta_e > threshold over > 5% of the panel Open issue; usually a theme token diff
layout Element bounding-box diff > pixel threshold Open issue; usually a spacing scale diff
rendering noiseBelow thresholds, no clusteringPass

The classifier writes a short LLM-style verdict per card to verdict.md.

Production readiness#

This skill works on the deployed production site. It does not require:

  • VM Service.
  • Source maps.
  • Flutter Semantics being enabled.

It only requires that the Jaspr page marks the two panels with stable selectors. The default selectors are listed in commands/match.md and can be overridden via --selectors=<yaml>.

When not to use#

  • A single render (Web-only or Flutter-only) — use /jaspr-web regression instead.
  • Native Flutter on iOS/Android — use cc-pixel-loop.
  • Cross-screenshot comparison across two different runs/timestamps — that's regression, not match.

Cross-references#

  • Sibling skill: cc-jaspr-web:jaspr-web
  • Native counterpart: cc-pixel-loop:pixel-loop
  • Article reference: Pixel-Perfect Flutter UIs with Figma, Maestro, and Dart MCPs — Very Good Ventures, May 2026 (informs tolerance defaults).

검색어를 입력하면 문서를 찾습니다.

↑ ↓ 이동 · Enter 열기Esc 닫기