WEBVTT 00:00:16.850 --> 00:00:18.090 CHARLES LOWELL: All right everybody. 00:00:18.090 --> 00:00:20.570 Thank you so much for coming. I'm really, 00:00:20.570 --> 00:00:24.250 I'm really honored. This morning we're gonna 00:00:24.250 --> 00:00:27.869 be talking about client-side UI. These are, 00:00:27.869 --> 00:00:30.130 this, your client that's, that's running inside 00:00:30.130 --> 00:00:33.040 the browser. Not in the server. And some of you 00:00:33.040 --> 00:00:36.110 might already be doing this a lot. Some of you 00:00:36.110 --> 00:00:39.780 maybe a little. But wherever you fall along that 00:00:39.780 --> 00:00:42.390 spectrum, you're going to be doing more of it, 00:00:42.390 --> 00:00:45.000 chances are, as time, as time goes on, and not 00:00:45.000 --> 00:00:47.610 less of it. And so I want, my goal here is to 00:00:47.610 --> 00:00:50.780 share with you some of the ways that I've come 00:00:50.780 --> 00:00:53.680 to think about clients, UIs, that can help you 00:00:53.680 --> 00:00:59.670 build user interfaces that reactive, that are 00:00:59.670 --> 00:01:02.670 educational and ultimately satisfying to your users. 00:01:02.670 --> 00:01:05.519 What I want to share with you is the power of m. 00:01:05.519 --> 00:01:11.450 My name is Charles. I'm cowboyd on GitHub and 00:01:11.450 --> 00:01:13.680 Twitter, and I work at the Front Side, where 00:01:13.680 --> 00:01:20.240 we've been doing UI for almost ten years, exclusively. 00:01:20.240 --> 00:01:22.619 And when I talk about m, of course I'm 00:01:22.619 --> 00:01:26.049 talking about m as in MVC. We're all familiar, 00:01:26.049 --> 00:01:30.450 we've probably heard about the MVC pattern, model-view-controller. It's 00:01:30.450 --> 00:01:35.930 what underpins all UIs. At least ostensibly. 00:01:35.930 --> 00:01:39.759 But it can actually be pretty notoriously difficult to 00:01:39.759 --> 00:01:45.140 pin down what, exactly, is MVC. It's a difficult 00:01:45.140 --> 00:01:48.539 question, and if you ask two people, you're likely 00:01:48.539 --> 00:01:54.659 to get a very different answer. And my, what 00:01:54.659 --> 00:01:59.119 I'm. I don't want to, to, to go in 00:01:59.119 --> 00:02:02.840 too much to try and define, give you one 00:02:02.840 --> 00:02:06.729 particular version of MVC. I think there are many. 00:02:06.729 --> 00:02:10.038 And, in fact, you find people asking the question, 00:02:10.038 --> 00:02:12.140 is Rails MVC? 00:02:12.140 --> 00:02:14.580 And some people are really, really stodgy about this. 00:02:14.580 --> 00:02:20.150 They're, Rails MVC - pshaw. I'm more relaxed about 00:02:20.150 --> 00:02:24.140 it. I say yes. Rails is MVC. It's server-side 00:02:24.140 --> 00:02:29.030 MVC. It's a flavor of, of MVC. But what 00:02:29.030 --> 00:02:31.980 I've come to realize is that MVC is, it's 00:02:31.980 --> 00:02:34.920 kind of like Kung-Fu. There's lots of different schools. 00:02:34.920 --> 00:02:37.610 There's lots of different ways to, to practition. Each 00:02:37.610 --> 00:02:40.840 with its own strengths, each with its own weaknesses, 00:02:40.840 --> 00:02:43.760 and, you know, which one you choose, you need 00:02:43.760 --> 00:02:48.000 to, is, is, needs to be appropriate for the 00:02:48.000 --> 00:02:50.050 context. 00:02:50.050 --> 00:02:53.750 But today we're gonna be talking about client-side UI, 00:02:53.750 --> 00:02:55.970 which is different than, different than the, than the 00:02:55.970 --> 00:03:00.670 server-side MVC, and one of the things that, that 00:03:00.670 --> 00:03:02.500 really sets it apart is, when you're working on 00:03:02.500 --> 00:03:04.760 the client, you constantly have to manage state. The 00:03:04.760 --> 00:03:06.870 client's always on. It's not like a Rails application 00:03:06.870 --> 00:03:09.480 where you're basically setting up the world and then 00:03:09.480 --> 00:03:12.420 throwing it away with every request. On the client, 00:03:12.420 --> 00:03:15.620 you're always on. And so you have values that 00:03:15.620 --> 00:03:17.120 relate to each other, and when one of those 00:03:17.120 --> 00:03:20.930 values changes, you have to update the, the, the 00:03:20.930 --> 00:03:25.450 other values to reflect that. 00:03:25.450 --> 00:03:32.450 So, when we're thinking about MVC, I've come to, 00:03:33.170 --> 00:03:35.010 to realize that really what you want to do 00:03:35.010 --> 00:03:38.650 is you want to focus on the model. When 00:03:38.650 --> 00:03:42.370 you first come to the, to the acronym, MVC, 00:03:42.370 --> 00:03:47.090 model-view-controller, you tend to, to give equal billing to 00:03:47.090 --> 00:03:50.560 the letters, because they're, they're, there's, no one is 00:03:50.560 --> 00:03:56.930 set apart from, in, in the acronym. But I've 00:03:56.930 --> 00:03:59.760 come to find that while the view and the 00:03:59.760 --> 00:04:03.790 controller are important, they orbit the model. 00:04:03.790 --> 00:04:07.760 So, I actually draw inspiration from, from this guy. 00:04:07.760 --> 00:04:09.760 This is Plato. He's one of the ancient software 00:04:09.760 --> 00:04:11.870 developers. You can actually tell. He's got a ChromeBook 00:04:11.870 --> 00:04:15.580 Pixel there in his, in his hand. 00:04:15.580 --> 00:04:19.389 And I think that he made an analogy, long 00:04:19.389 --> 00:04:22.680 time ago, that I think really, cleanly captures this 00:04:22.680 --> 00:04:26.530 concept. He had this allegory of a cave, and 00:04:26.530 --> 00:04:31.610 the idea is that living in this world is, 00:04:31.610 --> 00:04:35.760 is like being inside a cave, and back up 00:04:35.760 --> 00:04:38.430 at the entrance of the cave, where you can't 00:04:38.430 --> 00:04:42.820 see, there's this fire burning. And shapes pass in 00:04:42.820 --> 00:04:45.330 front of the fire, and they cast shadows on 00:04:45.330 --> 00:04:48.230 the wall. And we, inside the world, the only 00:04:48.230 --> 00:04:51.330 thing that we can actually see is the shadows. 00:04:51.330 --> 00:04:54.610 The shapes and the fire are hidden from us. 00:04:54.610 --> 00:04:56.410 But if we look at the, the, the shadows, 00:04:56.410 --> 00:04:59.460 we can extrapolate those shapes, and the shapes that 00:04:59.460 --> 00:05:02.480 we see on the wall take their form purely 00:05:02.480 --> 00:05:05.090 as a function of the shape in front of 00:05:05.090 --> 00:05:07.150 the fire. They are as they are and are 00:05:07.150 --> 00:05:12.060 no other way because, because of those true forms 00:05:12.060 --> 00:05:15.660 and then the way that they interact. 00:05:15.660 --> 00:05:18.560 And so this is all, this is all very, 00:05:18.560 --> 00:05:21.700 very abstract. We've covered, you know, who I am. 00:05:21.700 --> 00:05:26.360 We've covered the, the, an ancient philosopher, which I 00:05:26.360 --> 00:05:31.030 guess is obligatory. But, I really want to give 00:05:31.030 --> 00:05:34.030 a demonstration of this principle in action so that 00:05:34.030 --> 00:05:38.240 you can see a little bit more concretely what 00:05:38.240 --> 00:05:40.250 it is that I'm talking about. And so, to 00:05:40.250 --> 00:05:44.190 do this, we're going to explore the concept of 00:05:44.190 --> 00:05:47.580 a color. It's a, a, a very simple concept. 00:05:47.580 --> 00:05:50.230 It's something that most of us can perceive very 00:05:50.230 --> 00:05:52.700 easily. We, we, we know what it is, but 00:05:52.700 --> 00:05:57.300 can be surprisingly difficult to, to pin down. 00:05:57.300 --> 00:06:01.030 There's many, many, many different ways to represent it. 00:06:01.030 --> 00:06:03.650 But we're gonna have, we're gonna have a color, 00:06:03.650 --> 00:06:05.680 and this is gonna serve as the basic value 00:06:05.680 --> 00:06:06.990 in our system. You can think of it as 00:06:06.990 --> 00:06:09.530 like, an integer value or a string value, or, 00:06:09.530 --> 00:06:11.520 or something like that, and we're going to see 00:06:11.520 --> 00:06:14.620 how this when, when we have this color, what 00:06:14.620 --> 00:06:16.940 kind of, what kind of reflections we can make 00:06:16.940 --> 00:06:19.360 on that wall. 00:06:19.360 --> 00:06:22.550 So, the first example is we're just going to, 00:06:22.550 --> 00:06:23.919 we're just going to project this color onto a 00:06:23.919 --> 00:06:28.510 single div. We're going to list this color value 00:06:28.510 --> 00:06:30.210 on the right. We're going to be able to 00:06:30.210 --> 00:06:33.389 set a color, remove a color, set a color, 00:06:33.389 --> 00:06:37.110 and as we do that, the, the, the swatch, 00:06:37.110 --> 00:06:39.210 the color swatch will, will update itself. And I 00:06:39.210 --> 00:06:43.790 actually have a little demo here. And I've got 00:06:43.790 --> 00:06:45.740 it hard-coded, just statically, so that when I check 00:06:45.740 --> 00:06:49.620 this checkbox, the, the swatch will turn green. And 00:06:49.620 --> 00:06:51.740 I can uncheck it and check it. 00:06:51.740 --> 00:06:55.040 It's not, not too much. It's simple but it's 00:06:55.040 --> 00:06:58.490 surprisingly satisfying. When I was putting this talk together 00:06:58.490 --> 00:07:01.340 I actually would just sit there and click on, 00:07:01.340 --> 00:07:04.389 off. It's great. 00:07:04.389 --> 00:07:05.480 And you can do the same thing. We can 00:07:05.480 --> 00:07:09.110 actually connect one color to two swatches. So we've 00:07:09.110 --> 00:07:11.600 got, there's no reason we can't, can't duplicate that. 00:07:11.600 --> 00:07:14.669 We'll take two of these swatches and, and bind 00:07:14.669 --> 00:07:17.990 them to the, the, the same color. The, there's, 00:07:17.990 --> 00:07:20.020 there's, so there's only one color in the system, 00:07:20.020 --> 00:07:23.139 but the effect is the same. 00:07:23.139 --> 00:07:29.600 Again, I could do that forever. 00:07:29.600 --> 00:07:30.980 And this is what data binding is. You might 00:07:30.980 --> 00:07:35.120 hear about data binding, and most people kind of 00:07:35.120 --> 00:07:37.550 equate data binding with templates, because that's usually where 00:07:37.550 --> 00:07:39.160 we come to it first, right. We change this 00:07:39.160 --> 00:07:40.960 one value and the string value updates, right. But 00:07:40.960 --> 00:07:43.610 templates are really just a special case of data 00:07:43.610 --> 00:07:48.760 binding. In the abstract, it's really just about taking 00:07:48.760 --> 00:07:51.840 two values and putting, putting them together so that 00:07:51.840 --> 00:07:55.139 they occupy the same space in your application. There 00:07:55.139 --> 00:07:58.669 really is no difference, conceptually, between them. 00:07:58.669 --> 00:08:02.949 Some, this is, this is different than observation, which 00:08:02.949 --> 00:08:05.130 is kind of another pillar on which client-side UIs 00:08:05.130 --> 00:08:08.260 are built, where you can observe for value changes 00:08:08.260 --> 00:08:10.870 in a model, and when that value changes you 00:08:10.870 --> 00:08:17.410 get a callback. But. With data binding, you really 00:08:17.410 --> 00:08:20.080 need to think of it taking two separate properties 00:08:20.080 --> 00:08:22.870 and really just making them overlap and becoming the, 00:08:22.870 --> 00:08:24.729 the absolute, the, the same thing. 00:08:24.729 --> 00:08:27.570 Now, it is built on observation. So, when we 00:08:27.570 --> 00:08:29.610 have a model and it's got some property. I've 00:08:29.610 --> 00:08:31.280 got one named a and one named b. We 00:08:31.280 --> 00:08:36.899 can use observers to, to, to implement the data 00:08:36.899 --> 00:08:40.979 binding, so if a value appears at a, we 00:08:40.979 --> 00:08:43.809 observe that and we immediately copy it onto b. 00:08:43.809 --> 00:08:46.769 And if a value appears on b, then we 00:08:46.769 --> 00:08:50.680 immediately copy it over into a. But I'm showing 00:08:50.680 --> 00:08:52.300 this, the mechanics of it, so that you can 00:08:52.300 --> 00:08:54.889 forget about them. Because you, when, when we're talking 00:08:54.889 --> 00:08:57.339 about sound traveling, you don't really want to think 00:08:57.339 --> 00:08:59.559 about the particles knocking together. What you really want 00:08:59.559 --> 00:09:02.180 to think about is the data flowing through, just 00:09:02.180 --> 00:09:05.889 like it's a pipe. 00:09:05.889 --> 00:09:08.240 And this is good, because it, it, it decouples 00:09:08.240 --> 00:09:10.730 that data flow from your computation, so you can 00:09:10.730 --> 00:09:13.649 compose your different models together just by making them 00:09:13.649 --> 00:09:17.869 overlap at well-known points. So to, to, to show 00:09:17.869 --> 00:09:20.410 this in action, I've got a model here called 00:09:20.410 --> 00:09:23.480 the desaturator. And on the left, it takes a 00:09:23.480 --> 00:09:26.089 color and on the bottom, there's a, a, a 00:09:26.089 --> 00:09:30.149 value, a real number between zero and one, and 00:09:30.149 --> 00:09:33.279 then the color on the right is a desaturated 00:09:33.279 --> 00:09:36.230 version of the color on the left. 00:09:36.230 --> 00:09:40.649 So and, and that relationship is, it's, it's a, 00:09:40.649 --> 00:09:43.899 it's, it's, it's pure. The, the value of that 00:09:43.899 --> 00:09:46.839 color on the right, no matter what the color 00:09:46.839 --> 00:09:49.139 on the left, is always going to be a 00:09:49.139 --> 00:09:52.300 desaturated version of that color. So if we see 00:09:52.300 --> 00:09:54.869 this, we can now plug it into our swatch 00:09:54.869 --> 00:10:00.009 assembly, just using data binding. So, let's see that 00:10:00.009 --> 00:10:02.300 in action. 00:10:02.300 --> 00:10:05.180 Here's our desaturater. I've got the green turned on. 00:10:05.180 --> 00:10:07.949 And as we up the desaturation, you can see 00:10:07.949 --> 00:10:09.670 that it literally just sucks the color right out 00:10:09.670 --> 00:10:14.449 until, if you're fully desaturated, you're at gray. If 00:10:14.449 --> 00:10:17.980 you ever, never heard the term of desaturation before, 00:10:17.980 --> 00:10:20.179 that's, that's, that's what it is. 00:10:20.179 --> 00:10:24.610 And, of course, if I change it to a 00:10:24.610 --> 00:10:28.199 different color, in this case black, which is the 00:10:28.199 --> 00:10:30.670 absence of color, then they're, they're both black, because 00:10:30.670 --> 00:10:35.079 a desaturated nothing is still nothing. But if I 00:10:35.079 --> 00:10:39.600 shine the color through again, then the, the desaturation 00:10:39.600 --> 00:10:42.230 remains. 00:10:42.230 --> 00:10:43.360 And this is all well and good when it 00:10:43.360 --> 00:10:47.240 comes to binding colors to colors. But when you've 00:10:47.240 --> 00:10:50.040 got two separate data types, because remember, you know, 00:10:50.040 --> 00:10:52.040 bindings can only work on the same data type. 00:10:52.040 --> 00:10:54.800 When you've got two separate data types, what are 00:10:54.800 --> 00:10:58.149 you gonna do? Well, you just need another model. 00:10:58.149 --> 00:11:04.269 And in this case, what I've implemented here is 00:11:04.269 --> 00:11:06.249 what I call a color syntax. And it's a 00:11:06.249 --> 00:11:09.160 model that's got a color on one end and 00:11:09.160 --> 00:11:12.160 a string on the other. And I'm, you know, 00:11:12.160 --> 00:11:13.689 there's a little bit of hand-waving here, because this 00:11:13.689 --> 00:11:16.899 model is a little bit complex on the inside, 00:11:16.899 --> 00:11:20.970 but from a composability standpoint, it's very simple. It 00:11:20.970 --> 00:11:24.910 just relates a color and a string. 00:11:24.910 --> 00:11:27.179 And it goes both ways. So that if a 00:11:27.179 --> 00:11:30.110 color appears on the top, that implies a string 00:11:30.110 --> 00:11:32.910 value on the bottom. And if a new string 00:11:32.910 --> 00:11:36.009 value appears on the bottom, that implies a different 00:11:36.009 --> 00:11:38.470 color value on the top. And so I can 00:11:38.470 --> 00:11:41.170 plug this in to our assembly, and I'm gonna 00:11:41.170 --> 00:11:42.649 go ahead and plug it in twice, to kind 00:11:42.649 --> 00:11:45.089 of fast forward and show you a little bit 00:11:45.089 --> 00:11:48.240 more the power of data binding here. 00:11:48.240 --> 00:11:53.319 So we've got two text inputs which produce strings. 00:11:53.319 --> 00:11:56.610 But they're bound to our color syntaxes, but both 00:11:56.610 --> 00:11:59.139 color syntaxes are bound to the same color, which 00:11:59.139 --> 00:12:01.670 is that swatch on the right. 00:12:01.670 --> 00:12:03.279 So we can see this in, in action here. 00:12:03.279 --> 00:12:05.839 So I've got my two, two text fields, and 00:12:05.839 --> 00:12:07.579 I can change the color of one, where probably 00:12:07.579 --> 00:12:11.420 most, we're used to dealing with hex values, and 00:12:11.420 --> 00:12:13.629 you can see that the, the colors update. Both 00:12:13.629 --> 00:12:17.350 in the swatch, the, the desaturated value of the 00:12:17.350 --> 00:12:24.350 swatch. And also in the other text field. So 00:12:25.100 --> 00:12:26.209 I can set it to cyan and then I 00:12:26.209 --> 00:12:29.129 get a desaturated cyan. Cause all I'm really doing 00:12:29.129 --> 00:12:32.079 is changing that one color value. 00:12:32.079 --> 00:12:37.290 Incidentally, these, these text fields, there's nothing special about 00:12:37.290 --> 00:12:38.629 the format, because the way I implemented it is 00:12:38.629 --> 00:12:42.220 a, a color syntax, I actually can take this 00:12:42.220 --> 00:12:49.220 here and, and copy it up here, and it'll 00:12:49.230 --> 00:12:53.309 still update the color because the, the syntax is 00:12:53.309 --> 00:12:55.929 format agnostic. So it doesn't really matter. And I 00:12:55.929 --> 00:12:58.449 can also use a RGB constructor here to make 00:12:58.449 --> 00:13:02.759 this red again. 00:13:02.759 --> 00:13:08.189 So. And that's good. You know, we can, we 00:13:08.189 --> 00:13:09.619 can play around with the colors. We can enter 00:13:09.619 --> 00:13:13.709 in RGB values here, one at a time, and 00:13:13.709 --> 00:13:15.139 see the kind of the affect they have on 00:13:15.139 --> 00:13:18.350 the mixed color. But that doesn't give us real 00:13:18.350 --> 00:13:21.360 insight about the, the, the individual components. So what 00:13:21.360 --> 00:13:23.550 we can do is we can actually add another 00:13:23.550 --> 00:13:27.220 model to decompose this color into its RBG value. 00:13:27.220 --> 00:13:30.389 So we've got, again, we're relating over here on 00:13:30.389 --> 00:13:33.019 the left a color value, and over on the 00:13:33.019 --> 00:13:37.019 right, three different, three different coordinates, red, green, and 00:13:37.019 --> 00:13:40.529 blue. And we can see how those things relate 00:13:40.529 --> 00:13:45.399 to each other just by binding it into, binding 00:13:45.399 --> 00:13:47.989 it into our application. 00:13:47.989 --> 00:13:51.839 Now I've gotten rid of the, the desaturator and 00:13:51.839 --> 00:13:54.509 put this RGB selector in here. So let's see 00:13:54.509 --> 00:13:57.429 what this ends up looking like. You can see 00:13:57.429 --> 00:14:01.970 I've got these sliders bound to those RGB values, 00:14:01.970 --> 00:14:05.519 and I can do things like bring in red 00:14:05.519 --> 00:14:08.360 so that I've got, now, a pure yellow, and 00:14:08.360 --> 00:14:12.399 I can fade out the green until I've got 00:14:12.399 --> 00:14:16.600 my pure red. And so I can see how 00:14:16.600 --> 00:14:22.339 each individual color affects the, the final value. 00:14:22.339 --> 00:14:24.369 Which is, you know, this is, this is, this 00:14:24.369 --> 00:14:28.519 is pretty neat. We're starting to, to get something 00:14:28.519 --> 00:14:33.850 of a, of a more non-trivial application. But we 00:14:33.850 --> 00:14:38.470 still, we're still not seeing how the color is 00:14:38.470 --> 00:14:41.319 actually constructed by the computer. And to do that, 00:14:41.319 --> 00:14:43.949 we can use, we can, we can visualize not 00:14:43.949 --> 00:14:47.129 just the, the final output in that swatch, but 00:14:47.129 --> 00:14:51.999 we can actually visualize each value for red, green, 00:14:51.999 --> 00:14:54.319 and blue, and how that relates to the original 00:14:54.319 --> 00:14:55.929 color. 00:14:55.929 --> 00:15:00.759 So, what I did was I made an RGB 00:15:00.759 --> 00:15:04.369 visualization component, and bound it to the color, so 00:15:04.369 --> 00:15:07.449 that when the color updated, we visualize not the 00:15:07.449 --> 00:15:11.100 whole color, like the swatch, but the actual different 00:15:11.100 --> 00:15:14.309 red, green, and blue values. And that's what this 00:15:14.309 --> 00:15:16.899 looks like. You can see we've got, right here 00:15:16.899 --> 00:15:22.540 a pure green. But we can bring red in, 00:15:22.540 --> 00:15:25.350 slowly. And you can see how you get that, 00:15:25.350 --> 00:15:28.100 that yellow there, and then if we bring in 00:15:28.100 --> 00:15:31.499 blue, how it goes to white. But what we're 00:15:31.499 --> 00:15:35.889 seeing, now, is we're actually seeing how the color 00:15:35.889 --> 00:15:41.259 is added by the, the, the actual hardware. RGC 00:15:41.259 --> 00:15:43.850 is an additive model. We're taking a red value, 00:15:43.850 --> 00:15:45.660 a green value, and a blue value and we're 00:15:45.660 --> 00:15:47.309 adding them together so that the part where all 00:15:47.309 --> 00:15:51.869 the circles overlap, that's all three colors added together. 00:15:51.869 --> 00:15:54.389 And then where only two of the circles overlap, 00:15:54.389 --> 00:15:56.139 those are where the other two circles are, are 00:15:56.139 --> 00:15:58.689 together. So you can see that if I've got 00:15:58.689 --> 00:16:02.179 a pure yellow or I've got a pure cyan. 00:16:02.179 --> 00:16:06.699 Oops. If I've got a pure cyan, you know, 00:16:06.699 --> 00:16:09.600 I have no, I have no red component, and 00:16:09.600 --> 00:16:12.989 so the, the, the swatch or the part in 00:16:12.989 --> 00:16:15.079 the middle is the exact same as the overlap 00:16:15.079 --> 00:16:16.910 for green and blue. And so you can kind 00:16:16.910 --> 00:16:18.819 of play around with this and see how the 00:16:18.819 --> 00:16:22.339 individual colors mix and not be, not be distracted 00:16:22.339 --> 00:16:26.739 by the, the, the overall sum. 00:16:26.739 --> 00:16:29.600 And RGB is a great. RGB is great, if 00:16:29.600 --> 00:16:33.199 you happen to be a pixel. It can be 00:16:33.199 --> 00:16:36.209 difficult for us to understand RGB. The reason that 00:16:36.209 --> 00:16:38.739 we use RGB coordinates is because it's very easy 00:16:38.739 --> 00:16:40.839 for a monitor to take three values, add them 00:16:40.839 --> 00:16:42.899 together, and like, that's the frequency of light that 00:16:42.899 --> 00:16:45.389 I need to emit. But that's not how we, 00:16:45.389 --> 00:16:50.929 as humans, actually perceive it. And so there are, 00:16:50.929 --> 00:16:53.259 there are other coordinate systems that are more in 00:16:53.259 --> 00:16:56.459 tune with the way that we perceive color, which 00:16:56.459 --> 00:16:59.059 unfortunately we don't actually use. You know, RGB is 00:16:59.059 --> 00:17:02.850 kind of like the assembly language of, of color. 00:17:02.850 --> 00:17:06.429 It's what the machine understand. 00:17:06.429 --> 00:17:11.760 So, probably the most, the other most popular format, 00:17:11.760 --> 00:17:14.859 the most popular coordinate system for describing color is 00:17:14.859 --> 00:17:18.900 called HSL. And it, it stands for hue, saturation, 00:17:18.900 --> 00:17:22.230 and lightness. To read briefly what these, these mean 00:17:22.230 --> 00:17:23.638 or what they're defined as. 00:17:23.638 --> 00:17:26.059 So, hue is the degree to which a stimulus 00:17:26.059 --> 00:17:28.519 can be described as similar to or different from 00:17:28.519 --> 00:17:31.000 stimuli that are described as red, green, blue, and 00:17:31.000 --> 00:17:35.840 yellow. Saturation. The colorfulness of a color relative to 00:17:35.840 --> 00:17:41.090 its own brightness. Lightness. The subjective brightness, perception of 00:17:41.090 --> 00:17:44.870 a color for humans along a lightness/darkness axis. 00:17:44.870 --> 00:17:48.679 Now, if you're like me, that really, even though 00:17:48.679 --> 00:17:51.860 it's aimed at me, it's completely and totally incomprehensible. 00:17:51.860 --> 00:17:56.760 The, the, the vocabulary definitely is about humans and 00:17:56.760 --> 00:17:59.880 human perception, but it's still a black box. It's 00:17:59.880 --> 00:18:03.429 still completely opaque. But, what we can do is 00:18:03.429 --> 00:18:05.690 we can add another model, and we can decompose 00:18:05.690 --> 00:18:08.500 that to unpack those individual coordinates and see how 00:18:08.500 --> 00:18:13.529 they effect our, the, effect the different color values. 00:18:13.529 --> 00:18:15.409 So let's go ahead and plug that in. I've 00:18:15.409 --> 00:18:17.960 got an HSL selector, just like I had the 00:18:17.960 --> 00:18:20.240 RGB selector, and we can see the, the, the 00:18:20.240 --> 00:18:22.720 hue, saturation, and lightness coordinates over there on the 00:18:22.720 --> 00:18:26.169 left. So, right now we have a pure green. 00:18:26.169 --> 00:18:29.250 I can take it down to a pure red. 00:18:29.250 --> 00:18:31.590 We can move the h. We're gonna keep s 00:18:31.590 --> 00:18:33.130 and l, and you can see as I go 00:18:33.130 --> 00:18:34.919 to green, the red fades out til I've got 00:18:34.919 --> 00:18:36.820 a pure green, and then the blue fades in 00:18:36.820 --> 00:18:39.669 till we've got a pure cyan. Then the green 00:18:39.669 --> 00:18:43.039 fades out so that we've got a pure blue, 00:18:43.039 --> 00:18:46.169 and then red fades back in to purple, and 00:18:46.169 --> 00:18:48.389 then blue fades back out to red. 00:18:48.389 --> 00:18:51.110 I particularly, I love as I, as you watch 00:18:51.110 --> 00:18:55.490 the hue, seeing where the RGB sliders are going. 00:18:55.490 --> 00:18:57.440 So you can see that the hue is going 00:18:57.440 --> 00:19:01.010 around that color circle. It's going around the color 00:19:01.010 --> 00:19:05.820 circle. And then as you adjust the saturation, you 00:19:05.820 --> 00:19:09.789 can see, OK. The red's coming down and the 00:19:09.789 --> 00:19:11.760 green and the blue are coming up in unison, 00:19:11.760 --> 00:19:14.179 and when I fully have zero saturation, then we're 00:19:14.179 --> 00:19:20.360 at a gray. And if I bring the saturation 00:19:20.360 --> 00:19:22.019 up, the, the green and blue go down in 00:19:22.019 --> 00:19:25.120 unison, and we're back to that pure color, that 00:19:25.120 --> 00:19:26.429 pure hue. 00:19:26.429 --> 00:19:31.019 So I think that this gives a, a much 00:19:31.019 --> 00:19:36.860 better view on, on these different coordinates. Same thing 00:19:36.860 --> 00:19:39.059 with lightness. You can see as we go from 00:19:39.059 --> 00:19:41.240 point five to one, it's almost like we're just 00:19:41.240 --> 00:19:45.260 mixing in white unless you've got nothing but white, 00:19:45.260 --> 00:19:47.260 and as we decrease the lightness, you can see 00:19:47.260 --> 00:19:50.289 those, the green and the blue come down together. 00:19:50.289 --> 00:19:54.039 And then as we go from point five lightness 00:19:54.039 --> 00:19:58.480 to zero, we're just fading that hue to black. 00:19:58.480 --> 00:20:01.570 And so I think, even though the terminology that 00:20:01.570 --> 00:20:04.679 you might read on Wikipedia about what HSL is 00:20:04.679 --> 00:20:09.169 is very opaque, it actually becomes pretty clear about 00:20:09.169 --> 00:20:10.940 what it is when you, when you can play 00:20:10.940 --> 00:20:13.299 with the individual coordinates and see how it relates 00:20:13.299 --> 00:20:20.299 to both the color at large, the, the, and, 00:20:20.340 --> 00:20:22.350 and also the, the additive color model that the 00:20:22.350 --> 00:20:26.139 computer's using. 00:20:26.139 --> 00:20:27.759 And we can also, and we can, we can 00:20:27.759 --> 00:20:34.139 visualize the HSL by making another visualizer, just like 00:20:34.139 --> 00:20:35.880 we did with RGB. And we can bind it 00:20:35.880 --> 00:20:38.070 into our color model. I think we've got what, 00:20:38.070 --> 00:20:42.929 one, two, three, four, five different things. Six different 00:20:42.929 --> 00:20:45.169 things. Let's see. One, two, three, four, five, six, 00:20:45.169 --> 00:20:47.990 seven different things bound to this color. 00:20:47.990 --> 00:20:51.980 So, we've got quite a robot we're building here. 00:20:51.980 --> 00:20:54.190 And so this is, this is actually HSL space, 00:20:54.190 --> 00:20:56.460 and you might already be familiar with the color 00:20:56.460 --> 00:20:59.360 selectors that use HSL. You can see that as 00:20:59.360 --> 00:21:04.210 I adjust the hue here, I'm going around that 00:21:04.210 --> 00:21:09.450 color wheel. And those, you can see where the 00:21:09.450 --> 00:21:12.960 color wheel fits on those, along the points. And 00:21:12.960 --> 00:21:17.159 the color that's selected is, is right down there. 00:21:17.159 --> 00:21:21.330 This, so what we're seeing here is the hue 00:21:21.330 --> 00:21:23.309 goes around in a circle. It's an actually a 00:21:23.309 --> 00:21:27.049 radial component. So, which is why it's from, you 00:21:27.049 --> 00:21:32.889 know, zero to three-sixty. And then the saturation, or 00:21:32.889 --> 00:21:36.110 the intensity of the hue, is the radius of 00:21:36.110 --> 00:21:40.169 that circle. And then if we look at the 00:21:40.169 --> 00:21:46.320 lightness here, you can see that the lightness, we 00:21:46.320 --> 00:21:50.179 fade up to white at the top and then 00:21:50.179 --> 00:21:53.389 fade down to black. There, so as we adjust 00:21:53.389 --> 00:21:56.380 the, the lightness, we can go, we go up 00:21:56.380 --> 00:21:59.110 to white at the top and down to black 00:21:59.110 --> 00:22:02.630 at the bottom. 00:22:02.630 --> 00:22:06.200 So, that's, that's pretty neat. I think, I think 00:22:06.200 --> 00:22:12.529 there's a lot of power in that. By taking, 00:22:12.529 --> 00:22:14.700 you know, just, just, just by binding to a 00:22:14.700 --> 00:22:19.679 single value. But values, values are actually not just 00:22:19.679 --> 00:22:22.850 on the client. You can actually treat a server, 00:22:22.850 --> 00:22:25.370 for example, as a simple model. And so here, 00:22:25.370 --> 00:22:28.200 I'm, we're going to have a server component. And 00:22:28.200 --> 00:22:31.019 a server's a black box, but from the perspective 00:22:31.019 --> 00:22:32.889 of the rest of the client, it behaves just 00:22:32.889 --> 00:22:34.429 like any other model. 00:22:34.429 --> 00:22:38.159 If a color appears at that point, it's sent 00:22:38.159 --> 00:22:40.120 into the black box. It can be sent to 00:22:40.120 --> 00:22:43.710 the server, serialized, whatever. And by the same token, 00:22:43.710 --> 00:22:45.330 something can happen on the server and it can 00:22:45.330 --> 00:22:52.299 make a color value appear right there. 00:22:52.299 --> 00:22:55.509 So, we can use this concept to develop color 00:22:55.509 --> 00:22:57.940 book, which is the first social network for color 00:22:57.940 --> 00:23:00.179 values, which I'm about to show you. And we 00:23:00.179 --> 00:23:03.889 can do this just by plugging in our server 00:23:03.889 --> 00:23:05.610 into our robot. I was actually kind of running 00:23:05.610 --> 00:23:09.659 out of room, so same basic concept. It's a 00:23:09.659 --> 00:23:12.519 little bit of a snakey cable there. 00:23:12.519 --> 00:23:15.090 And so now we'll do an actual live demo 00:23:15.090 --> 00:23:19.690 in here. So I've got, I wrote a little 00:23:19.690 --> 00:23:26.549 Rails app that uses web sockets to implement those 00:23:26.549 --> 00:23:31.389 servers. Or implement that, the, the, the endpoints on 00:23:31.389 --> 00:23:36.710 the servers. So, we can now open up that 00:23:36.710 --> 00:23:43.710 example that you saw in two separate tabs. 00:23:46.149 --> 00:23:49.070 And then we can see them acting in unison 00:23:49.070 --> 00:23:54.029 here. And so what's actually happening here is I 00:23:54.029 --> 00:24:01.029 got two different client-side applications, but they're all bound 00:24:01.720 --> 00:24:08.720 together. 00:24:13.179 --> 00:24:20.179 So, one of the things I hope to demonstrate 00:24:27.110 --> 00:24:31.190 is that there is actual power in simplicity, with 00:24:31.190 --> 00:24:33.720 keeping your models simple and keeping them composable. I 00:24:33.720 --> 00:24:35.889 think that, you know, this is probably, in terms 00:24:35.889 --> 00:24:39.990 of API, this was probably the, the most complex 00:24:39.990 --> 00:24:42.100 model that we had in the system. It's got, 00:24:42.100 --> 00:24:44.090 you know, four points that you can, you can 00:24:44.090 --> 00:24:48.840 bind to. 00:24:48.840 --> 00:24:54.179 But because, you know, because we understand the relationship 00:24:54.179 --> 00:24:57.259 between them, we can use each one of these 00:24:57.259 --> 00:25:01.159 individual models, which are very, very simple, to link 00:25:01.159 --> 00:25:04.909 together in simple ways to make a very complex 00:25:04.909 --> 00:25:08.789 and, and interesting application. And so I shied away 00:25:08.789 --> 00:25:12.250 from, from actually defining a model, because like I 00:25:12.250 --> 00:25:14.429 said, I don't want to get into nomenclature wars. 00:25:14.429 --> 00:25:16.740 But I think it's fair to define a model 00:25:16.740 --> 00:25:20.750 as just a group of values with well understood 00:25:20.750 --> 00:25:25.409 relationships. Values with well understood relationships. 00:25:25.409 --> 00:25:28.009 And if we understand those relationships than we can 00:25:28.009 --> 00:25:32.769 compose them in very simple and easy ways. But 00:25:32.769 --> 00:25:36.919 it's actually understanding the relationships that's the hard part. 00:25:36.919 --> 00:25:39.909 The is where the, the bulk of the work 00:25:39.909 --> 00:25:43.350 is. 00:25:43.350 --> 00:25:45.429 And I think that, that Plato got that, you 00:25:45.429 --> 00:25:48.340 know, when he original made this allegory of the 00:25:48.340 --> 00:25:52.610 cave, one of his goals was to explain to 00:25:52.610 --> 00:25:58.029 people what exactly a philosopher does. What his job 00:25:58.029 --> 00:26:01.299 is. The philosopher's job is to look at those 00:26:01.299 --> 00:26:02.960 pictures, which is the only thing that we can 00:26:02.960 --> 00:26:07.629 conceive, and from it, infer and construct that model 00:26:07.629 --> 00:26:11.610 or form that's standing in front of the fire. 00:26:11.610 --> 00:26:14.330 And so when it comes to UI and, and 00:26:14.330 --> 00:26:19.590 software in general, the philosophy part falls to you. 00:26:19.590 --> 00:26:24.029 That's your job. It can be very satisfying and, 00:26:24.029 --> 00:26:26.330 and rewarding and I hope you have fun with 00:26:26.330 --> 00:26:27.970 it. 00:26:27.970 --> 00:26:28.610 Thank you.