add official Chrome feature demos
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
const panel = document.querySelector("#panel");
|
||||
const buttons = Array.from(document.querySelectorAll("[data-view]"));
|
||||
|
||||
const views = {
|
||||
orders: {
|
||||
title: "订单工作台",
|
||||
body: "状态从列表切换到业务面板,浏览器负责把 DOM 更新过渡成连续动画。",
|
||||
metrics: ["128 个待处理", "96.4% 准时率"],
|
||||
},
|
||||
analytics: {
|
||||
title: "实时分析",
|
||||
body: "适合展示页面状态、卡片位置、详情视图之间的平滑切换。",
|
||||
metrics: ["42ms INP", "3 条异常趋势"],
|
||||
},
|
||||
settings: {
|
||||
title: "权限设置",
|
||||
body: "在支持的浏览器里使用 View Transitions;不支持时保留普通状态切换。",
|
||||
metrics: ["7 个角色", "24 项权限"],
|
||||
},
|
||||
};
|
||||
|
||||
function render(view) {
|
||||
const data = views[view];
|
||||
panel.innerHTML = `
|
||||
<article class="card">
|
||||
<p class="eyebrow">Current view</p>
|
||||
<h2>${data.title}</h2>
|
||||
<p>${data.body}</p>
|
||||
</article>
|
||||
<section class="summary">
|
||||
${data.metrics
|
||||
.map((metric) => `<article class="card"><strong>${metric}</strong><span>View transition keeps the context visible.</span></article>`)
|
||||
.join("")}
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
|
||||
function setActive(view) {
|
||||
buttons.forEach((button) => {
|
||||
button.classList.toggle("active", button.dataset.view === view);
|
||||
});
|
||||
render(view);
|
||||
}
|
||||
|
||||
buttons.forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const next = button.dataset.view;
|
||||
if (document.startViewTransition) {
|
||||
document.startViewTransition(() => setActive(next));
|
||||
return;
|
||||
}
|
||||
setActive(next);
|
||||
});
|
||||
});
|
||||
|
||||
setActive("orders");
|
||||
@@ -0,0 +1,29 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>View Transitions Demo</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main class="shell">
|
||||
<section class="hero">
|
||||
<p class="eyebrow">Chrome UI capability</p>
|
||||
<h1>View Transitions</h1>
|
||||
<p>点击不同状态,观察浏览器把 DOM 更新包装成一次连续过渡。没有支持时,页面仍然即时切换。</p>
|
||||
</section>
|
||||
|
||||
<section class="app" id="app">
|
||||
<nav class="tabs" aria-label="Demo states">
|
||||
<button class="active" data-view="orders">订单</button>
|
||||
<button data-view="analytics">分析</button>
|
||||
<button data-view="settings">设置</button>
|
||||
</nav>
|
||||
<div class="panel" id="panel"></div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script src="./app.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,126 @@
|
||||
:root {
|
||||
color-scheme: light;
|
||||
--ink: #17202a;
|
||||
--muted: #66717c;
|
||||
--paper: #f3f5f7;
|
||||
--panel: #ffffff;
|
||||
--line: #d8dee6;
|
||||
--blue: #1a5fb4;
|
||||
--green: #16784e;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
color: var(--ink);
|
||||
background: var(--paper);
|
||||
font-family: ui-sans-serif, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
|
||||
.shell {
|
||||
width: min(1040px, calc(100vw - 32px));
|
||||
margin: 0 auto;
|
||||
padding: 42px 0 60px;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
margin: 0 0 10px;
|
||||
color: var(--blue);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h1,
|
||||
p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 14px;
|
||||
font-family: Georgia, "Times New Roman", serif;
|
||||
font-size: clamp(44px, 8vw, 96px);
|
||||
line-height: 0.9;
|
||||
}
|
||||
|
||||
.hero p {
|
||||
max-width: 680px;
|
||||
color: var(--muted);
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.app {
|
||||
margin-top: 26px;
|
||||
border: 1px solid var(--line);
|
||||
background: var(--panel);
|
||||
box-shadow: 0 22px 70px rgb(23 32 42 / 0.14);
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
button {
|
||||
min-height: 40px;
|
||||
border: 1px solid var(--line);
|
||||
background: #fff;
|
||||
color: var(--ink);
|
||||
cursor: pointer;
|
||||
padding: 9px 14px;
|
||||
font: inherit;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
button.active {
|
||||
border-color: var(--blue);
|
||||
background: #e8f0ff;
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
.panel {
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
min-height: 380px;
|
||||
padding: 22px;
|
||||
view-transition-name: demo-panel;
|
||||
}
|
||||
|
||||
.summary {
|
||||
display: grid;
|
||||
grid-template-columns: 1.2fr 0.8fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 1px solid var(--line);
|
||||
background: #fff;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.card strong {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 34px;
|
||||
}
|
||||
|
||||
::view-transition-old(demo-panel),
|
||||
::view-transition-new(demo-panel) {
|
||||
animation-duration: 320ms;
|
||||
animation-timing-function: cubic-bezier(0.2, 0, 0, 1);
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.tabs,
|
||||
.summary {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user