Rich image view smooth zoom

This commit is contained in:
Nikita Lisitsa 2021-03-05 20:09:15 +03:00
parent 2b2b2be560
commit 74423000cb
2 changed files with 20 additions and 9 deletions

View file

@ -36,6 +36,8 @@ namespace psemek::ui
struct shape const & shape() const override { return shape_; }
void reshape(geom::box<float, 2> const & bbox) override;
void update(float dt) override;
void draw(painter & p) const override;
protected:
@ -45,6 +47,7 @@ namespace psemek::ui
std::shared_ptr<gfx::texture_2d> image_;
geom::interval<float> zoom_range_ = {0.f, std::numeric_limits<float>::infinity()};
float zoom_ = 1.f;
float zoom_tgt_ = 1.f;
geom::point<float, 2> center_{0.f, 0.f};
bool allow_overflow_ = false;
gfx::color_rgba color_{0, 0, 0, 0};

View file

@ -46,13 +46,8 @@ namespace psemek::ui
// (mouse - bbox.center) / zoom0 + center0 = (mouse - bbox.center) / zoom1 + center1
// center1 - center0 = (mouse - bbox.center) * (1 / zoom0 - 1 / zoom1)
auto new_center = center_;
if (mouse_)
new_center += (geom::cast<float>(*mouse_) - shape_.box.center()) * (1.f / zoom_ - 1.f / zoom);
zoom_ = zoom;
set_center(new_center);
zoom_tgt_ = zoom;
set_center(center_);
}
geom::box<float, 2> rich_image_view::region() const
@ -80,7 +75,6 @@ namespace psemek::ui
{
set_center(center_ + geom::cast<float>(*drag_ - e.position) / zoom_);
drag_ = e.position;
return true;
}
return false;
}
@ -107,7 +101,7 @@ namespace psemek::ui
{
if (mouseover_)
{
set_zoom(zoom_ * std::pow(1.25f, e.delta));
set_zoom(zoom_tgt_ * std::pow(1.25f, e.delta));
return true;
}
return false;
@ -137,6 +131,20 @@ namespace psemek::ui
post_region_changed();
}
void rich_image_view::update(float dt)
{
float new_zoom = zoom_ + (zoom_tgt_ - zoom_) * std::min(1.f, dt * 20.f);
auto new_center = center_;
if (mouse_)
new_center += (geom::cast<float>(*mouse_) - shape_.box.center()) * (1.f / zoom_ - 1.f / new_zoom);
zoom_ = new_zoom;
set_center(new_center);
}
void rich_image_view::draw(painter & p) const
{
auto st = merged_style();