From d138eccceec4d1619fd2c14c71a42bb9e1316fa6 Mon Sep 17 00:00:00 2001 From: JJ Date: Wed, 19 Nov 2025 04:53:56 +0000 Subject: [PATCH] rotate fix --- nodes/draw_shapes.py | 34 +++++++++++++++++++++++++--------- nodes/draw_shapes_dr.py | 14 +++++++++++--- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/nodes/draw_shapes.py b/nodes/draw_shapes.py index 16cd3ce..0085946 100644 --- a/nodes/draw_shapes.py +++ b/nodes/draw_shapes.py @@ -214,16 +214,15 @@ Locations are center locations. Allows coordinates outside the frame for 'fly-in if apply_scale_to_offset is None: apply_scale_to_offset = driver_info.get('driver_type') != 'box' - # For box drivers, make the offset purely translational so that - # driven points follow only the box's positional change. Box - # scale / radius_delta should not expand or contract the offset - # applied to other layers. + # For box drivers, keep the offset purely translational in terms of + # box radius/scale, but still allow d_scale (D_scale) to scale how + # much of the box motion is applied to driven layers. if driver_info.get('driver_type') == 'box': - d_scale = 1.0 - driver_scale_factor = 1.0 - driver_radius_delta = 0.0 + driver_scale_factor = 1.0 # ignore box scale for offsets + driver_radius_delta = 0.0 # no radial push from box radius + apply_scale_to_offset = True # ensure d_scale affects offset - return calculate_driver_offset( + offset_x, offset_y = calculate_driver_offset( eff_frame, driver_path, (0, 0), total_frames, d_scale, frame_width, frame_height, driver_scale_factor=driver_scale_factor, driver_radius_delta=driver_radius_delta, @@ -231,6 +230,20 @@ Locations are center locations. Allows coordinates outside the frame for 'fly-in apply_scale_to_offset=apply_scale_to_offset ) + rotate_degrees = driver_info.get('rotate', 0.0) + if rotate_degrees and rotate_degrees != 0.0: + try: + angle_rad = math.radians(float(rotate_degrees)) + cos_a = math.cos(angle_rad) + sin_a = math.sin(angle_rad) + rx = offset_x * cos_a - offset_y * sin_a + ry = offset_x * sin_a + offset_y * cos_a + offset_x, offset_y = rx, ry + except Exception: + pass + + return offset_x, offset_y + def _accumulate_driver_offsets(driver_info: Optional[Dict[str, Any]], base_frame_index: int) -> Tuple[float, float]: if not driver_info: return 0.0, 0.0 @@ -824,6 +837,7 @@ Locations are center locations. Allows coordinates outside the frame for 'fly-in for idx, driver_info in enumerate(static_points_driver_info_list): if driver_info and isinstance(driver_info, dict): driver_path = driver_info.get('path') + driver_rotate = driver_info.get('rotate', 0.0) driver_d_scale = driver_info.get('d_scale', DRIVER_SCALE_FACTOR) # Use driver's own interpolation parameters if available, otherwise fall back to defaults @@ -834,7 +848,8 @@ Locations are center locations. Allows coordinates outside the frame for 'fly-in if driver_path and len(driver_path) > 0: interpolated = process_driver_path( driver_path, total_frames, static_points_driver_smooth, - driver_easing_function, driver_easing_path, driver_easing_strength, TRAILING_WEIGHT_FACTOR + driver_easing_function, driver_easing_path, driver_easing_strength, + TRAILING_WEIGHT_FACTOR, rotate_degrees=driver_rotate ) if interpolated: scale_profile = driver_info.get('driver_scale_profile', []) @@ -855,6 +870,7 @@ Locations are center locations. Allows coordinates outside the frame for 'fly-in static_points_interpolated_drivers[idx] = { 'path': interpolated, + 'rotate': driver_rotate, 'd_scale': driver_d_scale, 'easing_function': driver_easing_function, 'easing_path': driver_easing_path, diff --git a/nodes/draw_shapes_dr.py b/nodes/draw_shapes_dr.py index 68f2819..d578a9f 100644 --- a/nodes/draw_shapes_dr.py +++ b/nodes/draw_shapes_dr.py @@ -524,13 +524,21 @@ def process_driver_path( easing_path: str, easing_strength: float, trailing_weight_factor: float = 0.5, + rotate_degrees: float = 0.0, ) -> Optional[List[Dict[str, Any]]]: if not raw_path: return None try: - if len(raw_path) != total_frames: + source_path = raw_path + if rotate_degrees and rotate_degrees != 0.0: + try: + source_path = draw_utils.rotate_path(source_path, rotate_degrees) + except Exception: + source_path = raw_path + + if len(source_path) != total_frames: processed = draw_utils.InterpMath.interpolate_or_downsample_path( - raw_path, + source_path, total_frames, easing_function, easing_path, @@ -538,7 +546,7 @@ def process_driver_path( easing_strength=easing_strength, ) else: - processed = [dict(p) for p in raw_path] + processed = [dict(p) for p in source_path] if smooth_strength and smooth_strength > 0.0 and len(processed) > 2: smoothed = [processed[0].copy()]