Skip to content

Commit

Permalink
enhance: expose shape fields
Browse files Browse the repository at this point in the history
  • Loading branch information
carrascomj committed Dec 30, 2024
1 parent c321a36 commit 8e13f53
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 3 deletions.
105 changes: 105 additions & 0 deletions examples/dynamic_stroke_size.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//! Demonstrate surgical changes on the fields of `Shape` (path, fill, stroke).
//! The triangle changes fill color; the hexagon changes stroke width; and
//! the node positions of all shapes are extracted from the path to apply different
//! rotations on size.
use bevy::{color::palettes::css::*, prelude::*};
use bevy_prototype_lyon::prelude::*;

fn main() {
App::new()
.add_plugins((DefaultPlugins, ShapePlugin))
.add_systems(Startup, setup_system)
.add_systems(Update, redraw_line_width)
.add_systems(Update, redraw_fill)
.add_systems(Update, rotate_shape_by_size)
.run();
}

// Marker traits to uniquely identify entities.
#[derive(Component)]
struct HexagonShape;
#[derive(Component)]
struct TriangleShape;

/// Walk Path to get the maximum x coordinate.
fn get_max_x(shape: &Shape) -> f32 {
shape
.path
.iter()
.map(|p| p.to().x)
.chain(shape.path.iter().map(|p| p.from().x))
.fold(0f32, |acc, x| if x - acc > 1e-8 { x } else { acc })
}

/// Over time, rotate smaller shapes faster.
fn rotate_shape_by_size(mut query: Query<(&mut Transform, &Shape)>, time: Res<Time>) {
let delta = time.delta_secs();

for (mut transform, shape) in query.iter_mut() {
transform.rotate(Quat::from_rotation_z(200. / get_max_x(shape) * delta));
}
}

/// Change line width of the hexagon over time.
fn redraw_line_width(mut query: Query<&mut Shape, With<HexagonShape>>, time: Res<Time>) {
let outline_width = 2.0 + time.elapsed_secs_f64().sin().abs() * 10.0;

let mut shape = query.single_mut();
shape.stroke = shape.stroke.map(|mut s| {
s.options.line_width = outline_width as f32;
s
});
}

/// Change fill color of the triangle over time.
fn redraw_fill(mut query: Query<&mut Shape, With<TriangleShape>>, time: Res<Time>) {
let hue = (time.elapsed_secs_f64() * 50.0) % 360.0;
let color = Color::hsl(hue as f32, 1.0, 0.5);

let mut shape = query.single_mut();
shape.fill = shape.fill.map(|mut f| {
f.color = color;
f
});
}

fn setup_system(mut commands: Commands) {
let triangle = shapes::RegularPolygon {
sides: 3,
feature: shapes::RegularPolygonFeature::Radius(100.0),
..shapes::RegularPolygon::default()
};
let hexagon = shapes::RegularPolygon {
sides: 6,
feature: shapes::RegularPolygonFeature::Radius(200.0),
..shapes::RegularPolygon::default()
};
let big_square = shapes::RegularPolygon {
sides: 4,
feature: shapes::RegularPolygonFeature::Radius(300.0),
..shapes::RegularPolygon::default()
};

commands.spawn((Camera2d, Msaa::Sample4));
commands.spawn((
ShapeBuilder::with(&triangle)
.fill(DARK_CYAN)
.stroke((BLACK, 10.0))
.build(),
Transform::default().with_translation(Vec3::new(0., 0., 2.)),
TriangleShape,
));
commands.spawn((
ShapeBuilder::with(&hexagon)
.fill(DARK_CYAN)
.stroke((BLACK, 10.0))
.build(),
Transform::default().with_translation(Vec3::new(0., 0., 1.)),
HexagonShape,
));
commands.spawn((ShapeBuilder::with(&big_square)
.fill(ORANGE)
.stroke((BLACK, 10.0))
.build(),));
}
9 changes: 6 additions & 3 deletions src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ impl Default for ShapeBundle {
#[derive(Component, Default, Clone)]
#[require(Mesh2d, MeshMaterial2d<ColorMaterial>(color_material_handle), Transform, Visibility)]
pub struct Shape {
path: tess::path::Path,
fill: Option<Fill>,
stroke: Option<Stroke>,
/// Geometry of a shape.
pub path: tess::path::Path,
/// Fill data, changes are propagated to the mesh.
pub fill: Option<Fill>,
/// Stroke data, changes are propagated to the mesh.
pub stroke: Option<Stroke>,
}

impl Shape {
Expand Down

0 comments on commit 8e13f53

Please sign in to comment.