gdritter repos here-comes-a-thought / d413ef5
Hacky and quick sky generator Getty Ritter 6 years ago
3 changed file(s) with 138 addition(s) and 0 deletion(s). Collapse all Expand all
1 /target/
2 **/*.rs.bk
3 *~
1 [package]
2 name = "here-comes-a-thought"
3 version = "0.1.0"
4 authors = ["gdritter"]
5
6 [dependencies]
7 cairo-rs = { version = "0.3.0", features = ["png"] }
8 png = "0.11.0"
9 rand = "0.3.18"
10 palette = "0.2.1"
1 extern crate cairo;
2 extern crate palette;
3 extern crate rand;
4
5 use rand::Rng;
6 use cairo::Gradient;
7
8 const WIDTH: i32 = 3840;
9 const HEIGHT: i32 = 2160;
10
11 fn cloud(ctx: &cairo::Context, rng: &mut rand::ThreadRng) {
12 let x_scale = rng.gen::<f64>() * 2.0 + 1.0;
13 let x = (rng.gen::<f64>() * WIDTH as f64) / x_scale;
14 let y = rng.gen::<f64>() * HEIGHT as f64;
15 let num_circles = 2 + (rng.gen::<isize>() % 2);
16 let vec: Vec<(f64, f64)> = (0..num_circles).map(|_| {
17 let width = 60.0 + rng.gen::<f64>() * 200.0;
18 let dist = 30.0 + rng.gen::<f64>() * 30.0;
19 (width, dist)
20 }).collect();
21
22 let surf = cairo::Context::new(&ctx.get_target().create_similar(cairo::Content::Alpha, WIDTH, HEIGHT));
23
24 surf.save();
25 let mut max_y = 0.0;
26 let mut offset = x;
27 surf.scale(x_scale, 1.0);
28 surf.set_source_rgba(1.0, 1.0, 1.0, 1.0);
29 for (width, dist) in vec {
30 surf.arc(offset, y, width, 0.0, 3.14159 * 2.0);
31 surf.fill();
32 offset = offset + width + dist;
33 max_y = if width > max_y { width } else { max_y };
34 }
35 surf.set_source_rgba(0.0, 0.0, 0.0, 0.0);
36 surf.set_operator(cairo::Operator::Source);
37 surf.rectangle(x - 260.0, y, offset + 260.0, max_y);
38 surf.fill();
39 surf.restore();
40
41 surf.set_source_rgba(1.0, 1.0, 1.0, 0.8);
42 ctx.mask(&cairo::SurfacePattern::create(&surf.get_target()));
43 }
44
45 fn shinedies(ctx: &cairo::Context, rng: &mut rand::ThreadRng) {
46 let r = rng.gen::<f64>();
47 for _ in 0..20 {
48 let surf = cairo::Context::new(&ctx.get_target().create_similar(cairo::Content::Alpha, WIDTH, HEIGHT));
49
50 surf.save();
51 surf.scale(0.5, 0.5);
52 surf.translate(rng.gen::<f64>() * WIDTH as f64 * 2.0, rng.gen::<f64>() * HEIGHT as f64 * 2.0);
53 surf.rotate(r);
54 surf.set_source_rgba(1.0, 1.0, 1.0, 1.0);
55 let w = 300.0 + rng.gen::<f64>() * 1200.0;
56 let r = rng.gen::<f64>() * 300.0;
57 surf.arc(0.0, 0.0, r, 0.0, 3.14159 * 2.0);
58 surf.fill();
59 surf.arc(w, 0.0, r, 0.0, 3.14159 * 2.0);
60 surf.fill();
61 surf.rectangle(0.0, -r, w, r * 2.0);
62 surf.fill();
63 surf.restore();
64
65 ctx.set_source_rgba(1.0, 1.0, 1.0, 0.3);
66 ctx.mask(&cairo::SurfacePattern::create(&surf.get_target()));
67 }
68 }
69
70 fn stars(ctx: &cairo::Context, rng: &mut rand::ThreadRng) {
71 ctx.set_source_rgba(1.0, 1.0, 1.0, 0.8);
72 for _ in 0..200 {
73 let x = rng.gen::<f64>() * WIDTH as f64;
74 let y = rng.gen::<f64>() * HEIGHT as f64;
75 let s = 4.0 + rng.gen::<f64>() * 6.0 as f64;
76 ctx.arc(x, y, s, 0.0, 3.14159 * 2.0);
77 ctx.fill();
78 }
79 }
80
81 fn get_sky_colors(rng: &mut rand::ThreadRng) -> (palette::Rgb, palette::Rgb) {
82 use palette::{RgbHue, Hsv, Hue};
83 let default_dark: Hsv = Hsv::from(palette::Rgb::new(0.188, 0.333, 0.51));
84 let default_light: Hsv = Hsv::from(palette::Rgb::new(0.482, 0.749, 0.839));
85 let shift = RgbHue::from_radians(rng.gen::<f32>() * 3.14159 * 2.0);
86 (default_dark.shift_hue(shift).into(), default_light.shift_hue(shift).into())
87 }
88
89 fn main() {
90 let surf = cairo::ImageSurface::create(
91 cairo::Format::Rgb24,
92 WIDTH,
93 HEIGHT
94 ).unwrap();
95
96 let mut rng = rand::thread_rng();
97 let ctx = cairo::Context::new(&surf);
98 let w = rng.gen::<u8>() % 3;
99 ctx.set_source_rgb(
100 if w == 0 { 0.4 } else { 0.2 },
101 if w == 1 { 0.4 } else { 0.2 },
102 if w == 2 { 0.4 } else { 0.2 },
103 );
104 ctx.paint();
105
106 let g = cairo::LinearGradient::new(
107 0.0, 0.0, 0.0, HEIGHT as f64
108 );
109 let (dark, light) = get_sky_colors(&mut rng);
110 g.add_color_stop_rgb(0.0, dark.red as f64, dark.green as f64, dark.blue as f64);
111 g.add_color_stop_rgb(1.0, light.red as f64, light.green as f64, light.blue as f64);
112 ctx.set_source(&g);
113 ctx.paint();
114
115 stars(&ctx, &mut rng);
116 for _ in 0..10 {
117 cloud(&ctx, &mut rng);
118 }
119 shinedies(&ctx, &mut rng);
120
121 {
122 let mut f = std::fs::File::create("image.png").unwrap();
123 surf.write_to_png(&mut f).unwrap();
124 }
125 }