Add Image::rotate and Mesh::rotate (#1371)
Co-authored-by: Hunter Morgan <hmorgan@bellflight.com>
This commit is contained in:
parent
805539b50d
commit
0a400a5bcc
3 changed files with 38 additions and 2 deletions
|
@ -4,7 +4,10 @@ use eframe::egui;
|
|||
use egui_extras::RetainedImage;
|
||||
|
||||
fn main() {
|
||||
let options = eframe::NativeOptions::default();
|
||||
let options = eframe::NativeOptions {
|
||||
initial_window_size: Some(egui::vec2(500.0, 900.0)),
|
||||
..Default::default()
|
||||
};
|
||||
eframe::run_native(
|
||||
"Show an image with eframe/egui",
|
||||
options,
|
||||
|
@ -34,6 +37,12 @@ impl eframe::App for MyApp {
|
|||
ui.heading("This is an image:");
|
||||
self.image.show(ui);
|
||||
|
||||
ui.heading("This is a rotated image:");
|
||||
ui.add(
|
||||
egui::Image::new(self.image.texture_id(ctx), self.image.size_vec2())
|
||||
.rotate(45.0_f32.to_radians(), egui::Vec2::splat(0.5)),
|
||||
);
|
||||
|
||||
ui.heading("This is an image you can click:");
|
||||
ui.add(egui::ImageButton::new(
|
||||
self.image.texture_id(ctx),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::*;
|
||||
use emath::Rot2;
|
||||
|
||||
/// An widget to show an image of a given size.
|
||||
///
|
||||
|
@ -36,6 +37,7 @@ pub struct Image {
|
|||
bg_fill: Color32,
|
||||
tint: Color32,
|
||||
sense: Sense,
|
||||
rotation: Option<(Rot2, Vec2)>,
|
||||
}
|
||||
|
||||
impl Image {
|
||||
|
@ -47,6 +49,7 @@ impl Image {
|
|||
bg_fill: Default::default(),
|
||||
tint: Color32::WHITE,
|
||||
sense: Sense::hover(),
|
||||
rotation: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,6 +78,17 @@ impl Image {
|
|||
self.sense = sense;
|
||||
self
|
||||
}
|
||||
|
||||
/// Rotate the image about an origin by some angle
|
||||
///
|
||||
/// Positive angle is clockwise.
|
||||
/// Origin is a vector in normalized UV space ((0,0) in top-left, (1,1) bottom right).
|
||||
///
|
||||
/// To rotate about the center you can pass `Vec2::splat(0.5)` as the origin.
|
||||
pub fn rotate(mut self, angle: f32, origin: Vec2) -> Self {
|
||||
self.rotation = Some((Rot2::from_angle(angle), origin));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Image {
|
||||
|
@ -88,10 +102,11 @@ impl Image {
|
|||
let Self {
|
||||
texture_id,
|
||||
uv,
|
||||
size: _,
|
||||
size,
|
||||
bg_fill,
|
||||
tint,
|
||||
sense: _,
|
||||
rotation,
|
||||
} = self;
|
||||
|
||||
if *bg_fill != Default::default() {
|
||||
|
@ -104,6 +119,9 @@ impl Image {
|
|||
// TODO: builder pattern for Mesh
|
||||
let mut mesh = Mesh::with_texture(*texture_id);
|
||||
mesh.add_rect_with_uv(rect, *uv, *tint);
|
||||
if let Some((rot, origin)) = rotation {
|
||||
mesh.rotate(*rot, rect.min + *origin * *size);
|
||||
}
|
||||
ui.painter().add(Shape::mesh(mesh));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -254,6 +254,15 @@ impl Mesh {
|
|||
v.pos += delta;
|
||||
}
|
||||
}
|
||||
|
||||
/// Rotate by some angle about an origin, in-place.
|
||||
///
|
||||
/// Origin is a position in screen space.
|
||||
pub fn rotate(&mut self, rot: Rot2, origin: Pos2) {
|
||||
for v in &mut self.vertices {
|
||||
v.pos = origin + rot * (v.pos - origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue