compute ScreenBounds once

This commit is contained in:
Evan Carroll 2026-01-26 23:03:54 -06:00
parent c434321376
commit 30722bed8f
2 changed files with 22 additions and 22 deletions

View file

@ -354,12 +354,8 @@ pub fn Avatar(
/// Opacity for fade-out animation (0.0 to 1.0, default 1.0). /// Opacity for fade-out animation (0.0 to 1.0, default 1.0).
#[prop(default = 1.0)] #[prop(default = 1.0)]
opacity: f64, opacity: f64,
/// Scene width in scene coordinates (for boundary calculations). /// Screen bounds for clamping (computed once at scene level).
#[prop(optional)] screen_bounds: Signal<ScreenBounds>,
scene_width: Option<Signal<f64>>,
/// Scene height in scene coordinates (for boundary calculations).
#[prop(optional)]
scene_height: Option<Signal<f64>>,
/// Active speech bubble for this avatar (None if not speaking). /// Active speech bubble for this avatar (None if not speaking).
#[prop(optional)] #[prop(optional)]
active_bubble: Option<Signal<Option<ActiveBubble>>>, active_bubble: Option<Signal<Option<ActiveBubble>>>,
@ -397,12 +393,8 @@ pub fn Avatar(
&m.avatar.emotion_layer, &m.avatar.emotion_layer,
); );
// Get scene dimensions (use large defaults if not provided) // Use passed-in screen bounds (computed once at scene level)
let sw = scene_width.map(|s| s.get()).unwrap_or(10000.0); let boundaries = screen_bounds.get();
let sh = scene_height.map(|s| s.get()).unwrap_or(10000.0);
// Compute screen boundaries and avatar screen position
let boundaries = ScreenBounds::from_transform(sw, sh, sx, sy, ox, oy);
let avatar_screen_x = m.member.position_x * sx + ox; let avatar_screen_x = m.member.position_x * sx + ox;
let avatar_screen_y = m.member.position_y * sy + oy; let avatar_screen_y = m.member.position_y * sy + oy;
@ -513,16 +505,14 @@ pub fn Avatar(
&m.avatar.emotion_layer, &m.avatar.emotion_layer,
); );
// Get scene dimensions and transform parameters // Get transform parameters for computing avatar screen position
let sx = scale_x.get(); let sx = scale_x.get();
let sy = scale_y.get(); let sy = scale_y.get();
let ox = offset_x.get(); let ox = offset_x.get();
let oy = offset_y.get(); let oy = offset_y.get();
let sw = scene_width.map(|s| s.get()).unwrap_or(10000.0);
let sh = scene_height.map(|s| s.get()).unwrap_or(10000.0);
// Create unified layout - same calculation as style closure // Use passed-in screen bounds (computed once at scene level)
let boundaries = ScreenBounds::from_transform(sw, sh, sx, sy, ox, oy); let boundaries = screen_bounds.get();
let avatar_screen_x = m.member.position_x * sx + ox; let avatar_screen_x = m.member.position_x * sx + ox;
let avatar_screen_y = m.member.position_y * sy + oy; let avatar_screen_y = m.member.position_y * sy + oy;

View file

@ -22,7 +22,7 @@ use uuid::Uuid;
use chattyness_db::models::{ChannelMemberWithAvatar, LooseProp, Scene}; use chattyness_db::models::{ChannelMemberWithAvatar, LooseProp, Scene};
use super::avatar::{Avatar, member_key}; use super::avatar::{Avatar, ScreenBounds, member_key};
#[cfg(feature = "hydrate")] #[cfg(feature = "hydrate")]
use super::canvas_utils::hit_test_canvas; use super::canvas_utils::hit_test_canvas;
use super::chat_types::ActiveBubble; use super::chat_types::ActiveBubble;
@ -450,6 +450,18 @@ pub fn RealmSceneViewer(
let scene_width_signal = Signal::derive(move || scene_width_f); let scene_width_signal = Signal::derive(move || scene_width_f);
let scene_height_signal = Signal::derive(move || scene_height_f); let scene_height_signal = Signal::derive(move || scene_height_f);
// Compute ScreenBounds once for all avatars (instead of each avatar computing it)
let screen_bounds = Signal::derive(move || {
ScreenBounds::from_transform(
scene_width_signal.get(),
scene_height_signal.get(),
scale_x_signal.get(),
scale_y_signal.get(),
offset_x_signal.get(),
offset_y_signal.get(),
)
});
let members_by_key = Signal::derive(move || { let members_by_key = Signal::derive(move || {
sorted_members.get().into_iter().enumerate() sorted_members.get().into_iter().enumerate()
.map(|(idx, m)| (member_key(&m), (idx, m))) .map(|(idx, m)| (member_key(&m), (idx, m)))
@ -520,8 +532,7 @@ pub fn RealmSceneViewer(
prop_size=prop_size prop_size=prop_size
z_index=z z_index=z
text_em_size=text_em_size text_em_size=text_em_size
scene_width=scene_width_signal screen_bounds=screen_bounds
scene_height=scene_height_signal
active_bubble=bubble_signal active_bubble=bubble_signal
/> />
} }
@ -553,8 +564,7 @@ pub fn RealmSceneViewer(
z_index=5 z_index=5
text_em_size=text_em_size text_em_size=text_em_size
opacity=opacity opacity=opacity
scene_width=scene_width_signal screen_bounds=screen_bounds
scene_height=scene_height_signal
/> />
}) })
} else { None } } else { None }