astrion-website/demo/site-assets/anim3-demo.css

283 lines
8.9 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 修改记录动画 —— 智能体持笔在 3D 倾斜纸上改写内容,
纸摊平后绿行抽出展开为红绿 diff。无边框无底色融于星空无 glow。 */
:root {
--bg-0: #0c1120;
--bg-1: #111830;
--bg-panel: #151c31;
--text-1: #eef1f8;
--text-2: #a7b0c4;
--text-3: #6b7488;
--line: rgba(168, 180, 210, 0.14);
--accent: #a9c2f0;
--accent-strong: #c1d4f6;
--danger: #d47b6b;
--ok: #7ba889;
/* 收盒文件:与编辑中的 3D 纸同款底色,边框用更亮的白边(叠放分层清晰) */
--file-paper: var(--bg-panel);
--file-line: rgba(238, 240, 246, 0.35);
--font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC",
"Noto Sans SC", "Helvetica Neue", "Microsoft YaHei", sans-serif;
--font-mono: ui-monospace, "SF Mono", "SFMono-Regular", Menlo, Consolas, monospace;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: var(--font-sans);
background: linear-gradient(180deg, var(--bg-1) 0%, var(--bg-0) 60%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-1);
}
.stage { display: flex; flex-direction: column; align-items: center; gap: 18px; }
.hint { font-size: 13px; color: var(--text-3); }
/* ───────── 动画容器 ───────── */
.anim3-window {
width: 540px;
height: 380px;
}
.anim3-stage {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
cursor: pointer;
user-select: none; /* 演示区禁止选中文本,避免鼠标划过时出现系统选中高亮(黑光) */
-webkit-user-select: none;
}
/* ───────── 智能体(右上) ───────── */
.writer {
position: absolute;
right: 58px;
top: 26px;
width: 84px;
height: 84px;
}
.writer-avatar {
display: block;
width: 84px;
height: 84px;
color: var(--text-1);
}
.writer-avatar .astrion-avatar { width: 100%; height: 100%; }
/* ───────── 笔(双层结构) ─────────
外层 pen-posJS 逐帧/过渡定位,使笔尖精确落在文字进度点上;
内层 svg以笔尖为圆心旋转摇摆transform-origin 在笔尖),
既有晃动,笔尖又不会脱离位置。 */
.pen-pos {
position: absolute;
left: 0;
top: 0;
z-index: 40; /* 最高层:高于 3D 纸、盒子30与堆叠纸21~23笔不能被挡 */
width: 40px;
height: 40px;
color: var(--accent);
will-change: transform;
transition: transform 0.45s cubic-bezier(.4,0,.2,1); /* 飞行/移动用过渡 */
}
.pen-pos.is-live {
transition: none; /* 写字逐帧驱动时关闭过渡 */
}
.writer-pen {
width: 40px;
height: 40px;
/* origin = 笔尖视觉触点SVG (2.65,21.02) → 40px 盒内 (4.4,35.0)),与 nibRef 同点:
摇摆时笔尖钉住不动,只有笔身晃 */
transform-origin: 11% 87.6%;
}
.writer-pen.is-writing {
animation: pen-write 0.42s ease-in-out infinite;
}
/* 擦除origin 切到笔尾橡皮触点SVG (19.2,4.8) → 盒内 (32,8)),与 eraserRef 同点 */
.writer-pen.is-erasing {
transform-origin: 80% 20%;
}
@keyframes pen-write {
0%, 100% { transform: rotate(-5deg); }
50% { transform: rotate(6deg); }
}
/* ───────── 3D 倾斜的纸 ───────── */
/* perspective 让纸呈平行四边形(不倾斜就只是一条线) */
.paper3d {
position: absolute;
left: 280px;
top: 130px;
width: 192px;
height: 122px;
transform: perspective(760px) rotateX(42deg) rotateZ(-7deg);
transform-style: preserve-3d;
}
.paper-sheet {
width: 100%;
height: 100%;
background: var(--bg-panel);
border: 1px solid var(--line);
border-radius: 6px;
padding: 18px 16px;
display: flex;
flex-direction: column;
gap: 14px;
}
/* 内容行:横线代表一行内容(行宽由 JS 逐帧驱动,不用 transitionopacity 过渡供轮间换内容淡出) */
.pline {
position: relative;
height: 4px;
border-radius: 2px;
background: var(--text-3);
opacity: 0.75;
transition: opacity 0.28s ease;
}
.paper3d.is-refilling .pline { opacity: 0; }
/* 线右端锚点0 尺寸,随线的 3D/倾斜变换,供 JS 实测真实右端点 */
.pline-end {
position: absolute;
right: 0;
top: 50%;
width: 0;
height: 0;
margin-top: -0px; /* 点本身无尺寸top:50% 即线厚中心 */
}
/* 写入行不再用绿色:与其他行同色(修改记录靠的是 diff 区,不是纸面变色) */
/* ───────── diff 区 ───────── */
.diff-view {
position: absolute;
left: 134px; /* 盒子水平中线86+48diff 中心对齐盒子中线 */
transform: translateX(-50%); /* 克隆切片内 transform 已被覆盖,不受影响 */
top: 0;
font-family: var(--font-mono);
font-size: 12.5px;
line-height: 1.5;
display: flex;
flex-direction: column;
gap: 3px;
z-index: 20; /* 盒内堆叠纸(21~23)之下——genie 时已隐藏,由切片接管 */
border-radius: 6px;
transition: background 0.25s ease;
}
/* genie 前:四行 diff 合为一张纸的底板(不加 outlineshorthand 不可过渡,会闪白框) */
.diff-view.is-sheet {
background: rgba(24, 30, 52, 0.92);
}
/* 轮间重置:禁用过渡,红绿底色/符号瞬时消失(否则恢复显示时会闪一下空白红绿块) */
.diff-view.no-fade { transition: none; }
.diff-view.no-fade .dline::before { transition: none; }
.diff-view.no-fade .dsign { transition: none; }
/* ───────── 收盒文件卡片(单元素裁切式 genie ─────────
卡片全程同一个 DOM 元素clip-path 多边形裁切(不压缩内容),
body 每帧定位到轮廓包围盒,文字矢量缩小——全程清晰无损 */
.file-flight {
position: absolute;
pointer-events: none;
opacity: 0;
transition: opacity 0.45s ease;
/* SVG 视口默认 hidden 会把描边外半侧0.5px裁掉——visible 让边缘描边完整 */
overflow: visible;
}
.file-flight.is-on { opacity: 1; }
/* SVG 卡片path 轮廓即卡片外形——fill 纸色 + stroke 描边跟随轮廓S 曲线斜边也有描边) */
.file-flight-shape {
fill: var(--file-paper);
stroke: var(--file-line);
stroke-width: 1;
}
.file-cover-name {
font-family: var(--font-mono);
font-size: 15px;
letter-spacing: 0.02em;
fill: var(--text-3); /* 和纸上线条同色 */
}
.file-cover-stat {
font-family: var(--font-mono);
font-size: 11px;
}
.file-cover-stat .add { fill: var(--ok); }
.file-cover-stat .del { fill: var(--danger); }
.dline {
position: relative;
display: flex;
gap: 12px;
padding: 3px 10px;
border-radius: 4px;
/* 容器本身始终不透明:转正落位的字符立即可见,不经历消失→淡入;
红/绿底色由 ::before 独立淡入,+/- 符号独立淡入 */
white-space: nowrap;
}
.dline::before {
content: '';
position: absolute;
inset: 0;
border-radius: 4px;
opacity: 0;
transition: opacity 0.3s ease;
pointer-events: none;
}
.dline.is-del::before { background: rgba(212, 123, 107, 0.08); }
.dline.is-add::before { background: rgba(123, 168, 137, 0.10); }
.dline.is-shown::before { opacity: 1; }
.dline .dsign { flex: none; width: 10px; opacity: 0; transition: opacity 0.3s ease; }
.dline.is-shown .dsign { opacity: 1; }
.dline.is-del { color: var(--danger); }
.dline.is-add { color: var(--ok); }
/* diff 行内单字符:占位时透明;落位转正后 is-lit 实色显示 */
.dch { opacity: 0; }
.dch.is-lit { opacity: 1; }
/* 飘行的字母:从笔的擦/写位置飞向 diff 行字符位,落位后转正为流内字符 */
.dch-ghost {
position: absolute;
left: 0;
top: 0;
font-family: var(--font-mono);
font-size: 12.5px;
line-height: 1.5;
pointer-events: none;
/* 不设 will-change合成层位图与转正后的矢量重绘之间会出现大小/清晰度跳变 */
transition: transform 0.34s cubic-bezier(.35,.1,.25,1);
z-index: 35; /* 高于盒前壁30飞行字母不被盒子挡 */
}
/* 参考点(校准期红色可见,校准后改回透明) */
/* 笔尖/橡皮定位参考点visibility 隐藏(保留几何盒供 getBoundingClientRect 实测),
同时清掉 fill/stroke 防止从 SVG 根继承描边显形 */
.pen-ref { visibility: hidden; fill: none; stroke: none; pointer-events: none; }
/* ───────── 收件箱genie 收盒) ─────────
后壁 z1纸挡住它、前壁 z4它挡住纸——纸从前后壁之间沉入 */
.inbox-part {
position: absolute;
left: 86px; /* 中心线 x=134 */
top: 166px;
width: 96px;
height: 96px;
color: var(--text-1);
opacity: 0;
transition: opacity 0.35s ease;
pointer-events: none;
}
.inbox-part.is-shown { opacity: 1; }
.box-back { z-index: 10; }
.box-front { z-index: 30; }
/* 前壁盒身填实色:不能透出后面收进去的纸(凹口线保持描边不填) */
.box-front path { fill: var(--bg-1); }
/* 盒内纸叠genie 终态的文件卡片(.file-flight本身就是插在盒子里的纸 */