Skip to content

Commit 6388a32

Browse files
authored
Fix an assortment of small bugs (#3968)
* Fix an assertion failure bug when scaling a line in the transform cage * Fix missing defaults on node gradient inputs * Fix Blend Shapes path input wire not updating to show in the UI after Layer > Blend * Fix assertion failure due to browser non-monotonic timestamp * Fix SVG renderer drawing 1px strokes as half-width when using stroke alignment * Fix incorrect appearance of the ColorInput widget when set to "none" and "disabled" * Fix lerp function in Fill enum to handle None cases correctly * Fix stroke alignment bug
1 parent 865e971 commit 6388a32

File tree

7 files changed

+26
-12
lines changed

7 files changed

+26
-12
lines changed

editor/src/messages/input_mapper/utility_types/misc.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ impl FrameTimeInfo {
139139
}
140140

141141
pub fn advance_timestamp(&mut self, next_timestamp: Duration) {
142-
debug_assert!(next_timestamp >= self.timestamp);
142+
// Guard against non-monotonic timestamps from the browser (Keavon observed this once in Chrome)
143+
let next_timestamp = next_timestamp.max(self.timestamp);
143144

144145
self.prev_timestamp = Some(self.timestamp);
145146
self.timestamp = next_timestamp;

editor/src/messages/portfolio/document/utility_types/network_interface.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4005,6 +4005,14 @@ impl NodeNetworkInterface {
40054005
}
40064006
}
40074007
(_, NodeInput::Node { node_id: upstream_node_id, .. }) => {
4008+
// If the old input wasn't exposed but the new one is (`Node` inputs are always exposed),
4009+
// the node's port count changed, so its click targets need to be recomputed
4010+
if !old_input.is_exposed()
4011+
&& let InputConnector::Node { node_id, .. } = input_connector
4012+
{
4013+
self.unload_node_click_targets(node_id, network_path);
4014+
}
4015+
40084016
// Load structure if the change is to the document network and to the first or second
40094017
if network_path.is_empty() {
40104018
if matches!(input_connector, InputConnector::Export(0)) {

editor/src/messages/tool/common_functionality/transformation_cage.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,16 +212,15 @@ impl SelectedEdges {
212212
let original_from_pivot = updated - pivot; // The original vector from the point to the pivot
213213
let mut scale_factor = new_from_pivot / original_from_pivot;
214214

215-
// Constrain should always scale by the same factor in x and y
215+
// Constrain should always scale by the same factor in x and y.
216+
// When one axis of `original_from_pivot` is near zero (e.g. for a line's degenerate bounding box),
217+
// the scale factor for that axis is numerically unstable, so we copy from the more stable axis.
216218
if constrain {
217-
// When the point is on the pivot, we simply copy the other axis.
218-
if original_from_pivot.x.abs() < 1e-5 {
219+
if original_from_pivot.x.abs() < original_from_pivot.y.abs() {
219220
scale_factor.x = scale_factor.y;
220-
} else if original_from_pivot.y.abs() < 1e-5 {
221+
} else {
221222
scale_factor.y = scale_factor.x;
222223
}
223-
224-
debug_assert!((scale_factor.x - scale_factor.y).abs() < 1e-5);
225224
}
226225

227226
if !(self.left || self.right || constrain) {

frontend/src/components/widgets/inputs/ColorInput.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
background-repeat: var(--color-transparent-checkered-background-repeat);
117117
}
118118
119-
&:not(.disabled).none > button {
119+
&.none > button {
120120
background: var(--color-none);
121121
background-repeat: var(--color-none-repeat);
122122
background-position: var(--color-none-position);
@@ -132,6 +132,7 @@
132132
left: 0;
133133
right: 0;
134134
background: var(--color-4-dimgray);
135+
opacity: 0.5;
135136
}
136137
137138
&:not(.disabled):hover > button .text-label,

node-graph/graph-craft/src/document/value.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ macro_rules! tagged_value {
127127
// Tries using the default for the tagged value type. If it not implemented, then uses the default used in document_node_types. If it is not used there, then TaggedValue::None is returned.
128128
Some(match concrete_type.id? {
129129
x if x == TypeId::of::<()>() => TaggedValue::None,
130+
// Table-wrapped types need a single-row default with the element's default, not an empty table
131+
x if x == TypeId::of::<Table<Color>>() => TaggedValue::Color(Table::new_from_element(Color::default())),
132+
x if x == TypeId::of::<Table<GradientStops>>() => TaggedValue::GradientTable(Table::new_from_element(GradientStops::default())),
130133
$( x if x == TypeId::of::<$ty>() => TaggedValue::$identifier(Default::default()), )*
131134
_ => return None,
132135
})

node-graph/libraries/rendering/src/render_ext.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,10 @@ impl RenderExt for Stroke {
112112
return String::new();
113113
}
114114

115+
let default_weight = if self.align != StrokeAlign::Center && render_params.aligned_strokes { 1. / 2. } else { 1. };
116+
115117
// Set to None if the value is the SVG default
116-
let weight = (self.weight != 1.).then_some(self.weight);
118+
let weight = (self.weight != default_weight).then_some(self.weight);
117119
let dash_array = (!self.dash_lengths.is_empty()).then_some(self.dash_lengths());
118120
let dash_offset = (self.dash_offset != 0.).then_some(self.dash_offset);
119121
let stroke_cap = (self.cap != StrokeCap::Butt).then_some(self.cap);

node-graph/libraries/vector-types/src/vector/style.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ impl Fill {
6464

6565
pub fn lerp(&self, other: &Self, time: f64) -> Self {
6666
let transparent = Self::solid(Color::TRANSPARENT);
67-
let a = if *self == Self::None { &transparent } else { self };
68-
let b = if *other == Self::None { &transparent } else { other };
67+
let a = if *self == Self::None && *other != Self::None { &transparent } else { self };
68+
let b = if *other == Self::None && *self != Self::None { &transparent } else { other };
6969

7070
match (a, b) {
7171
(Self::Solid(a), Self::Solid(b)) => Self::Solid(a.lerp(b, time as f32)),
@@ -82,7 +82,7 @@ impl Fill {
8282
Self::Gradient(a.lerp(b, time))
8383
}
8484
(Self::Gradient(a), Self::Gradient(b)) => Self::Gradient(a.lerp(b, time)),
85-
_ => Self::None,
85+
(Self::None, _) | (_, Self::None) => Self::None,
8686
}
8787
}
8888

0 commit comments

Comments
 (0)