diff --git a/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs b/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs index d489c95377..7d6d1e52a8 100644 --- a/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs +++ b/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs @@ -234,7 +234,6 @@ impl MessageHandler> for TransformOperation::Grabbing(translation) => { let translation_viewport = self.state.local_to_viewport_transform().matrix2 * translation.to_dvec(&self.state, document); let pivot = document_to_viewport.transform_point2(self.grab_target); - let quad = Quad::from_box([pivot, pivot + translation_viewport]); responses.add(SelectToolMessage::PivotShift { offset: Some(translation_viewport), @@ -242,7 +241,27 @@ impl MessageHandler> for }); let typed_string = (!self.typing.digits.is_empty() && self.transform_operation.can_begin_typing()).then(|| self.typing.string.clone()); - overlay_context.translation_box(translation_viewport / document_to_viewport.matrix2.y_axis.length(), quad, typed_string); + + // When constrained to a single axis in local space, the translation vector is tilted along the layer's + // local axis. Draw one dashed line (with a single measurement label) along that axis, instead of the + // axis-aligned box, which would incorrectly show both the X and Y screen-space components. + if self.state.is_transforming_in_local_space && axis_constraint != Axis::Both { + let end_point = pivot + translation_viewport; + overlay_context.dashed_line(pivot, end_point, None, None, Some(2.), Some(2.), Some(0.5)); + + let axis_direction = self.state.constraint_axis(axis_constraint).unwrap_or(DVec2::X).normalize_or(DVec2::X); + let length = translation_viewport.dot(axis_direction) / document_to_viewport.matrix2.y_axis.length(); + let label = match typed_string { + Some(typed_string) => typed_string, + None => format!("{length:.2}").trim_end_matches('0').trim_end_matches('.').to_string(), + }; + let text_position = pivot.midpoint(end_point) + translation_viewport.perp().normalize_or(DVec2::X) * 24.; + let transform = DAffine2::from_translation(text_position); + overlay_context.text(&label, COLOR_OVERLAY_BLUE, None, transform, 16., [Pivot::Middle, Pivot::Middle]); + } else { + let quad = Quad::from_box([pivot, pivot + translation_viewport]); + overlay_context.translation_box(translation_viewport / document_to_viewport.matrix2.y_axis.length(), quad, typed_string); + } } TransformOperation::Scaling(scale) => { let scale = scale.to_f64(self.state.is_rounded_to_intervals);