diff --git a/web/src/components/TimelineEventOverlay.jsx b/web/src/components/TimelineEventOverlay.jsx
new file mode 100644
index 000000000..33c6b99bf
--- /dev/null
+++ b/web/src/components/TimelineEventOverlay.jsx
@@ -0,0 +1,65 @@
+import { Fragment, h } from 'preact';
+import { useCallback, useState } from 'preact/hooks';
+import Heading from './Heading';
+
+export default function TimelineEventOverlay({ event, 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];
+ const height = eventOverlay.data.box[3];
+ return Math.round(100 * width / height) / 100;
+ };
+
+ return (
+