1.0.2 • Published 6 months ago

inview-detection v1.0.2

Weekly downloads
-
License
ISC
Repository
github
Last release
6 months ago

A powerful javascript library to create sequential animations based on in-view detection. Powered by GSAP.

Features

  • Standalone elements
  • Scoping, bind elements to parent
  • Custom queuing and animations
  • Trigger callbacks
  • Staggered text animations with SplitText
  • Repeatable
  • Target specific screen sizes
  • Debugging mode
  • Lightweight (>3Kb gzipped)

Dependencies

The following must be instantiated before:

Quick start

Installation

InviewDetection.js requires the GSAP library, as well as ScrollTrigger and SplitText (Club GreenSock) to work. You need to include all of them before InviewDetection.js.

Boilerplate

We have already included the file in our Boilerplate.

Use from CDN

<!-- Include GSAP -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/ScrollTrigger.min.js"></script>
<script src="/path-to/SplitText.min.js"></script>

<!-- Include InviewDetection -->
<script src="https://cdn.jsdelivr.net/gh/coderesolution/InviewDetection.js/bundled/InviewDetection.min.js"></script>

<script>
	// Register GSAP
	gsap.registerPlugin(ScrollTrigger, SplitText)

	// Initialise InviewDetection
	const inview = new InviewDetection(/*options*/)
</script>

<!-- For better results, hide SplitText by default -->
<style>
	[data-inview-split] {
		visibility: hidden;
	}
</style>

Alternatively, you can register GSAP inside the inview initialisation:

<script>
	// Initialise InviewDetection and register GSAP ScrollTrigger and SplitText plugins
	const inview = new InviewDetection({
		registerGsapPlugins: true,
	})
</script>

If you wish to initiate the module but not start it yet, you can do so by setting the autoStart to false and running inview.start(). This can be helpful if you experience incorrect results when using the data-inview-split feature that uses GSAP:

<script>
	// Create instance but do not start automatically
	const inview = new InviewDetection({
		autoStart: false,
	})

	// Start it when you are ready
	document.addEventListener('DOMContentLoaded', (event) => {
		inview.start()
	})
</script>

Install NPM module

import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
import { SplitText } from 'gsap/SplitText'
import InviewDetection from './path-to/InviewDetection'

// Register GSAP
gsap.registerPlugin(ScrollTrigger, SplitText)

// Initialise InviewDetection
const inview = new InviewDetection(/*options*/)

Defaults

You can configure InviewDetection.js default via options (and overwrite them on a per-animation basis using modifiers):

const inview = new InviewDetection({
	elements: '[data-inview]',
	screen: '(min-width: 1025px)',
	duration: 1,
	delay: 1,
	start: 'top 90%',
	ease: 'power4',
	stagger: 0.155,
	animationFrom: {
		opacity: 0,
		'will-change': 'transform',
		y: 20,
	},
	animationTo: {
		opacity: 1,
		y: 0,
	},
	autoStart: true,
	registerGsapPlugins: false,
	inviewClass: 'is-inview',
	viewedClass: 'has-viewed',
})
NameTypeDefaultDescription
elementsstringdata-inviewTrigger elements, defaults to
screenstring'(min-width: 1025px)'Set media query conditions via matchMedia to target specific screen sizes. Use 'all' for every size.
durationnumber1Duration of each animation.
delaynumber.1Delay before animation.
startstringtop 90%ScrollTrigger's starting position.
easestringpower4Easing of animation (help).
staggernumber0.08Time between each animation. Defaults to
animationFromjson{"opacity": 0, "y": 20}The beginning of each animation.
animationTojson{"opacity": 1, "y": 0}The ending of each animation.
autoStartbooleantrueInitialise straight-away. Useful if a delay is needed to fix SplitText issues.
registerGsapPluginsbooleanfalseRegister ScrollTrigger and SplitText automatically.
inviewClassstringis-inviewClass applied to parent elements (not scoped) that are inview.
viewedClassstringhas-viewedClass applied to parent elements (not scoped) that have been viewed.

Instructions

Usage

NameTypeDescription
data-inviewApply attribute to trigger elements that are either standalone or parents of nested items by including a data-inview-scope
data-inview-scopestringApply to data-inview element to specify the scope of nested elements. Use wildcards like *, > * or selectors .class, #id. By default, it will scope only data-inview-child and data-inview-split elements
data-inview-childApply attribute to elements that should animate when parent comes into to view
data-inview-splitstringSame as data-inview-child, however, apply SplitText to direct text elements to animate per line. Set a value to target specific elements, i.e. p, li

Modifiers

Apply any of the following to [data-inview] element to apply custom settings:

NameTypeDefaultDescription
data-inview-debugSet GSAP markers and output helpful console information.
data-inview-screen'(min-width: 1025px)'Enable animation only at specific screen sizes. Use 'all' for every size.
data-inview-durationnumber1Duration of each element transition.
data-inview-delaynumber.1Delay before entire sequence begins.
data-inview-staggernumber0.08Delay between each element in sequence.
data-inview-easestringpower4GSAP easing.
data-inview-ordernumberApply an index to scoped elements, either [data-inview-child] or [data-inview-split] or elements specified in the respective parent's [data-inview-scope]. This will adjust the order of the element within the animation sequence. Negative numbers appear first, then positive numbers
data-inview-startstringtop 90%When animation begins.
data-inview-fromjson{"opacity": 0, "y": 20}Apply custom gsap.from() properties for every element. Example: {"opacity": 0, "y": 20, "rotation": 0}
data-inview-tojson{"opacity": 1, "y": 0}Apply custom gsap.to() properties for every element. Example: {"opacity": 1, "y": 0, "rotation": 10}
data-inview-repeatWhether or not to repeat animations when they re-enter the viewport. Disabled by default.
data-inview-callstringFire custom events when elements enter, re-enter. Example: data-inview-call="scrollEvent".

Methods

Start

Start the initialisation if autoStart is set to false.

inview.start()

Tip: This is useful if you want to start after the page has loaded, like so:

document.addEventListener('DOMContentLoaded', (event) => {
	inview.start()
})

Refresh

Update ScrollTrigger calculations.

inview.refresh()

Stop

Stop all animations so anything not yet visible does not load in.

inview.stop()

Restart

Stop and restart all animations.

inview.restart()

Classes

ClassApplication
is-inviewOnce the element has came into view at least once.
has-viewedToggles when the element is in view.

The application remains the same even if the classes have been changed from their default setting.

Events

Element enter/leave the viewport

Detect when a animation (re)fires from a particular direction.

inview.on('onEnter', (element) => {
	console.log('Entering top of view:', element)
})
inview.on('onLeave', (element) => {
	console.log('Leaving bottom of view:', element)
})
inview.on('onEnterBack', (element) => {
	console.log('Entering bottom of view:', element)
})
inview.on('onLeaveBack', (element) => {
	console.log('Leaving top of view:', element)
})

Refresh

Detect when the inview.refresh() method is fired.

inview.on('refresh', () => {
	console.log('Refreshed')
})

Stop

Detect when the inview.stop() method is fired.

inview.on('stop', (target) => {
	console.log('Stopped', target)
})

Restart

Detect when the inview.restart() method is fired.

inview.on('restart', () => {
	console.log('Restarted')
})

Custom Callbacks

Events

Fire custom events when elements enter or leave the viewport.

<div data-inview data-inview-call="inviewEvent">Trigger</div>
window.addEventListener('inviewEvent', (e) => {
	console.log('target', e.detail.target)
})

FAQ

Reason

This is because Javascript has to load before it can hide the elements.

Solution

Here are recommended solutions:

  • Use critical CSS to apply essential styles on load, such as hiding above-the-fold elements that you wish to animate.
  • Add a page transition.
  • Add a pre-loader.

Reason

This may happen is the text or its' container is modified by Javascript.

Solution

As a result, it is best to try disabling autoStart by setting it false and running inview.start() when everything else has ran.

Example

<script>
	// Create instance but do not start automatically
	const inview = new InviewDetection({
		autoStart: false,
	})

	// Start it when you are ready
	document.addEventListener('DOMContentLoaded', (event) => {
		inview.start()
	})
</script>

<!-- Hide split elements on load -->
<style>
	[data-inview-split] {
		visibility: hidden;
	}
</style>

Reason

This is purely frustrating having so many speech-marks and apostrophes, so here are some easy work-arounds that beat opening/closing PHP.

Solution

As a result, it is best to try disabling autoStart by setting it false and running inview.start() when everything else has ran.

Example

a. Concatenate strings:

<?php
$attr = '{"opacity": 0, "scale": 20}';
echo '" data-inview data-inview-from=' . $attr . '">';
?>

b. Use an array and json_encode:

<?php
$attr = ['opacity' => 0, 'scale' => 20];
echo '" data-inview data-inview-from=' . json_encode($attr) . '">';
?>

c. Use heredoc or nowdoc syntax:

<?php echo <<<EOF
" data-inview data-inview-from={"opacity": 0, "scale": 20}">
EOF;
?>

Examples of use

License

The MIT License (MIT)

1.0.2

6 months ago

1.0.1

6 months ago