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