{"id":17036003,"url":"https://github.com/phucbm/cuajs","last_synced_at":"2025-09-03T00:33:21.749Z","repository":{"id":177225320,"uuid":"656604112","full_name":"phucbm/cuajs","owner":"phucbm","description":"Crab-walk through your website with CuaJs.","archived":false,"fork":false,"pushed_at":"2024-10-24T02:16:17.000Z","size":538,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-12T13:14:12.511Z","etag":null,"topics":["horizontal-scrolling","lenis","smooth-scrolling"],"latest_commit_sha":null,"homepage":"https://cuajs.netlify.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phucbm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-21T09:18:46.000Z","updated_at":"2024-10-24T02:16:20.000Z","dependencies_parsed_at":"2024-10-22T17:34:29.843Z","dependency_job_id":null,"html_url":"https://github.com/phucbm/cuajs","commit_stats":null,"previous_names":["phucbm/cuajs"],"tags_count":4,"template":false,"template_full_name":"phucbm/js-webpack-boilerplate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phucbm%2Fcuajs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phucbm%2Fcuajs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phucbm%2Fcuajs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phucbm%2Fcuajs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phucbm","download_url":"https://codeload.github.com/phucbm/cuajs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248571839,"owners_count":21126522,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["horizontal-scrolling","lenis","smooth-scrolling"],"created_at":"2024-10-14T08:48:54.828Z","updated_at":"2025-09-03T00:33:21.732Z","avatar_url":"https://github.com/phucbm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n![banner](https://github.com/phucbm/cuajs/assets/14942380/c68bba3d-cbcc-4a2b-853d-1f898426d29d)\n\n[![npm version](https://badgen.net/npm/v/cuajs?icon=npm)](https://www.npmjs.com/package/cuajs)\n[![npm downloads](https://badgen.net/npm/dm/cuajs?icon=npm)](https://www.npmjs.com/package/cuajs)\n[![npm dependents](https://badgen.net/npm/dependents/cuajs?icon=npm)](https://www.npmjs.com/package/cuajs)\n[![github stars](https://badgen.net/github/stars/phucbm/cuajs?icon=github)](https://github.com/phucbm/cuajs/)\n[![jsdelivr hits](https://badgen.net/jsdelivr/hits/gh/phucbm/cuajs?icon=jsdelivr)](https://www.jsdelivr.com/package/gh/phucbm/cuajs)\n[![jsdelivr npm rank](https://badgen.net/jsdelivr/rank/npm/cuajs?icon=npm)](https://www.npmjs.com/package/cuajs)\n[![github license](https://badgen.net/github/license/phucbm/cuajs?icon=github)](https://github.com/phucbm/cuajs/blob/main/LICENSE)\n[![Made in Vietnam](https://raw.githubusercontent.com/webuild-community/badge/master/svg/made.svg)](https://webuild.community)\n[![Netlify Status](https://api.netlify.com/api/v1/badges/315eb0d1-7cd6-420c-abca-08ac09fde584/deploy-status)](https://app.netlify.com/sites/cuajs/deploys)\n\n**Why scroll down when you can *cua* across?**\n\n_(Cua is a Vietnamese word for crab)_\n\u003cp\u003e\u003cimg src=\"https://github.com/phucbm/cuajs/assets/14942380/321169e6-c33f-4e0c-9c71-67992b347ed4\" width=\"150\"\u003e\u003c/p\u003e\n\n\u003c/div\u003e\n\n## Introduction\n\nCuaJs is a lightweight, powerful JavaScript library that transforms traditional vertical scrolling into a smooth,\nintuitive horizontal experience.\nWith Lenis smooth scrolling deeply integrated for fluid animations, it delivers buttery-smooth transitions and\nscroll-based effects.\nNamed after the Vietnamese word for crab, CuaJs brings a sideways 'crab walk' to web navigation.\nSee [Demo](https://cuajs.netlify.app).\n\n### Key Features\n\n- 🖱️ **Native Scrollbar Respect**: Maintains browser scrollbar functionality for optimal accessibility.\n- 🔗 **Seamless Integration**: Preserves default scrolling events without DOM manipulation.\n- 📱 **Cross-Device Compatibility**: Fully tested on keyboard, trackpad, mouse wheel, and touch screens.\n- 📐 **Responsive Design**: Automatically switches to vertical scrolling on mobile devices.\n- 🧈 **Smooth Scrolling**: Integrates beautifully with Lenis for a buttery-smooth scroll experience.\n- 🚀 **Easy Implementation**: Simple HTML data attributes for quick setup and customization.\n- 🧭 **Flexible Navigation**: Supports programmatic scrolling to specific sections or positions.\n\nCuaJs offers web developers a unique tool to create engaging, horizontally-scrolling websites without sacrificing\nusability or accessibility.\nWhether you're building a portfolio, product showcase, or innovative web experience, CuaJs provides the framework for\nsmooth, intuitive sideways navigation.\n\n## Installation\n\nCuaJs can run independently, but integrating [Lenis](https://github.com/studio-freight/lenis) unlocks enhanced features\nlike butter-smooth animations, optimized scroll transitions, and improved cross-browser scrolling behavior.\n\n### Download\n\nUsing a package manager:\n\n```shell\nnpm i @studio-freight/lenis\nnpm i cuajs\n```\n\n```js\nimport Lenis from '@studio-freight/lenis'\nimport \"cuajs\";\n```\n\nUsing CDN:\n\n```html\n\u003c!-- Lenis smooth scroll --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/gh/studio-freight/lenis@1/bundled/lenis.min.js\"\u003e\u003c/script\u003e\n\n\u003c!-- CuaJs --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/gh/phucbm/cuajs@0.0.5/dist/cua.min.js\"\u003e\u003c/script\u003e\n\n\u003c!-- Cua Animate (optional, for animation only) --\u003e\n\u003clink rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/phucbm/cuajs@0.0.5/dist/cua-animate.css\"\u003e\n```\n\n### Quick start\n\n#### 1. HTML setup\n\n```html\n\u003c!-- [data-cua] must be defined --\u003e\n\u003cdiv data-cua\u003e\n    \u003c!-- Each child of wrapper must have [data-cua-section] --\u003e\n    \u003csection data-cua-section\u003e\u003c/section\u003e\n    \u003csection data-cua-section\u003e\u003c/section\u003e\n\u003c/div\u003e\n```\n\nSetting options via HTML\n\n```html\n\u003cdiv data-cua='{\"verticalBreakpoint\":\"1024\"}'\u003e\n\u003c/div\u003e\n```\n\n#### 2. JavaScript setup\n\n```js\nconst instance = CuaJs.init({\n    wrapper: document.querySelector('.wrapper')\n});\n```\n\nAfter `init()`, you can either use `instance` which is returned from the init function, or `CuaInstance` to access methods.\n\n## API\n\n### Options\n\n| Attribute              | Type        | Default     | Description                                                                 |\n|------------------------|-------------|-------------|-----------------------------------------------------------------------------|\n| `wrapper`              | DOM element | `undefined` | Required. Wrapper element.                                                  |\n| `smoothScroll`         | boolean     | `true`      | Enable smooth scroll                                                        |\n| `verticalBreakpoint`   | number      | `1024`      | Switch to vertical layout mode when `window.innerWidth \u003c= 1024`             |\n| `smoothVerticalScroll` | boolean     | `true`      | Enable smooth scroll for vertical layout mode                               |\n| `keyScrollDistance`    | number      | `200`       | Distance to scroll on each key press (px)                                   |\n| `keyScroll`            | boolean     | `true`      | Enable navigate by a arrow key                                              |\n| `onScrollableContent`  | function    | `undefined` | Callback on each scrollable content                                         |\n| `once`                 | boolean     | `true`      | *Scroll Observer*: Only run \"enter\" callback once.                          |\n| `rootMargin`           | string      | `0px`       | *Scroll Observer*: Margin around the viewport for intersection calculations |\n| `threshold`            | number      | `0.1`       | *Scroll Observer*: Percentage of element visibility to trigger intersection |\n| `draggable`            | boolean     | `false`     | Enable drag to scroll                                                       |\n| `scrollSnap`           | boolean     | `false`     | Snap to the nearest section                                                 |\n\n### Methods\n\n| Name                   | Usage                                                                    | Description                                    | \n|------------------------|--------------------------------------------------------------------------|------------------------------------------------|\n| `assignScrollObserver` | `CuaInstance.assignScrollObserver({element, options, enter,leave,once})` | Assign a scroll observer to a specific element |\n| `on`                   | `CuaInstance.on()`                                                       | Assign events                                  |\n\n### Events\n\nAssign `onScroll` event:\n\n```js\nCuaInstance.on('onScroll', (data) =\u003e {\n    console.log(data.axis, data.progress);\n\n    // more info\n    console.log(data);\n});\n```\n\n```js\nCuaInstance.on('onSectionChange', ({index, instance, section}) =\u003e {\n    console.log(`Active index`, index);\n});\n```\n\n## Features\n### data-cua-observe\nScroll Observer is a functionality that utilizes Intersection Observer to monitor a specific element and trigger a callback function when that element enters or exits the viewport. This feature is particularly useful for creating animations that appear as elements come into view.\n\nBy default, Scroll Observer adds the class `\"cua-intersection\"` to an element when it enters the viewport and removes this class when the element leaves. To activate this default behavior, simply add the attribute `data-cua-observe` to the desired element.\n\n```html\n\u003cdiv data-cua\u003e\n    \u003csection data-cua-section\u003e\n        \u003cdiv data-cua-observe\u003e\n            Item with scroll observer\n        \u003c/div\u003e\n    \u003c/section\u003e\n\u003c/div\u003e\n```\n\n\nFor more customized control, you can define a custom observer using the `assignScrollObserver` function. Here's an example of how to implement this:\n\n```js\nCuaInstance.assignScrollObserver({\n    element: document.querySelector('.my-element'),\n    options: {\n        rootMargin: '0px',\n        threshold: 0.5,\n        once: true\n    },\n    enter: (entry) =\u003e {\n        console.log('Element entered viewport:', entry.target);\n        // Add your enter logic here\n    },\n    leave: (entry) =\u003e {\n        console.log('Element left viewport:', entry.target);\n        // Add your leave logic here\n    }\n});\n```\n\n### data-cua-animate\n\nWhen Lenis is enabled, CuaJs exposes scroll velocity through the CSS variable `--scroll-velocity` on the wrapper\nelement.\nThis enables powerful scroll-based animations like parallax effects, scroll-triggered animations, and more.\n\nAdd animations using data-cua-animate with values like \"mask\", \"tilt\", or \"fade-in\". \nCreate custom scroll animations using CSS variables `--scroll-velocity`, `--scroll-progress`, and `--scroll-direction`. Check demos at https://cuajs.netlify.app.\n\n## Deployment\n\n```shell\n# Install\nnpm i\n\n# Run dev server\nnpm run dev\n\n# Build dev site\nnpm run build\n\n# Generate production files\nnpm run prod\n```\n\n## License\n\n[MIT License](https://github.com/phucbm/cuajs/blob/main/LICENSE)\n\nCopyright (c) 2024 PHUCBM\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphucbm%2Fcuajs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphucbm%2Fcuajs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphucbm%2Fcuajs/lists"}