diff --git a/web/src/components/TimelineEventOverlay.jsx b/web/src/components/TimelineEventOverlay.jsx
new file mode 100644
index 000000000..717b3809a
--- /dev/null
+++ b/web/src/components/TimelineEventOverlay.jsx
@@ -0,0 +1,65 @@
+import { Fragment, h } from 'preact';
+import { useState } from 'preact/hooks';
+
+export default function TimelineEventOverlay({ eventOverlay, cameraConfig }) {
+ const boxLeftEdge = Math.round(eventOverlay.data.box[0] * 100);
+ const boxTopEdge = Math.round(eventOverlay.data.box[1] * 100);
+ const boxRightEdge = Math.round((1 - eventOverlay.data.box[2] - eventOverlay.data.box[0]) * 100);
+ const boxBottomEdge = Math.round((1 - eventOverlay.data.box[3] - eventOverlay.data.box[1]) * 100);
+
+ const [isHovering, setIsHovering] = useState(false);
+ const getHoverStyle = () => {
+ if (boxLeftEdge < 15) {
+ // show object stats on right side
+ return {
+ left: `${boxLeftEdge + eventOverlay.data.box[2] * 100 + 1}%`,
+ top: `${boxTopEdge}%`,
+ };
+ }
+
+ return {
+ right: `${boxRightEdge + eventOverlay.data.box[2] * 100 + 1}%`,
+ top: `${boxTopEdge}%`,
+ };
+ };
+
+ const getObjectArea = () => {
+ const width = eventOverlay.data.box[2] * cameraConfig.detect.width;
+ const height = eventOverlay.data.box[3] * cameraConfig.detect.height;
+ return Math.round(width * height);
+ };
+
+ const getObjectRatio = () => {
+ const width = eventOverlay.data.box[2] * cameraConfig.detect.width;
+ const height = eventOverlay.data.box[3] * cameraConfig.detect.height;
+ return Math.round(100 * (width / height)) / 100;
+ };
+
+ return (
+