#Widget 动画
本文介绍,如何为自定义的 绝对定位 的 Widget,实现从右侧淡入、淡出的动画效果
播放器的 Widget 区域划分为四个固定位置:
- ⬅️ 左上角
- ➡️ 右上角
- ⬇️ 左下角
- ↘️ 右下角
在用户点击屏幕时,如果这些区域中的 Widget 当前处于显示状态,播放器会自动触发动画使其隐藏。
上述四个位置的动画行为为内置实现,只要 Widget 插入在这些区域内,就会默认遵循该逻辑。
💡 但对于使用 绝对定位 的自定义 Widget,您需要手动适配隐藏/显示的动画逻辑。
#Demo:插入绝对定位的 Widget
下面我们将实现一个 Demo,实现以下逻辑:
- 在左下角添加一个按钮;
- 点击按钮时,插入一个绝对定位的 Widget;
- 若该 Widget 已经存在,则再次点击按钮时将其隐藏;
- 该绝对定位 Widget 将适配播放器的动画系统,使其在点击屏幕后自动淡出
#使用示例
import React, { useEffect, useState } from 'react';
import { View } from '@ray-js/components';
import clsx from 'clsx';
import {
IPCPlayerIntegration,
useCtx,
useComponentHideState,
ComponentConfigProps,
} from '@ray-js/ipc-player-integration';
import Styles from './index.module.less';
import '@ray-js/ipc-player-integration/iconfont/iconfont.css';
function WidgetAbsolute(props: ComponentConfigProps) {
const [clickHidden, setClickHidden] = useState(false);
const [allComponentShouldHidden] = useComponentHideState();
const listen = () => {
setClickHidden(prev => !prev);
};
useEffect(() => {
// 监听 WidgetButtonClick 事件
props.event.on('WidgetButtonClick', listen);
return () => {
props.event.off('WidgetButtonClick', listen);
};
}, [listen]);
// ipc-plugin-absolute-move-in-right ipc-plugin-absolute-move-in-right-hide
// 是预先设置好的 CSS 类型,用于实现右侧的淡入淡出动画
return (
<View
className={clsx('ipc-plugin-absolute-move-in-right', {
'ipc-plugin-absolute-move-in-right-hide': allComponentShouldHidden || clickHidden,
})}
style={{ width: '100px', height: '100px', backgroundColor: '#fff', color: '#ff6700' }}
>
1111
</View>
);
}
function WidgetButton(props: ComponentConfigProps) {
const id = 'WidgetAbsolute';
const handClick = () => {
// 当点击按钮时,WidgetAbsolute 是否已经存在
// 若存在就通过事件系统发布 WidgetButtonClick 事件
// 否则将 WidgetAbsolute 插入到播放器中
if (props.hasContent('absolute', id)) {
props.event.emit('WidgetButtonClick');
} else {
props.addContent('absolute', {
id: 'WidgetAbsolute',
content: WidgetAbsolute,
// 或者把样式写到 absoluteContentClassName css 类名里
absolutePosition: {
position: 'absolute',
right: '30px',
top: '50%',
transform: 'translateY(-50%)',
},
});
}
};
return (
<View onClick={handClick} style={{ color: 'var(--fontColor)' }}>
Button
</View>
);
}
export default function PageHome() {
const devId = 'devId'; // your deviceId
const instance = useCtx({
devId,
});
useEffect(() => {
instance.addContent('bottomLeft', {
id: 'WidgetButton',
content: WidgetButton,
});
}, []);
return (
<View className={Styles.container}>
<View className={Styles.playerWarp} style={{ marginTop: 300 }}>
<IPCPlayerIntegration
style={{ height: '300px' }}
instance={instance}
devId={instance.devId}
playerFit="cover"
/>
</View>
</View>
);
}