iter(g192): 动效时长字面值归零补循环档

This commit is contained in:
HIsheR
2026-10-26 17:55:13 +08:00
parent 0e996e42af
commit 68bfbddc82
6 changed files with 43 additions and 16 deletions
+6 -1
View File
@@ -64,10 +64,15 @@
--ua-shadow-accent: 0 3px 10px color-mix(in srgb, var(--ua-color-accent) 25%, transparent); /* 主题色投影:主按钮 / 强调控件悬停浮起 */
--ua-shadow-accent-strong: 0 8px 20px color-mix(in srgb, var(--ua-color-accent) 35%, transparent); /* 主题色强投影:返回顶部等悬浮强调件 */
/* ---- 动效:三档时长 + 两条主缓动曲线 ---- */
/* ---- 动效:四档交互时长 + 四档循环时长 + 两条主缓动曲线 ---- */
--ua-duration-fast: 0.15s; /* 快:hover / 聚焦 / 颜色与边框变化(既有样式的主流时长) */
--ua-duration-base: 0.2s; /* 中:展开收起 / 位移 / 透明度过渡 */
--ua-duration-slow: 0.25s; /* 慢:浮层出入场 / 较大面积变化 */
--ua-duration-slower: 0.35s; /* 更慢:进度条宽度推进 / 描边长度等大跨度形变(比浮层出场再长一档) */
--ua-duration-loop-fast: 0.6s; /* 循环快档:条纹滚动等细微循环 */
--ua-duration-loop-mid: 0.8s; /* 循环中档:加载转圈 / 开关内转圈(0.7 与 0.8 收敛到此档) */
--ua-duration-loop-slow: 1.2s; /* 循环慢档:骨架扫光 / 不确定进度条(1.4 收敛到此档) */
--ua-duration-loop-long: 1.6s; /* 循环长档:时间线呼吸等低频脉冲,别再用在加载态上 */
--ua-ease: cubic-bezier(0.2, 0.8, 0.2, 1); /* 标准缓动:先快后缓,控件交互默认用这条 */
--ua-ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* 出场缓动:元素进入视口 / 弹层出现时使用 */
+6 -1
View File
@@ -114,7 +114,12 @@
"duration": {
"fast": "0.15s",
"base": "0.2s",
"slow": "0.25s"
"slow": "0.25s",
"slower": "0.35s",
"loopFast": "0.6s",
"loopMid": "0.8s",
"loopSlow": "1.2s",
"loopLong": "1.6s"
},
"ease": "cubic-bezier(0.2, 0.8, 0.2, 1)",
"easeOut": "cubic-bezier(0.16, 1, 0.3, 1)"
+9 -9
View File
@@ -322,7 +322,7 @@ body.ua-col-resizing {
background: transparent;
border: 2px solid color-mix(in srgb, var(--ua-color-bg) 40%, transparent);
border-top-color: var(--ua-color-bg);
animation: ua-switch-spin 0.7s linear infinite;
animation: ua-switch-spin var(--ua-duration-loop-mid) linear infinite;
}
@keyframes ua-switch-spin {
to { transform: rotate(360deg); }
@@ -1380,7 +1380,7 @@ button.ua-step-dot:hover {
inset: 0;
transform: translateX(-100%);
background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--ua-color-bg) 65%, transparent), transparent);
animation: ua-shimmer 1.4s ease-in-out infinite;
animation: ua-shimmer var(--ua-duration-loop-slow) ease-in-out infinite;
}
@keyframes ua-shimmer {
to {
@@ -1478,7 +1478,7 @@ button.ua-step-dot:hover {
border: 2px solid var(--ua-color-border);
border-top-color: var(--ua-color-accent);
border-radius: 50%;
animation: ua-spin 0.8s linear infinite;
animation: ua-spin var(--ua-duration-loop-mid) linear infinite;
}
@keyframes ua-spin {
to {
@@ -1506,7 +1506,7 @@ button.ua-step-dot:hover {
width: 0;
border-radius: inherit;
background: linear-gradient(90deg, color-mix(in srgb, var(--ua-color-accent) 65%, transparent), var(--ua-color-accent));
transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
transition: width var(--ua-duration-slower) cubic-bezier(0.4, 0, 0.2, 1);
}
.ua-progress-fill::after {
content: '';
@@ -1514,7 +1514,7 @@ button.ua-step-dot:hover {
inset: 0;
background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.18) 0 6px, transparent 6px 12px);
background-size: 17px 100%;
animation: ua-stripe 0.6s linear infinite;
animation: ua-stripe var(--ua-duration-loop-fast) linear infinite;
}
.ua-progress-fill.ua-done {
background: var(--ua-color-success);
@@ -1537,7 +1537,7 @@ button.ua-step-dot:hover {
.ua-progress-fill.ua-indeterminate {
width: 35%;
transition: none;
animation: ua-indeterminate 1.2s ease-in-out infinite;
animation: ua-indeterminate var(--ua-duration-loop-slow) ease-in-out infinite;
}
.ua-progress-fill.ua-indeterminate::after {
animation: none;
@@ -2238,7 +2238,7 @@ button.ua-step-dot:hover {
.ua-tl-dot-pending {
background: var(--ua-color-bg);
border: 1px dashed var(--ua-color-accent);
animation: ua-tl-pulse 1.6s ease-in-out infinite;
animation: ua-tl-pulse var(--ua-duration-loop-long) ease-in-out infinite;
}
.ua-tl-head {
display: flex;
@@ -2565,7 +2565,7 @@ button.ua-step-dot:hover {
.ua-carousel-track {
display: flex;
height: 100%;
transition: transform 0.32s ease;
transition: transform var(--ua-duration-slower) ease;
}
.ua-carousel-slide {
flex: 0 0 100%;
@@ -4730,7 +4730,7 @@ h5.ua-type-title { font-size: var(--ua-font-size-md); }
.ua-progress-ring-arc {
stroke: var(--ua-color-accent);
stroke-linecap: round;
transition: stroke-dashoffset 0.3s ease;
transition: stroke-dashoffset var(--ua-duration-slower) ease;
}
.ua-progress-ring.is-success .ua-progress-ring-arc { stroke: var(--ua-color-success); }
.ua-progress-ring.is-warning .ua-progress-ring-arc { stroke: var(--ua-color-warning); }
+13 -1
View File
@@ -194,8 +194,19 @@ const DURATION_STEPS = [
{ max: 0.17, token: 'var(--ua-duration-fast)' },
{ max: 0.23, token: 'var(--ua-duration-base)' },
{ max: 0.2501, token: 'var(--ua-duration-slow)' },
{ max: 0.36, token: 'var(--ua-duration-slower)' },
];
/*** 作用:循环动效(infinite)的时长 → 循环四档;0.7/0.8 收敛到中档、1.2/1.4 收敛到慢档,表外保留 ***/
const LOOP_DURATIONS = new Map([
['0.6s', 'var(--ua-duration-loop-fast)'],
['0.7s', 'var(--ua-duration-loop-mid)'],
['0.8s', 'var(--ua-duration-loop-mid)'],
['1.2s', 'var(--ua-duration-loop-slow)'],
['1.4s', 'var(--ua-duration-loop-slow)'],
['1.6s', 'var(--ua-duration-loop-long)'],
]);
/*** 作用:控件高度三档的字面值 → 令牌(28/34/40px 三个值保留给控件高度档位,其余尺寸不入此口径) ***/
const CONTROL_H_TOKENS = new Map([
['28px', 'var(--ua-control-h-sm)'],
@@ -305,12 +316,13 @@ function hasTiming(value) {
/*** 作用:迁移单个动效声明值(逐段替换时长,缺缓动时补 --ua-ease);返回 null 表示无需改动 ***/
function migrateMotion(prop, core) {
const shorthand = prop === 'transition' || prop === 'animation'; // 只有简写能补缓动,-duration 属性补了是非法的
const loop = /infinite/.test(core) && (prop === 'animation' || prop === 'animation-duration'); // 无限循环走循环四档
const parts = splitTopLevel(core);
let hits = 0;
const next = parts.map((segment) => {
let replaced = 0;
let out = segment.replace(/(\d*\.?\d+)(ms|s)\b/gi, (token) => {
const mapped = durationToken(token);
const mapped = loop ? LOOP_DURATIONS.get(token.toLowerCase()) ?? null : durationToken(token);
if (!mapped) return token; // 表外时长保留,交给后续视觉条目单独评估
replaced++;
hits++;