
๐ Rust Code
use nannou::prelude::*;
struct Shape {
pos_x: f32,
pos_y: f32,
vel_x: f32,
vel_y: f32,
size: f32,
color: Hsla,
kind: ShapeKind,
}
enum ShapeKind {
Circle,
Rectangle,
}
struct Model {
shapes: Vec<Shape>,
}
fn main() {
nannou::app(model).update(update).run();
}
fn model(app: &App) -> Model {
app.new_window().size(1080, 1080).title("Moving Shapes with Trail").view(view).build().unwrap();
let mut shapes = Vec::new();
for _ in 0..50 {
let shape = Shape {
pos_x: rand::random_range(-540.0..=540.0),
pos_y: rand::random_range(-540.0..=540.0),
vel_x: rand::random_range(-0.5..0.5),
vel_y: rand::random_range(-0.5..0.5),
size: rand::random_range(5.0..100.0),
color: hsla(rand::random_range(0.0..1.0), 0.0, 0.7, 0.5),
kind: if rand::random() {
ShapeKind::Circle
} else {
ShapeKind::Rectangle
},
};
shapes.push(shape);
}
Model { shapes }
}
fn update(app: &App, model: &mut Model, _update: Update) {
let win_rect = app.window_rect();
for shape in &mut model.shapes {
shape.pos_x += shape.vel_x;
shape.pos_y += shape.vel_y;
if shape.pos_x > win_rect.right() + 50.0 {
shape.pos_x = win_rect.left() - 50.0;
} else if shape.pos_x < win_rect.left() - 50.0 {
shape.pos_x = win_rect.right() + 50.0;
}
if shape.pos_y > win_rect.top() + 50.0 {
shape.pos_y = win_rect.bottom() - 50.0;
} else if shape.pos_y < win_rect.bottom() - 50.0 {
shape.pos_y = win_rect.top() + 50.0;
}
}
}
fn view(app: &App, model: &Model, frame: Frame) {
let draw = app.draw();
let frame_no = frame.nth();
if frame_no == 0 {
draw.background().color(hsla(0.0, 0.0, 0.0, 1.0));
} else {
draw.rect().wh(app.window_rect().wh()).color(hsla(0.0, 0.0, 0.0, 0.02));
}
for shape in &model.shapes {
match shape.kind {
ShapeKind::Circle => {
draw.ellipse()
.x_y(shape.pos_x, shape.pos_y)
.radius(shape.size / 2.0)
.color(shape.color);
}
ShapeKind::Rectangle => {
draw.rect()
.x_y(shape.pos_x, shape.pos_y)
.w_h(shape.size, shape.size)
.color(shape.color);
}
}
}
draw.to_frame(app, &frame).unwrap();
}
use nannou::prelude::*;
struct Shape {
pos_x: f32,
pos_y: f32,
vel_x: f32,
vel_y: f32,
size: f32,
color: Hsla,
kind: ShapeKind,
}
enum ShapeKind {
Circle,
Rectangle,
}
struct Model {
shapes: Vec<Shape>,
}
fn main() {
nannou::app(model)
.update(update)
.run();
}
fn model(app: &App) -> Model {
app.new_window()
.size(1080, 1080)
.title("Moving Shapes with Trail")
.view(view)
.build()
.unwrap();
let mut shapes = Vec::new();
for _ in 0..50 {
let shape = Shape {
pos_x: rand::random_range(-540.0..=540.0),
pos_y: rand::random_range(-540.0..=540.0),
vel_x: rand::random_range(-0.5..0.5),
vel_y: rand::random_range(-0.5..0.5),
size: rand::random_range(5.0..100.0),
color: hsla(rand::random_range(0.0..1.0), 0.0, 0.7, 0.5),
kind: if rand::random() {
ShapeKind::Circle
} else {
ShapeKind::Rectangle
},
};
shapes.push(shape);
}
Model { shapes }
}
fn update(app: &App, model: &mut Model, _update: Update) {
let win_rect = app.window_rect();
for shape in &mut model.shapes {
shape.pos_x += shape.vel_x;
shape.pos_y += shape.vel_y;
if shape.pos_x > win_rect.right() + 50.0 {
shape.pos_x = win_rect.left() - 50.0;
} else if shape.pos_x < win_rect.left() - 50.0 {
shape.pos_x = win_rect.right() + 50.0;
}
if shape.pos_y > win_rect.top() + 50.0 {
shape.pos_y = win_rect.bottom() - 50.0;
} else if shape.pos_y < win_rect.bottom() - 50.0 {
shape.pos_y = win_rect.top() + 50.0;
}
}
}
fn view(app: &App, model: &Model, frame: Frame) {
let draw = app.draw();
let frame_no = frame.nth();
if frame_no == 0 {
draw.background().color(hsla(0.0, 0.0, 0.0, 1.0));
} else {
draw.rect()
.wh(app.window_rect().wh())
.color(hsla(0.0, 0.0, 0.0, 0.02));
}
for shape in &model.shapes {
match shape.kind {
ShapeKind::Circle => {
draw.ellipse()
.x_y(shape.pos_x, shape.pos_y)
.radius(shape.size / 2.0)
.color(shape.color);
}
ShapeKind::Rectangle => {
draw.rect()
.x_y(shape.pos_x, shape.pos_y)
.w_h(shape.size, shape.size)
.color(shape.color);
}
}
}
draw.to_frame(app, &frame).unwrap();
}