@reimujs/aos 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,65 +1,47 @@
1
1
  # aos.js
2
2
 
3
- ![NPM License](https://img.shields.io/npm/l/%40reimujs%2Faos) ![NPM Version](https://img.shields.io/npm/v/%40reimujs%2Faos) ![npm bundle size](https://img.shields.io/bundlephobia/min/%40reimujs%2Faos)
3
+ ![NPM License](https://img.shields.io/npm/l/%40reimujs%2Faos) ![NPM Version](https://img.shields.io/npm/v/%40reimujs%2Faos) ![npm bundle size](https://img.shields.io/bundlephobia/min/%40reimujs%2Faos) [![Coverage Status](https://coveralls.io/repos/github/D-Sketon/aos.js/badge.svg?branch=main)](https://coveralls.io/github/D-Sketon/aos.js?branch=main)
4
4
 
5
- Animate on scroll library.
5
+ Animate on scroll library. A modern TypeScript rewrite of [michalsnik/aos](https://github.com/michalsnik/aos).
6
6
 
7
- Rewrite [aos](https://github.com/michalsnik/aos) using typescript.
7
+ ## Features
8
+
9
+ - Full TypeScript support with type definitions
10
+ - Smaller bundle size: 5.7KB + 23.3KB (vs 14.7KB + 26.1KB)
11
+ - Modern browser optimizations
12
+ - Custom scrollable container support
13
+ - Enhanced API with `destroy()` method
14
+ - Compatible with React, Vue, Angular, Astro, and more
8
15
 
9
16
  ## Installation
10
17
 
11
18
  ```bash
12
- npm install @reimujs/aos --save
19
+ npm install @reimujs/aos
13
20
  ```
14
21
 
15
- or
22
+ CDN:
16
23
 
17
24
  ```html
18
- <link
19
- rel="stylesheet"
20
- href="https://cdn.jsdelivr.net/npm/@reimujs/aos/dist/aos.css"
21
- />
25
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@reimujs/aos/dist/aos.css" />
22
26
  <script src="https://cdn.jsdelivr.net/npm/@reimujs/aos/dist/aos.umd.js"></script>
23
27
  ```
24
28
 
25
- ## Difference
26
-
27
- So what's the difference between aos and @reimujs/aos?
28
-
29
- - Typescript friendly
30
- - Smaller package size (from 14.7KB + 26.1KB to 6.15KB + 23.3KB)
31
- - Only support modern browsers
32
- - Support additional settings
33
- - Support additional API
34
-
35
- ### Additional settings
36
-
37
- #### container
38
-
39
- merge from [aos#223](https://github.com/michalsnik/aos/issues/223), you can set the container of AOS, accepts CSS Selector (e.g. ".my-awesome-container") or HTMLElement.
29
+ ## Usage
40
30
 
41
31
  ```typescript
42
- container: window, // AOS Container, accepts CSS Selector (e.g. ".my-awesome-container") or HTMLElement
43
- ```
44
-
45
- ### Additional API
46
-
47
- #### AOS.destroy()
32
+ import AOS from "@reimujs/aos";
33
+ import "@reimujs/aos/dist/aos.css";
48
34
 
49
- ```typescript
50
- function destroy(): void;
35
+ AOS.init();
51
36
  ```
52
37
 
53
- Remove all event listeners and disconnect MutationObserver.
54
-
55
- ## Usage
38
+ ```html
39
+ <div data-aos="fade-up">Animate on scroll</div>
40
+ ```
56
41
 
57
- Just same as aos@next. For more information, please visit [aos-how-to-use-it](https://github.com/michalsnik/aos?tab=readme-ov-file#-how-to-use-it).
42
+ ## Configuration
58
43
 
59
44
  ```typescript
60
- import AOS from "@reimujs/aos";
61
- import "@reimujs/aos/dist/aos.css";
62
-
63
45
  AOS.init({
64
46
  // Global settings:
65
47
  disable: false, // accepts following values: 'phone', 'tablet', 'mobile', boolean, expression or function
@@ -85,6 +67,38 @@ AOS.init({
85
67
  });
86
68
  ```
87
69
 
70
+ ## Animations
71
+
72
+ Available animation types:
73
+ - **Fade**: `fade`, `fade-up`, `fade-down`, `fade-left`, `fade-right`, `fade-up-right`, `fade-up-left`, `fade-down-right`, `fade-down-left`
74
+ - **Flip**: `flip-up`, `flip-down`, `flip-left`, `flip-right`
75
+ - **Slide**: `slide-up`, `slide-down`, `slide-left`, `slide-right`
76
+ - **Zoom**: `zoom-in`, `zoom-in-up`, `zoom-in-down`, `zoom-in-left`, `zoom-in-right`, `zoom-out`, `zoom-out-up`, `zoom-out-down`, `zoom-out-left`, `zoom-out-right`
77
+
78
+ Available easing functions:
79
+ - `linear`, `ease`, `ease-in`, `ease-out`, `ease-in-out`
80
+ - `ease-in-back`, `ease-out-back`, `ease-in-out-back`
81
+ - `ease-in-sine`, `ease-out-sine`, `ease-in-out-sine`
82
+ - `ease-in-quad`, `ease-out-quad`, `ease-in-out-quad`
83
+ - `ease-in-cubic`, `ease-out-cubic`, `ease-in-out-cubic`
84
+ - `ease-in-quart`, `ease-out-quart`, `ease-in-out-quart`
85
+
86
+ ## API
87
+
88
+ ### `AOS.init(options?)`
89
+ Initialize AOS with optional configuration.
90
+
91
+ ### `AOS.refresh()`
92
+ Recalculate element positions after dynamic content changes.
93
+
94
+ ### `AOS.refreshHard()`
95
+ Force complete reinitialization.
96
+
97
+ ### `AOS.destroy()`
98
+ Remove all event listeners and observers.
99
+
100
+ ## Framework Examples
101
+
88
102
  ### Next.js
89
103
 
90
104
  ```typescript
@@ -101,9 +115,9 @@ export default function Page() {
101
115
  }
102
116
  ```
103
117
 
104
- ### Nuxt
118
+ ### Vue / Nuxt
105
119
 
106
- ```html
120
+ ```vue
107
121
  <script lang="ts" setup>
108
122
  import { onMounted } from "vue";
109
123
  import "@reimujs/aos/dist/aos.css";
@@ -116,7 +130,7 @@ onMounted(() => {
116
130
  </script>
117
131
  ```
118
132
 
119
- ### Augular
133
+ ### Angular
120
134
 
121
135
  ```typescript
122
136
  import { Component, Inject, PLATFORM_ID } from '@angular/core';
@@ -125,9 +139,7 @@ import '@reimujs/aos/dist/aos.css';
125
139
 
126
140
  @Component({})
127
141
  export class AppComponent {
128
- constructor(
129
- @Inject(PLATFORM_ID) private platformId: Object
130
- ) {
142
+ constructor(@Inject(PLATFORM_ID) private platformId: Object) {
131
143
  if (isPlatformBrowser(this.platformId)) {
132
144
  import("@reimujs/aos").then(({ default: AOS }) => {
133
145
  AOS.init();
@@ -139,10 +151,11 @@ export class AppComponent {
139
151
 
140
152
  ### Astro
141
153
 
142
- ```html
154
+ ```astro
143
155
  ---
144
156
  import "@reimujs/aos/dist/aos.css";
145
157
  ---
158
+
146
159
  <script>
147
160
  import AOS from "@reimujs/aos";
148
161
  AOS.init();
@@ -150,5 +163,5 @@ import "@reimujs/aos/dist/aos.css";
150
163
  ```
151
164
 
152
165
  ## License
153
-
166
+
154
167
  MIT
package/dist/aos.cjs.js CHANGED
@@ -4,35 +4,34 @@ function debounce(func, delay) {
4
4
  let timeoutId;
5
5
  return (...args) => {
6
6
  clearTimeout(timeoutId);
7
- timeoutId = setTimeout(() => {
8
- func.apply(this, args);
9
- }, delay);
7
+ timeoutId = setTimeout(() => func(...args), delay);
10
8
  };
11
9
  }
12
10
  function throttle(func, limit) {
13
11
  let lastFunc, lastRan;
14
12
  return (...args) => {
15
- const context = this;
16
- if (!lastRan || Date.now() - lastRan >= limit) {
17
- func.apply(context, args);
18
- lastRan = Date.now();
13
+ const now = Date.now();
14
+ if (!lastRan || now - lastRan >= limit) {
15
+ func(...args);
16
+ lastRan = now;
19
17
  }
20
18
  else {
21
19
  clearTimeout(lastFunc);
22
20
  lastFunc = setTimeout(() => {
23
- func.apply(context, args);
21
+ func(...args);
24
22
  lastRan = Date.now();
25
- }, limit - (Date.now() - lastRan));
23
+ }, limit - (now - lastRan));
26
24
  }
27
25
  };
28
26
  }
29
27
 
30
28
  const phoneRe = /iphone|ipod|android.*mobile|windows phone|blackberry|opera mini|mobile|phone/i;
31
29
  const tabletRe = /ipad|android(?!.*mobile)|tablet|kindle/i;
30
+ const check = (regex) => regex.test(navigator.userAgent);
32
31
  var detect = {
33
- phone: () => phoneRe.test(navigator.userAgent),
34
- mobile: () => phoneRe.test(navigator.userAgent) || tabletRe.test(navigator.userAgent),
35
- tablet: () => tabletRe.test(navigator.userAgent),
32
+ phone: () => check(phoneRe),
33
+ mobile: () => check(phoneRe) || check(tabletRe),
34
+ tablet: () => check(tabletRe),
36
35
  };
37
36
 
38
37
  const resolveContainer = (container) => {
@@ -53,8 +52,8 @@ const getElementOffset = (container) => {
53
52
  : container.scrollTop;
54
53
  };
55
54
 
56
- const fireEvent = (eventName, data) => document.dispatchEvent(new CustomEvent(eventName, {
57
- detail: data,
55
+ const fireEvent = (eventName, detail) => document.dispatchEvent(new CustomEvent(eventName, {
56
+ detail,
58
57
  }));
59
58
  const toggleClasses = (el, isVisible) => {
60
59
  if (el.animated === isVisible)
@@ -94,75 +93,50 @@ var getInlineOption = (el, key, fallback) => {
94
93
  return attr || fallback;
95
94
  };
96
95
 
97
- const getOffset = function (el, container) {
98
- let left = 0;
96
+ const getOffsetTop = function (el, container) {
99
97
  let top = 0;
100
98
  while (el) {
101
- left += el.offsetLeft - (el.tagName != "BODY" ? el.scrollLeft : 0);
102
99
  top += el.offsetTop - (el.tagName != "BODY" ? el.scrollTop : 0);
103
100
  el =
104
101
  el.offsetParent === container ? null : el.offsetParent;
105
102
  }
106
- return {
107
- top,
108
- left,
109
- };
103
+ return top;
104
+ };
105
+ const getAnchor = (el, container) => {
106
+ const anchor = getInlineOption(el, "anchor");
107
+ if (anchor) {
108
+ const queryResult = (container === window ? document : container).querySelector(anchor);
109
+ if (queryResult)
110
+ return queryResult;
111
+ }
112
+ return el;
110
113
  };
111
114
  const getPositionIn = (el, defaultOffset, defaultAnchorPlacement, container) => {
112
115
  const containerHeight = getElementHeight(container);
113
- const anchor = getInlineOption(el, "anchor");
114
116
  const inlineAnchorPlacement = getInlineOption(el, "anchor-placement");
115
117
  const additionalOffset = Number(getInlineOption(el, "offset", inlineAnchorPlacement ? 0 : defaultOffset));
116
118
  const anchorPlacement = inlineAnchorPlacement || defaultAnchorPlacement;
117
- let finalEl = el;
118
- if (anchor) {
119
- const queryResult = (container === window ? document : container).querySelector(anchor);
120
- if (queryResult)
121
- finalEl = queryResult;
119
+ const finalEl = getAnchor(el, container);
120
+ let triggerPoint = getOffsetTop(finalEl, container) - containerHeight;
121
+ const [elementPart, viewportPart] = anchorPlacement.split("-");
122
+ if (viewportPart === "center") {
123
+ triggerPoint += containerHeight / 2;
124
+ }
125
+ else if (viewportPart === "top") {
126
+ triggerPoint += containerHeight;
122
127
  }
123
- let triggerPoint = getOffset(finalEl, container).top - containerHeight;
124
- switch (anchorPlacement) {
125
- case "top-bottom":
126
- // Default offset
127
- break;
128
- case "center-bottom":
129
- triggerPoint += finalEl.offsetHeight / 2;
130
- break;
131
- case "bottom-bottom":
132
- triggerPoint += finalEl.offsetHeight;
133
- break;
134
- case "top-center":
135
- triggerPoint += containerHeight / 2;
136
- break;
137
- case "center-center":
138
- triggerPoint += containerHeight / 2 + finalEl.offsetHeight / 2;
139
- break;
140
- case "bottom-center":
141
- triggerPoint += containerHeight / 2 + finalEl.offsetHeight;
142
- break;
143
- case "top-top":
144
- triggerPoint += containerHeight;
145
- break;
146
- case "bottom-top":
147
- triggerPoint += containerHeight + finalEl.offsetHeight;
148
- break;
149
- case "center-top":
150
- triggerPoint += containerHeight + finalEl.offsetHeight / 2;
151
- break;
128
+ if (elementPart === "center") {
129
+ triggerPoint += finalEl.offsetHeight / 2;
130
+ }
131
+ else if (elementPart === "bottom") {
132
+ triggerPoint += finalEl.offsetHeight;
152
133
  }
153
134
  return triggerPoint + additionalOffset;
154
135
  };
155
136
  const getPositionOut = (el, defaultOffset, container) => {
156
- const anchor = getInlineOption(el, "anchor");
157
137
  const additionalOffset = getInlineOption(el, "offset", defaultOffset);
158
- let finalEl = el;
159
- if (anchor) {
160
- const queryResult = (container === window ? document : container).querySelector(anchor);
161
- if (queryResult)
162
- finalEl = queryResult;
163
- }
164
- const elementOffsetTop = getOffset(finalEl, container).top;
165
- return elementOffsetTop + finalEl.offsetHeight - additionalOffset;
138
+ const finalEl = getAnchor(el, container);
139
+ return (getOffsetTop(finalEl, container) + finalEl.offsetHeight - additionalOffset);
166
140
  };
167
141
 
168
142
  function prepare(elements, options, container) {
@@ -252,7 +226,7 @@ class Aos {
252
226
  (optionDisable === "mobile" && detect.mobile()) ||
253
227
  (optionDisable === "phone" && detect.phone()) ||
254
228
  (optionDisable === "tablet" && detect.tablet()) ||
255
- (typeof optionDisable === "function" && optionDisable() === true));
229
+ (typeof optionDisable === "function" && optionDisable()));
256
230
  }
257
231
  initializeScroll() {
258
232
  const { container } = this;
package/dist/aos.esm.js CHANGED
@@ -2,35 +2,34 @@ function debounce(func, delay) {
2
2
  let timeoutId;
3
3
  return (...args) => {
4
4
  clearTimeout(timeoutId);
5
- timeoutId = setTimeout(() => {
6
- func.apply(this, args);
7
- }, delay);
5
+ timeoutId = setTimeout(() => func(...args), delay);
8
6
  };
9
7
  }
10
8
  function throttle(func, limit) {
11
9
  let lastFunc, lastRan;
12
10
  return (...args) => {
13
- const context = this;
14
- if (!lastRan || Date.now() - lastRan >= limit) {
15
- func.apply(context, args);
16
- lastRan = Date.now();
11
+ const now = Date.now();
12
+ if (!lastRan || now - lastRan >= limit) {
13
+ func(...args);
14
+ lastRan = now;
17
15
  }
18
16
  else {
19
17
  clearTimeout(lastFunc);
20
18
  lastFunc = setTimeout(() => {
21
- func.apply(context, args);
19
+ func(...args);
22
20
  lastRan = Date.now();
23
- }, limit - (Date.now() - lastRan));
21
+ }, limit - (now - lastRan));
24
22
  }
25
23
  };
26
24
  }
27
25
 
28
26
  const phoneRe = /iphone|ipod|android.*mobile|windows phone|blackberry|opera mini|mobile|phone/i;
29
27
  const tabletRe = /ipad|android(?!.*mobile)|tablet|kindle/i;
28
+ const check = (regex) => regex.test(navigator.userAgent);
30
29
  var detect = {
31
- phone: () => phoneRe.test(navigator.userAgent),
32
- mobile: () => phoneRe.test(navigator.userAgent) || tabletRe.test(navigator.userAgent),
33
- tablet: () => tabletRe.test(navigator.userAgent),
30
+ phone: () => check(phoneRe),
31
+ mobile: () => check(phoneRe) || check(tabletRe),
32
+ tablet: () => check(tabletRe),
34
33
  };
35
34
 
36
35
  const resolveContainer = (container) => {
@@ -51,8 +50,8 @@ const getElementOffset = (container) => {
51
50
  : container.scrollTop;
52
51
  };
53
52
 
54
- const fireEvent = (eventName, data) => document.dispatchEvent(new CustomEvent(eventName, {
55
- detail: data,
53
+ const fireEvent = (eventName, detail) => document.dispatchEvent(new CustomEvent(eventName, {
54
+ detail,
56
55
  }));
57
56
  const toggleClasses = (el, isVisible) => {
58
57
  if (el.animated === isVisible)
@@ -92,75 +91,50 @@ var getInlineOption = (el, key, fallback) => {
92
91
  return attr || fallback;
93
92
  };
94
93
 
95
- const getOffset = function (el, container) {
96
- let left = 0;
94
+ const getOffsetTop = function (el, container) {
97
95
  let top = 0;
98
96
  while (el) {
99
- left += el.offsetLeft - (el.tagName != "BODY" ? el.scrollLeft : 0);
100
97
  top += el.offsetTop - (el.tagName != "BODY" ? el.scrollTop : 0);
101
98
  el =
102
99
  el.offsetParent === container ? null : el.offsetParent;
103
100
  }
104
- return {
105
- top,
106
- left,
107
- };
101
+ return top;
102
+ };
103
+ const getAnchor = (el, container) => {
104
+ const anchor = getInlineOption(el, "anchor");
105
+ if (anchor) {
106
+ const queryResult = (container === window ? document : container).querySelector(anchor);
107
+ if (queryResult)
108
+ return queryResult;
109
+ }
110
+ return el;
108
111
  };
109
112
  const getPositionIn = (el, defaultOffset, defaultAnchorPlacement, container) => {
110
113
  const containerHeight = getElementHeight(container);
111
- const anchor = getInlineOption(el, "anchor");
112
114
  const inlineAnchorPlacement = getInlineOption(el, "anchor-placement");
113
115
  const additionalOffset = Number(getInlineOption(el, "offset", inlineAnchorPlacement ? 0 : defaultOffset));
114
116
  const anchorPlacement = inlineAnchorPlacement || defaultAnchorPlacement;
115
- let finalEl = el;
116
- if (anchor) {
117
- const queryResult = (container === window ? document : container).querySelector(anchor);
118
- if (queryResult)
119
- finalEl = queryResult;
117
+ const finalEl = getAnchor(el, container);
118
+ let triggerPoint = getOffsetTop(finalEl, container) - containerHeight;
119
+ const [elementPart, viewportPart] = anchorPlacement.split("-");
120
+ if (viewportPart === "center") {
121
+ triggerPoint += containerHeight / 2;
122
+ }
123
+ else if (viewportPart === "top") {
124
+ triggerPoint += containerHeight;
120
125
  }
121
- let triggerPoint = getOffset(finalEl, container).top - containerHeight;
122
- switch (anchorPlacement) {
123
- case "top-bottom":
124
- // Default offset
125
- break;
126
- case "center-bottom":
127
- triggerPoint += finalEl.offsetHeight / 2;
128
- break;
129
- case "bottom-bottom":
130
- triggerPoint += finalEl.offsetHeight;
131
- break;
132
- case "top-center":
133
- triggerPoint += containerHeight / 2;
134
- break;
135
- case "center-center":
136
- triggerPoint += containerHeight / 2 + finalEl.offsetHeight / 2;
137
- break;
138
- case "bottom-center":
139
- triggerPoint += containerHeight / 2 + finalEl.offsetHeight;
140
- break;
141
- case "top-top":
142
- triggerPoint += containerHeight;
143
- break;
144
- case "bottom-top":
145
- triggerPoint += containerHeight + finalEl.offsetHeight;
146
- break;
147
- case "center-top":
148
- triggerPoint += containerHeight + finalEl.offsetHeight / 2;
149
- break;
126
+ if (elementPart === "center") {
127
+ triggerPoint += finalEl.offsetHeight / 2;
128
+ }
129
+ else if (elementPart === "bottom") {
130
+ triggerPoint += finalEl.offsetHeight;
150
131
  }
151
132
  return triggerPoint + additionalOffset;
152
133
  };
153
134
  const getPositionOut = (el, defaultOffset, container) => {
154
- const anchor = getInlineOption(el, "anchor");
155
135
  const additionalOffset = getInlineOption(el, "offset", defaultOffset);
156
- let finalEl = el;
157
- if (anchor) {
158
- const queryResult = (container === window ? document : container).querySelector(anchor);
159
- if (queryResult)
160
- finalEl = queryResult;
161
- }
162
- const elementOffsetTop = getOffset(finalEl, container).top;
163
- return elementOffsetTop + finalEl.offsetHeight - additionalOffset;
136
+ const finalEl = getAnchor(el, container);
137
+ return (getOffsetTop(finalEl, container) + finalEl.offsetHeight - additionalOffset);
164
138
  };
165
139
 
166
140
  function prepare(elements, options, container) {
@@ -250,7 +224,7 @@ class Aos {
250
224
  (optionDisable === "mobile" && detect.mobile()) ||
251
225
  (optionDisable === "phone" && detect.phone()) ||
252
226
  (optionDisable === "tablet" && detect.tablet()) ||
253
- (typeof optionDisable === "function" && optionDisable() === true));
227
+ (typeof optionDisable === "function" && optionDisable()));
254
228
  }
255
229
  initializeScroll() {
256
230
  const { container } = this;
package/dist/aos.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).AOS=t()}(this,(function(){"use strict";const e=/iphone|ipod|android.*mobile|windows phone|blackberry|opera mini|mobile|phone/i,t=/ipad|android(?!.*mobile)|tablet|kindle/i;var s=()=>e.test(navigator.userAgent),n=()=>e.test(navigator.userAgent)||t.test(navigator.userAgent),i=()=>t.test(navigator.userAgent);const o=(e,t)=>document.dispatchEvent(new CustomEvent(e,{detail:t})),a=(e,t)=>{if(e.animated===t)return;const{options:s,node:n}=e,i=t?"aos:in":"aos:out",a=t?"add":"remove";s.animatedClassNames?.forEach((e=>n.classList[a](e))),o(i,n),s.id&&o(`${i}:${s.id}`,n),e.animated=t};var r=(e,t)=>{e.forEach((e=>((e,t)=>{const{options:s,position:n}=e;s.mirror&&t>=n.out&&!s.once?a(e,!1):t>=n.in?a(e,!0):e.animated&&!s.once&&a(e,!1)})(e,(e=>e===window?e.pageYOffset:e.scrollTop)(t))))},l=(e,t,s)=>{const n=e.getAttribute(`data-aos-${t}`);return"true"===n||"false"!==n&&(n||s)};const d=function(e,t){let s=0,n=0;for(;e;)s+=e.offsetLeft-("BODY"!=e.tagName?e.scrollLeft:0),n+=e.offsetTop-("BODY"!=e.tagName?e.scrollTop:0),e=e.offsetParent===t?null:e.offsetParent;return{top:n,left:s}},c=(e,t,s,n)=>{const i=(e=>e===window?e.innerHeight:e.clientHeight)(n),o=l(e,"anchor"),a=l(e,"anchor-placement"),r=Number(l(e,"offset",a?0:t)),c=a||s;let h=e;if(o){const e=(n===window?document:n).querySelector(o);e&&(h=e)}let m=d(h,n).top-i;switch(c){case"top-bottom":break;case"center-bottom":m+=h.offsetHeight/2;break;case"bottom-bottom":m+=h.offsetHeight;break;case"top-center":m+=i/2;break;case"center-center":m+=i/2+h.offsetHeight/2;break;case"bottom-center":m+=i/2+h.offsetHeight;break;case"top-top":m+=i;break;case"bottom-top":m+=i+h.offsetHeight;break;case"center-top":m+=i+h.offsetHeight/2}return m+r},h=(e,t,s)=>{const n=l(e,"anchor"),i=l(e,"offset",t);let o=e;if(n){const e=(s===window?document:s).querySelector(n);e&&(o=e)}return d(o,s).top+o.offsetHeight-i};const m=e=>[...e].some((e=>e.dataset?.aos||e.children&&m(e.children))),u={offset:120,delay:0,easing:"ease",duration:400,disable:!1,once:!1,mirror:!1,anchorPlacement:"top-bottom",startEvent:"DOMContentLoaded",animatedClassName:"aos-animate",initClassName:"aos-init",useClassNames:!1,disableMutationObserver:!1,throttleDelay:99,debounceDelay:50,container:window};class f{elements=[];initialized=!1;options=u;container=null;observer=null;scrollHandler=null;resizeHandler=null;startHandler=null;static getElements(e){return[...(e===window?document:e).querySelectorAll("[data-aos]")].map((e=>({node:e})))}static isDisabled(e){return!0===e||"mobile"===e&&n()||"phone"===e&&s()||"tablet"===e&&i()||"function"==typeof e&&!0===e()}initializeScroll(){const{container:e}=this;return this.elements=function(e,t,s){return e.forEach((e=>{const{node:n}=e,i=l(n,"mirror",t.mirror),o=l(n,"once",t.once),a=l(n,"id"),r=t.useClassNames&&n.getAttribute("data-aos")?.split(" ")||[],d=[t.animatedClassName,...r].filter((e=>"string"==typeof e));t.initClassName&&n.classList.add(t.initClassName),e.position={in:c(n,t.offset,t.anchorPlacement,s),out:i&&h(n,t.offset,s)},e.options={once:o,mirror:i,animatedClassNames:d,id:a}})),e}(this.elements,this.options,e),r(this.elements,this.container),this.scrollHandler=function(e,t){let s,n;return(...i)=>{const o=this;!n||Date.now()-n>=t?(e.apply(o,i),n=Date.now()):(clearTimeout(s),s=setTimeout((()=>{e.apply(o,i),n=Date.now()}),t-(Date.now()-n)))}}((()=>{r(this.elements,e)}),this.options.throttleDelay),e.addEventListener("scroll",this.scrollHandler,{passive:!0}),this.elements}init(e={}){this.destroy(),this.options={...u,...e};const t=(e=>e instanceof Element||e===window?e:"string"==typeof e?document.querySelector(e):null)(this.options.container);if(!t)throw"AOS - cannot find the container element. The container option must be an HTMLElement or a CSS Selector.";if(this.elements=f.getElements(t),this.container=t,f.isDisabled(this.options.disable))return this.disable();this.options.disableMutationObserver||(this.observer=(e=>{const t=new MutationObserver((t=>{t?.some((({addedNodes:e,removedNodes:t})=>m([...e,...t])))&&e()}));return t.observe(document.documentElement,{childList:!0,subtree:!0}),t})(this.refreshHard.bind(this))),document.body.setAttribute("data-aos-easing",this.options.easing),document.body.setAttribute("data-aos-duration",this.options.duration),document.body.setAttribute("data-aos-delay",this.options.delay),this.startHandler={handler:this.refresh.bind(this),type:"document"},["DOMContentLoaded","load"].includes(this.options.startEvent)?(window.addEventListener("load",this.startHandler.handler),this.startHandler.type="window"):document.addEventListener(this.options.startEvent,this.startHandler.handler),"DOMContentLoaded"===this.options.startEvent&&["complete","interactive"].indexOf(document.readyState)>-1&&this.refresh(!0),this.resizeHandler=function(e,t){let s;return(...n)=>{clearTimeout(s),s=setTimeout((()=>{e.apply(this,n)}),t)}}(this.refresh.bind(this),this.options.debounceDelay),window.addEventListener("resize",this.resizeHandler),window.addEventListener("orientationchange",this.resizeHandler)}refresh(e=!1){e&&(this.initialized=!0),this.initialized&&this.initializeScroll()}refreshHard(){if(this.elements=f.getElements(this.container),f.isDisabled(this.options.disable))return this.disable();this.refresh()}disable(){this.elements.forEach((({node:e})=>{e.removeAttribute("data-aos"),e.removeAttribute("data-aos-easing"),e.removeAttribute("data-aos-duration"),e.removeAttribute("data-aos-delay"),this.options.initClassName&&e.classList.remove(this.options.initClassName),this.options.animatedClassName&&e.classList.remove(this.options.animatedClassName)}))}destroy(){if(this.observer?.disconnect(),this.observer=null,this.startHandler){const{handler:e,type:t}=this.startHandler;"document"===t?document.removeEventListener(this.options.startEvent,e):window.removeEventListener("load",e),this.startHandler=null}this.scrollHandler&&(window.removeEventListener("scroll",this.scrollHandler),this.scrollHandler=null),this.resizeHandler&&(window.removeEventListener("resize",this.resizeHandler),window.removeEventListener("orientationchange",this.resizeHandler),this.resizeHandler=null)}}return new f}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).AOS=t()}(this,(function(){"use strict";const e=/iphone|ipod|android.*mobile|windows phone|blackberry|opera mini|mobile|phone/i,t=/ipad|android(?!.*mobile)|tablet|kindle/i,n=e=>e.test(navigator.userAgent),i=(e,t)=>document.dispatchEvent(new CustomEvent(e,{detail:t})),s=(e,t)=>{if(e.animated===t)return;const{options:n,node:s}=e,o=t?"aos:in":"aos:out",a=t?"add":"remove";n.animatedClassNames?.forEach((e=>s.classList[a](e))),i(o,s),n.id&&i(`${o}:${n.id}`,s),e.animated=t};var o=(e,t)=>{e.forEach((e=>((e,t)=>{const{options:n,position:i}=e;n.mirror&&t>=i.out&&!n.once?s(e,!1):t>=i.in?s(e,!0):e.animated&&!n.once&&s(e,!1)})(e,(e=>e===window?e.pageYOffset:e.scrollTop)(t))))},a=(e,t,n)=>{const i=e.getAttribute(`data-aos-${t}`);return"true"===i||"false"!==i&&(i||n)};const r=function(e,t){let n=0;for(;e;)n+=e.offsetTop-("BODY"!=e.tagName?e.scrollTop:0),e=e.offsetParent===t?null:e.offsetParent;return n},l=(e,t)=>{const n=a(e,"anchor");if(n){const e=(t===window?document:t).querySelector(n);if(e)return e}return e},d=(e,t,n,i)=>{const s=(e=>e===window?e.innerHeight:e.clientHeight)(i),o=a(e,"anchor-placement"),d=Number(a(e,"offset",o?0:t)),c=o||n,h=l(e,i);let m=r(h,i)-s;const[u,f]=c.split("-");return"center"===f?m+=s/2:"top"===f&&(m+=s),"center"===u?m+=h.offsetHeight/2:"bottom"===u&&(m+=h.offsetHeight),m+d},c=(e,t,n)=>{const i=a(e,"offset",t),s=l(e,n);return r(s,n)+s.offsetHeight-i},h=e=>[...e].some((e=>e.dataset?.aos||e.children&&h(e.children))),m={offset:120,delay:0,easing:"ease",duration:400,disable:!1,once:!1,mirror:!1,anchorPlacement:"top-bottom",startEvent:"DOMContentLoaded",animatedClassName:"aos-animate",initClassName:"aos-init",useClassNames:!1,disableMutationObserver:!1,throttleDelay:99,debounceDelay:50,container:window};class u{elements=[];initialized=!1;options=m;container=null;observer=null;scrollHandler=null;resizeHandler=null;startHandler=null;static getElements(e){return[...(e===window?document:e).querySelectorAll("[data-aos]")].map((e=>({node:e})))}static isDisabled(i){return!0===i||"mobile"===i&&(n(e)||n(t))||"phone"===i&&n(e)||"tablet"===i&&n(t)||"function"==typeof i&&i()}initializeScroll(){const{container:e}=this;return this.elements=function(e,t,n){return e.forEach((e=>{const{node:i}=e,s=a(i,"mirror",t.mirror),o=a(i,"once",t.once),r=a(i,"id"),l=t.useClassNames&&i.getAttribute("data-aos")?.split(" ")||[],h=[t.animatedClassName,...l].filter((e=>"string"==typeof e));t.initClassName&&i.classList.add(t.initClassName),e.position={in:d(i,t.offset,t.anchorPlacement,n),out:s&&c(i,t.offset,n)},e.options={once:o,mirror:s,animatedClassNames:h,id:r}})),e}(this.elements,this.options,e),o(this.elements,this.container),this.scrollHandler=function(e,t){let n,i;return(...s)=>{const o=Date.now();!i||o-i>=t?(e(...s),i=o):(clearTimeout(n),n=setTimeout((()=>{e(...s),i=Date.now()}),t-(o-i)))}}((()=>{o(this.elements,e)}),this.options.throttleDelay),e.addEventListener("scroll",this.scrollHandler,{passive:!0}),this.elements}init(e={}){this.destroy(),this.options={...m,...e};const t=(e=>e instanceof Element||e===window?e:"string"==typeof e?document.querySelector(e):null)(this.options.container);if(!t)throw"AOS - cannot find the container element. The container option must be an HTMLElement or a CSS Selector.";if(this.elements=u.getElements(t),this.container=t,u.isDisabled(this.options.disable))return this.disable();this.options.disableMutationObserver||(this.observer=(e=>{const t=new MutationObserver((t=>{t?.some((({addedNodes:e,removedNodes:t})=>h([...e,...t])))&&e()}));return t.observe(document.documentElement,{childList:!0,subtree:!0}),t})(this.refreshHard.bind(this))),document.body.setAttribute("data-aos-easing",this.options.easing),document.body.setAttribute("data-aos-duration",this.options.duration),document.body.setAttribute("data-aos-delay",this.options.delay),this.startHandler={handler:this.refresh.bind(this),type:"document"},["DOMContentLoaded","load"].includes(this.options.startEvent)?(window.addEventListener("load",this.startHandler.handler),this.startHandler.type="window"):document.addEventListener(this.options.startEvent,this.startHandler.handler),"DOMContentLoaded"===this.options.startEvent&&["complete","interactive"].indexOf(document.readyState)>-1&&this.refresh(!0),this.resizeHandler=function(e,t){let n;return(...i)=>{clearTimeout(n),n=setTimeout((()=>e(...i)),t)}}(this.refresh.bind(this),this.options.debounceDelay),window.addEventListener("resize",this.resizeHandler),window.addEventListener("orientationchange",this.resizeHandler)}refresh(e=!1){e&&(this.initialized=!0),this.initialized&&this.initializeScroll()}refreshHard(){if(this.elements=u.getElements(this.container),u.isDisabled(this.options.disable))return this.disable();this.refresh()}disable(){this.elements.forEach((({node:e})=>{e.removeAttribute("data-aos"),e.removeAttribute("data-aos-easing"),e.removeAttribute("data-aos-duration"),e.removeAttribute("data-aos-delay"),this.options.initClassName&&e.classList.remove(this.options.initClassName),this.options.animatedClassName&&e.classList.remove(this.options.animatedClassName)}))}destroy(){if(this.observer?.disconnect(),this.observer=null,this.startHandler){const{handler:e,type:t}=this.startHandler;"document"===t?document.removeEventListener(this.options.startEvent,e):window.removeEventListener("load",e),this.startHandler=null}this.scrollHandler&&(window.removeEventListener("scroll",this.scrollHandler),this.scrollHandler=null),this.resizeHandler&&(window.removeEventListener("resize",this.resizeHandler),window.removeEventListener("orientationchange",this.resizeHandler),this.resizeHandler=null)}}return new u}));
package/package.json CHANGED
@@ -1,25 +1,44 @@
1
1
  {
2
2
  "name": "@reimujs/aos",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "main": "dist/aos.cjs.js",
5
5
  "module": "dist/aos.esm.js",
6
6
  "browser": "dist/aos.umd.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
- "build": "rollup -c"
9
+ "build": "rollup -c",
10
+ "test": "vitest run",
11
+ "test-cov": "vitest run --coverage"
10
12
  },
13
+ "files": [
14
+ "dist",
15
+ "LICENSE",
16
+ "LICENSE-aos"
17
+ ],
18
+ "keywords": [
19
+ "aos",
20
+ "animate",
21
+ "scroll",
22
+ "animation",
23
+ "library",
24
+ "javascript",
25
+ "typescript"
26
+ ],
11
27
  "author": "D-Sketon",
12
28
  "license": "MIT",
13
29
  "description": "Animate on scroll library",
14
30
  "devDependencies": {
15
- "@rollup/plugin-node-resolve": "^15.3.0",
31
+ "@rollup/plugin-node-resolve": "^16.0.3",
16
32
  "@rollup/plugin-terser": "^0.4.4",
17
- "@rollup/plugin-typescript": "^12.1.4",
18
- "rollup": "^4.44.2",
33
+ "@rollup/plugin-typescript": "^12.3.0",
34
+ "@vitest/coverage-v8": "^4.0.14",
35
+ "jsdom": "^27.2.0",
36
+ "rollup": "^4.53.3",
19
37
  "rollup-plugin-scss": "^3.0.0",
20
- "sass": "^1.89.2",
38
+ "sass": "^1.94.2",
21
39
  "tslib": "^2.8.1",
22
- "typescript": "^5.8.3"
40
+ "typescript": "^5.9.3",
41
+ "vitest": "^4.0.14"
23
42
  },
24
43
  "repository": {
25
44
  "type": "git",