mirror of
https://github.com/Noratrieb/colouncher.git
synced 2026-03-14 21:26:10 +01:00
trying to animate
This commit is contained in:
parent
a68d0dff63
commit
9a255f9a7d
3 changed files with 128 additions and 9 deletions
8
TODO.md
Normal file
8
TODO.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# TODOs
|
||||
|
||||
Nicely animate the transition into the voronoi diagram.
|
||||
Actually making a cool animation with movement likely requires knowing the distance to the voronoi center of any point.
|
||||
To know this we will likely have to construct the voronoi diagram on the CPU beforehand and having it as geometry.
|
||||
To do this, we probably need to generate it in 3D (using something like Bowyer-Watson) and then project it into 2D somehow (using magic) and then do things.
|
||||
|
||||
Actually use a good gradient that doesn't look kinda bad.
|
||||
107
src/main.rs
107
src/main.rs
|
|
@ -106,6 +106,12 @@ struct App {
|
|||
pointers: HashMap<WlSeat, WlPointer>,
|
||||
layer_surfaces: Vec<OutputSurface>,
|
||||
}
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum AnimationState {
|
||||
Descending { last_time: Option<u32> },
|
||||
Paused,
|
||||
Ascending { last_time: Option<u32> },
|
||||
}
|
||||
|
||||
struct OutputSurface {
|
||||
// must be first to be dropped before the Wayland surface
|
||||
|
|
@ -115,6 +121,71 @@ struct OutputSurface {
|
|||
width: u32,
|
||||
height: u32,
|
||||
voronoi_progress: f32,
|
||||
animation_running: AnimationState,
|
||||
}
|
||||
|
||||
const VORONOI_SPEED: f32 = 1000.;
|
||||
|
||||
impl OutputSurface {
|
||||
fn request_frame_if_necessary(&self, qh: &QueueHandle<App>) {
|
||||
if self.animation_running != AnimationState::Paused {
|
||||
self.layer_surface
|
||||
.wl_surface()
|
||||
.frame(qh, self.layer_surface.wl_surface().clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn tick_animation(&mut self, new_time: u32) {
|
||||
match self.animation_running {
|
||||
AnimationState::Paused => {}
|
||||
AnimationState::Descending { last_time: None } => {
|
||||
self.animation_running = AnimationState::Descending {
|
||||
last_time: Some(new_time),
|
||||
}
|
||||
}
|
||||
AnimationState::Ascending { last_time: None } => {
|
||||
self.animation_running = AnimationState::Ascending {
|
||||
last_time: Some(new_time),
|
||||
}
|
||||
}
|
||||
AnimationState::Ascending {
|
||||
last_time: Some(last_time),
|
||||
} => {
|
||||
let delta_time = new_time - last_time;
|
||||
|
||||
self.voronoi_progress = f32::min(
|
||||
self.voronoi_progress + delta_time as f32 / VORONOI_SPEED,
|
||||
1.0,
|
||||
);
|
||||
|
||||
if self.voronoi_progress >= 1.0 {
|
||||
self.animation_running = AnimationState::Paused;
|
||||
} else {
|
||||
self.animation_running = AnimationState::Ascending {
|
||||
last_time: Some(new_time),
|
||||
};
|
||||
}
|
||||
}
|
||||
AnimationState::Descending {
|
||||
last_time: Some(last_time),
|
||||
} => {
|
||||
let delta_time = new_time - last_time;
|
||||
|
||||
self.voronoi_progress = f32::max(
|
||||
self.voronoi_progress - delta_time as f32 / VORONOI_SPEED,
|
||||
0.0,
|
||||
);
|
||||
|
||||
if self.voronoi_progress <= 0.0 {
|
||||
self.animation_running = AnimationState::Paused;
|
||||
} else {
|
||||
self.animation_running = AnimationState::Descending {
|
||||
last_time: Some(new_time),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ProvidesRegistryState for App {
|
||||
|
|
@ -167,6 +238,7 @@ impl OutputHandler for App {
|
|||
width: 0,
|
||||
height: 0,
|
||||
voronoi_progress: 0.0,
|
||||
animation_running: AnimationState::Paused,
|
||||
});
|
||||
}
|
||||
Err(err) => error!(
|
||||
|
|
@ -231,11 +303,26 @@ impl CompositorHandler for App {
|
|||
fn frame(
|
||||
&mut self,
|
||||
_conn: &Connection,
|
||||
_qh: &QueueHandle<Self>,
|
||||
_surface: &wayland_client::protocol::wl_surface::WlSurface,
|
||||
_time: u32,
|
||||
qh: &QueueHandle<Self>,
|
||||
wl_surface: &wayland_client::protocol::wl_surface::WlSurface,
|
||||
time: u32,
|
||||
) {
|
||||
dbg!("yeet");
|
||||
let Some(surface) = self
|
||||
.layer_surfaces
|
||||
.iter_mut()
|
||||
.find(|surface| surface.layer_surface.wl_surface() == wl_surface)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
surface.tick_animation(time);
|
||||
surface
|
||||
.gpu
|
||||
.set_voronoi_progress(&self.gpu, surface.voronoi_progress);
|
||||
surface.request_frame_if_necessary(qh);
|
||||
surface.gpu.draw(&self.gpu);
|
||||
|
||||
dbg!((&surface.animation_running, surface.voronoi_progress));
|
||||
}
|
||||
|
||||
fn surface_enter(
|
||||
|
|
@ -371,7 +458,7 @@ impl PointerHandler for App {
|
|||
fn pointer_frame(
|
||||
&mut self,
|
||||
_conn: &Connection,
|
||||
_qh: &QueueHandle<Self>,
|
||||
qh: &QueueHandle<Self>,
|
||||
_pointer: &wayland_client::protocol::wl_pointer::WlPointer,
|
||||
events: &[smithay_client_toolkit::seat::pointer::PointerEvent],
|
||||
) {
|
||||
|
|
@ -419,22 +506,28 @@ impl PointerHandler for App {
|
|||
PointerEventKind::Press {
|
||||
button: BTN_RIGHT, ..
|
||||
} => {
|
||||
surface.voronoi_progress = 1.0;
|
||||
surface.animation_running = AnimationState::Ascending { last_time: None };
|
||||
|
||||
surface
|
||||
.gpu
|
||||
.set_voronoi_progress(&self.gpu, surface.voronoi_progress);
|
||||
|
||||
surface.request_frame_if_necessary(qh);
|
||||
|
||||
surface.gpu.draw(&self.gpu);
|
||||
}
|
||||
PointerEventKind::Release {
|
||||
button: BTN_RIGHT, ..
|
||||
}
|
||||
| PointerEventKind::Leave { .. } => {
|
||||
surface.voronoi_progress = 0.0;
|
||||
surface.animation_running = AnimationState::Descending { last_time: None };
|
||||
|
||||
surface
|
||||
.gpu
|
||||
.set_voronoi_progress(&self.gpu, surface.voronoi_progress);
|
||||
|
||||
surface.request_frame_if_necessary(qh);
|
||||
|
||||
surface.gpu.draw(&self.gpu);
|
||||
}
|
||||
_ => (),
|
||||
|
|
|
|||
|
|
@ -47,15 +47,33 @@ fn fs_main(@builtin(position) pos: vec4<f32>) -> @location(0) vec4<f32> {
|
|||
}
|
||||
}
|
||||
var voronoi_color = best;
|
||||
|
||||
color = mix(color, voronoi_color, input.voronoi_progress);
|
||||
|
||||
var distance_to_center = sqrt(best_score); // a value like 0.1 is pretty good in the grand scheme
|
||||
var badness = clamp(distance_to_center * 5, 0, 0.5); // 0..1, 1=terrible 0=perfect
|
||||
// badness determines at which point in the animation progress the animation should start.
|
||||
// if it's 0.3, we start the animation at 0.3 and end it at 1.0
|
||||
// so we need to scale and shift input progress (0.3=>0.0, 0.65=>0.5, 1.0=>1.0)
|
||||
var voronoi_progress_shifted = transform_progress(input.voronoi_progress, badness);
|
||||
|
||||
var final_progress = clamp(voronoi_progress_shifted, 0, 1);
|
||||
// mix with red to see how terrible it looks
|
||||
color = mix(color, voronoi_color, final_progress);
|
||||
|
||||
//color.x = distance_to_center;
|
||||
// keep it in sync with the cpu implementation
|
||||
var srgbcolor = oklab_to_linear_srgb(color);
|
||||
|
||||
return vec4<f32>(srgbcolor.x, srgbcolor.y, srgbcolor.z, 1.0);
|
||||
}
|
||||
|
||||
fn transform_progress(x: f32, badness: f32) -> f32 {
|
||||
return ((x) - badness) * (1 / (1 - badness));
|
||||
}
|
||||
fn wobble(x: f32) -> f32 {
|
||||
var wobble_factor = 0.0;
|
||||
return sin(x * wobble_factor) / 2.0 + 1;
|
||||
}
|
||||
|
||||
// keep it in sync with the cpu implementation
|
||||
fn diff_colors(oklab_a: vec3f, oklab_b: vec3f) -> f32 {
|
||||
var diff = oklab_a - oklab_b;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue