1 00:00:16,850 --> 00:00:18,090 CHARLES LOWELL: All right everybody. 2 00:00:18,090 --> 00:00:20,570 Thank you so much for coming. I'm really, 3 00:00:20,570 --> 00:00:24,250 I'm really honored. This morning we're gonna 4 00:00:24,250 --> 00:00:27,869 be talking about client-side UI. These are, 5 00:00:27,869 --> 00:00:30,130 this, your client that's, that's running inside 6 00:00:30,130 --> 00:00:33,040 the browser. Not in the server. And some of you 7 00:00:33,040 --> 00:00:36,110 might already be doing this a lot. Some of you 8 00:00:36,110 --> 00:00:39,780 maybe a little. But wherever you fall along that 9 00:00:39,780 --> 00:00:42,390 spectrum, you're going to be doing more of it, 10 00:00:42,390 --> 00:00:45,000 chances are, as time, as time goes on, and not 11 00:00:45,000 --> 00:00:47,610 less of it. And so I want, my goal here is to 12 00:00:47,610 --> 00:00:50,780 share with you some of the ways that I've come 13 00:00:50,780 --> 00:00:53,680 to think about clients, UIs, that can help you 14 00:00:53,680 --> 00:00:59,670 build user interfaces that reactive, that are 15 00:00:59,670 --> 00:01:02,670 educational and ultimately satisfying to your users. 16 00:01:02,670 --> 00:01:05,519 What I want to share with you is the power of m. 17 00:01:05,519 --> 00:01:11,450 My name is Charles. I'm cowboyd on GitHub and 18 00:01:11,450 --> 00:01:13,680 Twitter, and I work at the Front Side, where 19 00:01:13,680 --> 00:01:20,240 we've been doing UI for almost ten years, exclusively. 20 00:01:20,240 --> 00:01:22,619 And when I talk about m, of course I'm 21 00:01:22,619 --> 00:01:26,049 talking about m as in MVC. We're all familiar, 22 00:01:26,049 --> 00:01:30,450 we've probably heard about the MVC pattern, model-view-controller. It's 23 00:01:30,450 --> 00:01:35,930 what underpins all UIs. At least ostensibly. 24 00:01:35,930 --> 00:01:39,759 But it can actually be pretty notoriously difficult to 25 00:01:39,759 --> 00:01:45,140 pin down what, exactly, is MVC. It's a difficult 26 00:01:45,140 --> 00:01:48,539 question, and if you ask two people, you're likely 27 00:01:48,539 --> 00:01:54,659 to get a very different answer. And my, what 28 00:01:54,659 --> 00:01:59,119 I'm. I don't want to, to, to go in 29 00:01:59,119 --> 00:02:02,840 too much to try and define, give you one 30 00:02:02,840 --> 00:02:06,729 particular version of MVC. I think there are many. 31 00:02:06,729 --> 00:02:10,038 And, in fact, you find people asking the question, 32 00:02:10,038 --> 00:02:12,140 is Rails MVC? 33 00:02:12,140 --> 00:02:14,580 And some people are really, really stodgy about this. 34 00:02:14,580 --> 00:02:20,150 They're, Rails MVC - pshaw. I'm more relaxed about 35 00:02:20,150 --> 00:02:24,140 it. I say yes. Rails is MVC. It's server-side 36 00:02:24,140 --> 00:02:29,030 MVC. It's a flavor of, of MVC. But what 37 00:02:29,030 --> 00:02:31,980 I've come to realize is that MVC is, it's 38 00:02:31,980 --> 00:02:34,920 kind of like Kung-Fu. There's lots of different schools. 39 00:02:34,920 --> 00:02:37,610 There's lots of different ways to, to practition. Each 40 00:02:37,610 --> 00:02:40,840 with its own strengths, each with its own weaknesses, 41 00:02:40,840 --> 00:02:43,760 and, you know, which one you choose, you need 42 00:02:43,760 --> 00:02:48,000 to, is, is, needs to be appropriate for the 43 00:02:48,000 --> 00:02:50,050 context. 44 00:02:50,050 --> 00:02:53,750 But today we're gonna be talking about client-side UI, 45 00:02:53,750 --> 00:02:55,970 which is different than, different than the, than the 46 00:02:55,970 --> 00:03:00,670 server-side MVC, and one of the things that, that 47 00:03:00,670 --> 00:03:02,500 really sets it apart is, when you're working on 48 00:03:02,500 --> 00:03:04,760 the client, you constantly have to manage state. The 49 00:03:04,760 --> 00:03:06,870 client's always on. It's not like a Rails application 50 00:03:06,870 --> 00:03:09,480 where you're basically setting up the world and then 51 00:03:09,480 --> 00:03:12,420 throwing it away with every request. On the client, 52 00:03:12,420 --> 00:03:15,620 you're always on. And so you have values that 53 00:03:15,620 --> 00:03:17,120 relate to each other, and when one of those 54 00:03:17,120 --> 00:03:20,930 values changes, you have to update the, the, the 55 00:03:20,930 --> 00:03:25,450 other values to reflect that. 56 00:03:25,450 --> 00:03:32,450 So, when we're thinking about MVC, I've come to, 57 00:03:33,170 --> 00:03:35,010 to realize that really what you want to do 58 00:03:35,010 --> 00:03:38,650 is you want to focus on the model. When 59 00:03:38,650 --> 00:03:42,370 you first come to the, to the acronym, MVC, 60 00:03:42,370 --> 00:03:47,090 model-view-controller, you tend to, to give equal billing to 61 00:03:47,090 --> 00:03:50,560 the letters, because they're, they're, there's, no one is 62 00:03:50,560 --> 00:03:56,930 set apart from, in, in the acronym. But I've 63 00:03:56,930 --> 00:03:59,760 come to find that while the view and the 64 00:03:59,760 --> 00:04:03,790 controller are important, they orbit the model. 65 00:04:03,790 --> 00:04:07,760 So, I actually draw inspiration from, from this guy. 66 00:04:07,760 --> 00:04:09,760 This is Plato. He's one of the ancient software 67 00:04:09,760 --> 00:04:11,870 developers. You can actually tell. He's got a ChromeBook 68 00:04:11,870 --> 00:04:15,580 Pixel there in his, in his hand. 69 00:04:15,580 --> 00:04:19,389 And I think that he made an analogy, long 70 00:04:19,389 --> 00:04:22,680 time ago, that I think really, cleanly captures this 71 00:04:22,680 --> 00:04:26,530 concept. He had this allegory of a cave, and 72 00:04:26,530 --> 00:04:31,610 the idea is that living in this world is, 73 00:04:31,610 --> 00:04:35,760 is like being inside a cave, and back up 74 00:04:35,760 --> 00:04:38,430 at the entrance of the cave, where you can't 75 00:04:38,430 --> 00:04:42,820 see, there's this fire burning. And shapes pass in 76 00:04:42,820 --> 00:04:45,330 front of the fire, and they cast shadows on 77 00:04:45,330 --> 00:04:48,230 the wall. And we, inside the world, the only 78 00:04:48,230 --> 00:04:51,330 thing that we can actually see is the shadows. 79 00:04:51,330 --> 00:04:54,610 The shapes and the fire are hidden from us. 80 00:04:54,610 --> 00:04:56,410 But if we look at the, the, the shadows, 81 00:04:56,410 --> 00:04:59,460 we can extrapolate those shapes, and the shapes that 82 00:04:59,460 --> 00:05:02,480 we see on the wall take their form purely 83 00:05:02,480 --> 00:05:05,090 as a function of the shape in front of 84 00:05:05,090 --> 00:05:07,150 the fire. They are as they are and are 85 00:05:07,150 --> 00:05:12,060 no other way because, because of those true forms 86 00:05:12,060 --> 00:05:15,660 and then the way that they interact. 87 00:05:15,660 --> 00:05:18,560 And so this is all, this is all very, 88 00:05:18,560 --> 00:05:21,700 very abstract. We've covered, you know, who I am. 89 00:05:21,700 --> 00:05:26,360 We've covered the, the, an ancient philosopher, which I 90 00:05:26,360 --> 00:05:31,030 guess is obligatory. But, I really want to give 91 00:05:31,030 --> 00:05:34,030 a demonstration of this principle in action so that 92 00:05:34,030 --> 00:05:38,240 you can see a little bit more concretely what 93 00:05:38,240 --> 00:05:40,250 it is that I'm talking about. And so, to 94 00:05:40,250 --> 00:05:44,190 do this, we're going to explore the concept of 95 00:05:44,190 --> 00:05:47,580 a color. It's a, a, a very simple concept. 96 00:05:47,580 --> 00:05:50,230 It's something that most of us can perceive very 97 00:05:50,230 --> 00:05:52,700 easily. We, we, we know what it is, but 98 00:05:52,700 --> 00:05:57,300 can be surprisingly difficult to, to pin down. 99 00:05:57,300 --> 00:06:01,030 There's many, many, many different ways to represent it. 100 00:06:01,030 --> 00:06:03,650 But we're gonna have, we're gonna have a color, 101 00:06:03,650 --> 00:06:05,680 and this is gonna serve as the basic value 102 00:06:05,680 --> 00:06:06,990 in our system. You can think of it as 103 00:06:06,990 --> 00:06:09,530 like, an integer value or a string value, or, 104 00:06:09,530 --> 00:06:11,520 or something like that, and we're going to see 105 00:06:11,520 --> 00:06:14,620 how this when, when we have this color, what 106 00:06:14,620 --> 00:06:16,940 kind of, what kind of reflections we can make 107 00:06:16,940 --> 00:06:19,360 on that wall. 108 00:06:19,360 --> 00:06:22,550 So, the first example is we're just going to, 109 00:06:22,550 --> 00:06:23,919 we're just going to project this color onto a 110 00:06:23,919 --> 00:06:28,510 single div. We're going to list this color value 111 00:06:28,510 --> 00:06:30,210 on the right. We're going to be able to 112 00:06:30,210 --> 00:06:33,389 set a color, remove a color, set a color, 113 00:06:33,389 --> 00:06:37,110 and as we do that, the, the, the swatch, 114 00:06:37,110 --> 00:06:39,210 the color swatch will, will update itself. And I 115 00:06:39,210 --> 00:06:43,790 actually have a little demo here. And I've got 116 00:06:43,790 --> 00:06:45,740 it hard-coded, just statically, so that when I check 117 00:06:45,740 --> 00:06:49,620 this checkbox, the, the swatch will turn green. And 118 00:06:49,620 --> 00:06:51,740 I can uncheck it and check it. 119 00:06:51,740 --> 00:06:55,040 It's not, not too much. It's simple but it's 120 00:06:55,040 --> 00:06:58,490 surprisingly satisfying. When I was putting this talk together 121 00:06:58,490 --> 00:07:01,340 I actually would just sit there and click on, 122 00:07:01,340 --> 00:07:04,389 off. It's great. 123 00:07:04,389 --> 00:07:05,480 And you can do the same thing. We can 124 00:07:05,480 --> 00:07:09,110 actually connect one color to two swatches. So we've 125 00:07:09,110 --> 00:07:11,600 got, there's no reason we can't, can't duplicate that. 126 00:07:11,600 --> 00:07:14,669 We'll take two of these swatches and, and bind 127 00:07:14,669 --> 00:07:17,990 them to the, the, the same color. The, there's, 128 00:07:17,990 --> 00:07:20,020 there's, so there's only one color in the system, 129 00:07:20,020 --> 00:07:23,139 but the effect is the same. 130 00:07:23,139 --> 00:07:29,600 Again, I could do that forever. 131 00:07:29,600 --> 00:07:30,980 And this is what data binding is. You might 132 00:07:30,980 --> 00:07:35,120 hear about data binding, and most people kind of 133 00:07:35,120 --> 00:07:37,550 equate data binding with templates, because that's usually where 134 00:07:37,550 --> 00:07:39,160 we come to it first, right. We change this 135 00:07:39,160 --> 00:07:40,960 one value and the string value updates, right. But 136 00:07:40,960 --> 00:07:43,610 templates are really just a special case of data 137 00:07:43,610 --> 00:07:48,760 binding. In the abstract, it's really just about taking 138 00:07:48,760 --> 00:07:51,840 two values and putting, putting them together so that 139 00:07:51,840 --> 00:07:55,139 they occupy the same space in your application. There 140 00:07:55,139 --> 00:07:58,669 really is no difference, conceptually, between them. 141 00:07:58,669 --> 00:08:02,949 Some, this is, this is different than observation, which 142 00:08:02,949 --> 00:08:05,130 is kind of another pillar on which client-side UIs 143 00:08:05,130 --> 00:08:08,260 are built, where you can observe for value changes 144 00:08:08,260 --> 00:08:10,870 in a model, and when that value changes you 145 00:08:10,870 --> 00:08:17,410 get a callback. But. With data binding, you really 146 00:08:17,410 --> 00:08:20,080 need to think of it taking two separate properties 147 00:08:20,080 --> 00:08:22,870 and really just making them overlap and becoming the, 148 00:08:22,870 --> 00:08:24,729 the absolute, the, the same thing. 149 00:08:24,729 --> 00:08:27,570 Now, it is built on observation. So, when we 150 00:08:27,570 --> 00:08:29,610 have a model and it's got some property. I've 151 00:08:29,610 --> 00:08:31,280 got one named a and one named b. We 152 00:08:31,280 --> 00:08:36,899 can use observers to, to, to implement the data 153 00:08:36,899 --> 00:08:40,979 binding, so if a value appears at a, we 154 00:08:40,979 --> 00:08:43,809 observe that and we immediately copy it onto b. 155 00:08:43,809 --> 00:08:46,769 And if a value appears on b, then we 156 00:08:46,769 --> 00:08:50,680 immediately copy it over into a. But I'm showing 157 00:08:50,680 --> 00:08:52,300 this, the mechanics of it, so that you can 158 00:08:52,300 --> 00:08:54,889 forget about them. Because you, when, when we're talking 159 00:08:54,889 --> 00:08:57,339 about sound traveling, you don't really want to think 160 00:08:57,339 --> 00:08:59,559 about the particles knocking together. What you really want 161 00:08:59,559 --> 00:09:02,180 to think about is the data flowing through, just 162 00:09:02,180 --> 00:09:05,889 like it's a pipe. 163 00:09:05,889 --> 00:09:08,240 And this is good, because it, it, it decouples 164 00:09:08,240 --> 00:09:10,730 that data flow from your computation, so you can 165 00:09:10,730 --> 00:09:13,649 compose your different models together just by making them 166 00:09:13,649 --> 00:09:17,869 overlap at well-known points. So to, to, to show 167 00:09:17,869 --> 00:09:20,410 this in action, I've got a model here called 168 00:09:20,410 --> 00:09:23,480 the desaturator. And on the left, it takes a 169 00:09:23,480 --> 00:09:26,089 color and on the bottom, there's a, a, a 170 00:09:26,089 --> 00:09:30,149 value, a real number between zero and one, and 171 00:09:30,149 --> 00:09:33,279 then the color on the right is a desaturated 172 00:09:33,279 --> 00:09:36,230 version of the color on the left. 173 00:09:36,230 --> 00:09:40,649 So and, and that relationship is, it's, it's a, 174 00:09:40,649 --> 00:09:43,899 it's, it's, it's pure. The, the value of that 175 00:09:43,899 --> 00:09:46,839 color on the right, no matter what the color 176 00:09:46,839 --> 00:09:49,139 on the left, is always going to be a 177 00:09:49,139 --> 00:09:52,300 desaturated version of that color. So if we see 178 00:09:52,300 --> 00:09:54,869 this, we can now plug it into our swatch 179 00:09:54,869 --> 00:10:00,009 assembly, just using data binding. So, let's see that 180 00:10:00,009 --> 00:10:02,300 in action. 181 00:10:02,300 --> 00:10:05,180 Here's our desaturater. I've got the green turned on. 182 00:10:05,180 --> 00:10:07,949 And as we up the desaturation, you can see 183 00:10:07,949 --> 00:10:09,670 that it literally just sucks the color right out 184 00:10:09,670 --> 00:10:14,449 until, if you're fully desaturated, you're at gray. If 185 00:10:14,449 --> 00:10:17,980 you ever, never heard the term of desaturation before, 186 00:10:17,980 --> 00:10:20,179 that's, that's, that's what it is. 187 00:10:20,179 --> 00:10:24,610 And, of course, if I change it to a 188 00:10:24,610 --> 00:10:28,199 different color, in this case black, which is the 189 00:10:28,199 --> 00:10:30,670 absence of color, then they're, they're both black, because 190 00:10:30,670 --> 00:10:35,079 a desaturated nothing is still nothing. But if I 191 00:10:35,079 --> 00:10:39,600 shine the color through again, then the, the desaturation 192 00:10:39,600 --> 00:10:42,230 remains. 193 00:10:42,230 --> 00:10:43,360 And this is all well and good when it 194 00:10:43,360 --> 00:10:47,240 comes to binding colors to colors. But when you've 195 00:10:47,240 --> 00:10:50,040 got two separate data types, because remember, you know, 196 00:10:50,040 --> 00:10:52,040 bindings can only work on the same data type. 197 00:10:52,040 --> 00:10:54,800 When you've got two separate data types, what are 198 00:10:54,800 --> 00:10:58,149 you gonna do? Well, you just need another model. 199 00:10:58,149 --> 00:11:04,269 And in this case, what I've implemented here is 200 00:11:04,269 --> 00:11:06,249 what I call a color syntax. And it's a 201 00:11:06,249 --> 00:11:09,160 model that's got a color on one end and 202 00:11:09,160 --> 00:11:12,160 a string on the other. And I'm, you know, 203 00:11:12,160 --> 00:11:13,689 there's a little bit of hand-waving here, because this 204 00:11:13,689 --> 00:11:16,899 model is a little bit complex on the inside, 205 00:11:16,899 --> 00:11:20,970 but from a composability standpoint, it's very simple. It 206 00:11:20,970 --> 00:11:24,910 just relates a color and a string. 207 00:11:24,910 --> 00:11:27,179 And it goes both ways. So that if a 208 00:11:27,179 --> 00:11:30,110 color appears on the top, that implies a string 209 00:11:30,110 --> 00:11:32,910 value on the bottom. And if a new string 210 00:11:32,910 --> 00:11:36,009 value appears on the bottom, that implies a different 211 00:11:36,009 --> 00:11:38,470 color value on the top. And so I can 212 00:11:38,470 --> 00:11:41,170 plug this in to our assembly, and I'm gonna 213 00:11:41,170 --> 00:11:42,649 go ahead and plug it in twice, to kind 214 00:11:42,649 --> 00:11:45,089 of fast forward and show you a little bit 215 00:11:45,089 --> 00:11:48,240 more the power of data binding here. 216 00:11:48,240 --> 00:11:53,319 So we've got two text inputs which produce strings. 217 00:11:53,319 --> 00:11:56,610 But they're bound to our color syntaxes, but both 218 00:11:56,610 --> 00:11:59,139 color syntaxes are bound to the same color, which 219 00:11:59,139 --> 00:12:01,670 is that swatch on the right. 220 00:12:01,670 --> 00:12:03,279 So we can see this in, in action here. 221 00:12:03,279 --> 00:12:05,839 So I've got my two, two text fields, and 222 00:12:05,839 --> 00:12:07,579 I can change the color of one, where probably 223 00:12:07,579 --> 00:12:11,420 most, we're used to dealing with hex values, and 224 00:12:11,420 --> 00:12:13,629 you can see that the, the colors update. Both 225 00:12:13,629 --> 00:12:17,350 in the swatch, the, the desaturated value of the 226 00:12:17,350 --> 00:12:24,350 swatch. And also in the other text field. So 227 00:12:25,100 --> 00:12:26,209 I can set it to cyan and then I 228 00:12:26,209 --> 00:12:29,129 get a desaturated cyan. Cause all I'm really doing 229 00:12:29,129 --> 00:12:32,079 is changing that one color value. 230 00:12:32,079 --> 00:12:37,290 Incidentally, these, these text fields, there's nothing special about 231 00:12:37,290 --> 00:12:38,629 the format, because the way I implemented it is 232 00:12:38,629 --> 00:12:42,220 a, a color syntax, I actually can take this 233 00:12:42,220 --> 00:12:49,220 here and, and copy it up here, and it'll 234 00:12:49,230 --> 00:12:53,309 still update the color because the, the syntax is 235 00:12:53,309 --> 00:12:55,929 format agnostic. So it doesn't really matter. And I 236 00:12:55,929 --> 00:12:58,449 can also use a RGB constructor here to make 237 00:12:58,449 --> 00:13:02,759 this red again. 238 00:13:02,759 --> 00:13:08,189 So. And that's good. You know, we can, we 239 00:13:08,189 --> 00:13:09,619 can play around with the colors. We can enter 240 00:13:09,619 --> 00:13:13,709 in RGB values here, one at a time, and 241 00:13:13,709 --> 00:13:15,139 see the kind of the affect they have on 242 00:13:15,139 --> 00:13:18,350 the mixed color. But that doesn't give us real 243 00:13:18,350 --> 00:13:21,360 insight about the, the, the individual components. So what 244 00:13:21,360 --> 00:13:23,550 we can do is we can actually add another 245 00:13:23,550 --> 00:13:27,220 model to decompose this color into its RBG value. 246 00:13:27,220 --> 00:13:30,389 So we've got, again, we're relating over here on 247 00:13:30,389 --> 00:13:33,019 the left a color value, and over on the 248 00:13:33,019 --> 00:13:37,019 right, three different, three different coordinates, red, green, and 249 00:13:37,019 --> 00:13:40,529 blue. And we can see how those things relate 250 00:13:40,529 --> 00:13:45,399 to each other just by binding it into, binding 251 00:13:45,399 --> 00:13:47,989 it into our application. 252 00:13:47,989 --> 00:13:51,839 Now I've gotten rid of the, the desaturator and 253 00:13:51,839 --> 00:13:54,509 put this RGB selector in here. So let's see 254 00:13:54,509 --> 00:13:57,429 what this ends up looking like. You can see 255 00:13:57,429 --> 00:14:01,970 I've got these sliders bound to those RGB values, 256 00:14:01,970 --> 00:14:05,519 and I can do things like bring in red 257 00:14:05,519 --> 00:14:08,360 so that I've got, now, a pure yellow, and 258 00:14:08,360 --> 00:14:12,399 I can fade out the green until I've got 259 00:14:12,399 --> 00:14:16,600 my pure red. And so I can see how 260 00:14:16,600 --> 00:14:22,339 each individual color affects the, the final value. 261 00:14:22,339 --> 00:14:24,369 Which is, you know, this is, this is, this 262 00:14:24,369 --> 00:14:28,519 is pretty neat. We're starting to, to get something 263 00:14:28,519 --> 00:14:33,850 of a, of a more non-trivial application. But we 264 00:14:33,850 --> 00:14:38,470 still, we're still not seeing how the color is 265 00:14:38,470 --> 00:14:41,319 actually constructed by the computer. And to do that, 266 00:14:41,319 --> 00:14:43,949 we can use, we can, we can visualize not 267 00:14:43,949 --> 00:14:47,129 just the, the final output in that swatch, but 268 00:14:47,129 --> 00:14:51,999 we can actually visualize each value for red, green, 269 00:14:51,999 --> 00:14:54,319 and blue, and how that relates to the original 270 00:14:54,319 --> 00:14:55,929 color. 271 00:14:55,929 --> 00:15:00,759 So, what I did was I made an RGB 272 00:15:00,759 --> 00:15:04,369 visualization component, and bound it to the color, so 273 00:15:04,369 --> 00:15:07,449 that when the color updated, we visualize not the 274 00:15:07,449 --> 00:15:11,100 whole color, like the swatch, but the actual different 275 00:15:11,100 --> 00:15:14,309 red, green, and blue values. And that's what this 276 00:15:14,309 --> 00:15:16,899 looks like. You can see we've got, right here 277 00:15:16,899 --> 00:15:22,540 a pure green. But we can bring red in, 278 00:15:22,540 --> 00:15:25,350 slowly. And you can see how you get that, 279 00:15:25,350 --> 00:15:28,100 that yellow there, and then if we bring in 280 00:15:28,100 --> 00:15:31,499 blue, how it goes to white. But what we're 281 00:15:31,499 --> 00:15:35,889 seeing, now, is we're actually seeing how the color 282 00:15:35,889 --> 00:15:41,259 is added by the, the, the actual hardware. RGC 283 00:15:41,259 --> 00:15:43,850 is an additive model. We're taking a red value, 284 00:15:43,850 --> 00:15:45,660 a green value, and a blue value and we're 285 00:15:45,660 --> 00:15:47,309 adding them together so that the part where all 286 00:15:47,309 --> 00:15:51,869 the circles overlap, that's all three colors added together. 287 00:15:51,869 --> 00:15:54,389 And then where only two of the circles overlap, 288 00:15:54,389 --> 00:15:56,139 those are where the other two circles are, are 289 00:15:56,139 --> 00:15:58,689 together. So you can see that if I've got 290 00:15:58,689 --> 00:16:02,179 a pure yellow or I've got a pure cyan. 291 00:16:02,179 --> 00:16:06,699 Oops. If I've got a pure cyan, you know, 292 00:16:06,699 --> 00:16:09,600 I have no, I have no red component, and 293 00:16:09,600 --> 00:16:12,989 so the, the, the swatch or the part in 294 00:16:12,989 --> 00:16:15,079 the middle is the exact same as the overlap 295 00:16:15,079 --> 00:16:16,910 for green and blue. And so you can kind 296 00:16:16,910 --> 00:16:18,819 of play around with this and see how the 297 00:16:18,819 --> 00:16:22,339 individual colors mix and not be, not be distracted 298 00:16:22,339 --> 00:16:26,739 by the, the, the overall sum. 299 00:16:26,739 --> 00:16:29,600 And RGB is a great. RGB is great, if 300 00:16:29,600 --> 00:16:33,199 you happen to be a pixel. It can be 301 00:16:33,199 --> 00:16:36,209 difficult for us to understand RGB. The reason that 302 00:16:36,209 --> 00:16:38,739 we use RGB coordinates is because it's very easy 303 00:16:38,739 --> 00:16:40,839 for a monitor to take three values, add them 304 00:16:40,839 --> 00:16:42,899 together, and like, that's the frequency of light that 305 00:16:42,899 --> 00:16:45,389 I need to emit. But that's not how we, 306 00:16:45,389 --> 00:16:50,929 as humans, actually perceive it. And so there are, 307 00:16:50,929 --> 00:16:53,259 there are other coordinate systems that are more in 308 00:16:53,259 --> 00:16:56,459 tune with the way that we perceive color, which 309 00:16:56,459 --> 00:16:59,059 unfortunately we don't actually use. You know, RGB is 310 00:16:59,059 --> 00:17:02,850 kind of like the assembly language of, of color. 311 00:17:02,850 --> 00:17:06,429 It's what the machine understand. 312 00:17:06,429 --> 00:17:11,760 So, probably the most, the other most popular format, 313 00:17:11,760 --> 00:17:14,859 the most popular coordinate system for describing color is 314 00:17:14,859 --> 00:17:18,900 called HSL. And it, it stands for hue, saturation, 315 00:17:18,900 --> 00:17:22,230 and lightness. To read briefly what these, these mean 316 00:17:22,230 --> 00:17:23,638 or what they're defined as. 317 00:17:23,638 --> 00:17:26,059 So, hue is the degree to which a stimulus 318 00:17:26,059 --> 00:17:28,519 can be described as similar to or different from 319 00:17:28,519 --> 00:17:31,000 stimuli that are described as red, green, blue, and 320 00:17:31,000 --> 00:17:35,840 yellow. Saturation. The colorfulness of a color relative to 321 00:17:35,840 --> 00:17:41,090 its own brightness. Lightness. The subjective brightness, perception of 322 00:17:41,090 --> 00:17:44,870 a color for humans along a lightness/darkness axis. 323 00:17:44,870 --> 00:17:48,679 Now, if you're like me, that really, even though 324 00:17:48,679 --> 00:17:51,860 it's aimed at me, it's completely and totally incomprehensible. 325 00:17:51,860 --> 00:17:56,760 The, the, the vocabulary definitely is about humans and 326 00:17:56,760 --> 00:17:59,880 human perception, but it's still a black box. It's 327 00:17:59,880 --> 00:18:03,429 still completely opaque. But, what we can do is 328 00:18:03,429 --> 00:18:05,690 we can add another model, and we can decompose 329 00:18:05,690 --> 00:18:08,500 that to unpack those individual coordinates and see how 330 00:18:08,500 --> 00:18:13,529 they effect our, the, effect the different color values. 331 00:18:13,529 --> 00:18:15,409 So let's go ahead and plug that in. I've 332 00:18:15,409 --> 00:18:17,960 got an HSL selector, just like I had the 333 00:18:17,960 --> 00:18:20,240 RGB selector, and we can see the, the, the 334 00:18:20,240 --> 00:18:22,720 hue, saturation, and lightness coordinates over there on the 335 00:18:22,720 --> 00:18:26,169 left. So, right now we have a pure green. 336 00:18:26,169 --> 00:18:29,250 I can take it down to a pure red. 337 00:18:29,250 --> 00:18:31,590 We can move the h. We're gonna keep s 338 00:18:31,590 --> 00:18:33,130 and l, and you can see as I go 339 00:18:33,130 --> 00:18:34,919 to green, the red fades out til I've got 340 00:18:34,919 --> 00:18:36,820 a pure green, and then the blue fades in 341 00:18:36,820 --> 00:18:39,669 till we've got a pure cyan. Then the green 342 00:18:39,669 --> 00:18:43,039 fades out so that we've got a pure blue, 343 00:18:43,039 --> 00:18:46,169 and then red fades back in to purple, and 344 00:18:46,169 --> 00:18:48,389 then blue fades back out to red. 345 00:18:48,389 --> 00:18:51,110 I particularly, I love as I, as you watch 346 00:18:51,110 --> 00:18:55,490 the hue, seeing where the RGB sliders are going. 347 00:18:55,490 --> 00:18:57,440 So you can see that the hue is going 348 00:18:57,440 --> 00:19:01,010 around that color circle. It's going around the color 349 00:19:01,010 --> 00:19:05,820 circle. And then as you adjust the saturation, you 350 00:19:05,820 --> 00:19:09,789 can see, OK. The red's coming down and the 351 00:19:09,789 --> 00:19:11,760 green and the blue are coming up in unison, 352 00:19:11,760 --> 00:19:14,179 and when I fully have zero saturation, then we're 353 00:19:14,179 --> 00:19:20,360 at a gray. And if I bring the saturation 354 00:19:20,360 --> 00:19:22,019 up, the, the green and blue go down in 355 00:19:22,019 --> 00:19:25,120 unison, and we're back to that pure color, that 356 00:19:25,120 --> 00:19:26,429 pure hue. 357 00:19:26,429 --> 00:19:31,019 So I think that this gives a, a much 358 00:19:31,019 --> 00:19:36,860 better view on, on these different coordinates. Same thing 359 00:19:36,860 --> 00:19:39,059 with lightness. You can see as we go from 360 00:19:39,059 --> 00:19:41,240 point five to one, it's almost like we're just 361 00:19:41,240 --> 00:19:45,260 mixing in white unless you've got nothing but white, 362 00:19:45,260 --> 00:19:47,260 and as we decrease the lightness, you can see 363 00:19:47,260 --> 00:19:50,289 those, the green and the blue come down together. 364 00:19:50,289 --> 00:19:54,039 And then as we go from point five lightness 365 00:19:54,039 --> 00:19:58,480 to zero, we're just fading that hue to black. 366 00:19:58,480 --> 00:20:01,570 And so I think, even though the terminology that 367 00:20:01,570 --> 00:20:04,679 you might read on Wikipedia about what HSL is 368 00:20:04,679 --> 00:20:09,169 is very opaque, it actually becomes pretty clear about 369 00:20:09,169 --> 00:20:10,940 what it is when you, when you can play 370 00:20:10,940 --> 00:20:13,299 with the individual coordinates and see how it relates 371 00:20:13,299 --> 00:20:20,299 to both the color at large, the, the, and, 372 00:20:20,340 --> 00:20:22,350 and also the, the additive color model that the 373 00:20:22,350 --> 00:20:26,139 computer's using. 374 00:20:26,139 --> 00:20:27,759 And we can also, and we can, we can 375 00:20:27,759 --> 00:20:34,139 visualize the HSL by making another visualizer, just like 376 00:20:34,139 --> 00:20:35,880 we did with RGB. And we can bind it 377 00:20:35,880 --> 00:20:38,070 into our color model. I think we've got what, 378 00:20:38,070 --> 00:20:42,929 one, two, three, four, five different things. Six different 379 00:20:42,929 --> 00:20:45,169 things. Let's see. One, two, three, four, five, six, 380 00:20:45,169 --> 00:20:47,990 seven different things bound to this color. 381 00:20:47,990 --> 00:20:51,980 So, we've got quite a robot we're building here. 382 00:20:51,980 --> 00:20:54,190 And so this is, this is actually HSL space, 383 00:20:54,190 --> 00:20:56,460 and you might already be familiar with the color 384 00:20:56,460 --> 00:20:59,360 selectors that use HSL. You can see that as 385 00:20:59,360 --> 00:21:04,210 I adjust the hue here, I'm going around that 386 00:21:04,210 --> 00:21:09,450 color wheel. And those, you can see where the 387 00:21:09,450 --> 00:21:12,960 color wheel fits on those, along the points. And 388 00:21:12,960 --> 00:21:17,159 the color that's selected is, is right down there. 389 00:21:17,159 --> 00:21:21,330 This, so what we're seeing here is the hue 390 00:21:21,330 --> 00:21:23,309 goes around in a circle. It's an actually a 391 00:21:23,309 --> 00:21:27,049 radial component. So, which is why it's from, you 392 00:21:27,049 --> 00:21:32,889 know, zero to three-sixty. And then the saturation, or 393 00:21:32,889 --> 00:21:36,110 the intensity of the hue, is the radius of 394 00:21:36,110 --> 00:21:40,169 that circle. And then if we look at the 395 00:21:40,169 --> 00:21:46,320 lightness here, you can see that the lightness, we 396 00:21:46,320 --> 00:21:50,179 fade up to white at the top and then 397 00:21:50,179 --> 00:21:53,389 fade down to black. There, so as we adjust 398 00:21:53,389 --> 00:21:56,380 the, the lightness, we can go, we go up 399 00:21:56,380 --> 00:21:59,110 to white at the top and down to black 400 00:21:59,110 --> 00:22:02,630 at the bottom. 401 00:22:02,630 --> 00:22:06,200 So, that's, that's pretty neat. I think, I think 402 00:22:06,200 --> 00:22:12,529 there's a lot of power in that. By taking, 403 00:22:12,529 --> 00:22:14,700 you know, just, just, just by binding to a 404 00:22:14,700 --> 00:22:19,679 single value. But values, values are actually not just 405 00:22:19,679 --> 00:22:22,850 on the client. You can actually treat a server, 406 00:22:22,850 --> 00:22:25,370 for example, as a simple model. And so here, 407 00:22:25,370 --> 00:22:28,200 I'm, we're going to have a server component. And 408 00:22:28,200 --> 00:22:31,019 a server's a black box, but from the perspective 409 00:22:31,019 --> 00:22:32,889 of the rest of the client, it behaves just 410 00:22:32,889 --> 00:22:34,429 like any other model. 411 00:22:34,429 --> 00:22:38,159 If a color appears at that point, it's sent 412 00:22:38,159 --> 00:22:40,120 into the black box. It can be sent to 413 00:22:40,120 --> 00:22:43,710 the server, serialized, whatever. And by the same token, 414 00:22:43,710 --> 00:22:45,330 something can happen on the server and it can 415 00:22:45,330 --> 00:22:52,299 make a color value appear right there. 416 00:22:52,299 --> 00:22:55,509 So, we can use this concept to develop color 417 00:22:55,509 --> 00:22:57,940 book, which is the first social network for color 418 00:22:57,940 --> 00:23:00,179 values, which I'm about to show you. And we 419 00:23:00,179 --> 00:23:03,889 can do this just by plugging in our server 420 00:23:03,889 --> 00:23:05,610 into our robot. I was actually kind of running 421 00:23:05,610 --> 00:23:09,659 out of room, so same basic concept. It's a 422 00:23:09,659 --> 00:23:12,519 little bit of a snakey cable there. 423 00:23:12,519 --> 00:23:15,090 And so now we'll do an actual live demo 424 00:23:15,090 --> 00:23:19,690 in here. So I've got, I wrote a little 425 00:23:19,690 --> 00:23:26,549 Rails app that uses web sockets to implement those 426 00:23:26,549 --> 00:23:31,389 servers. Or implement that, the, the, the endpoints on 427 00:23:31,389 --> 00:23:36,710 the servers. So, we can now open up that 428 00:23:36,710 --> 00:23:43,710 example that you saw in two separate tabs. 429 00:23:46,149 --> 00:23:49,070 And then we can see them acting in unison 430 00:23:49,070 --> 00:23:54,029 here. And so what's actually happening here is I 431 00:23:54,029 --> 00:24:01,029 got two different client-side applications, but they're all bound 432 00:24:01,720 --> 00:24:08,720 together. 433 00:24:13,179 --> 00:24:20,179 So, one of the things I hope to demonstrate 434 00:24:27,110 --> 00:24:31,190 is that there is actual power in simplicity, with 435 00:24:31,190 --> 00:24:33,720 keeping your models simple and keeping them composable. I 436 00:24:33,720 --> 00:24:35,889 think that, you know, this is probably, in terms 437 00:24:35,889 --> 00:24:39,990 of API, this was probably the, the most complex 438 00:24:39,990 --> 00:24:42,100 model that we had in the system. It's got, 439 00:24:42,100 --> 00:24:44,090 you know, four points that you can, you can 440 00:24:44,090 --> 00:24:48,840 bind to. 441 00:24:48,840 --> 00:24:54,179 But because, you know, because we understand the relationship 442 00:24:54,179 --> 00:24:57,259 between them, we can use each one of these 443 00:24:57,259 --> 00:25:01,159 individual models, which are very, very simple, to link 444 00:25:01,159 --> 00:25:04,909 together in simple ways to make a very complex 445 00:25:04,909 --> 00:25:08,789 and, and interesting application. And so I shied away 446 00:25:08,789 --> 00:25:12,250 from, from actually defining a model, because like I 447 00:25:12,250 --> 00:25:14,429 said, I don't want to get into nomenclature wars. 448 00:25:14,429 --> 00:25:16,740 But I think it's fair to define a model 449 00:25:16,740 --> 00:25:20,750 as just a group of values with well understood 450 00:25:20,750 --> 00:25:25,409 relationships. Values with well understood relationships. 451 00:25:25,409 --> 00:25:28,009 And if we understand those relationships than we can 452 00:25:28,009 --> 00:25:32,769 compose them in very simple and easy ways. But 453 00:25:32,769 --> 00:25:36,919 it's actually understanding the relationships that's the hard part. 454 00:25:36,919 --> 00:25:39,909 The is where the, the bulk of the work 455 00:25:39,909 --> 00:25:43,350 is. 456 00:25:43,350 --> 00:25:45,429 And I think that, that Plato got that, you 457 00:25:45,429 --> 00:25:48,340 know, when he original made this allegory of the 458 00:25:48,340 --> 00:25:52,610 cave, one of his goals was to explain to 459 00:25:52,610 --> 00:25:58,029 people what exactly a philosopher does. What his job 460 00:25:58,029 --> 00:26:01,299 is. The philosopher's job is to look at those 461 00:26:01,299 --> 00:26:02,960 pictures, which is the only thing that we can 462 00:26:02,960 --> 00:26:07,629 conceive, and from it, infer and construct that model 463 00:26:07,629 --> 00:26:11,610 or form that's standing in front of the fire. 464 00:26:11,610 --> 00:26:14,330 And so when it comes to UI and, and 465 00:26:14,330 --> 00:26:19,590 software in general, the philosophy part falls to you. 466 00:26:19,590 --> 00:26:24,029 That's your job. It can be very satisfying and, 467 00:26:24,029 --> 00:26:26,330 and rewarding and I hope you have fun with 468 00:26:26,330 --> 00:26:27,970 it. 469 00:26:27,970 --> 00:26:28,610 Thank you.