2.3 Colored Spotlight Mask
In this lesson, we’ll see how to load two overlaid images, create a mask that follows your mouse, and use that mask to create the effect of peeking through one image to see the other. We’ll also bring in an adjustment filter and learn how to use it to modify the colors of our images.
1.Introduction2 lessons, 07:53
2.Up and Running With PixiJS10 lessons, 1:57:28
3.Conclusion1 lesson, 03:18
2.3 Colored Spotlight Mask
Hey, welcome back to Up and Running with PixiJS. In the last lesson, we created this godray effect using one of the inbuilt filters in PixiJS' filter library. In this lesson, we're gonna be using filters again, and we're also going to be using masking. You're going to need an image for this lesson. And you can get it from this pack of space backgrounds. There's a link in the notes below this video. When you download it, you're gonna want this 06.jpg file. It's gonna be too big by default. So go ahead and downscale it to 1200 pixels wide by 800 pixels high. So what we're gonna do with this image is we're gonna add it into our application twice. We're gonna have a black and white version. We're gonna make it black and white by using the same adjustment filter that we used in the last lesson. And we're just gonna have a default colored version. And we're going to create a circle shape which we'll use as a mask that we'll have follow the mouse around. And the effect that we're going to generate is making it look like wherever your mouse goes you have a circle of color appearing overlayed on the default black and white state. So let's go ahead and put that together. So as we've been doing so far, we're just gonna save the file that we're working on as something new. And let's just call this masking. We are not gonna need the godray filter anymore. So we'll drop that and drop its settings. Take it out of our array of filters here. And instead of loading in the forest, we wanna load that space background. I've named my nebula.jpg, so I'm just gonna add that in. As I said, there's gonna be two versions of this image. One's gonna be black and white, and one is gonna be color. We're gonna load the black and white version in first and then the color version over the top. So we're gonna rename this variable so that it makes sense for what we're doing. This first instance of the image is gonna be the black and white one. So we're gonna change this variable to ImageBW for black and white. And just to make sure this isn't confusing, we are gonna be using the adjustment filter. We're gonna be using it to convert the image into black and white. So let's change this so it says bw filter, so we know that we're using this to make our image black and white. Now, instead of modifying the contrast of the image, we're gonna modify the saturation, and we're gonna change it all the way down to zero. So gonna take all the color out of the image. We also are not going to need animation anymore, so we're gonna delete this bit of code as well. So now let's load up the correct file. And that is perfect, a black and white version of our image. Now let's duplicate the code that we just created. Copy, paste. And I'm gonna change this variable so that instead of saying ImageBW, it says image color. For the colored version of our image, we are also gonna be using the adjustment filter on this later. So we're gonna leave that there but get rid of this saturation value. We don't need that. And this is for our colored image so we're gonna change this to colorFilter. So now when we look at our preview, now there's the colored version of our image. And what we wanna do is create a circle about this big, and set it up so the only portion of the colored image you can see is through that circular shape. And we are gonna do that by taking advantage of Pixi's inbuilt graphic API which lets you generate images in the fly. So what we're gonna do is create another variable that's gonna hold our masking shape. So we're gonna say let MaskShape = new Pixi graphics. That gets us into that graphics API. Now we're gonna use the method beginFill. This is where we can define the color that we're going to apply to the background of the shape that we are creating. And as with all masking, we use the color white to determine the area that you can see through the masks. So we are going to add in white here, 0xffffff. Now we need to chain in a method to decide what shape we're gonna use here, and we do that by using drawCircle. There are a few of these that you can use to create different types of shapes. We'll need to pass some parameters through that which we'll do in just a moment. But first we're gonna round up this chain by adding in endFill. So wherever you use beginFill, you also need to use endFill. Again, you'll find a link in the notes below this video to the documentation for the drawCircle method. And you'll see that there are three parameters that we need to pass through here. We need to set the x position of the center of the circle we're creating, as well as the y position. We also need to set up the radius, so the size of the circle. We are not gonna be using just a hard-edged circle. We wanna blur the edges of the circle so that it has a nice soft fade out on the masking area. And we're going to do that with the blur filter. But we need to take into consideration the size of our blur when we're determining what the radius and the center point of our circle needs to be. So we're gonna set up a couple more variables. We're gonna say let maskRadius =, and we're gonna set this to 250. And we're gonna say let mask blur =, and we're gonna set that to 64. Now we're gonna create our blur filter. We're gonna apply it in the same way that we applied filters up here, nearly the same way. We're gonna say maskShape filters, and we're just going to add the filter directly inside the array. So here we add in a variable. But this time we're only gonna be using this one filter, so we're just gonna add it straight in. We're gonna say New PixiFiltersBlurFilter(). And in here we're gonna take the blur variable that we just created and pass it as the parameter. So that's gonna give us a blur around the outside of our circle of 64 pixels. Now we can use these two numbers to create the correct numbers to pass through as our x, y, and radius values. So because the size of the blur is gonna add to the outside of our circle, we can tell where the x position should be by just adding together the mask radius and the mask blur. So the radius is always half the width of the circle. The blur is applied to both sides. So that will give us our halfway point across the width of the circle overall. So we're gonna just add in maskBlur plus maskRadius. And that will work for both the x and y values. And then we can just pass our mask radius value in here as the correct radius. Now, I mentioned earlier that before you can add anything onto the stage as an image in PixiJS, it needs to be converted into a sprite first. So even though we've set up our circle here and our mask shape, we have to go through a process to turn it into a sprite before we actually do anything with it. To do that we're gonna have to go through a couple more steps. First we're gonna need to generate a texture from our circle, then we can convert that texture into a sprite. Now, to create the texture, we're gonna use the method generate texture. And there's a link to the docs in the notes below this video. To use this method we're gonna need to pass it a display object that's gonna be the mask shape that we just created. We're going to need to set the scale mode. Select the pixel ratio, whether we wanna blow up the original object into a different size when we convert it into a texture. And then we're also gonna need to set a region. So for example, if we wanted to, we could just turn say a quarter of our circle into a texture, so that it looked like a little pie shape. In our case, we want the whole circle. So we're gonna need to generate a rectangle. That's the same height and width as our circle. So let's go ahead and do that part now. So we're gonna create the rectangle that we need to set the region, it'll basically be the boundaries of our mask. So we're gonna create another variable. We're gonna call it maskBounds. And we're gonna use Pixi to define a rectangle. So we're gonna say new PIXI.Rectangle(). And in the docs for Rectangle you can see that we need to set an x and y position. So we're gonna need to define where the top left corner needs to be and then we need to pass the width and the height. For our rectangle, the top and left corner can just be defined as zero and zero. And we know from before that this value gives us half of the width of our mask shape. So we're gonna take this in here, put it between brackets and then multiply it by two. And that will give us the correct full width for our boundary here. And we'll do that again for the height. Now, we're ready take our circle that we created and convert it into a texture. So we'll need another variable, the texture =. For this we're gonna need to dig into the renderer that's inside the app. So we're gonna go app renderer generate texture, using that method that we looked at in the docs a moment ago. And now we need to pass those values that we looked at, display object, scale mode, resolution, and region. We know our display object is a mask shape. Our scale mode can be PIXI.scale_modes. Cuz we need to draw from predefined values for this. And here we're gonna be using the scaling mode nearest. So if this texture needs to be resized, this just determines what method is used to basically reposition the pixels when the scaling process happens. We're gonna set our resolution to 1, so it's just a a one to one shape. And then for our region, we're gonna pass in our mask bounds rectangle. And now we have something that we can actually turn into a sprite or we can put onto the stage. We'll grab our texture variable. We're gonna make another new variable, this one will be called masker. And all we have to do to turn this into a sprite is just a new PIXI.sprite. And then pass our texture variable. Now we have a sprite, we can add it to the stage. So we're gonna say app.stage.addChild(). And here we're gonna add our masker. Actually sorry, I just spotted a typo, that should be graphics, plural, not singular. All right, so now we've added a masker to the stage. Let's take a look. All right, and there's our white circle with the blurred edge. Now we're gonna set that white circle to act as a mask on our colored image. This is quite straightforward to do. All we need to do is grab the variable that's holding our colored image. It has an inbuilt property, mask. And then we can just set our masker to be that mask. There we go. Now you can see that it's just showing the colored image through that mask only. Now, what we wanna do is make this shape follow our mouse around so that it kind of looks like you are shining a colored spotlight on the stage. To make that happen, the first thing we're gonna need to do is set the stage to be interactive, so that it is gonna receive information about our mouse movements around the stage. So we're gonna say app Stage interactive = true. Now we can start capturing mouse events. We're gonna say app stage on. We're gonna listen for the mousemove event. And when we hear that event, we're gonna run the function moveMask. Now, let's go ahead and make that function, function moveMask. We're gonna need to grab that mousemove event through the function, so that we can get information about where the mouse is. Now we can start updating the position of our mask shape. So we're gonna set its position on the x axis by getting the x position of the mouse from this event variable. So we're gonna say event data global x. Then we need to make sure that the mouse stays in the center of our shape. Then we're also gonna need to subtract the width of the masker divided by 2. So we would say masker.width / 2. And then we're just gonna copy this line and paste it and change these x values to y and change this width to height. Now let's take a look. All right, there we go. Now we can move our mouse around and it looks like we're shining a colored spotlight onto the stage. So you're able to see just that shape of the colored image and nothing else. Now if remember the PixiJS website that we looked at earlier in the course, you'll notice that this is the basis of the effect that you have in here, a unit here. So this great big blob is a mask. Rather than just showing an image, it's showing videos, which is something we're also gonna do a little bit later. But if you were to animate the masking shape and have it follow your mouse with a delay, then you'd be able to create these type of an effect. So what we've done here is the first of the foundational steps towards creating that type of an effect. Now the next lesson is gonna be quite a quick one. It's not gonna take very long, but it is gonna be a significant lesson because we're gonna look at how you can bring in your own image and use it as the mouse point when you're hovering over your PixiJS Canvas. And when you go to a whole bunch of trouble to make a really cool looking background, this gives you the ability to make sure that your mouse isn't sticking out like a sore thumb like the mouse that you can see on the screen now. So we're gonna look at how you can do that in the next lesson. I'll see you there.