1
1
use super :: utility_functions:: overlay_canvas_context;
2
2
use crate :: consts:: {
3
- COLOR_OVERLAY_BLUE , COLOR_OVERLAY_TRANSPARENT , COLOR_OVERLAY_WHITE , COLOR_OVERLAY_YELLOW , MANIPULATOR_GROUP_MARKER_SIZE , PIVOT_CROSSHAIR_LENGTH , PIVOT_CROSSHAIR_THICKNESS , PIVOT_DIAMETER ,
3
+ COLOR_OVERLAY_BLUE , COLOR_OVERLAY_GREEN , COLOR_OVERLAY_RED , COLOR_OVERLAY_WHITE , COLOR_OVERLAY_YELLOW , COMPASS_ROSE_ARROW_SIZE , COMPASS_ROSE_HOVER_RING_DIAMETER , COMPASS_ROSE_MAIN_RING_DIAMETER ,
4
+ COMPASS_ROSE_RING_INNER_DIAMETER , MANIPULATOR_GROUP_MARKER_SIZE , PIVOT_CROSSHAIR_LENGTH , PIVOT_CROSSHAIR_THICKNESS , PIVOT_DIAMETER ,
4
5
} ;
5
6
use crate :: messages:: prelude:: Message ;
6
7
@@ -9,7 +10,7 @@ use graphene_core::renderer::Quad;
9
10
use graphene_std:: vector:: { PointId , SegmentId , VectorData } ;
10
11
11
12
use core:: borrow:: Borrow ;
12
- use core:: f64:: consts:: TAU ;
13
+ use core:: f64:: consts:: { FRAC_PI_2 , TAU } ;
13
14
use glam:: { DAffine2 , DVec2 } ;
14
15
use std:: collections:: HashMap ;
15
16
use wasm_bindgen:: JsValue ;
@@ -294,9 +295,15 @@ impl OverlayContext {
294
295
295
296
pub fn draw_scale ( & mut self , start : DVec2 , scale : f64 , radius : f64 , text : & str ) {
296
297
let sign = scale. signum ( ) ;
298
+ let mut fill_color = graphene_std:: Color :: from_rgb_str ( crate :: consts:: COLOR_OVERLAY_WHITE . strip_prefix ( '#' ) . unwrap ( ) )
299
+ . unwrap ( )
300
+ . with_alpha ( 0.05 )
301
+ . rgba_hex ( ) ;
302
+ fill_color. insert ( 0 , '#' ) ;
303
+ let fill_color = Some ( fill_color. as_str ( ) ) ;
297
304
self . line ( start + DVec2 :: X * radius * sign, start + DVec2 :: X * ( radius * scale) , None ) ;
298
- self . circle ( start, radius, Some ( COLOR_OVERLAY_TRANSPARENT ) , None ) ;
299
- self . circle ( start, radius * scale. abs ( ) , Some ( COLOR_OVERLAY_TRANSPARENT ) , None ) ;
305
+ self . circle ( start, radius, fill_color , None ) ;
306
+ self . circle ( start, radius * scale. abs ( ) , fill_color , None ) ;
300
307
self . text (
301
308
text,
302
309
COLOR_OVERLAY_BLUE ,
@@ -307,7 +314,77 @@ impl OverlayContext {
307
314
)
308
315
}
309
316
310
- pub fn pivot ( & mut self , position : DVec2 ) {
317
+ pub fn compass_rose ( & mut self , compass_center : DVec2 , angle : f64 , show_compass_with_hover_ring : Option < bool > ) {
318
+ const HOVER_RING_OUTER_RADIUS : f64 = COMPASS_ROSE_HOVER_RING_DIAMETER / 2. ;
319
+ const MAIN_RING_OUTER_RADIUS : f64 = COMPASS_ROSE_MAIN_RING_DIAMETER / 2. ;
320
+ const MAIN_RING_INNER_RADIUS : f64 = COMPASS_ROSE_RING_INNER_DIAMETER / 2. ;
321
+ const ARROW_RADIUS : f64 = COMPASS_ROSE_ARROW_SIZE / 2. ;
322
+ const HOVER_RING_STROKE_WIDTH : f64 = HOVER_RING_OUTER_RADIUS - MAIN_RING_INNER_RADIUS ;
323
+ const HOVER_RING_CENTERLINE_RADIUS : f64 = ( HOVER_RING_OUTER_RADIUS + MAIN_RING_INNER_RADIUS ) / 2. ;
324
+ const MAIN_RING_STROKE_WIDTH : f64 = MAIN_RING_OUTER_RADIUS - MAIN_RING_INNER_RADIUS ;
325
+ const MAIN_RING_CENTERLINE_RADIUS : f64 = ( MAIN_RING_OUTER_RADIUS + MAIN_RING_INNER_RADIUS ) / 2. ;
326
+
327
+ let Some ( show_hover_ring) = show_compass_with_hover_ring else { return } ;
328
+
329
+ self . start_dpi_aware_transform ( ) ;
330
+
331
+ let center = compass_center. round ( ) - DVec2 :: splat ( 0.5 ) ;
332
+
333
+ // Save the old line width to restore it later
334
+ let old_line_width = self . render_context . line_width ( ) ;
335
+
336
+ // Hover ring
337
+ if show_hover_ring {
338
+ let mut fill_color = graphene_std:: Color :: from_rgb_str ( COLOR_OVERLAY_BLUE . strip_prefix ( '#' ) . unwrap ( ) ) . unwrap ( ) . with_alpha ( 0.5 ) . rgba_hex ( ) ;
339
+ fill_color. insert ( 0 , '#' ) ;
340
+
341
+ self . render_context . set_line_width ( HOVER_RING_STROKE_WIDTH ) ;
342
+ self . render_context . begin_path ( ) ;
343
+ self . render_context . arc ( center. x , center. y , HOVER_RING_CENTERLINE_RADIUS , 0. , TAU ) . expect ( "Failed to draw hover ring" ) ;
344
+ self . render_context . set_stroke_style_str ( & fill_color) ;
345
+ self . render_context . stroke ( ) ;
346
+ }
347
+
348
+ // Arrows
349
+ self . render_context . set_line_width ( 0.01 ) ;
350
+ for i in 0 ..4 {
351
+ let direction = DVec2 :: from_angle ( i as f64 * FRAC_PI_2 + angle) ;
352
+ let color = if i % 2 == 0 { COLOR_OVERLAY_RED } else { COLOR_OVERLAY_GREEN } ;
353
+
354
+ let tip = center + direction * HOVER_RING_OUTER_RADIUS ;
355
+ let base = center + direction * ( MAIN_RING_INNER_RADIUS + MAIN_RING_OUTER_RADIUS ) / 2. ;
356
+
357
+ let r = ( ARROW_RADIUS . powi ( 2 ) + MAIN_RING_INNER_RADIUS . powi ( 2 ) ) . sqrt ( ) ;
358
+ let ( cos, sin) = ( MAIN_RING_INNER_RADIUS / r, ARROW_RADIUS / r) ;
359
+ let side1 = center + r * DVec2 :: new ( cos * direction. x - sin * direction. y , sin * direction. x + direction. y * cos) ;
360
+ let side2 = center + r * DVec2 :: new ( cos * direction. x + sin * direction. y , -sin * direction. x + direction. y * cos) ;
361
+
362
+ self . render_context . begin_path ( ) ;
363
+ self . render_context . move_to ( tip. x , tip. y ) ;
364
+ self . render_context . line_to ( side1. x , side1. y ) ;
365
+ self . render_context . line_to ( base. x , base. y ) ;
366
+ self . render_context . line_to ( side2. x , side2. y ) ;
367
+ self . render_context . close_path ( ) ;
368
+
369
+ self . render_context . set_fill_style_str ( color) ;
370
+ self . render_context . fill ( ) ;
371
+ self . render_context . set_stroke_style_str ( color) ;
372
+ self . render_context . stroke ( ) ;
373
+ }
374
+
375
+ // Main ring
376
+ self . render_context . set_line_width ( MAIN_RING_STROKE_WIDTH ) ;
377
+ self . render_context . begin_path ( ) ;
378
+ self . render_context . arc ( center. x , center. y , MAIN_RING_CENTERLINE_RADIUS , 0. , TAU ) . expect ( "Failed to draw main ring" ) ;
379
+ self . render_context . set_stroke_style_str ( COLOR_OVERLAY_BLUE ) ;
380
+ self . render_context . stroke ( ) ;
381
+
382
+ // Restore the old line width
383
+ self . render_context . set_line_width ( old_line_width) ;
384
+ }
385
+
386
+ pub fn pivot ( & mut self , position : DVec2 , angle : f64 ) {
387
+ let uv = DVec2 :: from_angle ( angle) ;
311
388
let ( x, y) = ( position. round ( ) - DVec2 :: splat ( 0.5 ) ) . into ( ) ;
312
389
313
390
self . start_dpi_aware_transform ( ) ;
@@ -322,19 +399,19 @@ impl OverlayContext {
322
399
// Crosshair
323
400
324
401
// Round line caps add half the stroke width to the length on each end, so we subtract that here before halving to get the radius
325
- let crosshair_radius = ( PIVOT_CROSSHAIR_LENGTH - PIVOT_CROSSHAIR_THICKNESS ) / 2. ;
402
+ const CROSSHAIR_RADIUS : f64 = ( PIVOT_CROSSHAIR_LENGTH - PIVOT_CROSSHAIR_THICKNESS ) / 2. ;
326
403
327
404
self . render_context . set_stroke_style_str ( COLOR_OVERLAY_YELLOW ) ;
328
405
self . render_context . set_line_cap ( "round" ) ;
329
406
330
407
self . render_context . begin_path ( ) ;
331
- self . render_context . move_to ( x - crosshair_radius , y) ;
332
- self . render_context . line_to ( x + crosshair_radius , y) ;
408
+ self . render_context . move_to ( x + CROSSHAIR_RADIUS * uv . x , y + CROSSHAIR_RADIUS * uv . y ) ;
409
+ self . render_context . line_to ( x - CROSSHAIR_RADIUS * uv . x , y - CROSSHAIR_RADIUS * uv . y ) ;
333
410
self . render_context . stroke ( ) ;
334
411
335
412
self . render_context . begin_path ( ) ;
336
- self . render_context . move_to ( x, y - crosshair_radius ) ;
337
- self . render_context . line_to ( x, y + crosshair_radius ) ;
413
+ self . render_context . move_to ( x - CROSSHAIR_RADIUS * uv . y , y + CROSSHAIR_RADIUS * uv . x ) ;
414
+ self . render_context . line_to ( x + CROSSHAIR_RADIUS * uv . y , y - CROSSHAIR_RADIUS * uv . x ) ;
338
415
self . render_context . stroke ( ) ;
339
416
340
417
self . render_context . set_line_cap ( "butt" ) ;
0 commit comments