mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-03-18 06:08:22 +03:00
Merge pull request #34 from ibs0d/codex/fix-zoom-behavior-in-draggablegridlayout
Apply grid zoom to video layer only and keep overlays anchored
This commit is contained in:
commit
e36d12d9f9
@ -51,6 +51,11 @@ type LivePlayerProps = {
|
|||||||
setFullResolution?: React.Dispatch<React.SetStateAction<VideoResolutionType>>;
|
setFullResolution?: React.Dispatch<React.SetStateAction<VideoResolutionType>>;
|
||||||
onError?: (error: LivePlayerError) => void;
|
onError?: (error: LivePlayerError) => void;
|
||||||
onResetLiveMode?: () => void;
|
onResetLiveMode?: () => void;
|
||||||
|
contentTransform?: {
|
||||||
|
scale: number;
|
||||||
|
positionX: number;
|
||||||
|
positionY: number;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function LivePlayer({
|
export default function LivePlayer({
|
||||||
@ -76,6 +81,7 @@ export default function LivePlayer({
|
|||||||
setFullResolution,
|
setFullResolution,
|
||||||
onError,
|
onError,
|
||||||
onResetLiveMode,
|
onResetLiveMode,
|
||||||
|
contentTransform,
|
||||||
}: LivePlayerProps) {
|
}: LivePlayerProps) {
|
||||||
const { t } = useTranslation(["components/player"]);
|
const { t } = useTranslation(["components/player"]);
|
||||||
|
|
||||||
@ -371,7 +377,41 @@ export default function LivePlayer({
|
|||||||
lowerClassName="md:rounded-2xl"
|
lowerClassName="md:rounded-2xl"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{player}
|
<div
|
||||||
|
className="absolute inset-0"
|
||||||
|
style={
|
||||||
|
contentTransform
|
||||||
|
? {
|
||||||
|
transform: `translate(${contentTransform.positionX}px, ${contentTransform.positionY}px) scale(${contentTransform.scale})`,
|
||||||
|
transformOrigin: "0 0",
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{player}
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"absolute inset-0 w-full",
|
||||||
|
showStillWithoutActivity &&
|
||||||
|
!liveReady &&
|
||||||
|
!isReEnabling &&
|
||||||
|
cameraEnabled
|
||||||
|
? "visible"
|
||||||
|
: "invisible",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<AutoUpdatingCameraImage
|
||||||
|
className="pointer-events-none size-full"
|
||||||
|
cameraClasses="relative size-full flex justify-center"
|
||||||
|
camera={cameraConfig.name}
|
||||||
|
showFps={false}
|
||||||
|
reloadInterval={stillReloadInterval}
|
||||||
|
periodicCache
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{cameraEnabled &&
|
{cameraEnabled &&
|
||||||
!offline &&
|
!offline &&
|
||||||
(!showStillWithoutActivity || isReEnabling) &&
|
(!showStillWithoutActivity || isReEnabling) &&
|
||||||
@ -429,27 +469,6 @@ export default function LivePlayer({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"absolute inset-0 w-full",
|
|
||||||
showStillWithoutActivity &&
|
|
||||||
!liveReady &&
|
|
||||||
!isReEnabling &&
|
|
||||||
cameraEnabled
|
|
||||||
? "visible"
|
|
||||||
: "invisible",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<AutoUpdatingCameraImage
|
|
||||||
className="pointer-events-none size-full"
|
|
||||||
cameraClasses="relative size-full flex justify-center"
|
|
||||||
camera={cameraConfig.name}
|
|
||||||
showFps={false}
|
|
||||||
reloadInterval={stillReloadInterval}
|
|
||||||
periodicCache
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{offline && inDashboard && (
|
{offline && inDashboard && (
|
||||||
<>
|
<>
|
||||||
<div className="absolute inset-0 rounded-lg bg-black/50 md:rounded-2xl" />
|
<div className="absolute inset-0 rounded-lg bg-black/50 md:rounded-2xl" />
|
||||||
|
|||||||
@ -514,7 +514,8 @@ export default function DraggableGridLayout({
|
|||||||
cursorX,
|
cursorX,
|
||||||
cursorY,
|
cursorY,
|
||||||
);
|
);
|
||||||
const content = event.currentTarget.firstElementChild as HTMLElement | null;
|
const content = event.currentTarget
|
||||||
|
.firstElementChild as HTMLElement | null;
|
||||||
const persisted = toPersistedCameraZoomState(next, {
|
const persisted = toPersistedCameraZoomState(next, {
|
||||||
viewportWidth: bounds.width,
|
viewportWidth: bounds.width,
|
||||||
viewportHeight: bounds.height,
|
viewportHeight: bounds.height,
|
||||||
@ -787,59 +788,52 @@ export default function DraggableGridLayout({
|
|||||||
}}
|
}}
|
||||||
onWheel={(event) => handleCardWheelZoom(camera.name, event)}
|
onWheel={(event) => handleCardWheelZoom(camera.name, event)}
|
||||||
>
|
>
|
||||||
<div
|
<LivePlayer
|
||||||
className="size-full"
|
key={camera.name}
|
||||||
style={{
|
streamName={streamName}
|
||||||
transform: `translate(${zoomTransform.positionX}px, ${zoomTransform.positionY}px) scale(${zoomTransform.scale})`,
|
autoLive={autoLive ?? globalAutoLive}
|
||||||
transformOrigin: "0 0",
|
showStillWithoutActivity={
|
||||||
|
showStillWithoutActivity ?? true
|
||||||
|
}
|
||||||
|
alwaysShowCameraName={displayCameraNames}
|
||||||
|
useWebGL={useWebGL}
|
||||||
|
cameraRef={cameraRef}
|
||||||
|
contentTransform={zoomTransform}
|
||||||
|
className={cn(
|
||||||
|
"draggable-live-grid-mse-cover size-full rounded-lg bg-black md:rounded-2xl",
|
||||||
|
camera.ui?.rotate &&
|
||||||
|
"draggable-live-grid-rotated [--frigate-mse-grid-rotated:1] [--frigate-mse-grid-rotation:rotate(90deg)]",
|
||||||
|
isEditMode &&
|
||||||
|
showCircles &&
|
||||||
|
"outline-2 outline-muted-foreground hover:cursor-grab hover:outline-4 active:cursor-grabbing",
|
||||||
|
)}
|
||||||
|
windowVisible={
|
||||||
|
windowVisible && visibleCameras.includes(camera.name)
|
||||||
|
}
|
||||||
|
cameraConfig={camera}
|
||||||
|
preferredLiveMode={
|
||||||
|
preferredLiveModes[camera.name] ?? "mse"
|
||||||
|
}
|
||||||
|
playInBackground={false}
|
||||||
|
showStats={statsStates[camera.name] ?? true}
|
||||||
|
onClick={() => {
|
||||||
|
!isEditMode && onSelectCamera(camera.name);
|
||||||
}}
|
}}
|
||||||
>
|
onError={(e) => {
|
||||||
<LivePlayer
|
setPreferredLiveModes((prevModes) => {
|
||||||
key={camera.name}
|
const newModes = { ...prevModes };
|
||||||
streamName={streamName}
|
if (e === "mse-decode") {
|
||||||
autoLive={autoLive ?? globalAutoLive}
|
delete newModes[camera.name];
|
||||||
showStillWithoutActivity={
|
}
|
||||||
showStillWithoutActivity ?? true
|
return newModes;
|
||||||
}
|
});
|
||||||
alwaysShowCameraName={displayCameraNames}
|
}}
|
||||||
useWebGL={useWebGL}
|
onResetLiveMode={() =>
|
||||||
cameraRef={cameraRef}
|
resetPreferredLiveMode(camera.name)
|
||||||
className={cn(
|
}
|
||||||
"draggable-live-grid-mse-cover size-full rounded-lg bg-black md:rounded-2xl",
|
playAudio={audioStates[camera.name]}
|
||||||
camera.ui?.rotate &&
|
volume={volumeStates[camera.name]}
|
||||||
"draggable-live-grid-rotated [--frigate-mse-grid-rotated:1] [--frigate-mse-grid-rotation:rotate(90deg)]",
|
/>
|
||||||
isEditMode &&
|
|
||||||
showCircles &&
|
|
||||||
"outline-2 outline-muted-foreground hover:cursor-grab hover:outline-4 active:cursor-grabbing",
|
|
||||||
)}
|
|
||||||
windowVisible={
|
|
||||||
windowVisible && visibleCameras.includes(camera.name)
|
|
||||||
}
|
|
||||||
cameraConfig={camera}
|
|
||||||
preferredLiveMode={
|
|
||||||
preferredLiveModes[camera.name] ?? "mse"
|
|
||||||
}
|
|
||||||
playInBackground={false}
|
|
||||||
showStats={statsStates[camera.name] ?? true}
|
|
||||||
onClick={() => {
|
|
||||||
!isEditMode && onSelectCamera(camera.name);
|
|
||||||
}}
|
|
||||||
onError={(e) => {
|
|
||||||
setPreferredLiveModes((prevModes) => {
|
|
||||||
const newModes = { ...prevModes };
|
|
||||||
if (e === "mse-decode") {
|
|
||||||
delete newModes[camera.name];
|
|
||||||
}
|
|
||||||
return newModes;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
onResetLiveMode={() =>
|
|
||||||
resetPreferredLiveMode(camera.name)
|
|
||||||
}
|
|
||||||
playAudio={audioStates[camera.name]}
|
|
||||||
volume={volumeStates[camera.name]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{isEditMode && showCircles && <CornerCircles />}
|
{isEditMode && showCircles && <CornerCircles />}
|
||||||
</GridLiveContextMenu>
|
</GridLiveContextMenu>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user