@@ -324,12 +324,12 @@ impl CursorLayer {
324324 // Apply zoom scaling to cursor size to match position transformation
325325 let zoom_scale = 1.0 / zoom. display_amount ( ) . max ( 0.001 ) ; // Avoid division by zero
326326
327- // Calculate hotspot based on base size (before click scaling) to maintain consistent positioning
327+ // Calculate hotspot based on base size (before zoom and click scaling) in frame space
328328 let cursor_base_size_px: XY < f64 > = cursor_base_size_px. into ( ) ;
329- let cursor_base_size_zoomed = cursor_base_size_px * zoom_scale;
330- let hotspot_px = cursor_texture. hotspot * cursor_base_size_zoomed;
329+ let hotspot_frame_px = cursor_texture. hotspot * cursor_base_size_px;
331330
332- // Apply click scaling for rendering size only
331+ // Apply zoom and click scaling for rendering size
332+ let cursor_base_size_zoomed = cursor_base_size_px * zoom_scale;
333333 let cursor_size_px = cursor_base_size_zoomed * click_scale_factor as f64 ;
334334
335335 let position = {
@@ -339,7 +339,8 @@ impl CursorLayer {
339339 resolution_base,
340340 ) ;
341341
342- frame_position. coord = frame_position. coord - hotspot_px. map ( |v| v as f64 ) ;
342+ // Subtract hotspot in frame space before zoom transformation
343+ frame_position. coord = frame_position. coord - hotspot_frame_px. map ( |v| v as f64 ) ;
343344
344345 frame_position
345346 . to_zoomed_frame_space ( & constants. options , & uniforms. project , resolution_base, zoom)
@@ -532,24 +533,19 @@ impl CursorTexture {
532533 // Calculate scale to fit the SVG into the target size while maintaining aspect ratio
533534 let scale_x = width as f32 / rtree. size ( ) . width ( ) ;
534535 let scale_y = SVG_CURSOR_RASTERIZED_HEIGHT as f32 / rtree. size ( ) . height ( ) ;
535- let scale = scale_x. min ( scale_y) * 1.5 ;
536- let transform = tiny_skia:: Transform :: from_row (
537- scale,
538- 0.0 ,
539- 0.0 ,
540- scale,
541- ( SVG_CURSOR_RASTERIZED_HEIGHT / 4 ) as f32 * -1.0 ,
542- ( SVG_CURSOR_RASTERIZED_HEIGHT / 4 ) as f32 * -1.0 ,
543- ) ;
536+ let scale = scale_x. min ( scale_y) ;
537+ let transform = tiny_skia:: Transform :: from_scale ( scale, scale) ;
544538
545539 resvg:: render ( & rtree, transform, & mut pixmap. as_mut ( ) ) ;
546540
547541 let rgba: Vec < u8 > = pixmap
548542 . pixels ( )
549543 . iter ( )
550- . flat_map ( |p| [ p. red ( ) , p. green ( ) , p. red ( ) , p. alpha ( ) ] )
544+ . flat_map ( |p| [ p. red ( ) , p. green ( ) , p. blue ( ) , p. alpha ( ) ] )
551545 . collect ( ) ;
552546
547+ // Keep hotspot in normalized coordinates (0.0-1.0) for consistency
548+
553549 Ok ( Self :: prepare (
554550 constants,
555551 & rgba,
0 commit comments