Implement ObjectFit::ScaleDown for images (#10063)
While working towards fixes for the image viewer, @mikayla-maki and I discovered that we didn't have `object-fit: scale-down` implemented. This doesn't _fully_ solve the image issues as there is some issue where only the bounds width is updating on layout change that I haven't fully chased down. Co-Authored-By: @mikayla-maki Release Notes: - N/A --------- Co-authored-by: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
parent
c64c2758c0
commit
c7961b9054
2 changed files with 102 additions and 58 deletions
|
@ -99,6 +99,8 @@ pub enum ObjectFit {
|
|||
Contain,
|
||||
/// The image will be scaled to cover the bounds of the element.
|
||||
Cover,
|
||||
/// The image will be scaled down to fit within the bounds of the element.
|
||||
ScaleDown,
|
||||
/// The image will maintain its original size.
|
||||
None,
|
||||
}
|
||||
|
@ -114,7 +116,7 @@ impl ObjectFit {
|
|||
let image_ratio = image_size.width / image_size.height;
|
||||
let bounds_ratio = bounds.size.width / bounds.size.height;
|
||||
|
||||
match self {
|
||||
let result_bounds = match self {
|
||||
ObjectFit::Fill => bounds,
|
||||
ObjectFit::Contain => {
|
||||
let new_size = if bounds_ratio > image_ratio {
|
||||
|
@ -137,6 +139,42 @@ impl ObjectFit {
|
|||
size: new_size,
|
||||
}
|
||||
}
|
||||
ObjectFit::ScaleDown => {
|
||||
// Check if the image is larger than the bounds in either dimension.
|
||||
if image_size.width > bounds.size.width || image_size.height > bounds.size.height {
|
||||
// If the image is larger, use the same logic as Contain to scale it down.
|
||||
let new_size = if bounds_ratio > image_ratio {
|
||||
size(
|
||||
image_size.width * (bounds.size.height / image_size.height),
|
||||
bounds.size.height,
|
||||
)
|
||||
} else {
|
||||
size(
|
||||
bounds.size.width,
|
||||
image_size.height * (bounds.size.width / image_size.width),
|
||||
)
|
||||
};
|
||||
|
||||
Bounds {
|
||||
origin: point(
|
||||
bounds.origin.x + (bounds.size.width - new_size.width) / 2.0,
|
||||
bounds.origin.y + (bounds.size.height - new_size.height) / 2.0,
|
||||
),
|
||||
size: new_size,
|
||||
}
|
||||
} else {
|
||||
// If the image is smaller than or equal to the container, display it at its original size,
|
||||
// centered within the container.
|
||||
let original_size = size(image_size.width, image_size.height);
|
||||
Bounds {
|
||||
origin: point(
|
||||
bounds.origin.x + (bounds.size.width - original_size.width) / 2.0,
|
||||
bounds.origin.y + (bounds.size.height - original_size.height) / 2.0,
|
||||
),
|
||||
size: original_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
ObjectFit::Cover => {
|
||||
let new_size = if bounds_ratio > image_ratio {
|
||||
size(
|
||||
|
@ -162,7 +200,9 @@ impl ObjectFit {
|
|||
origin: bounds.origin,
|
||||
size: image_size,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
result_bounds
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue