little men sliding around
This commit is contained in:
@@ -21,7 +21,9 @@ pub struct CursorPosition {
|
|||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, Type)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, Type)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct CursorPositions {
|
pub struct CursorPositions {
|
||||||
|
/// Absolute cursor coordinates in physical pixels.
|
||||||
pub raw: CursorPosition,
|
pub raw: CursorPosition,
|
||||||
|
/// Cursor coordinates normalized to the source monitor for scale-independent projection.
|
||||||
pub mapped: CursorPosition,
|
pub mapped: CursorPosition,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,6 +182,25 @@ mod tests {
|
|||||||
assert_eq!(snapshot.len(), 2);
|
assert_eq!(snapshot.len(), 2);
|
||||||
assert_eq!(snapshot["local"].raw.x, 3.0);
|
assert_eq!(snapshot["local"].raw.x, 3.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn physical_cursor_positions_normalize_across_display_scale_factors() {
|
||||||
|
let one_x = transform_coords(&CursorPosition { x: 720.0, y: 450.0 }, true, 1440.0, 900.0);
|
||||||
|
let two_x = transform_coords(
|
||||||
|
&CursorPosition {
|
||||||
|
x: 1440.0,
|
||||||
|
y: 900.0,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
2880.0,
|
||||||
|
1800.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(one_x.x, 0.5);
|
||||||
|
assert_eq!(one_x.y, 0.5);
|
||||||
|
assert_eq!(two_x.x, one_x.x);
|
||||||
|
assert_eq!(two_x.y, one_x.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop cursor tracking and unregister all listeners.
|
/// Stop cursor tracking and unregister all listeners.
|
||||||
|
|||||||
+9
-1
@@ -84,7 +84,15 @@ export type ConnectionState = "connecting" | "connected" | "disconnected"
|
|||||||
export type ConnectionStatus = { remoteId: string; address: string; name: string | null; state: ConnectionState }
|
export type ConnectionStatus = { remoteId: string; address: string; name: string | null; state: ConnectionState }
|
||||||
export type CursorPosition = { x: number; y: number }
|
export type CursorPosition = { x: number; y: number }
|
||||||
export type CursorPositionChanged = { positions: Partial<{ [key in string]: CursorPositions }> }
|
export type CursorPositionChanged = { positions: Partial<{ [key in string]: CursorPositions }> }
|
||||||
export type CursorPositions = { raw: CursorPosition; mapped: CursorPosition }
|
export type CursorPositions = {
|
||||||
|
/**
|
||||||
|
* Absolute cursor coordinates in physical pixels.
|
||||||
|
*/
|
||||||
|
raw: CursorPosition;
|
||||||
|
/**
|
||||||
|
* Cursor coordinates normalized to the source monitor for scale-independent projection.
|
||||||
|
*/
|
||||||
|
mapped: CursorPosition }
|
||||||
export type ForegroundAppChanged = { meta: AppMeta }
|
export type ForegroundAppChanged = { meta: AppMeta }
|
||||||
export type FriendForegroundAppChanged = { friendId: string; meta: AppMeta }
|
export type FriendForegroundAppChanged = { friendId: string; meta: AppMeta }
|
||||||
export type FriendsChanged = { friends: User[] }
|
export type FriendsChanged = { friends: User[] }
|
||||||
|
|||||||
@@ -1,12 +1,35 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { startHitboxSync } from "./hitboxes";
|
import { startHitboxSync } from "./hitboxes";
|
||||||
|
import { liveMetadata } from "$lib/listeners/live-metadata";
|
||||||
|
|
||||||
onMount(startHitboxSync);
|
onMount(startHitboxSync);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="size-full flex flex-col justify-end">
|
<div class="size-full flex flex-col justify-end">
|
||||||
<div role="banner" class="scene-hitbox w-full h-min bg-white text-black">
|
<div role="banner" class="relative h-8 w-full my-2">
|
||||||
<p class="w-max">WYD</p>
|
{#each Object.entries($liveMetadata.cursorPositions) as [userId, cursor] (userId)}
|
||||||
|
{@const ico = $liveMetadata.foregroundApps.get(userId)?.ico}
|
||||||
|
{#if cursor}
|
||||||
|
<div
|
||||||
|
class="scene-hitbox absolute bottom-0 left-0 flex flex-col gap-1 items-center transition-transform ease-linear duration-1000"
|
||||||
|
style:transform={`translateX(${cursor.mapped.x * 100}vw)`}
|
||||||
|
>
|
||||||
|
{#if ico}
|
||||||
|
<img
|
||||||
|
src={`data:image/png;base64,${ico}`}
|
||||||
|
alt=""
|
||||||
|
class="size-4 object-contain"
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
<img
|
||||||
|
src="/fa.png"
|
||||||
|
alt=""
|
||||||
|
class="size-6"
|
||||||
|
style="filter: sepia(1) saturate(200%) hue-rotate(100deg);"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 191 KiB |
Reference in New Issue
Block a user