
๐ Rust Code
use nannou::prelude::*;
struct Model {
shapes: Vec<Shape>,
max_radius: f32,
}
struct Shape {
i: f32,
radius_multiplier: f32,
angle: f32,
current_radius: f32,
}
impl Shape {
fn new(index: usize, max_radius: f32) -> Self {
Shape {
i: index as f32 * 0.01,
radius_multiplier: 0.0,
angle: 0.0,
current_radius: (index as f32 % max_radius),
}
}
fn move_shape(&mut self, max_radius: f32) {
self.current_radius += 1.0;
if self.current_radius > max_radius {
self.current_radius = 0.0;
}
}
fn display(&mut self, draw: &Draw, frame_count: f32) {
self.radius_multiplier = ((self.i * 3.0).cos() - (self.i * 6.0).cos() + 9.0) * 0.45;
self.angle = self.i / 2.0 + ((self.i * 3.0).sin() - (self.i * 6.0).sin()) / 3.0;
let hue = 200.0 * (self.angle * 10.0 + frame_count * 0.1).sin();
let hue_normalized = (hue + 360.0) % 360.0 / 360.0;
let x = self.current_radius * self.radius_multiplier * self.angle.cos();
let y = self.current_radius * self.radius_multiplier * self.angle.sin();
let size = self.current_radius * 0.2 * (self.i * 11.0).sin();
if size.abs() > 0.1 {
draw.ellipse()
.x_y(x, y)
.radius(size.abs())
.hsv(hue_normalized, 0.8, 0.2);
}
}
}
fn main() {
nannou::app(model)
.update(update)
.simple_window(view)
.size(800, 800)
.run();
}
fn model(_app: &App) -> Model {
const SHAPES_NUM: usize = 5000;
let max_radius = 800.0 * 0.3;
let mut shapes = Vec::with_capacity(SHAPES_NUM);
for i in 0..SHAPES_NUM {
shapes.push(Shape::new(i, max_radius));
}
Model {
shapes,
max_radius,
}
}
fn update(_app: &App, model: &mut Model, _update: Update) {
for shape in &mut model.shapes {
shape.move_shape(model.max_radius);
}
}
fn view(app: &App, model: &Model, frame: Frame) {
let draw = app.draw();
let win = app.window_rect();
draw.rect()
.wh(win.wh())
.rgba(0.137, 0.137, 0.137, 0.1);
let frame_count = app.elapsed_frames() as f32;
for shape in &model.shapes {
let mut shape_copy = Shape {
i: shape.i,
radius_multiplier: shape.radius_multiplier,
angle: shape.angle,
current_radius: shape.current_radius,
};
shape_copy.display(&draw, frame_count);
}
draw.to_frame(app, &frame).unwrap();
}