diff --git a/source/Component/Recorder/Recorder.scss b/source/Component/Recorder/Recorder.scss new file mode 100644 index 0000000..84d1461 --- /dev/null +++ b/source/Component/Recorder/Recorder.scss @@ -0,0 +1,136 @@ +@import "../Theme/Theme.scss"; + +div.recorder-root { + width: 100%; + box-sizing: border-box; + padding: 10px; + + div.recorder-slider { + width: 100%; + + div.ms-Slider-slideBox { + height: 16px; + } + + span.ms-Slider-thumb { + width: 12px; + height: 12px; + line-height: 16px; + border-width: 3px; + top: -4px; + } + + span.ms-Slider-active { + height: 3px; + } + + span.ms-Slider-inactive { + height: 3px; + } + } + + div.recorder-content { + width: 100%; + height: 32px; + display: flex; + justify-content: space-between; + align-items: center; + box-sizing: border-box; + padding: 0 8px; + + div.time-view { + flex-shrink: 1; + width: 50%; + text-align: left; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + div.ctrl-button { + cursor: pointer; + user-select: none; + width: 96px; + flex-shrink: 0; + text-align: center; + display: flex; + justify-content: center; + align-items: center; + + div.ctrl-action { + width: 32px; + height: 32px; + display: flex; + justify-content: center; + align-items: center; + } + + div.ctrl-action-main { + font-size: 1.5em; + } + } + + div.speed-view { + flex-shrink: 1; + width: 50%; + text-align: right; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } +} + +div.recorder-root.light { + + div.recorder-slider { + + span.ms-Slider-thumb { + background-color: $lt-bg-color-lvl1-light; + border-color: $lt-font-color-normal-light; + } + + span.ms-Slider-active { + background-color: $lt-font-color-normal-light; + } + + span.ms-Slider-inactive { + background-color: $lt-bg-color-lvl1-light; + } + } + + div.recorder-content { + + div.ctrl-button div.ctrl-action:hover { + background-color: $lt-bg-color-lvl3-light; + color: $lt-font-color-lvl1-light; + } + } +} + +div.recorder-root.dark { + + div.recorder-slider { + + span.ms-Slider-thumb { + background-color: $lt-bg-color-lvl1-dark; + border-color: $lt-font-color-normal-dark; + } + + span.ms-Slider-active { + background-color: $lt-font-color-normal-dark; + } + + span.ms-Slider-inactive { + background-color: $lt-bg-color-lvl1-dark; + } + } + + div.recorder-content { + + div.ctrl-button div.ctrl-action:hover { + background-color: $lt-bg-color-lvl3-dark; + color: $lt-font-color-lvl1-dark; + } + } +} \ No newline at end of file diff --git a/source/Component/Recorder/Recorder.tsx b/source/Component/Recorder/Recorder.tsx new file mode 100644 index 0000000..c5ffef2 --- /dev/null +++ b/source/Component/Recorder/Recorder.tsx @@ -0,0 +1,73 @@ +import { Localization } from "@Component/Localization/Localization"; +import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme"; +import { Icon, Slider } from "@fluentui/react"; +import { Component, ReactNode } from "react"; +import "./Recorder.scss"; + +interface IRecorderProps { + mode?: "P" | "R", + name?: string; + fps?: number; + allFrame?: number; + currentFrame?: number; + allTime?: number; + currentTime?: number; +} + +class Recorder extends Component { + + private parseTime(time?: number): string { + if (time === undefined) { + return "--:--:--:--"; + } + const h = Math.floor(time / 3600); + const m = Math.floor((time % 3600) / 60); + const s = Math.floor((time % 3600) % 60); + const ms = Math.floor((time % 1) * 1000); + return `${h}:${m}:${s}:${ms}`; + } + + public render(): ReactNode { + return + +
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ {this.props.name} +
+
+
; + } +} + +export { Recorder }; \ No newline at end of file diff --git a/source/Localization/EN-US.ts b/source/Localization/EN-US.ts index 2138ff9..d91c50c 100644 --- a/source/Localization/EN-US.ts +++ b/source/Localization/EN-US.ts @@ -53,6 +53,9 @@ const EN_US = { "Panel.Info.Behavior.List.View": "Edit view behavior list", "Panel.Title.Behavior.Details.View": "Behavior", "Panel.Info.Behavior.Details.View": "Edit view Behavior attributes", + "Panel.Title.Behavior.Clip.Player": "Recording", + "Panel.Info.Behavior.Clip.Player": "Pre render recorded data", + "Panel.Info.Behavior.Clip.Time.Formate": "{current} / {all} / {fps}fps", "Popup.Title.Unnamed": "Popup message", "Popup.Title.Confirm": "Confirm message", "Popup.Action.Yes": "Confirm", diff --git a/source/Localization/ZH-CN.ts b/source/Localization/ZH-CN.ts index 1ee7e39..a538e1d 100644 --- a/source/Localization/ZH-CN.ts +++ b/source/Localization/ZH-CN.ts @@ -53,6 +53,9 @@ const ZH_CN = { "Panel.Info.Behavior.List.View": "编辑查看行为列表", "Panel.Title.Behavior.Details.View": "行为", "Panel.Info.Behavior.Details.View": "编辑查看行为属性", + "Panel.Title.Behavior.Clip.Player": "录制", + "Panel.Info.Behavior.Clip.Player": "预渲染录制数据", + "Panel.Info.Behavior.Clip.Time.Formate": "{current} / {all} / {fps} fps", "Popup.Title.Unnamed": "弹窗消息", "Popup.Title.Confirm": "确认消息", "Popup.Action.Yes": "确定", diff --git a/source/Page/SimulatorWeb/SimulatorWeb.tsx b/source/Page/SimulatorWeb/SimulatorWeb.tsx index 255b201..cfdfd1f 100644 --- a/source/Page/SimulatorWeb/SimulatorWeb.tsx +++ b/source/Page/SimulatorWeb/SimulatorWeb.tsx @@ -55,7 +55,7 @@ class SimulatorWeb extends Component { items: [ {panels: ["RenderView"]}, { - items: [{panels: ["BehaviorList"]}, {panels: ["LabelList"]}], + items: [{panels: ["ClipPlayer", "BehaviorList"]}, {panels: ["LabelList"]}], scale: 80, layout: LayoutDirection.X } diff --git a/source/Panel/ClipPlayer/ClipPlayer.scss b/source/Panel/ClipPlayer/ClipPlayer.scss new file mode 100644 index 0000000..e69de29 diff --git a/source/Panel/ClipPlayer/ClipPlayer.tsx b/source/Panel/ClipPlayer/ClipPlayer.tsx new file mode 100644 index 0000000..557871c --- /dev/null +++ b/source/Panel/ClipPlayer/ClipPlayer.tsx @@ -0,0 +1,13 @@ +import { Component, ReactNode } from "react"; +import "./ClipPlayer.scss"; + +class ClipPlayer extends Component { + + public render(): ReactNode { + return <> + + ; + } +} + +export { ClipPlayer }; \ No newline at end of file diff --git a/source/Panel/ClipPlayer/ClipRecorder.tsx b/source/Panel/ClipPlayer/ClipRecorder.tsx new file mode 100644 index 0000000..9304ff3 --- /dev/null +++ b/source/Panel/ClipPlayer/ClipRecorder.tsx @@ -0,0 +1,10 @@ +import { Component, ReactNode } from "react"; +import { Recorder } from "@Component/Recorder/Recorder"; + +class ClipRecorder extends Component { + public render(): ReactNode { + return + } +} + +export { ClipRecorder }; \ No newline at end of file diff --git a/source/Panel/Panel.tsx b/source/Panel/Panel.tsx index c7ba6fc..ef3542b 100644 --- a/source/Panel/Panel.tsx +++ b/source/Panel/Panel.tsx @@ -10,6 +10,8 @@ import { LabelDetails } from "@Panel/LabelDetails/LabelDetails"; import { GroupDetails } from "@Panel/GroupDetails/GroupDetails"; import { BehaviorList } from "@Panel/BehaviorList/BehaviorList"; import { BehaviorDetails } from "@Panel/BehaviorDetails/BehaviorDetails"; +import { ClipPlayer } from "@Panel/ClipPlayer/ClipPlayer"; +import { ClipRecorder } from "@Panel/ClipPlayer/ClipRecorder"; interface IPanelInfo { nameKey: string; @@ -31,6 +33,7 @@ type PanelId = "" | "GroupDetails" // 群属性 | "BehaviorList" // 行为列表 | "BehaviorDetails" // 行为属性 +| "ClipPlayer" // 剪辑影片 ; const PanelInfoMap = new Map(); @@ -66,6 +69,10 @@ PanelInfoMap.set("BehaviorDetails", { nameKey: "Panel.Title.Behavior.Details.View", introKay: "Panel.Info.Behavior.Details.View", class: BehaviorDetails }); +PanelInfoMap.set("ClipPlayer", { + nameKey: "Panel.Title.Behavior.Clip.Player", introKay: "Panel.Info.Behavior.Clip.Player", + class: ClipPlayer, header: ClipRecorder, hidePadding: true +}); function getPanelById(panelId: PanelId): ReactNode { switch (panelId) {