Code Monkey home page Code Monkey logo

scrolltrigger's Introduction

ScrollTrigger

Build Deploy License Issues GitHub release npm (scoped)

Let your page react to scroll changes.

The most basic usage of ScrollTrigger is to trigger classes based on the current scroll position. E.g. when an element enters the viewport, fade it in. You can add custom offsets per element, or set offsets on the viewport (e.g. always trigger after the element reaches 20% of the viewport)

When using the callbacks ScrollTrigger becomes really powerfull. You can run custom code when an element enters / becomes visible, and even return Promises to halt the trigger if the callback fails. This makes lazy loading images very easy.

Installation

npm install @terwanerik/scrolltrigger or just add the dist/ScrollTrigger.min.js file to your project and import that.

How to use?

The easiest way to start is to create a new instance and add some triggers to it, with all default values. This will toggle the 'visible' class when the element comes into the viewport, and toggles the 'invisible' class when it scrolls out of the viewport.

// when using ES6 import / npm
import ScrollTrigger from '@terwanerik/scrolltrigger'
// Create a new ScrollTrigger instance with default options
const trigger = new ScrollTrigger() // When not using npm, create a new instance with 'new ScrollTrigger.default()'
// Add all html elements with attribute data-trigger
trigger.add('[data-trigger]')

Now in your CSS add the following classes, this fades the [data-trigger] elements in and out.

.visible, .invisible {
  opacity: 0.0;
  transition: opacity 0.5s ease;
}
.visible {
  opacity: 1.0;
}

⚠️ Attention Are you migrating from 0.x to 1.x? Checkout the migration guide!

Some more demo's

A more detailed example

Adding callbacks / different classes can be done globally, this becomes the default for all triggers you add, or you can specify custom configuration when adding a trigger.

// Create a new ScrollTrigger instance with some custom options
const trigger = new ScrollTrigger({
  trigger: {
    once: true
  }
})
// Add all html elements with attribute data-trigger, these elements will only be triggered once
trigger.add('[data-trigger]')
// Add all html elements with attribute data-triggerAlways, these elements will always be triggered
trigger.add('[data-triggerAlways]', { once: false })

Options

The full set of options is taken from the demo directory, for more info, check that out.

const trigger = new ScrollTrigger({
    // Set custom (default) options for the triggers, these can be overwritten
    // when adding new triggers to the ScrollTrigger instance. If you pass
    // options when adding new triggers, you'll only need to pass the object
    // `trigger`, e.g. { once: false }
    trigger: {
        // If the trigger should just work one time
        once: false,
        offset: {
            // Set an offset based on the elements position, returning an
            // integer = offset in px, float = offset in percentage of either
            // width (when setting the x offset) or height (when setting y)
            //
            // So setting an yOffset of 0.2 means 20% of the elements height,
            // the callback / class will be toggled when the element is 20%
            // in the viewport.
            element: {
                x: 0,
                y: (trigger, rect, direction) => {
                    // You can add custom offsets according to callbacks, you
                    // get passed the trigger, rect (DOMRect) and the scroll
                    // direction, a string of either top, left, right or
                    // bottom.
                    return 0.2
                }
            },
            // Setting an offset of 0.2 on the viewport means the trigger
            // will be called when the element is 20% in the viewport. So if
            // your screen is 1200x600px, the trigger will be called when the
            // user has scrolled for 120px.
            viewport: {
                x: 0,
                y: (trigger, frame, direction) => {
                    // We check if the trigger is visible, if so, the offset
                    // on the viewport is 0, otherwise it's 20% of the height
                    // of the viewport. This causes the triggers to animate
                    // 'on screen' when the element is in the viewport, but
                    // don't trigger the 'out' class until the element is out
                    // of the viewport.

                    // This is the same as returning Math.ceil(0.2 * frame.h)
                    return trigger.visible ? 0 : 0.2
                }
            }
        },
        toggle: {
            // The class(es) that should be toggled
            class: {
                in: 'visible', // Either a string, or an array of strings
                out: ['invisible', 'extraClassToToggleWhenHidden']
            },
            callback: {
                // A callback when the element is going in the viewport, you can
                // return a Promise here, the trigger will not be called until
                // the promise resolves.
                in: null,
                // A callback when the element is visible on screen, keeps
                // on triggering for as long as 'sustain' is set
                visible: null,
                // A callback when the element is going out of the viewport.
                // You can also return a promise here, like in the 'in' callback.
                //
                // Here an example where all triggers take 10ms to trigger
                // the 'out' class.
                out: (trigger) => {
                    // `trigger` contains the Trigger object that goes out
                    // of the viewport
                    return new Promise((resolve, reject) => {
                        setTimeout(resolve, 10)
                    })
                }
            }
        },
    },
    // Set custom options and callbacks for the ScrollAnimationLoop
    scroll: {
        // The amount of ms the scroll loop should keep triggering after the
        // scrolling has stopped. This is sometimes nice for canvas
        // animations.
        sustain: 200,
        // Window|HTMLDocument|HTMLElement to check for scroll events
        element: window,
        // Add a callback when the user has scrolled, keeps on triggering for
        // as long as the sustain is set to do
        callback: didScroll,
        // Callback when the user started scrolling
        start: () => {},
        // Callback when the user stopped scrolling
        stop: () => {},
        // Callback when the user changes direction in scrolling
        directionChange: () => {}
    }
})

/***
 ** Methods on the ScrollTrigger instance
 ***/

/**
 * Creates a Trigger object from a given element and optional option set
 * @param {HTMLElement} element
 * @param {DefaultOptions.trigger} [options=DefaultOptions.trigger] options
 * @returns Trigger
 */
trigger.createTrigger(element, options)

/**
 * Creates an array of triggers
 * @param {HTMLElement[]|NodeList} elements
 * @param {Object} [options=null] options
 * @returns {Trigger[]} Array of triggers
 */
trigger.createTriggers(elements, options)

/**
 * Adds triggers
 * @param {string|HTMLElement|NodeList|Trigger|Trigger[]} objects A list of objects or a query
 * @param {Object} [options=null] options
 * @returns {ScrollTrigger}
 */
trigger.add(objects, options)

/**
 * Removes triggers
 * @param {string|HTMLElement|NodeList|Trigger|Trigger[]} objects A list of objects or a query
 * @returns {ScrollTrigger}
 */
trigger.remove(objects)

/**
 * Lookup one or multiple triggers by a query string
 * @param {string} selector
 * @returns {Trigger[]}
 */
trigger.query(selector)

/**
 * Lookup one or multiple triggers by a certain HTMLElement or NodeList
 * @param {HTMLElement|HTMLElement[]|NodeList} element
 * @returns {Trigger|Trigger[]|null}
 */
trigger.search(element)

/**
 * Reattaches the scroll listener
 */
trigger.listen()

/**
 * Kills the scroll listener
 */
trigger.kill()


/***
 ** Methods on a Trigger instance, e.g. when receiving from a callback or from a query
 ***/
const receivedTrigger = new Trigger()

/**
 * The HTML element
 */
receivedTrigger.element

/**
 * The offset settings
 */
receivedTrigger.offset

/**
 * The toggle settings
 */
receivedTrigger.toggle

/**
 * If the trigger should fire once, boolean
 */
receivedTrigger.once

/**
 * If the trigger is visible, boolean
 */
receivedTrigger.visible

Migrating from 0.x to 1.x

The main differences between 0.x and 1.x are the way you add and configure your triggers. 0.x added all HTMLElement's with the data-scroll attribute by default, 1.x doesn't do that, this requires you to add the triggers yourself. This improves the configuration of the triggers.

Also, please note that when not using a package manager / webpack, and you're just importing the minified version, you'll have to always use new ScrollTrigger.default().

<script src="dist/ScrollTrigger.min.js"></script>
<script>
var trigger = new ScrollTrigger.default()
</script>

Take for example the following element in ScrollTrigger 0.x:

<div data-scroll="once addHeight" data-scroll-showCallback="alert('Visible')" data-scroll-hideCallback="alert('Invisible')"></div>

In ScrollTrigger 1.x you would write this mostly in JavaScript:

// Say you have some divs with class 'animateMe'
const scrollTrigger = new ScrollTrigger()
scrollTrigger.add('.animateMe', {
    once: true, // same functionality as the `once` flag in v0.x
    offset: {
        element: {
            y: 1.0 // note that we pass a float instead of an integer, when the
                   // offset is a float, it takes it as a percentage, in this
                   // case, add 100% of the height of the element, the same
                   // functionality as the `addHeight` flag in v0.x
        }
    },
    toggle: {
        callback: {
            in: () => { // same as the data-scroll-showCallback, no need to set a
                        // custom callScope when calling custom functions and
                        // the possibility to return a Promise
                alert('Visible')
            },
            out: () => { // same as the data-scroll-hideCallback
                alert('Invisible')
            }
        }
    }
})

The advantage of writing all this in javascript is the configuration possible, say i want to change the offset of the element after the first time it's been visible (e.g. remove the addHeight flag after it's been shown):

scrollTrigger.add('.animateMe', {
    offset: {
        element: {
            y: 1.0
        }
    },
    toggle: {
        callback: {
            in: (trigger) => {
                // remove the element offset
                trigger.offset.element.y = 0
            }
        }
    }
})

Another example for setting custom classes per toggle;

<div data-scroll="toggle(animateIn, animateOut)"></div>

Becomes

const scrollTrigger = new ScrollTrigger()

scrollTrigger.add('[data-scroll]', {
    toggle: {
        class: {
            in: 'animateIn',
            out: 'animateOut'
        }
    }
})

If you have any questions on migrating to v1.x feel free to create a new issue.

Contributing

Fork, have a look in the src/ directory and enjoy! If you have improvements, start a new branch & create a pull request when you're all done :)

Troubleshooting

You can see really quickly if the Trigger is working by hitting 'inspect element'. Here you can see if the visible/invisble class is toggled when you scroll past the element.

If the classes don't toggle, check the JavaScript console. There might be some handy info in there.

Found an issue?

Ooh snap, well, bugs happen. Please create a new issue and mention the OS and browser (including version) that the issue is occurring on. If you are really kind, make a minimal, complete and verifiable example and upload that to codepen.

Legacy

Looking for the old ScrollTrigger? Check out the legacy branch!

scrolltrigger's People

Contributors

adriandmitroca avatar davidmerrique avatar dependabot[bot] avatar dhenson02 avatar nicolasmn avatar olegshilov avatar terwanerik avatar zalog avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scrolltrigger's Issues

Odd Issue with Toggle

First, this is a fantastic script. Thank you so much for publishing it.

I have noticed an odd issue when using the toggle() attribute. If the class you are toggling has too many hyphens, the toggle will fail to execute. This could come up as an issue for those using a BEM pattern for their coding.

As an example, these class will work correctly:

  • storefrontStoryInvisibleRight
  • storefront-story-invisible-right
  • storefrontSotry--invisible-right
  • storefront-story--invisibleRight

However, the correct BEM structure for this will fail:

  • storefront-story--invisible-right

I have scanned through the code, but I am stumped as to why this is happening.

bower main

Hi, script is really awesome.

I would have thought the bower 'main' should point to the unminified script, as most bower setups would be running packages through minification on build.

Callbacks don't work with nested functions

I have been trying to organise my callbacks into an object to avoid polluting the window namespace but have found that ScrollTrigger cannot call them.

This fails:

data-scroll-showCallback="myProject.doStuff"

I have also found that there is a problem with passing arguments - I think this is because you are using call when you should be using apply.

So, on line 613, this:

window[method].call(trigger.element, params);`

should read:

window[method].apply(trigger.element, params);`

Call only takes parameters not a node to apply the function to.

Responsive offset

Hi, just checking if there is maybe some built in way of switching offsets based on screen resolutions?
Or should I just check for desired screen size via simple if/else and switch accordingly.

For example, I would like to have y: 0.6 to be y: 0.2 on smaller screens.

trigger.add('[data-anim]', {
      offset: {
          element: {
              y: 0.6
          }
      },
      toggle: {
        callback: {
          in: () =>{
              animationScene.play()
          }
      }
      }
  })

custom data-scroll-showCallback="drawIt()" not firing

My custom callback is not firing when the item is already in view on refresh, it only fires when I do a little scrolling.

I see that the visible class is added on init, so it's specific to the custom callback.

scrollmagic

Is it possible to do scroll magic like tweening with this plugin, which reacts live to scrolling, not just triggers ;) #curious

overflow-y: scroll multi browser issues (doesn't show\animate)

first an apology, I'm not the best with front end development, so go easy on me if I'm making a stupid mistake.

I've come across an issue where overflow-y: scroll on a div is causing ScrollTrigger not to fire, rather the element with the data-scroll attribute remains hidden.

I've test with Chrome 80, FireFox 74, and whatever Edge is at as of today...

Below is the link to the codepen... I figured it might be better to just post a link to that instead of copy all the code here, but if not, I'll be happy to provide whatever answers y'all need from me.

Though here is a very rough layout. overflow-y: scroll is on main-container and there's a lot of flexbox involved. Removing overflow-y: scroll fixes the problem, but of course messes up the layout.

<body>
  <div class="page">
    <div class="page-container">
      <div class="page-header"> 
      </div>
        <div class="main-container"> 
          <div class="article">
          </div>
          <div class="article" data-scroll>
          </div>
          <div class="article">
          </div>
        </div>
        <div class="page-footer">
        </div>
      </div>
    </div>
</body>

https://codepen.io/david-angel/pen/Poqrbxx

Thanks in advance (for your patience with me.)

Can't access the html element in custom animations

I tried with "this" but it does not work :

`document.addEventListener('DOMContentLoaded', function(){
var trigger = new ScrollTrigger();

var callback = function(scrollLeft, scrollTop, width, height){
console.log(this);
trigger.detach(callback);
};

trigger.attach(callback);
});`

Any ideas what I'm doing wrong ?

mobile views

Hi i am beginner at coding and i have problem on mobile device. It doesn´t display anythink what i want to animate. On PC it works. In another on scroll animate plugin they had possibility to forbidden animating when display width is less then 700px for example, it´s up to you. I want to ask if you have some solution for mobile device ?

New features in v1.0

Alright, i'm starting this thread for new features you'd like to see in ScrollTrigger v1.0. I'd like to make the options more JS instead of passing them as attributes. If you have any thoughts, please comment below.

So far i got:

  • Different offsets for the 'in' and 'out' (including addWith and addHeight)
  • Using percentages and user defined functions as offset, for dynamic offsets
  • Allowing multiple classes to be toggled
  • Add logic to wait for animation to finish until toggling class

Delay OUT class until the element leaves viewport

Hi,

Loving this plugin, thanks!

Just a quick one - is there an easy way to prevent the 'out' class being assigned to the element until after it has left the viewport?

We have panels that we are animating the text up (and fading in) when it comes into the viewport but would like to prevent the fade out and drop down until after the block has completely left the user's viewport.

Sorry - one other thing - If an element is absolutely positioned to the left and then translated on the X axis with a negative percentage value, such as:

position:absolute;
left:0;
transform: translateX(-3%);

I cannot get the scrollTrigger to trigger. I see from another post that you recommend adding an offset but I can't get this to work with a percentage (used instead of px due to responsive nature). Any thoughts on this would be much appreciated too. :-)

Cheers,

Will

Not working on iOS

Hi,

Your demo page is working great, but my implementation of ScrollTrigger is not working on iOS. I am trying to track down the issue now. I am calling jQuery before it, which I think may be a factor. The initial invisible class is being applied, but not the visible

scroll does not into correct position

it sits about 1px above the section so when I click on my first nav it doesn't show it as being active, when I click on menu 2, menu 1 is highlighted as active but it has scrolled down to section 2, please help

How do I pass arguments or parameters to the callback function?

Hi there,

Thanks for the great script!

I have a problem that I've not been able to figure out yet. I want to be able to pass arguments to the data-scroll-showCallback function. Specifically, I would like to pass: 1) the HTML element that contains the data-scroll-showCallback attribute as the first argument; 2) a number; and 3) a Boolean.

Thank you for any help you can provide,
Jeremy

ScrollTrigger doesn't seem to work for sliding animations

I need to slide elements into my page from the side. ScrollTrigger has issues doing this because it flickers the visible/invisible classes rapid-fire constantly while scrolling. See the demo below showing the issue. Open your web inspector and scroll to the blue section and note how the classes flip rapidly back-and-forth while scrolling, even while the element is totally visible.

<!DOCTYPE html>
<html>
<head>
<title>ScrollTrigger bug demo</title>
<script src="https://apps.vividimpact.com/proofs/vividimpact.com/wp-content/themes/vivid-impact-theme/ScrollTrigger.min.js"></script>
<style>
	.visible {
		margin-left: -1000px;
		animation-duration: 5s;
		animation-name: slideAcross;
	}
	@keyframes slideAcross {
		from {
			margin-left: -2000px;
	}		
	to {
		margin-left: 2000px;
	}
	}
</style>
</head>
<body>
<div style="height: 3000px; background: red;"></div>
<div data-scroll style="height: 100px; background: blue;"></div>
<div style="height: 3000px; background: green;"></div>
<script>
	document.addEventListener('DOMContentLoaded', function() {
		var trigger = new ScrollTrigger();
	});
</script>
</body>
</html>

explorer error

HI. Thanks for making this good plugin.
It works good but doesn't on Explorer. Because there are some codes that Explorer does not support.
Although there's few people using Explorer, but still some contries use Explorer. I hope this support on Explorer.

Thanks.

Jumping when URL bar disappears on Android

The demo page jumps up and down a hole section when scrolling so the URL bar hides and shows (on Android, hasn't tried on iOS). I guess because the viewport height is changing when the URL bar hides or shows, and some calculations of the pages scroll position is based on the viewport size.

The bug is more visible in Chrome then in Firefox.

The visibility check on Microsoft Edge is always true

The _checkVisibility function uses the x and y values from the 'rect' object returned by getBoundingClientRect().

The getBoundingClientRect() function on Edge does not return these values so they are undefined.

Setting rect.x to rect.left and rect.y to rect.top fixed my issue on Edge.

Problem with multiple instances in the viewport

There's a problem with multiple instance in the same viewport where the once option is set to true. It removes the trigger after showing it here on line 372:

// remove trigger from triggers array
triggers.splice(i, 1);

This causes a change in the length of the triggers array and so the for loop doesn't loop over all the triggers thus not showing all instances. I've fixed this by adding an extra internal option 'shown' to the trigger object and set that to true instead of removing that trigger from the array. Then I wrapped the entire block inside that loop in if(!trigger.shown)

Maybe this is not the best approach, but it works for me now.

Elements slightly out of window not firing

Hi, thanks for this code, it's pretty handy. However, I have noticed one element which starts slightly off the window (with a translateX of -100 and a css rotation in this case) never fires on vertical scroll. I have tried doing xOffset but I think that's for horizontal scroll.

Is it a limitation of the software that all elements must start wholly within the window on the x axis for them to activate with vertical scrolling?

overflow-x: hidden chrome problem

Hi,
got problem when "overflow-x: hidden" is set for html, body the scrolltrigger is not working in chrome browser. In other browsers is everything working smoothly.

thanks

Not compatible with safari

These two lines not works in safari, because safari doesn't respect document.documentElement.scrollTop/Left

var currentTop = !_this.bindElement.scrollTop ? document.documentElement.scrollTop : _this.bindElement.scrollTop;
var currentLeft = !_this.bindElement.scrollLeft ? document.documentElement.scrollLeft : _this.bindElement.scrollLeft;

This is a complicated topic, so I just put a reference here, it is up to you to decide choose which solution: https://stackoverflow.com/questions/20514596/document-documentelement-scrolltop-return-value-differs-in-chrome/33462363#33462363

New data-scroll syntax

There is something i do not like about the strictly positioned parameters, they feel a bit old-school and sluggish, and way to strict. I would like a looser approach.

I was thinking about this yesterday, what do you guys think? Instead of having the scroll offset as the first parameter, being ambiguous and all, like so:
<div data-scroll="150 animateIn animateOut once"></div>

How about something more clear, like so:
<div data-scroll="animateIn animateOut offset(0,150) once"></div>

That way it is not strict to the first parameter, and we can use it for x as well as the y position. So now the only 2 strictly positioned parameters are the animateIn and animateOut classes. We can also eliminate those with something like this:
<div data-scroll="in(.animateIn) out(.animateOut) offset(0,150) once addHeight"></div>

That way the code is way more legible, adding the dot before the animateIn and animateOut classes hints the user that its a CSS class.

Another approach would be to use a single parameter for the animateIn and out classes, like so:
<div data-scroll="toggle(.animateIn, .animateOut) offset(0,150) once addHeight"></div>

What would you guys prefer?

Add animation delays

wow.js does this very nicely via:
data-wow-delay="5s"
It would be nice to see a similar feature in ScrollTrigger.

NPM support

Do you have any plans to publish this library to NPM? Would love to be able to bring this into my build system and update automatically if possible

timed delays

Add a time delay parameter eg data-scroll-delay=".5s" or data-scroll-delay="1.5s"

Can an on-screen element trigger an off-screen element?

Is it possible for object id A, once on-screen, to trigger a show / hide class change on object id B, which is off-screen?

I'm guessing that ... perhaps ... the correct approach involves creating a callback for object A that passes B as an argument, like in this issue?

#34

How can I refresh scrollTrigger?

I'm using scrollTrigger on a site that uses pjax, and it works great, except when I use the "once" option with a trigger.

Since a trigger is removed from the triggers array in this case, there's no way to for me to refresh/recollect those triggers later.

There should be a re-init/refresh method to call otherwise my triggers that are set to show once don't ever work again in an ajax environment.

Halt autoplay interval when carousel isn’t within the viewport

Hello! I’m a total JavaScript uninitiate and I’ve been trying to understand how I can achieve this for quite some time now.

I have a Siema carousel setup in which the slide changes every 2 seconds but stops when the user interacts with the carousel (either by sliding or by pressing the slide controls). A live demo can be seen on my website.

I’d like to know if I can pause the slide interval when the .siema element is off the viewport. Can I achieve that with ScrollTrigger?

This is my Siema code, by the way:

// SIEMA

const mySiema = new Siema({
    duration: 250,
    loop: true,
    easing: "cubic-bezier(.42,0,.58,1)",
    onInit: printSlideIndexWithIndicator,
    onChange: printSlideIndexWithIndicator,
});


// INDICATORS

function printSlideIndexWithIndicator() {
    let currentSlide = this.currentSlide;
    let currentSelector = document.querySelector('.siema-current');
    let totalSelector = document.querySelector('.siema-total');
    /*let zoomSelector = document.querySelector('.siema-zoom');*/
    if (currentSlide < 0) {
        currentSelector.innerHTML = this.innerElements.length + currentSlide + 1;
    } else {
        currentSelector.innerHTML = this.currentSlide + 1;
    }
    totalSelector.innerHTML = this.innerElements.length;
}


// AUTOPLAY

const myInterval = setInterval(() => mySiema.next(), 2000);

document.querySelector(".siema-prev").addEventListener("click", () => {
    mySiema.prev();
    clearInterval(myInterval);
});
document.querySelector(".siema-next").addEventListener("click", () => {
    mySiema.next();
    clearInterval(myInterval);
});
document.querySelector(".siema").addEventListener("mousedown", () => {
    clearInterval(myInterval);
});
document.querySelector(".siema").addEventListener("touchstart", () => {
    clearInterval(myInterval);
});

Use of .invisible as the class

Can you change the class .invisible to say .trigger-invisible (and trigger-visible) as Bootstrap already uses .invisible to hide elements.

Locomotivescroll

Hello there!

I have one question. Can i use locomotive scroll with scrolltrigger ?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.