Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Strange change of object lightness and colour in Nannou application
Building a Nannou App from their template. I want a circle to slowly fade in color and randomly change color when hitting the boundary of the window. But there is something strange going on when updating the colors.
My preamble looks like this:
use nannou::prelude::*;
use rand::Rng;
The model consists of a circle
and a boundary
.
struct Model {
// so this is a window id called _window -- I guess.
_window: window::Id,
circle: Circle,
boundary: Boundary,
}
The boundary
is just the outline of the application window and the circle
has a diameter, position, velocity and color.
struct Boundary {
x_min: f32,
x_max: f32,
y_min: f32,
y_max: f32,
}
struct Circle {
d: f32, // diameter
center: Point2,
vel: Point2,
color: Hsl,
}
Here is my model function:
fn model(app: &App) -> Model {
let _window = app.new_window().size(512, 512).view(view).build().unwrap();
// add the coordinates to a struct and add it to the model
let circle = Circle {
d: 50.0,
center: pt2(-50.0, 167.0),
vel: pt2(1.3, -0.9),
color: hsl(154.1, 100.0, 85.0),
};
let boundary = Boundary {
x_min: app.window_rect().x.start,
x_max: app.window_rect().x.end,
y_min: app.window_rect().y.start,
y_max: app.window_rect().y.end,
};
Model {
_window,
circle,
boundary,
}
}
I want three things to happen:
- The
circle
to bounce off of theboundary
. (This works) - The lightness of the color of the circle to slowly reduce at every time step.(Not Working)
- The color of the
circle
to randomly change whenever the circle hits the wall(seems to work for a split second)
This is how I update the model:
fn update(_app: &App, _model: &mut Model, _update: Update) {
// move circle by velocity
_model.circle.center.x += _model.circle.vel.x;
_model.circle.center.y += _model.circle.vel.y;
// update color
_model.circle.update_color();
// bounce of the wall
_model.circle.bounce_wall(&_model.boundary);
}
I created the update_color
and bounce_wall
functions for my Circle
:
impl Circle {
fn update_color(&mut self) {
let mut newlight = self.color.lightness - 0.1;
if newlight < 0.0 {
newlight = 0.0;
}
self.color = hsl(
self.color.hue.to_positive_degrees(),
self.color.saturation,
newlight,
);
}
fn bounce_wall(&mut self, boundary: &Boundary) {
// all the random number stuff is stolen from
// https://rust-lang-nursery.github.io/rust-cookbook/algorithms/randomness.html
let mut rng = rand::thread_rng(); // rng = random number generator
if self.center.x + 0.5 * self.d > boundary.x_max
|| self.center.x - 0.5 * self.d < boundary.x_min
{
self.color = hsl(rng.gen_range(0.0..360.0), rng.gen_range(0.0..100.0), 85.0);
self.vel.x = -self.vel.x;
}
if self.center.y + 0.5 * self.d > boundary.y_max
|| self.center.y - 0.5 * self.d < boundary.y_min
{
self.color = hsl(rng.gen_range(0.0..360.0), rng.gen_range(0.0..100.0), 85.0);
self.vel.y = -self.vel.y;
}
}
}
My view
function looks like this:
fn view(app: &App, _model: &Model, frame: Frame) {
let draw = app.draw();
draw.background().color(GRAY);
println!(
"new color lightness is ({})",
_model.circle.color.into_components().2
);
let ellipse = draw.ellipse();
ellipse
.color(_model.circle.color)
.x_y(_model.circle.center.x, _model.circle.center.y)
.w(_model.circle.d)
.h(_model.circle.d);
draw.to_frame(app, &frame).unwrap();
}
Here is what is happening that I do not understand:
- The lightness of the circle that the
view
function prints to the command line does go down but the color of thecircle
does not change at all. Why? - When bouncing of a wall, the color of the
circle
visibly changes for a very brief moment to some random color but then goes back to the initial color. So it works but is reset somehow? - When I remove the random color changing from the
bounce_wall()
function, the color of the circle switches to black once lightness reaches0
. So only changing the color to black is permanent?
Edit: Thanks to comments by elgonzo the solution was quite easy.
hsl expects the first component (hue) to be in [0.0, 1.0]
instead of [0.0, 360.0]
and the third components (lightness) to be in [0.0, 1.0]
instead of [0.0, 100.0]
.
So providing a lightness value that is slowly reducing from 1.0
is creating the effect I wanted.
1 answer
Thanks to comments by elgonzo the solution was quite easy.
hsl expects the first component (hue) to be in [0.0, 1.0]
instead of [0.0, 360.0]
and the third components (lightness) to be in [0.0, 1.0]
instead of [0.0, 100.0]
.
So providing a lightness value that is slowly reducing from 1.0
is creating the effect I wanted.
3 comment threads