Last active
October 16, 2019 18:23
-
-
Save kjintroverted/d67c7f12f68288f6ccf07cbd06fa66a8 to your computer and use it in GitHub Desktop.
A simple React component that creates a tiled background of recent posts from Instagram.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useEffect, useState } from 'react'; | |
import styled from 'styled-components'; | |
import PropTypes from 'prop-types'; | |
const IGBackground = ({ username, quality, filterOpts = [] }) => { | |
const [imageResources, setImages] = useState(null); | |
const [imageDims, setImageDims] = useState(0); | |
// CALCULATE HOW WIDE THE TILES SHOULD BE | |
function getImageDims() { | |
if (!imageResources || !imageResources.length) setImageDims(0); | |
else setImageDims( | |
Math.sqrt((window.innerHeight * window.innerWidth) / imageResources.length) | |
); | |
} | |
useEffect(() => { // LOADS POSTS WHEN USERNAME UPDATES | |
async function getMedia() { | |
if (!username) return; | |
const resp = await fetch(`https://www.instagram.com/${ username }/?__a=1`); | |
const { graphql } = await resp.json(); | |
setImages( | |
graphql.user | |
.edge_owner_to_timeline_media.edges | |
.map(({ node }) => node.thumbnail_resources) | |
) | |
} | |
getMedia(); | |
}, [username]); | |
// UPDATES TILE DIMENSIONS WHEN IG IMAGES LOAD | |
useEffect(getImageDims, [imageResources]); | |
// UPDATES TILE DIMENSIONS WHEN WINDOW RESIZES | |
window.addEventListener("resize", getImageDims) | |
// PARENT TILE FOR IMAGES | |
const Tile = styled.div` | |
width: ${imageDims }px; | |
height: ${imageDims }px; | |
flex-grow: 1; | |
` | |
// CREATES A FILTER OVER TOP | |
const Filter = styled.div` | |
position: fixed; | |
width: 100vw; | |
height: 100vh; | |
background-color: ${filterOpts }; /* USED IF ONE COLOR PASSED */ | |
background-image: linear-gradient(${filterOpts.join() }); /* USED IF GRADIENT OPTS PASSED */ | |
opacity: .7; | |
` | |
return ( | |
<Container> | |
{ imageResources && | |
imageResources.map(res => ( | |
<Tile key={ res[0].src }> | |
<Post src={ res[quality || 1].src } alt="recent post" /> | |
</Tile> | |
)) | |
} | |
<Filter /> | |
</Container> | |
) | |
} | |
export default IGBackground; | |
IGBackground.propTypes = { | |
username: PropTypes.string.isRequired, | |
quality: PropTypes.number, | |
filterOpts: PropTypes.arrayOf(PropTypes.string) | |
} | |
const Container = styled.div` | |
position: fixed; | |
width: 100vw; | |
height: 100vh; | |
display: flex; | |
flex-wrap: wrap; | |
` | |
const Post = styled.img` | |
height: 100%; | |
width: 100%; | |
object-fit: cover; | |
` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import styled from 'styled-components'; | |
import './App.css'; | |
import IGBackground from './components/IGBackground'; | |
import Splash from './components/Splash'; | |
function App() { | |
return ( | |
<Main> | |
<IGBackground | |
username="ferrytalecreative" | |
filterOpts={ ["to bottom right", "teal", "blue", "purple"] } | |
/> | |
<Fence> | |
<Splash /> | |
<Spacer /> | |
</Fence> | |
</Main> | |
); | |
} | |
export default App; | |
const Main = styled.div` | |
display: flex; | |
justify-content: center; | |
` | |
const Fence = styled.div` | |
position: fixed; | |
height: 100vh; | |
width: 100%; | |
max-width: 1000px; | |
display: flex; | |
align-items: center; | |
` | |
const Spacer = styled.div` | |
flex: 1; | |
` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The above options renders like this: