Reputation: 5615
The source code is here: https://codesandbox.io/s/gatsby-starter-default-nvhl7
And the deployed site is here: https://csb-nvhl7-24q4bchuz.now.sh/
The effect I am trying to achieve is simple and straightforward.
First I used this query to load all the image files from the images
folder
const data = useStaticQuery(graphql`
query {
allFile(
filter: {
extension: { regex: "/(jpg)|(jpeg)|(png)/" }
sourceInstanceName: { eq: "images" }
}
) {
edges {
node {
childImageSharp {
fluid(maxWidth: 800, quality: 95) {
aspectRatio
src
srcSet
originalName
srcWebp
srcSetWebp
sizes
}
}
}
}
}
}
Then I have a gallery
component to display them by dividing these images into three groups, and we can use project1
, project2
and project3
to navigate between them.
const Gallery = ({ minWidth }) => {
let refs = {}
const allPics = Image().map(({ childImageSharp }, i) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
refs[i] = useRef(null)
childImageSharp.index = i
return childImageSharp
})
const firsload = allPics.slice(0, 5)
const secload = allPics.slice(5, 10)
const third = allPics.slice(10)
const [imgs, setImgs] = useState(firsload)
const thumbnails = imgs.map(img => img.fluid.srcSet.split(" ")[0])
return (
<>
<ProjectsContainer>
<Project
onClick={() => {
setImgs(firsload)
}}
>
Project 1.
</Project>
<Project
onClick={() => {
setImgs(secload)
}}
>
Project 2.
</Project>
<Project
onClick={() => {
setImgs(third)
}}
>
Project 3.
</Project>
</ProjectsContainer>
<Mansory gap={"0em"} minWidth={minWidth}>
{imgs.map((img, i) => {
return (
<PicContainer key={img.index}>
<Enlarger
src={thumbnails[i]}
enlargedSrc={img.fluid.src}
index={img.index}
orderIndex={i}
onLoad={() => {
refs[img.index].current.toggleOpacity(1) <-- use ref to keep track of every Enlarger
}}
ref={refs[img.index]}
/>
</PicContainer>
)
})}
</Mansory>
</>
)
}
For every Enlarger
that gets rendered by the Gallery
, they are a zoom image component
import Img from "react-image-enlarger"
class Enlarger extends React.Component {
state = { zoomed: false, opacity: 0 } <--- initially every image's opacity is 0, then it shows up by being toggled opacity 1
toggleOpacity = o => {
this.setState({ opacity: o })
}
render() {
const { index, orderIndex, src, enlargedSrc, onLoad } = this.props
return (
<div style={{ margin: "0.25rem" }} onLoad={onLoad}> <-- where we toggle the opacity when the element is onloaded
<Img
style={{
opacity: this.state.opacity,
transition: "opacity 0.5s cubic-bezier(0.25,0.46,0.45,0.94)",
transitionDelay: `${orderIndex * 0.07}s`,
}}
zoomed={this.state.zoomed}
src={src}
enlargedSrc={enlargedSrc}
onClick={() => {
this.setState({ zoomed: true })
}}
onRequestClose={() => {
this.setState({ zoomed: false })
}}
/>
</div>
)
}
}
And I have made it clear in the code snippet where I implemented the sequential fade-in animation by using ref
to control every Enlarger
's toggleOpacity
method.
This code works great on localhost, i.e. during development. You can try the codesandbox link above to see it. However the bug appears only when the page is deployed.. Click on the deployed version (https://csb-nvhl7-24q4bchuz.now.sh/) you can see that when browser first loading the page, some pictures are missing, because their opacity are still 0, which I suspect is because refs[img.index].current.toggleOpacity(1)
somehow didn't get called on the image when they are onloaded. However the weird thing is, when you navigate between the projects, there's no problems at all with this animation and opacity change, they are normal. And when you refresh the page, the problem shows up again.
I been struggling with this problem for days and couldn't figure out why. Also although here I used ZEIT Now to deploy the site, the problem didn't go away when I used Netlify to deploy.
Upvotes: 4
Views: 882
Reputation: 106
In addition to Kishore's answer, you may want make your query after the page loaded (maybe in componentDidMount) and use setState to trigger react to re-render once that content has been fully loaded.
Upvotes: 0
Reputation: 476
Its not because of deployment, in Production Your images taking more time to load. See the image network call in the browser
Upvotes: 2