No description
  • Rust 96.5%
  • Shell 3.5%
Find a file
Alex eff5834738 Fix zoom animation always starting from 1.0 instead of current zoom
The start of the ease_range was hardcoded to 1.0, so every subsequent
zoom press snapped the zoom factor back to 1.0 before animating to the
target — the visible "bounce back" the user was seeing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 18:34:36 +02:00
src Fix zoom animation always starting from 1.0 instead of current zoom 2026-05-29 18:34:36 +02:00
.gitignore live in 3,2..1! 2025-12-18 04:34:00 +01:00
Cargo.lock Add Lua scripting, spring animation, and smoother zooming 2026-05-27 22:53:03 +02:00
Cargo.toml Add Lua scripting, spring animation, and smoother zooming 2026-05-27 22:53:03 +02:00
PKGBUILD Add PKGBUILD for Arch Linux installation 2026-05-27 22:57:22 +02:00
README.md update readme with notice, fix #1 2025-12-18 13:40:20 +01:00

About

A simple yet feature rich zoom utility for Hyprland.

Showcase

demo

Installation

Currently, the only installation method is building from source:

cargo install --git https://github.com/nouritsu/hyprzoom

Or manually git clone https://github.com/nouritsu/hyprzoom.git hyprzoom && cargo install --path hyprzoom.

Note that this requires you to have cargo installed and its bin directory in $PATH. You may also cargo build --release and copy the binary at target/release/hyprzoom to a directory in your $PATH.

Usage

Help

The following commands print the help message:

hyprzoom help
hyprzoom --help
hyprzoom -h

Help for subcommands zoom/z and inout/in_out/io:

hyprzoom zoom --help # can use z instead of zoom
hyprzoom inout -h # can use in_out or io instead of inout

Common

Both subcommands (zoom and inout) support the following options:

-s, --steps <steps>           Number of steps for the zoom animation      [default: 15]
-d, --duration <duration>     Duration of the zoom animation              [default: 250ms]

Steps is an integer greater than 0. A value of 1 would be an instant zoom, without animations.

Duration can be a human-readable string. For example 250ms for 250 milliseconds or 2s for 2 seconds. Obvious footgun: 1d.

Zoom To

The zoom (or z) subcommand zooms to a provided ztarget.

hyprzoom zoom <ztarget>

In addition to steps + duration, you can also specify the ease function using

hyprzoom zoom <target> --ease <ease_function>

The ease function is a string in format (case-insensitive) fn:qualifier where

  • fn denotes the specific function, such as quad, lin, elastic etc.
  • qualifier denotes the specific qualifier, such as in (or i), out (or o), inout (or io)

By default, it will

  • use the quad:in ease function
  • animate 15 frames over 0.25 seconds (60 fps, I think)

Zoom In/Out

The inout (or in_out, io) zooms to a provided ztarget and zooms out to the initial zoom level.

hyprzoom inout <ztarget>

As with the zoom function, you can specify the ease function(s, this time).

hyprzoom inout <ztarget> --in-ease <ease_function_in> --out-ease <ease_function_out>

these options are intentionally named so, because ease-in and ease-out is misleading

The ease functions follow the same format as described in the previous section.

In addition to steps + duration and the ease functions, you can also specify the duration spent zoomed in as

hyprzoom inout <ztarget> --zduration <zduration>

It follows the same format as described in the previous section.

By default, it will

  • use the quad:in ease function for zooming in
  • use the quad:out ease function for zooming out
  • animate 15 frames over 0.25 seconds of zooming in
  • wait 1 second zoomed in
  • animate 15 frames over 0.25 seconds of zooming out

Notice

A majority of this tool's functionality can be achieved using hyprland configuration. Rather than scrapping this project, it would be better to extend it to other compositors and add more configuration options.

A configuration for animations like below can be used (highlighted by u/SOA-determined on Reddit)

animations {
    enabled = true
    bezier = easeOut, 0.16, 1, 0.3, 1
    animation = zoomFactor, 1, 6, easeOut  # 6ds = 600ms (not 0.6!)
  }
  # Zoom binds
  bind = Ctrl+Super, mouse:274, exec, hyprctl keyword cursor:zoom_factor 3.0
  bindr = Ctrl+Super, mouse:274, exec, hyprctl keyword cursor:zoom_factor 1.0
}

Acknowledgements

  • A similar tool hypr-zoom does exist but it seems to be abandoned (unmerged PRs)
  • The demo showcases a waybar setup adapted from mechabar

Plans

  • animation caching (idek if this is worth it)
  • nix flake
  • toggle zoom (perhaps with an environment variable)