0

So, I'm trying to make a gallery like this with Flickity and React, but I get some strange flickering and the animation won't start until I try to resize the (output) window, and then everything plays nicely. On Firefox, sometimes it works, sometimes it doesn't, while Chrome is refusing to cooperate completely. Maybe, it's worth mentioning that I made this work with plain Javascript and Flickity, so I guess I'm doing something wrong in React. Here's the code:

HTML:

<div id="main"></div>

ReactJS

var Gallery = React.createClass({
    componentDidMount: function() {
        this.flkty = new Flickity('.gallery', {
            freeScroll: true,
            wrapAround: true,
            prevNextButtons: false,
            pageDots: false,
            freeScrollFriction: 0.00,
            lazyLoad: 2
        });
        this.flkty.velocity = 1;
        this.flkty.isFreeScrolling = true;
        this.flkty.startAnimation();
    },
    render: function() {
    return (
        <div className="gallery">
            <div key="01" className="gallery-cell">
                <img src="http://placehold.it/450x1500" />
            </div>
            <div key="02" className="gallery-cell">
                <img src="http://placehold.it/850x1200" />
            </div>
            <div key="03" className="gallery-cell">
                <img src="http://placehold.it/150x1500" />
            </div>
            <div key="04" className="gallery-cell">
                <img src="http://placehold.it/1850x1500" />
            </div>
            <div key="05" className="gallery-cell">
                <img src="http://placehold.it/650x1000" />
            </div>
            <div key="06" className="gallery-cell">
                <img src="http://placehold.it/350x2500" />
            </div>
        </div>
    )}
});

ReactDOM.render(
    <Gallery />, 
    document.getElementById('main')
);

SCSS:

html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
    background: #833;
}

div#main {
    margin: 0 auto;
    width: 750px;
    height: auto !important;
    height: 100%;
    min-height: 100%;
}

.gallery {
    background: #EEE;
    overflow: hidden;
}

.gallery-cell {
    display: inline-block;
    height: 100vh;
    img {
        border-left: 2px solid #444;
        height: 100%;
    }
}
El Gato Loco
  • 33
  • 1
  • 9

3 Answers3

0

I'm not sure if it will solve your answer but you could try something similar to another answer of mine Using MetricsGraphics.js with ReactJS by using refs. But honestly I'm worried it is something related to the Flickity library you are using rather than React.

Community
  • 1
  • 1
anvk
  • 1,183
  • 8
  • 10
0

Looks like a race condition to me. I know it's not the prettiest solution but try this:

  componentDidMount: function() {
    var self = this;

    setTimeout(function(){
      self.flkty = new Flickity('.gallery', {
        freeScroll: true,
        wrapAround: true,
        prevNextButtons: false,
        pageDots: false,
        freeScrollFriction: 0.00,
        lazyLoad: true
      });
      self.flkty.velocity = 1;
      self.flkty.isFreeScrolling = true;
      self.flkty.startAnimation();
     }, 500);
},

In Reacts componentDidMount documentation:

If you want to integrate with other JavaScript frameworks, set timers using setTimeout or setInterval, or send AJAX requests, perform those operations in this method.

Now that you know it's a race condition, see if there an event you can wait to fire the carousel on so you don't rely on a setTimeout.

im_benton
  • 2,541
  • 4
  • 21
  • 30
  • Thank you for pointing me in the right direction. I needed to require _flickity-imagesloaded_ (which is for some reason a separate library in npm, even though flickity's production bundle includes it) and set the _imagesLoaded_ flag to true. – El Gato Loco Jul 19 '16 at 18:17
0

As per docs, "Unloaded images have no size, which can throw off cell positions. To fix this, the imagesLoaded option re-positions cells once their images have loaded."

However, "As a stand-alone package, Flickity does not include imagesLoaded, asNavFor, and bgLazyLoad code. You can require these packages separately."

So, in order to solve the problem I had to do the following:

STEP 1: npm install flickity-imagesloaded --save

STEP 2: require('flickity-imagesloaded');

STEP 3: add imagesLoaded flag to the Flickity constructor.

componentDidMount: function() {
    this.flkty = new Flickity('.gallery', {
        freeScroll: true,
        wrapAround: true,
        prevNextButtons: false,
        pageDots: false,
        freeScrollFriction: 0.00,
        lazyLoad: 2,
        imagesLoaded: true
    });
El Gato Loco
  • 33
  • 1
  • 9