├── .editorconfig
├── .eslintrc.js
├── .github
└── workflows
│ └── publish.yml
├── .gitignore
├── .nova
├── Configuration.json
└── Tasks
│ └── Tasks.json
├── .prettierrc
├── LICENSE
├── README.md
├── docs
├── index.css
├── index.html
├── index.min.js
└── main.js
├── package.json
├── pnpm-lock.yaml
├── src
└── index.js
└── vite.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = false
7 | indent_style = tab
8 | indent_size = 4
9 | trim_trailing_whitespace = true
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es2021: true,
5 | node: true,
6 | },
7 | extends: ['standard', 'plugin:react-hooks/recommended', 'prettier'],
8 | parserOptions: {
9 | ecmaVersion: 'latest',
10 | },
11 | rules: {
12 | 'space-before-function-paren': 'off',
13 | 'comma-dangle': ['error', 'always-multiline'],
14 | },
15 | ignorePatterns: ['dist', 'node_modules', 'bundled'],
16 | }
17 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish to NPM
2 | on:
3 | release:
4 | types: [created]
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Checkout
10 | uses: actions/checkout@v3
11 |
12 | - name: Setup Node
13 | uses: actions/setup-node@v3
14 | with:
15 | node-version: 16
16 | registry-url: 'https://registry.npmjs.org'
17 |
18 | - name: Install pnpm
19 | uses: pnpm/action-setup@v2
20 | with:
21 | version: 7
22 | run_install: false
23 |
24 | - name: Install dependencies and build
25 | run: pnpm i --frozen-lockfile
26 | - name: Publish package on NPM
27 | run: npm publish
28 | env:
29 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | bundled
13 | dist-ssr
14 | *.local
15 |
16 | # Editor directories and files
17 | .vscode/*
18 | !.vscode/extensions.json
19 | .idea
20 | .DS_Store
21 | *.suo
22 | *.ntvs*
23 | *.njsproj
24 | *.sln
25 | *.sw?
--------------------------------------------------------------------------------
/.nova/Configuration.json:
--------------------------------------------------------------------------------
1 | {
2 | "workspace.name" : "inview-detection"
3 | }
4 |
--------------------------------------------------------------------------------
/.nova/Tasks/Tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "actions" : {
3 | "build" : {
4 | "enabled" : true,
5 | "script" : "npm run build"
6 | },
7 | "clean" : {
8 | "enabled" : true,
9 | "script" : "npm run clean"
10 | },
11 | "run" : {
12 | "enabled" : true,
13 | "script" : "npm run dev"
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 120,
3 | "endOfLine": "auto",
4 | "semi": false,
5 | "singleQuote": true
6 | }
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Code Resolution
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Inview Detection
4 |
5 | Inview Detection enables the creation of sequential animations based on in-view detection using custom `data-inview-*` attributes in the DOM. Powered by GSAP.
6 |
7 | [Walk-through video](https://cloud.cdrs.dev/h6BvSP9P)
8 |
9 |
10 |
11 |
12 |
13 |
14 | ## Features
15 |
16 | - Standalone elements
17 | - Scoping, bind elements to parent
18 | - Custom queuing and animations
19 | - Trigger callbacks
20 | - Conditional classes
21 | - Repeatable
22 | - Target specific screen sizes
23 | - Debugging mode
24 | - Lightweight (1.63 kB gzipped)
25 |
26 | ## Dependencies
27 |
28 | Ensure the following dependencies are installed and properly registered:
29 |
30 | - [GSAP v3](https://greensock.com/gsap/)
31 | - [GSAP ScrollTrigger](https://greensock.com/scrolltrigger/)
32 |
33 | ## Quick start
34 |
35 | Inview Detection requires the GSAP library as well as ScrollTrigger to function correctly. Ensure both are included **before** Inview Detection and registered within the instantiation.
36 |
37 | ### Install from NPM
38 |
39 | ```js
40 | import { gsap } from 'gsap'
41 | import { ScrollTrigger } from 'gsap/ScrollTrigger'
42 | import InviewDetection from 'inview-detection'
43 |
44 | // Register ScrollTrigger plugin
45 | gsap.registerPlugin(ScrollTrigger)
46 |
47 | // Initialise InviewDetection and pass in gsap and ScrollTrigger
48 | const inview = new InviewDetection(
49 | {
50 | /* options */
51 | },
52 | gsap,
53 | ScrollTrigger,
54 | )
55 | ```
56 |
57 | ### Delayed start (recommended)
58 |
59 | To initialise the module without starting it immediately, set `autoStart` option to `false`.
60 |
61 | ```js
62 | // Create instance but do not start automatically
63 | const inview = new InviewDetection(
64 | {
65 | autoStart: false,
66 | },
67 | gsap,
68 | ScrollTrigger,
69 | )
70 |
71 | // Start it when you are ready
72 | document.addEventListener('DOMContentLoaded', () => {
73 | inview.start()
74 | })
75 | ```
76 |
77 | With `autoStart` disabled, for extra clarity `inview.register` can be used to register `gsap` and `ScrollTrigger` outside of the instantiation.
78 |
79 | ```js
80 | // Standard
81 | const inview = new InviewDetection(
82 | {
83 | autoStart: false,
84 | },
85 | gsap,
86 | ScrollTrigger,
87 | )
88 | ```
89 |
90 | Optionally may be replaced with:
91 |
92 | ```js
93 | const inview = new InviewDetection({
94 | autoStart: false,
95 | })
96 |
97 | // Register gsap and ScrollTrigger separately
98 | inview.register(gsap, ScrollTrigger)
99 | ```
100 |
101 | ### Install from CDN
102 |
103 | If you prefer to use a CDN, here is an example:
104 |
105 | ```html
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
126 | ```
127 |
128 | ## Options
129 |
130 | You can configure Inview Detection via options:
131 |
132 | ```js
133 | const inview = new InviewDetection(
134 | {
135 | elements: '[data-inview]',
136 | autoStart: true,
137 | screen: '(min-width: 1025px)',
138 | duration: 1,
139 | delay: 0.1,
140 | start: 'top 90%',
141 | ease: 'power4',
142 | stagger: 0.08,
143 | animationFrom: {
144 | opacity: 0,
145 | 'will-change': 'transform',
146 | y: 20,
147 | },
148 | animationTo: {
149 | opacity: 1,
150 | y: 0,
151 | },
152 | inviewClass: 'is-inview',
153 | viewedClass: 'has-viewed',
154 | debug: false,
155 | },
156 | gsap,
157 | ScrollTrigger,
158 | )
159 | ```
160 |
161 | All options:
162 |
163 | | Name | Type | Default | Description |
164 | | :-------------- | :----: | :-----------------------: | :----------------------------------------------------------------------------------------------------------------------------------- |
165 | | `elements` | `str` | `[data-inview]` | What elements to apply inview animations to. |
166 | | `autoStart` | `bool` | `true` | Whether to start immediately. Set to `false` for a delayed start (recommended). |
167 | | `screen` | `str` | `'(min-width: 1025px)'` | Specify media query rules for animations. This can be overwritten on a per animation-basis. Set to `all` to remove queries entirely. |
168 | | `duration` | `num` | `1` | Duration of each animation. |
169 | | `delay` | `num` | `.1` | Delay before animation starts. |
170 | | `start` | `str` | `top 90%` | ScrollTrigger's starting position for the animation. |
171 | | `ease` | `str` | `power4` | Easing of animation ([help](https://greensock.com/docs/Easing)). |
172 | | `stagger` | `num` | `0.08` | Time between each animation in the sequence. |
173 | | `animationFrom` | `json` | `{"opacity": 0, "y": 20}` | The initial state of each animation. |
174 | | `animationTo` | `json` | `{"opacity": 1, "y": 0}` | The final state of each animation. |
175 | | `inviewClass` | `str` | `'is-inview'` | The class that is temporarily assigned to elements when they are within the viewport. |
176 | | `viewedClass` | `str` | `'has-viewed'` | The class that is permanently assigned to elements when they have been within the viewport. |
177 | | `debug` | `bool` | `false` | Set debug mode to all instances. Enables markers and console logs. |
178 |
179 | ## Attributes
180 |
181 | Apply any of the following data attributes in conjunction with `[data-inview]` to enable custom animations.
182 |
183 | - [scope](#scope)
184 | - [child](#child)
185 | - [debug](#debug)
186 | - [order](#order)
187 | - [repeat](#repeat)
188 | - [from/to](#fromto)
189 | - [start](#start)
190 | - [end](#end)
191 | - [screen](#screen)
192 | - [call](#call)
193 |
194 | ### Scope
195 |
196 | Attribute: `data-inview-scope`
197 | Type: `string`
198 |
199 | Specify the scope of nested elements using wildcards like `*`, `> *` or selectors `.class, #id`.
200 |
201 | ```html
202 |
203 |
204 |
205 | ```
206 |
207 | ### Child
208 |
209 | Attribute: `data-inview-child`
210 |
211 | Apply attribute to elements that should animate when parent comes into view. The parent must have `[data-inview]` and `[data-inview-scope]` attributes.
212 |
213 | ```html
214 |
215 |
Child 1
216 |
Child 2
217 |
218 | ```
219 |
220 | ### Debug
221 |
222 | Attribute: `data-inview-debug`
223 |
224 | Enable debugging markers and logs for animations.
225 |
226 | ```html
227 |
228 | ```
229 |
230 | ### Order
231 |
232 | Attribute: `data-inview-order`
233 | Type: `number`
234 |
235 | Specify the order of animation for elements within a scope.
236 |
237 | ```html
238 |
239 |
First
240 |
Second
241 |
242 | ```
243 |
244 | ### Repeat
245 |
246 | Attribute: `data-inview-repeat`
247 |
248 | Allow animations to re-trigger when elements re-enter the viewport.
249 |
250 | ```html
251 |
252 | ```
253 |
254 | ### From / To
255 |
256 | Attributes: `data-inview-from`, `data-inview-to`
257 | Type: `json`
258 |
259 | Specify custom `gsap.from()` and `gsap.to()` properties for animations.
260 |
261 | ```html
262 |
263 | Custom Animation
264 |
265 | ```
266 |
267 | ### Start
268 |
269 | Attribute: `data-inview-start`
270 | Default: `'top bottom'` or `'top top'` if (sticky)[#sticky] is set
271 | Type: `str`
272 |
273 | Adjust the point when the animation begins.
274 |
275 | The first value refers to the trigger and the second value refers to the viewport. Refer GSAP ScrollTrigger documentation for further information.
276 |
277 | ```html
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 | ```
286 |
287 | ### End
288 |
289 | Attribute: `data-inview-end`
290 | Default: `'bottom top'` or `bottom bottom` if (sticky)[#sticky] is set
291 | Type: `str`
292 |
293 | Adjust the point when the animation ends. See [preset](#preset) for automatic detection with offsets.
294 |
295 | The first value refers to the trigger and the second value refers to the viewport. Refer GSAP ScrollTrigger documentation for further information.
296 |
297 | ```html
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 | ```
306 |
307 | ### Screen
308 |
309 | Attribute: `data-inview-screen`
310 | Default: `'(min-width: 1025px)'` (configurable globally via [options](#options))
311 | Type: `str`
312 |
313 | Set screen size conditions for the animation. For example: animate on desktop and not mobile, or vice-versa. Expects media queries like `(min-width: 500px)` or `(min-width: 768px) and (max-width: 1000px)` etc. Set to `all` to animate on all screen sizes.
314 |
315 | ### Call
316 |
317 | Attribute: `data-inview-call`
318 | Default: Not set
319 | Type: `str`
320 |
321 | Fire custom JavaScript events when elements enter and leave the viewport.
322 | Data such as `target`, `direction` (up/down) and `when` (enter, re-enter, leave and leave-again) are accessible within an event listener.
323 |
324 | ```html
325 |