#!/usr/bin/env bash # render-figma.sh — chụp PNG từng màn hình × khung nhìn × trạng thái của HIFI bằng Chrome/Edge headless sẵn có (không cài thêm). # render-figma.sh [--scr SCR-01,SCR-03] [--views desktop,tablet,mobile] [--states default,loading,...] # Mặc định: mọi SCR có trong file · desktop+mobile · mọi trạng thái xuất hiện trong file (data-state). Ảnh: /SCR-xx...png set -euo pipefail HIFI="${1:?Thiếu đường dẫn HIFI.html}"; OUT="${2:?Thiếu thư mục output}"; shift 2 SCRS=""; VIEWS="desktop,mobile"; STATES="" while [ $# -gt 0 ]; do case "$1" in --scr) SCRS="$2"; shift 2;; --views) VIEWS="$2"; shift 2;; --states) STATES="$2"; shift 2;; *) echo "Tham số lạ: $1" >&2; exit 2;; esac; done BROWSER="" for b in google-chrome google-chrome-stable chromium chromium-browser microsoft-edge microsoft-edge-stable msedge; do command -v "$b" >/dev/null 2>&1 && { BROWSER="$b"; break; }; done for p in "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge" "/c/Program Files/Google/Chrome/Application/chrome.exe" "/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"; do [ -z "$BROWSER" ] && [ -x "$p" ] && BROWSER="$p"; done [ -z "$BROWSER" ] && { echo "blocked: không tìm thấy Chrome/Edge — chụp tay: mở HIFI với ?scr=&view=&state= rồi lưu ảnh vào $OUT" >&2; exit 3; } [ -z "$SCRS" ] && SCRS=$(grep -oE 'class="hf-frame"[^>]*id="SCR-[0-9]+"' "$HIFI" | grep -oE 'SCR-[0-9]+' | paste -sd, -) [ -z "$STATES" ] && STATES=$(grep -oE 'data-state="[a-z-]+"' "$HIFI" | grep -oE '"[a-z-]+"' | tr -d '"' | sort -u | paste -sd, -) mkdir -p "$OUT" ABS=$(cd "$(dirname "$HIFI")" && pwd)/$(basename "$HIFI") n=0 for scr in ${SCRS//,/ }; do for view in ${VIEWS//,/ }; do case "$view" in desktop) W=1440; H=900;; tablet) W=834; H=1112;; mobile) W=390; H=844;; *) echo "view lạ: $view" >&2; exit 2;; esac for st in ${STATES//,/ }; do f="$OUT/$scr.$view.$st.png" "$BROWSER" --headless=new --disable-gpu --no-first-run --no-default-browser-check --disable-extensions --hide-scrollbars \ --allow-file-access-from-files --virtual-time-budget=3000 --window-size="$W,$H" --screenshot="$f" \ "file://$ABS?scr=$scr&view=$view&state=$st&mode=mockup" >/dev/null 2>&1 && n=$((n+1)) || echo "lỗi: $scr $view $st" >&2 done done; done echo "ok: $n ảnh → $OUT (khung: desktop 1440×900 · tablet 834×1112 · mobile 390×844; nội dung dài hơn khung bị cắt — ghi chú trong DSPEC §1)"