1 module prova.graphics.color;
2 
3 ///
4 struct Color
5 {
6   ///
7   float r = 1;
8   ///
9   float g = 1;
10   ///
11   float b = 1;
12   ///
13   float a = 1;
14 
15   /// Hex string starting with a #
16   this(string hex)
17   {
18     import std.conv : to;
19 
20     r = to!int(hex[1..3], 16) / 255f;
21     g = to!int(hex[3..5], 16) / 255f;
22     b = to!int(hex[5..7], 16) / 255f;
23 
24     if(hex.length == 9) {
25       a = to!int(hex[7..9], 16) / 255f;
26     }
27   }
28 
29   ///
30   this(float r, float g, float b)
31   {
32     set(r, g, b, 1);
33   }
34 
35   ///
36   this(float r, float g, float b, float a)
37   {
38     set(r, g, b, a);
39   }
40 
41   /// Sets the values of r, g, and b in a single statement
42   void set(float r, float g, float b)
43   {
44     this.r = r;
45     this.g = g;
46     this.b = b;
47     this.a = 1;
48   }
49 
50   /// Sets the values of r, g, b, and a in a single statement
51   void set(float r, float g, float b, float a)
52   {
53     this.r = r;
54     this.g = g;
55     this.b = b;
56     this.a = a;
57   }
58 
59   invariant
60   {
61     // limit components to be [0-1]
62     assert(r <= 1 && r >= 0);
63     assert(g <= 1 && g >= 0);
64     assert(b <= 1 && b >= 0);
65     assert(a <= 1 && a >= 0);
66   }
67 }
68 
69 ///
70 Color lerp(Color from, Color to, float a)
71 {
72   return Color(
73     from.r * (1 - a) + to.r * a,
74     from.g * (1 - a) + to.g * a,
75     from.b * (1 - a) + to.b * a,
76     from.a * (1 - a) + to.a * a,
77   );
78 }
79 
80 unittest {
81   auto red = Color(1, 0, 0);
82   auto blue = Color(0, 0, 1);
83 
84   assert(lerp(red, blue, .5) == Color(.5, 0, .5));
85   assert(lerp(red, blue, .75) == Color(.25, 0, .75));
86 }