Get your first dev job by building these projects! #3: Instagram Feed with a Flashlight Effect
Tags: career, webdev, beginners, css
Published: 2020-07-02 21:54:26

[Youtube](https://www.youtube.com/channel/UC7khnAAAID1WQ_4gQO73Gmw) | [Twitter](https://www.twitter.com/catmcgeecode) | [Instagram](https://www.instagram.com/catmcgeecode)

Hello geeks! Today we're going to be building something super awesome. I'm so excited about this. It's an Instagram feed of any person you want (as long as their profile as public, more about that later) with a flashlight effect on top of it. Our mouse will dictate where the flashlight is. So it'll be like you're stalking them. Which is what Instagram is for anyway! It's perfect!

![Image](https://dev-to-uploads.s3.amazonaws.com/i/qnfdatq9iqgppua4kutj.png)

We'll be building this in HTML, CSS, and plain ol' Javascript. 

[Find the code here.](https://github.com/catmcgee/220-tutorails-flashlight-instagram-feed)

[Watch the 2 minute 20 second tutorial here.](https://www.youtube.com/watch?v=LqHB2jZsgh0&t=6s)

##Step 1: Make your HTML, CSS, and Javascript files 

Create your HTML file, your CSS file, and your Javascript file. Make sure to attach the CSS and the Javascript to the HTML! (I give this reminder in every tutorial because I always forget to do this.)

Your HTML should look a little like this. 

```html
<html>
    <head>
        <title>Instagram photos under a flashlight</title>
        <script type="text/javascript" src="actions.js"></script>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
    </body>
</html>
```

##Step 2: Request the photos from Instagram

The public Instagram API is incredibly easy to use, and you can get photos from any page at all!! This includes profile pages and tags. Because the API is public, we don't need to create a developer account, but it also means that we have no authentication and can't access private accounts. We only need to add `?__a=1` at the end of the URL. I'll be using my Instagram profile link in this tutorial, but feel free to use any!

```html
https://www.instagram.com/catmcgeecode/?__a=1
```

We're going to use async functions for this so that our code works asynchronously. Async functions allow the use of `await` which does exactly what it says on the tin - we'll wait for the promise to be fulfilled or rejected (i.e. we either get a valid response from Instagram or we're told we're not allowed) before we go onto the next task. Learn more about async functions [here.](https://javascript.info/async-await)

So let's use Javascript's [`fetch` API]([https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)), the easiest and best way to request data. 

Go ahead and put this fetch statement in an async function.

```jsx
async function getInstaPictures() {
    const response = await fetch("https://www.instagram.com/catmcgeecode/?__a=1");
}
```

We get a lot of data from this response, so we're going to want to read it as JSON. This will make it far easier to parse through and find the photos. 

```jsx
const jsonData = await response.json();
```

Let's `console.log` (or [`console.table()`](https://dev.to/catmcgeecode/javascript-5-cool-things-you-can-do-with-console-that-isn-t-console-log-45e3)) the response and run it so we can see what we're expecting and know where to find the photos in the response. And don't forget to call the function!

```jsx
async function getInstaPictures() {
    const response = await fetch("https://www.instagram.com/catmcgeecode/?__a=1");
		const jsonData = await response.json();
		console.log(jsonData)
}
getInstaPictures()
```

Now open the HTML file in your browser and have a look at the console (click Inspect to open developer tools, then click Console). You'll be able to see the response. It might look like nonsense, but spend some time looking through it and see what you can find.

If you look hard enough, you'll find that the image URLs can be found by navigating through like this:

`jsonData → graphql → user → edge_owner_to_timeline_media → edges`

Then, inside `edges` there are multiple `node`s and each `node` contains one `display_url` which is what we need.

So we need to iterate through each `node` inside `edges` and grab the display URL.

```jsx
const pictures = jsonData.graphql.user.edge_owner_to_timeline_media.edges; 
        for(i = 0; i < pictures.length ; i++) {
				// here we will show the images on the website
}
```

Still with me? (Because if so, you've come a long way.)

##Step 3: Display the pictures on the website

Each time we iterate through the data, we want to display the display URL as the source of an image in our HTML. 

So we're going to use the Javascript to create an image element (`document.createElement('img')`), then get `node.display_url` for each iteration and set it as the source of our new image element, and then add the image element to the HTML.

```jsx
for(i = 0; i < pictures.length ; i++) {
        let img = document.createElement('img');
        img.src = pictures[i].node.display_url;
        document.body.appendChild(img);
    }
```

That wasn't so hard was it?

Put all this together, open it up in a browser, and there you have it - all the photos from someone's Instagram page! If it's still not working for you, [here's the source code for the Javascript.]([https://github.com/catmcgee/220-tutorails-flashlight-instagram-feed/blob/master/actions.js](https://github.com/catmcgee/220-tutorails-flashlight-instagram-feed/blob/master/actions.js))

Change the styling a little bit so that they look good. In the video, I just changed the width to 350px as shown below, but you can play around with some flex-box styling to make it look real good.

```css
body img {
    width: 350px;
}
```

##Step 4: Make the flashlight effect

In this step, we're going to make it look like there is a flashlight over the Instagram photos, but we're not going to make it move just yet. We're going to make everything black except one transparent circle. So let's head to our CSS!

To make everything black, we are going to make the root element (HTML) black. We're going to use a pseudo-element ([learn more here](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements)) inside `root` and make this element cover the entire screen. The [content attribute along with `::before`](https://developer.mozilla.org/en-US/docs/Web/CSS/::before) helps us achieve this.

```css
:root:before {
    cursor: none;
    content: '';
    width: 100%;
    height: 100%;
    position: fixed;
}
```

We've also set the cursor here as `none` for added effect.

Run your code. Nothing has happened.

The magic happens in this next part - `radial-gradient`. (PS: Me trying to say this in an Irish accent is really funny.)

Radial gradient allows us to create a shape that has a gradient, progressing out from its origin. This shape can be a circle! It's pretty cool. So the idea here is that our background will be a radial gradient, with the primary colour being black, and our shape (a circle) will be transparent. The gradient will give it a kind of blurred appearance, which is perfect for a flashlight!

Add this to your :root:before:

```css
background: radial-gradient(
        circle 10vmax at var(--cursorX) var(--cursorY), 
        rgba(0,0,0,0),
        rgba(0,0,0,1)
    )
```

Phew. Let's go through this.

`circle` - we set the shape as a circle. Pretty self explanatory.

`10vmax` - vmax is all about relatively. 1vmax = 1% of the screen. So our flashlight will be the size of about 10% of the screen.

`at var(--cursorX) var(--cursorY)` - this is where things get groovy. This sets the x and y coordinates for where our circle is, but because it isn't the same (our flashlight moves with our mouse), we want to pass variables into it. We get these variables from Javascript later. 

first `rgba(0,0,0,0`) - this is transparent (the final 0 is opacity) and is the colour of the inside of our image.

second `rgba(0,0,0,1)` - this is black, and it is the colour that our circle gradient will progress into (as in - the rest of the background!)

Cool. If you run this code, you'll just see completely black. Can you take a guess as to why? It's because we don't have our `--cursorX` and `--cursorY` variables set yet. Let's just set these in the CSS so that we can make sure it's working before we move onto Javascript.

Your CSS should look like this:

```css
:root:before {
    --cursorX = 50vw;
    --cursorY = 50vh;
    cursor: none;
    content: '';
    width: 100%;
    height: 100%;
    position: fixed;
    background: radial-gradient( 
        circle 10vmax at var(--cursorX) var(--cursorY),
        rgba(0,0,0,0),
        rgba(0,0,0,1)
    ) 
}
```

##Step 5: Make the flashlight move

Now it's time to set our `--cursorX` and `--cursorY` variables to be in the position of our mouse every time we move our mouse. This is SUPER easy with Javascript. 

Open your Javascript file and create a function that will run when you move your mouse.

```jsx
document.addEventListener('mousemove', update)

function update(e) {
}
```

Here, `e` stands for event which has lots of different handlers, including the position of our mouse coordinates! 

Firstly, this function needs to read the X and Y coordinates of your mouse. This is super simple - you can just use e.`clientX` and e.`clientY`.

```jsx
let x = e.clientX; 
let y = e.clientY; 
```

Then we need to send these to the CSS, by setting them as properties on the styling.

```jsx
document.documentElement.style.setProperty('--cursorX', x + 'px'); 
document.documentElement.style.setProperty('--cursorY', y + 'px');
```

(It's the document element, because that's the root element, which in our case is the html element. I wish they had the same name too.)

All together now!

```jsx
document.addEventListener('mousemove', update)

function update(e) {
    let x = e.clientX; 
    let y = e.clientY; 

    document.documentElement.style.setProperty('--cursorX', x + 'px'); 
    document.documentElement.style.setProperty('--cursorY', y + 'px');
}
```

That's it. Open it up in your browser and you've got yourself a fun new way to stalk someone on Instagram.

##Now it's your turn!

I emphasize this on every one of these tutorials. To really make the most out of this, you've got to build something on top of it (and keep searching the internet to find out how!) I'm sure you have some creative ideas, but just in case you don't, here are some:

- Make it work better on mobile (maybe do something cool with phone gestures...)
- Change the size of the circle and the background colour
- Get different data from instagram
- Use the real instagram API and authenticate (you can use the Explore page or private accounts that you follow)
- Let the user choose the Instagram account first

Good luck! Happy coding, and make sure to comment or [DM me on Twitter](https://twitter.com/catmcgeecode) when you make something cool!