ScreenElement.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. 'use client';
  2. import { ElementTypes, type PPTElement } from '@/lib/types/slides';
  3. import { useMemo } from 'react';
  4. import { BaseImageElement } from '../components/element/ImageElement/BaseImageElement';
  5. import { BaseTextElement } from '../components/element/TextElement/BaseTextElement';
  6. import { BaseShapeElement } from '../components/element/ShapeElement/BaseShapeElement';
  7. import { BaseLineElement } from '../components/element/LineElement/BaseLineElement';
  8. import { BaseChartElement } from '../components/element/ChartElement/BaseChartElement';
  9. import { BaseLatexElement } from '../components/element/LatexElement/BaseLatexElement';
  10. import { BaseTableElement } from '../components/element/TableElement/BaseTableElement';
  11. import { BaseVideoElement } from '../components/element/VideoElement/BaseVideoElement';
  12. import { useSceneSelector } from '@/lib/contexts/scene-context';
  13. import type { SceneContent } from '@/lib/types/stage';
  14. interface ScreenElementProps {
  15. readonly elementInfo: PPTElement;
  16. readonly elementIndex: number;
  17. readonly animate?: boolean;
  18. }
  19. export function ScreenElement({ elementInfo, elementIndex, animate }: ScreenElementProps) {
  20. const CurrentElementComponent = useMemo(() => {
  21. // eslint-disable-next-line @typescript-eslint/no-explicit-any -- element components have varying prop signatures
  22. const elementTypeMap: Record<string, any> = {
  23. [ElementTypes.IMAGE]: BaseImageElement,
  24. [ElementTypes.TEXT]: BaseTextElement,
  25. [ElementTypes.SHAPE]: BaseShapeElement,
  26. [ElementTypes.LINE]: BaseLineElement,
  27. [ElementTypes.CHART]: BaseChartElement,
  28. [ElementTypes.LATEX]: BaseLatexElement,
  29. [ElementTypes.TABLE]: BaseTableElement,
  30. [ElementTypes.VIDEO]: BaseVideoElement,
  31. // TODO: Add other element types
  32. // [ElementTypes.AUDIO]: BaseAudioElement,
  33. };
  34. return elementTypeMap[elementInfo.type] || null;
  35. }, [elementInfo.type]);
  36. const theme = useSceneSelector<SceneContent, { fontColor: string; fontName: string }>(
  37. (content) => {
  38. if (content.type === 'slide') {
  39. return content.canvas.theme;
  40. }
  41. return {
  42. fontColor: '#333333',
  43. fontName: 'Microsoft YaHei',
  44. };
  45. },
  46. );
  47. if (!CurrentElementComponent) {
  48. return null;
  49. }
  50. return (
  51. <div
  52. className="screen-element"
  53. id={`screen-element-${elementInfo.id}`}
  54. style={{
  55. zIndex: elementIndex,
  56. color: theme.fontColor,
  57. fontFamily: theme.fontName,
  58. }}
  59. >
  60. <CurrentElementComponent elementInfo={elementInfo} animate={animate} />
  61. </div>
  62. );
  63. }