-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
264 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { Box } from "@mui/material" | ||
import { useEffect, useReducer, useState } from "react" | ||
import { | ||
SceneOverlayTag, | ||
SceneOverlayEvent, | ||
SceneOverlayEventKey, | ||
SceneOverlayTagEvent, | ||
SceneOverlayTagEventKey, | ||
} from "./SceneOverlayEvents" | ||
import Label, { LabelSize } from "./Label" | ||
|
||
const tagMap = new Map<number, SceneOverlayTag>() | ||
|
||
function SceneOverlay() { | ||
/* State to determine if the overlay is disabled */ | ||
const [isDisabled, setIsDisabled] = useState<boolean>(false) | ||
|
||
/* h1 text for each tagMap tag */ | ||
const [components, updateComponents] = useReducer(() => { | ||
if (isDisabled) return <></> // if the overlay is disabled, return nothing | ||
|
||
return [...tagMap.values()].map(x => ( | ||
<div | ||
key={x.id} | ||
style={{ | ||
position: "absolute", | ||
left: x.position[0], | ||
top: x.position[1], | ||
backgroundColor: "rgba(0, 0, 0, 0.5)", | ||
borderRadius: "8px", | ||
padding: "8px", | ||
whiteSpace: "nowrap", | ||
transform: "translate(-50%, -100%)", | ||
}} | ||
> | ||
<Label size={LabelSize.Large}>{x.text}</Label> | ||
</div> | ||
)) | ||
}, []) | ||
|
||
/* Creating listener for tag events to update tagMap and rerender overlay */ | ||
useEffect(() => { | ||
const onTagAdd = (e: Event) => { | ||
tagMap.set((e as SceneOverlayTagEvent).tag.id, (e as SceneOverlayTagEvent).tag) | ||
} | ||
|
||
const onTagRemove = (e: Event) => { | ||
tagMap.delete((e as SceneOverlayTagEvent).tag.id) | ||
} | ||
|
||
const onUpdate = (_: Event) => { | ||
updateComponents() | ||
} | ||
|
||
const onDisable = () => { | ||
setIsDisabled(true) | ||
updateComponents() | ||
} | ||
|
||
const onEnable = () => { | ||
setIsDisabled(false) | ||
updateComponents() | ||
} | ||
|
||
// listening for tags being added and removed | ||
SceneOverlayTagEvent.Listen(SceneOverlayTagEventKey.ADD, onTagAdd) | ||
SceneOverlayTagEvent.Listen(SceneOverlayTagEventKey.REMOVE, onTagRemove) | ||
|
||
// listening for updates to the overlay every frame | ||
SceneOverlayEvent.Listen(SceneOverlayEventKey.UPDATE, onUpdate) | ||
|
||
// listening for disabling and enabling scene tags | ||
SceneOverlayEvent.Listen(SceneOverlayEventKey.DISABLE, onDisable) | ||
SceneOverlayEvent.Listen(SceneOverlayEventKey.ENABLE, onEnable) | ||
|
||
// disposing all the tags and listeners when the scene is destroyed | ||
return () => { | ||
SceneOverlayTagEvent.RemoveListener(SceneOverlayTagEventKey.ADD, onTagAdd) | ||
SceneOverlayTagEvent.RemoveListener(SceneOverlayTagEventKey.REMOVE, onTagRemove) | ||
SceneOverlayEvent.RemoveListener(SceneOverlayEventKey.UPDATE, onUpdate) | ||
SceneOverlayEvent.RemoveListener(SceneOverlayEventKey.DISABLE, onDisable) | ||
SceneOverlayEvent.RemoveListener(SceneOverlayEventKey.ENABLE, onEnable) | ||
tagMap.clear() | ||
} | ||
}, []) | ||
|
||
/* Render the overlay as a box that spans the entire screen and does not intercept any user interaction */ | ||
return ( | ||
<Box | ||
component="div" | ||
display="flex" | ||
sx={{ | ||
position: "fixed", | ||
left: "0pt", | ||
top: "0pt", | ||
width: "100vw", | ||
height: "100vh", | ||
overflow: "hidden", | ||
pointerEvents: "none", | ||
}} | ||
> | ||
{components ?? <></>} | ||
</Box> | ||
) | ||
} | ||
|
||
export default SceneOverlay |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
let nextTagId = 0 | ||
|
||
/* Coordinates for tags in world space */ | ||
export type PixelSpaceCoord = [number, number] | ||
|
||
/** Contains the event keys for events that require a SceneOverlayTag as a parameter */ | ||
export const enum SceneOverlayTagEventKey { | ||
ADD = "SceneOverlayTagAddEvent", | ||
REMOVE = "SceneOverlayTagRemoveEvent", | ||
} | ||
|
||
/** Contains the event keys for other Scene Overlay Events */ | ||
export const enum SceneOverlayEventKey { | ||
UPDATE = "SceneOverlayUpdateEvent", | ||
DISABLE = "SceneOverlayDisableEvent", | ||
ENABLE = "SceneOverlayEnableEvent", | ||
} | ||
|
||
/** | ||
* Represents a tag that can be displayed on the screen | ||
* | ||
* @param text The text to display | ||
* @param position The position of the tag in screen space (default: [0,0]) | ||
*/ | ||
export class SceneOverlayTag { | ||
private _id: number | ||
public text: string | ||
public position: PixelSpaceCoord // Screen Space | ||
|
||
public get id() { | ||
return this._id | ||
} | ||
|
||
/** Create a new tag */ | ||
public constructor(text: string, position?: PixelSpaceCoord) { | ||
this._id = nextTagId++ | ||
|
||
this.text = text | ||
this.position = position ?? [0, 0] | ||
new SceneOverlayTagEvent(SceneOverlayTagEventKey.ADD, this) | ||
} | ||
|
||
/** Removing the tag */ | ||
public Dispose() { | ||
new SceneOverlayTagEvent(SceneOverlayTagEventKey.REMOVE, this) | ||
} | ||
} | ||
|
||
/** Event handler for events that use a SceneOverlayTag as a parameter */ | ||
export class SceneOverlayTagEvent extends Event { | ||
public tag: SceneOverlayTag | ||
|
||
public constructor(eventKey: SceneOverlayTagEventKey, tag: SceneOverlayTag) { | ||
super(eventKey) | ||
|
||
this.tag = tag | ||
|
||
window.dispatchEvent(this) | ||
} | ||
|
||
public static Listen(eventKey: SceneOverlayTagEventKey, func: (e: Event) => void) { | ||
window.addEventListener(eventKey, func) | ||
} | ||
|
||
public static RemoveListener(eventKey: SceneOverlayTagEventKey, func: (e: Event) => void) { | ||
window.removeEventListener(eventKey, func) | ||
} | ||
} | ||
|
||
/** Event handler for other SceneOverlay events */ | ||
export class SceneOverlayEvent extends Event { | ||
public constructor(eventKey: SceneOverlayEventKey) { | ||
super(eventKey) | ||
|
||
window.dispatchEvent(this) | ||
} | ||
|
||
public static Listen(eventKey: SceneOverlayEventKey, func: (e: Event) => void) { | ||
window.addEventListener(eventKey, func) | ||
} | ||
|
||
public static RemoveListener(eventKey: SceneOverlayEventKey, func: (e: Event) => void) { | ||
window.removeEventListener(eventKey, func) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters