Added support for gradients as background variants + other optimizations.

This commit is contained in:
Bingus 2023-05-11 09:12:06 -07:00
parent 669f7cc74b
commit 6551a0b2ab
No known key found for this signature in database
GPG key ID: 5F84D2AA40A9F170
41 changed files with 1658 additions and 1489 deletions

View file

@ -1,11 +0,0 @@
[package]
name = "modern_art"
version = "0.1.0"
authors = ["Bingus <shankern@protonmail.com>"]
edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["canvas", "tokio", "debug"] }
rand = "0.8.5"
env_logger = "0.9"

View file

@ -1,143 +0,0 @@
use iced::widget::canvas::{
self, gradient::Location, gradient::Position, Cache, Canvas, Cursor, Frame,
Geometry, Gradient,
};
use iced::{
executor, Application, Color, Command, Element, Length, Point, Rectangle,
Renderer, Settings, Size, Theme,
};
use rand::{thread_rng, Rng};
fn main() -> iced::Result {
env_logger::builder().format_timestamp(None).init();
ModernArt::run(Settings {
antialiasing: true,
..Settings::default()
})
}
#[derive(Debug, Clone, Copy)]
enum Message {}
struct ModernArt {
cache: Cache,
}
impl Application for ModernArt {
type Executor = executor::Default;
type Message = Message;
type Theme = Theme;
type Flags = ();
fn new(_flags: Self::Flags) -> (Self, Command<Self::Message>) {
(
ModernArt {
cache: Default::default(),
},
Command::none(),
)
}
fn title(&self) -> String {
String::from("Modern Art")
}
fn update(&mut self, _message: Message) -> Command<Message> {
Command::none()
}
fn view(&self) -> Element<'_, Self::Message, Renderer<Self::Theme>> {
Canvas::new(self)
.width(Length::Fill)
.height(Length::Fill)
.into()
}
}
impl<Message> canvas::Program<Message, Renderer> for ModernArt {
type State = ();
fn draw(
&self,
_state: &Self::State,
renderer: &Renderer,
_theme: &Theme,
bounds: Rectangle,
_cursor: Cursor,
) -> Vec<Geometry> {
let geometry = self.cache.draw(renderer, bounds.size(), |frame| {
let num_squares = thread_rng().gen_range(0..1200);
let mut i = 0;
while i <= num_squares {
generate_box(frame, bounds.size());
i += 1;
}
});
vec![geometry]
}
}
fn random_direction() -> Location {
match thread_rng().gen_range(0..8) {
0 => Location::TopLeft,
1 => Location::Top,
2 => Location::TopRight,
3 => Location::Right,
4 => Location::BottomRight,
5 => Location::Bottom,
6 => Location::BottomLeft,
7 => Location::Left,
_ => Location::TopLeft,
}
}
fn generate_box(frame: &mut Frame, bounds: Size) -> bool {
let solid = rand::random::<bool>();
let random_color = || -> Color {
Color::from_rgb(
thread_rng().gen_range(0.0..1.0),
thread_rng().gen_range(0.0..1.0),
thread_rng().gen_range(0.0..1.0),
)
};
let gradient = |top_left: Point, size: Size| -> Gradient {
let mut builder = Gradient::linear(Position::Relative {
top_left,
size,
start: random_direction(),
end: random_direction(),
});
let stops = thread_rng().gen_range(1..15u32);
let mut i = 0;
while i <= stops {
builder = builder.add_stop(i as f32 / stops as f32, random_color());
i += 1;
}
builder.build().unwrap()
};
let top_left = Point::new(
thread_rng().gen_range(0.0..bounds.width),
thread_rng().gen_range(0.0..bounds.height),
);
let size = Size::new(
thread_rng().gen_range(50.0..200.0),
thread_rng().gen_range(50.0..200.0),
);
if solid {
frame.fill_rectangle(top_left, size, random_color());
} else {
frame.fill_rectangle(top_left, size, gradient(top_left, size));
};
solid
}

View file

@ -7,4 +7,5 @@ publish = false
[dependencies]
iced = { path = "../..", features = ["canvas", "tokio", "debug"] }
env_logger = "0.10.0"
rand = "0.8.3"

View file

@ -10,9 +10,8 @@ use iced::application;
use iced::executor;
use iced::theme::{self, Theme};
use iced::widget::canvas;
use iced::widget::canvas::gradient::{self, Gradient};
use iced::widget::canvas::stroke::{self, Stroke};
use iced::widget::canvas::{Cursor, Path};
use iced::widget::canvas::{Cursor, Gradient, Path};
use iced::window;
use iced::{
Application, Color, Command, Element, Length, Point, Rectangle, Renderer,
@ -22,6 +21,8 @@ use iced::{
use std::time::Instant;
pub fn main() -> iced::Result {
env_logger::builder().format_timestamp(None).init();
SolarSystem::run(Settings {
antialiasing: true,
..Settings::default()
@ -208,15 +209,13 @@ impl<Message> canvas::Program<Message> for State {
let earth = Path::circle(Point::ORIGIN, Self::EARTH_RADIUS);
let earth_fill =
Gradient::linear(gradient::Position::Absolute {
start: Point::new(-Self::EARTH_RADIUS, 0.0),
end: Point::new(Self::EARTH_RADIUS, 0.0),
})
.add_stop(0.2, Color::from_rgb(0.15, 0.50, 1.0))
.add_stop(0.8, Color::from_rgb(0.0, 0.20, 0.47))
.build()
.expect("Build Earth fill gradient");
let earth_fill = Gradient::linear(
Point::new(-Self::EARTH_RADIUS, 0.0),
Point::new(Self::EARTH_RADIUS, 0.0),
)
.add_stop(0.2, Color::from_rgb(0.15, 0.50, 1.0))
.add_stop(0.8, Color::from_rgb(0.0, 0.20, 0.47))
.build();
frame.fill(&earth, earth_fill);

View file

@ -7,4 +7,4 @@ publish = false
[dependencies]
iced = { path = "../..", features = ["image", "debug"] }
env_logger = "0.8"
env_logger = "0.10.0"

View file

@ -1,11 +1,15 @@
use iced::alignment;
use iced::theme;
use iced::theme::Palette;
use iced::widget::{
checkbox, column, container, horizontal_space, image, radio, row,
scrollable, slider, text, text_input, toggler, vertical_space,
};
use iced::widget::{Button, Column, Container, Slider};
use iced::{Color, Element, Font, Length, Renderer, Sandbox, Settings};
use iced::{alignment, widget, Theme};
use iced::{
Color, Degrees, Element, Font, Gradient, Length, Radians, Renderer,
Sandbox, Settings,
};
pub fn main() -> iced::Result {
env_logger::init();
@ -53,9 +57,11 @@ impl Sandbox for Tour {
if steps.has_previous() {
controls = controls.push(
button("Back")
.on_press(Message::BackPressed)
.style(theme::Button::Secondary),
button("Back").on_press(Message::BackPressed).style(
theme::Button::Custom(Box::new(
CustomButtonStyle::Secondary,
)),
),
);
}
@ -63,9 +69,9 @@ impl Sandbox for Tour {
if steps.can_continue() {
controls = controls.push(
button("Next")
.on_press(Message::NextPressed)
.style(theme::Button::Primary),
button("Next").on_press(Message::NextPressed).style(
theme::Button::Custom(Box::new(CustomButtonStyle::Primary)),
),
);
}
@ -716,3 +722,39 @@ pub enum Layout {
Row,
Column,
}
enum CustomButtonStyle {
Primary,
Secondary,
}
impl widget::button::StyleSheet for CustomButtonStyle {
type Style = Theme;
fn active(&self, _style: &Self::Style) -> widget::button::Appearance {
match self {
CustomButtonStyle::Primary => widget::button::Appearance {
background: Gradient::linear(Degrees(270.0))
.add_stop(0.0, Palette::LIGHT.primary)
.add_stop(1.0, Color::from_rgb8(54, 80, 168))
.build()
.into(),
text_color: Color::WHITE,
border_radius: 5.0,
..Default::default()
},
CustomButtonStyle::Secondary => widget::button::Appearance {
background: Gradient::linear(Radians(
3.0 * std::f32::consts::PI / 2.0,
))
.add_stop(0.0, Color::from_rgb8(194, 194, 194))
.add_stop(1.0, Color::from_rgb8(126, 126, 126))
.build()
.into(),
text_color: Color::WHITE,
border_radius: 5.0,
..Default::default()
},
}
}
}