feat: 移动端沉浸式 Shorts 与播放器/下载徽章体验优化

- 移动端移除底部导航,Shorts 视频改为圆角卡片并适配 iOS 裁剪
- 播放进度条全局贴到视频最底,移动端精简控件(仅播放/全屏)
- 右侧互动栏下移,首页进入播放页增加模糊封面过渡
- 关于页下载入口改为标准 App Store / Google Play 徽章
- 新增自动连播下一集与自动播放被拦截时的开启声音提示
This commit is contained in:
Zhou Weidong committed 2026-11-12 15:14:09 +08:00
1 parent 6fd936ac97
commit 2d1f754a46
11 files changed
+267 -54

No files matched your search

+48
View File
@@ -0,0 +1,48 @@
// Author: fruit.com.cn
import { useLayoutEffect, useRef } from 'react';
const DURATION = 420;
const FADE = 180;
export function HeroTransition({ data, onDone }) {
const ref = useRef(null);
useLayoutEffect(() => {
if (!data) return undefined;
const node = ref.current;
if (!node) return undefined;
if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) {
onDone();
return undefined;
}
const rect = data;
const scale = Math.max(window.innerWidth / rect.width, window.innerHeight / rect.height) * 1.04;
const tx = (window.innerWidth - rect.width * scale) / 2 - rect.left;
const ty = (window.innerHeight - rect.height * scale) / 2 - rect.top;
const expand = node.animate(
[
{ transform: 'translate(0, 0) scale(1)', borderRadius: '12px' },
{ transform: `translate(${tx}px, ${ty}px) scale(${scale})`, borderRadius: '0px' },
],
{ duration: DURATION, easing: 'cubic-bezier(.2, .7, .3, 1)', fill: 'forwards' },
);
expand.onfinish = () => {
const fade = node.animate([{ opacity: 1 }, { opacity: 0 }], { duration: FADE, fill: 'forwards' });
fade.onfinish = onDone;
};
return () => expand.cancel();
}, [data, onDone]);
if (!data) return null;
const rect = data;
return (
<div
ref={ref}
className="hero-transition"
aria-hidden="true"
style={{ left: rect.left, top: rect.top, width: rect.width, height: rect.height }}
>
{data.src && <img src={data.src} alt="" />}
</div>
);
}