Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preload images? #586

Open
dylancristy opened this issue Jul 27, 2018 · 6 comments
Open

Preload images? #586

dylancristy opened this issue Jul 27, 2018 · 6 comments

Comments

@dylancristy
Copy link

I'm trying to create a Marvel-movie-intro-like effect by starting the timeline at the end, and then successively calling goToPrev() with a short delay between calls, to quickly flip backwards through all the slides.

That all works, but I don't see the images, I only see the grey "loading" square.

I tried to preload the images into the browser cache by using the technique here:

https://stackoverflow.com/a/901699/988264

whereby you just create a bunch of Image() objects and set their src property. That seems to work fine, if I look at my browser tools network tab while the page is loading, it looks like all the images load before the first call to goToPrev(), but I still am seeing the grey "loading" square.

Is there some way to preload the images into whatever cache TimelineJS is using?

@fastfasterfastest
Copy link

It appears there is an intentional delay showing the image to show that "loading" animation. I don't know if there is an official way to avoid that, but here is an unofficial way that accomplishes what I think you are after - it accesses undocumented stuff so it may break when a new version is released.

Instead of pre-loading the images the way you are doing now, do:
$.each(timeline._storyslider._slides, function(i, s){ s.loadMedia(); s.scrollToTop(); });

@dylancristy
Copy link
Author

That does seem to do the trick for everything except the last slide (which is the first shown since I am trying to start at the end and flip backwards), which is still subject to the 1200ms delay in the Media class' loadMedia function.

However I find that I'm also hemmed in by the slide transition animation duration. It seems as if I call timeline.goToPrev() any faster than every 750ms, the slide does not fully come into view, so you can't really see the image, before it moves on to the next.

And if I preload the images and call goToStart(), you see a few of the images, but for the most part it all flashes by too quickly.

@fastfasterfastest thanks for the suggestion! That definitely solves part of the problem. I will keep poking around to see if I can make it work somehow.

@fastfasterfastest
Copy link

For the last slide (the first one you show) you could delay showing it (i.e. navigating to it) until after its media has been loaded - it would still be a delay but not at that slide. You could e.g. display something else instead of the timeline in the meantime.

For the slide transition animation, doesn't options.duration and options.ease come into play?

@dylancristy
Copy link
Author

Yeah, I'll have to figure out my own "Loading..." animation for the beginning. But yes, you're right, options.duration and options.ease do come into play. I found easeInStrong and duration 100, with the first delay to goToPrev() of 250ms, and each subsequent delay being 0.95 times the previous delay gave a nice effect of quickly flipping through the slides, with the flipping accelerating slightly as it progressed.

Then when I reach the title slide, I reset everything by resetting the default values in timeline._storyslider.options.duration and timeline._storyslider.options.ease.

Very cool. Thanks very much, @fastfasterfastest !

@fastfasterfastest
Copy link

👍
If you can, post the url when/if it is public - may give others ideas of what can be done. And may give the maintainers hints about what users want/need exposed in the public API.

@dylancristy
Copy link
Author

If it is ever going to be public, it won't be until next year. It's for a touchscreen kiosk that's going in a visitor's center, and they may eventually add it to their public web site. But, since it's not going to be public for a while, I can post the code here. Keep in mind I only have 21 slides (including the title slide), so if you have more or less, you may need to play with some of the timing numbers.

Also, this is in a React component, so I'm using ES6 style code. And I'm not including any code to handle showing a custom loading screen to hide the loading of the last slide (as discussed in the posts above), this is just to get the flipping back through time effect:

    componentDidMount() {
        const opts = {
            'initial_zoom': 3,
            'start_at_end': true,
            'duration': 100,
            'ease': TL.Ease.easeInStrong
        };
        this.timeline = new TL.Timeline('timeline-root', data, opts);

        // pre-load images
        this.timeline._storyslider._slides.forEach(slide => {
            slide.loadMedia();
            slide.scrollToTop();
        });

        // even though we just forced all the images to load, there is still
        // a hardcoded delay of 1200ms during the loading process so we 
        // have to wait for that before we are ready to start the effect
        this.reverseOneSlide(1200, true);
    }

    reverseOneSlide = (delay, isFirst) => {
        setTimeout(() => {
            this.timeline.goToPrev();

            // the first time through we want the delay to
            // jump from the initial 1200ms to 250ms
            let newDelay = 250;

            // if it's not the first time through, we want the new delay to be
            // 95% of the last delay, but we don't want to get any faster
            // than what we set the animation duration to be
            if (!isFirst) {
                newDelay = Math.max(100, delay * 0.95);
            }

            // if we are not yet at the title slide, go back one more with the new delay value,
            // otherwise reset the animation duration and easing back to the default values
            if (this.timeline.current_id !== 'name-of-my-title-slide') {
                this.reverseOneSlide(newDelay, false);
            } else {
                this.timeline._storyslider.options.duration = 1000;
                this.timeline._storyslider.options.ease = TL.Ease.easeInOutQuint;
            }
        }, delay);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants