AgentBuild: 30 AI agent dựng trang trước mắt người xem
Hiệu ứng vào trang: từng khối của trang bị ẩn sau khung dây, một bầy con trỏ có tên bay tới, kéo khung chọn và "dựng" khối đó lên. Chỉ dùng DOM và CSS transition (không canvas, không thư viện), 30 con trỏ gần như không tốn tài nguyên.
File trong assets/:
| File | Dùng khi |
|---|---|
agent-build.js | Lõi. Dùng bằng <script> (tạo window.AgentBuild) hoặc import trong bundler (CommonJS). |
agent-build.css | Bắt buộc, đi kèm lõi. Đổi màu bằng biến --ab-*. |
agent-build.d.ts | Kiểu TypeScript cho lõi. |
AgentBuild.tsx | Bản bọc React/Next (client component). |
demo.html | Trang mẫu tự chạy, mở thẳng bằng trình duyệt. |
Cách gắn
Web HTML thường
- Chép
agent-build.jsvàagent-build.cssvào dự án. - Gắn CSS trong
<head>, script ở cuối<body>, rồi gọistartsau khi nội dung đã có trong DOM:
<link rel="stylesheet" href="agent-build.css" />
<script src="agent-build.js"></script>
<script>
AgentBuild.start({
root: "main", // vùng được dựng; lớp con trỏ nằm trong vùng này
targets: "main h1, main p, .card", // các khối, theo thứ tự ưu tiên
seenKey: "home", // mỗi trang một khoá
labels: { status: "{agents} agent · {edits} chỉnh sửa", building: "Đang dựng trang", done: "Đã dựng xong", skip: "Bỏ qua" },
});
</script>
React / Next.js (App Router)
- Chép
agent-build.js,agent-build.d.ts,AgentBuild.tsxvào cùng một thư mục, ví dụsrc/components/agent-build/. - Import
agent-build.cssmột lần trong stylesheet chung (@import "../components/agent-build/agent-build.css";). - Đặt component làm con đầu tiên của vùng cần dựng. Component lấy phần tử cha làm root:
<div className="landing">
<AgentBuild targets=".landing h1, .landing p, .card" seenKey="landing" />
...
</div>
Trang được render phía server vẫn chạy được vì component chỉ chạy ở client, và ẩn khối trong useLayoutEffect (trước lần vẽ đầu tiên), nên không bị lóe nội dung.
Chọn targets cho đúng
Đây là phần quyết định hiệu ứng đẹp hay rối.
- Chọn khối có nghĩa: tiêu đề, đoạn văn, nút, thẻ, ảnh. Không chọn
divbọc cả section, vì một khung khổng lồ trông giống lỗi. - Liệt kê theo thứ tự ưu tiên. Phần tử nằm bên trong một phần tử đã được chọn sẽ tự bị bỏ qua. Ví dụ đã chọn
.cardthìptrong thẻ không bị dựng riêng. Muốn dựng cả thẻ thì đặt.cardtrướcp. - Bỏ qua vùng đã có hiệu ứng riêng (chữ chạy theo cuộn, canvas) bằng
skipInside: ".tagline". - Phần tử rộng hoặc cao bằng 0 lúc bắt đầu sẽ bị bỏ qua.
- Khoảng 30 đến 140 khối là đẹp.
maxTargetsmặc định là 140. - Nếu dự án có sẵn hiệu ứng "hiện dần khi cuộn", hãy tắt nó trong lúc agent chạy, nếu không hai hiệu ứng chồng lên nhau. Ví dụ:
[data-agent-build] .reveal { opacity: 1; transform: none; transition: none; }(thuộc tínhdata-agent-buildđược gắn lên root trong lúc chạy).
Tuỳ chọn
| Tuỳ chọn | Mặc định | Ý nghĩa |
|---|---|---|
root | document.body | Phần tử hoặc selector. Được gắn position: relative trong lúc chạy. |
targets | h1, h2, h3, p, img, figure, li, button, .card | Danh sách khối. |
count | 30 (16 khi màn hình hẹp hơn 640px) | Số agent. |
once / seenKey | true / "agent-build" | Mỗi tab chỉ chạy một lần. |
forceParam | "agents" | Thêm ?agents vào URL để luôn chạy lại, tiện khi quay video. |
respectReducedMotion | true | Không chạy nếu người dùng bật giảm chuyển động. |
pill | true | Thanh trạng thái có nút Bỏ qua. |
labels | tiếng Anh | status (có {agents}, {edits}), building, done, skip. |
colors, roles | 8 màu, 10 vai trò | Màu và tên agent (layout-07). |
start() trả về { skip(), destroy(), started }. destroy() trả trang về nguyên trạng. Gọi nó khi rời trang (SPA) hoặc khi unmount component.
Đổi giao diện bằng biến CSS: --ab-wire (màu khung dây), --ab-pill-bg, --ab-pill-text, --ab-pill-muted, --ab-mono, --ab-ease.
Kiểm tra bằng số, không cần chụp ảnh liên tục
Dùng Playwright mở trang với ?agents, rồi đọc:
({
cursors: document.querySelectorAll(".ab-cursor:not([data-hidden])").length, // ~30 lúc đầu
waiting: document.querySelectorAll('[data-ab="wait"]').length, // giảm dần khi cuộn
on: !!document.querySelector("[data-agent-build]"), // false khi đã xong
})
Cuộn bằng window.scrollTo theo từng bước (đừng dùng mouse.wheel nếu trang có Lenis smooth scroll), chờ vài giây. Kết quả đúng: waiting về 0 và on thành false. Kiểm tra nút Bỏ qua: bấm .ab-skip, sau đó không còn [data-ab] nào. Chỉ chụp một ảnh khi cần đánh giá phần nhìn.
Lỗi đã gặp
- Khung hoặc con trỏ lệch chỗ: root không bao hết các khối. Chọn root là phần tử chứa toàn bộ
targets. - Ảnh
fill(Next/Image) phủ cả trang: không phải lỗi của skill này. Khung cha của ảnhfillcầnposition: relative. - Hiệu ứng không chạy lại: đã chạy một lần trong tab. Thêm
?agentsvào URL hoặc mở tab mới. - React StrictMode (dev chạy effect hai lần): lõi chỉ ghi "đã chạy" sau 1,2 giây, nên lần mount thứ hai vẫn chạy bình thường.