Asscroll
Ash's Smooth Scroll š
Install / Use
npx skills add ashthornton/asscrollInstalls into whichever agent you are using.
README
<h3 align="center"><strong>ASScroll is a Javascript hybrid smooth scroll setup that combines the<br>performance gains of virtual scroll with the reliability of native scroll.</strong></h3> <p align="center" style="padding: 0 15%">This setup aims to be a lightweight solution that provides a consistent smooth scrolling experience across all platforms, devices and hardware.</p>
Advantages over pure virtual scroll:
- Accessible and keyboard friendly (without overriding the browser's native scroll)
- No special cases to cater for when handling manual key detection (i.e. pressing space in a form input)
- Doesn't stop working when hovering over an iframe
- Handles hardware that doesn't fire the 'wheel' event i.e. Windows trackpads in Legacy Edge
- No lag between DOM and WebGL elements on mobile, whilst retaining native inertia scroll
Other Features:
- Horizontal scroll
- Custom scroll bar
- Use your own external RAF loop and resize events
- Consistent lerp speeds on high refresh rate displays
No animation features are included as there are other libraries that can be used with ASScroll. GreenSock's ScrollTrigger is a great example and a demo is included below
Demos
- Zero Config Demo
- Options Demo
- Using GSAP's ScrollTrigger with ASScroll
- Using PJAX Navigation (Highway) with ASScroll
- Touch-friendly DOM/WebGL Sync
Sites using ASScroll
Table of contents
<!--ts-->- Install
- Zero Config Setup
- API
- Custom Scrollbar
- External RAF Usage
- External Resize Usage
- Touch Devices
- Changelog
Install
npm i --save @ashthornton/asscroll or yarn add @ashthornton/asscroll
Also available via JSDelivr CDN which you can then include with a <script> tag.
Zero Config Setup
- Add the attribute
asscroll-containerto the parent element of the content to be smooth scrolled. By default, the first child found within will be scrolled. Both of these selectors be changed in the options.
<body>
<div asscroll-container>
<div><!-- The Y translation will be applied to this element --></div>
</div>
</body>
- Import and initialise in Javascript
import ASScroll from '@ashthornton/asscroll'
const asscroll = new ASScroll()
window.addEventListener('load', () => {
asscroll.enable()
})
<a name="ASScroll"></a>
ASScroll
Ash's Smooth Scroll š
- ASScroll
- new ASScroll([parameters])
- .targetPos ā <code>number</code>
- .currentPos ā <code>number</code>
- .maxScroll ā <code>number</code>
- .containerElement ā <code>HTMLElement</code>
- .scrollElements ā <code>Array</code>
- .isHorizontal ā <code>boolean</code>
- .isScrollJacking ā <code>boolean</code>
- ~~.scrollPos~~
- ~~.smoothScrollPos~~
- .enable([parameters])
- .disable([parameters])
- .update()
- .resize([parameters])
- .on(eventName, callback)
- .off(eventName, callback)
- .scrollTo(targetPos, [emitEvent])
- ~~.onRaf()~~
- ~~.onResize()~~
<a name="new_ASScroll_new"></a>
new ASScroll([parameters])
Creates an ASScroll instance
| Param | Type | Default | Description | | --- | --- | --- | --- | | [parameters] | <code>object</code> | | | | [parameters.containerElement] | <code>string</code> | <code>HTMLElement</code> | <code>"[asscroll-container]"</code> | The selector string for the outer container element, or the element itself | | [parameters.scrollElements] | <code>string</code> | <code>HTMLElement</code> | <code>NodeList</code> | <code>"[asscroll]"</code> | The selector string for the elements to scroll, or the elements themselves | | [parameters.ease] | <code>number</code> | <code>0.075</code> | The ease amount for the transform lerp | | [parameters.touchEase] | <code>number</code> | <code>1</code> | The ease amount for the transform lerp on touch devices | | [parameters.touchScrollType] | <code>string</code> | <code>"none"</code> | Set the scrolling method on touch devices. Other options are 'transform' and 'scrollTop'. See the Touch Devices section for more info | | [parameters.lockIOSBrowserUI] | <code>boolean</code> | <code>false</code> | When using an iOS device and touchScrollType is 'transform', this will change the setup to prevent the browser UI from showing/hiding to stop resize events on scroll. | | [parameters.scrollbarEl] | <code>string</code> | <code>".asscrollbar"</code> | The selector string for the custom scrollbar element | | [parameters.scrollbarHandleEl] | <code>string</code> | <code>".asscrollbar__handle"</code> | The selector string for the custom scrollbar handle element | | [parameters.customScrollbar] | <code>boolean</code> | <code>true</code> | Toggle the custom scrollbar | | [parameters.scrollbarStyles] | <code>boolean</code> | <code>true</code> | Include the scrollbar CSS via Javascript | | [parameters.disableNativeScrollbar] | <code>boolean</code> | <code>true</code> | Disable the native browser scrollbar | | [parameters.disableRaf] | <code>boolean</code> | <code>false</code> | Disable internal requestAnimationFrame loop in order to use an external one | | [parameters.disableResize] | <code>boolean</code> | <code>false</code> | Disable internal resize event on the window in order to use an external one | | [parameters.limitLerpRate] | <code>boolean</code> | <code>true</code> | Match lerp speed on >60Hz displays to that of a 60Hz display | | [parameters.blockScrollClass] | <code>string</code> | <code>".asscroll-block"</code> | The class to add to elements that should block ASScroll when hovered |
<a name="ASScroll+targetPos"></a>
asscroll.targetPos ā <code>number</code>
Returns the target scroll position.
Returns: <code>number</code> - Target scroll position
<a name="ASScroll+currentPos"></a>
asscroll.currentPos ā <code>number</code>
Gets or sets the current scroll position.
Returns: <code>number</code> - Current scroll position
| Param | Type | Description | | --- | --- | --- | | scrollPos | <code>number</code> | The desired scroll position |
Example (Sets the scroll position to 200, bypassing any lerps)
asscroll.currentPos = 200
<a name="ASScroll+maxScroll"></a>
asscroll.maxScroll ā <code>number</code>
Returns the maximum scroll height of the page.
Returns: <code>number</code> - Maxmium scroll height
<a name="ASScroll+containerElement"></a>
asscroll.containerElement ā <code>HTMLElement</code>
Returns the outer element that ASScroll is attached to.
Returns: <code>HTMLElement</code> - The outer element
<a name="ASScroll+scrollElements"></a>
asscroll.scrollElements ā <code>Array</code>
Returns the the element(s) that ASScroll is scrolling.
Returns: <code>Array</code> - An array of elements ASScroll is scrolling
<a name="ASScroll+isHorizontal"></a>
asscroll.isHorizontal ā <code>boolean</code>
Returns whether or not ASScroll is in horizontal scroll mode
Returns: <code>boolean</code> - The status of horizontal scroll
<a name="ASScroll+isScrollJacking"></a>
asscroll.isScrollJacking ā <code>boolean</code>
Returns whether or not ASScroll is actively transforming the page element(s). For example, would return false if running on a touch device and touchScrollType !== 'transform', or if ASScroll was currently disabled via the .disable() method.
Returns: <code>boolean</code> - The status of actively controlling the page scroll
<a name="ASScroll+scrollPos"></a>
~~asscroll.scrollPos~~
Deprecated
See: targetPos
<a name="ASScroll+smoothScrollPos"></a>
~~asscroll.smoothScrollPos~~
Deprecated
See: currentPos
<a name="ASScroll+enable"></a>
asscroll.enable([parame
Related Skills
node-connect
385.5kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
blender-python-addon
40.5kBlender Python add-on rules for operators, panels, properties, registration, testing, and API-safe scripting
flutter-development-guidelines-cursorrules-prompt-file
40.5kCursor rules for Flutter development with MVVM architecture, Riverpod state management, Material widgets, and Dart style guidelines.
commit-push-pr
140.7kCommit, push, and open a PR
