Welcome to Scroller Demo
198 |Click on any demo in the sidebar to get started
199 |├── .github └── workflows │ └── deploy-demos.yml ├── .gitignore ├── DEVELOPMENT.md ├── LICENSE.txt ├── README.md ├── biome.json ├── demo ├── asset │ ├── Tiling.js │ ├── render.js │ ├── ui.css │ └── ui.js ├── canvas.html ├── dom-list.html ├── dom-paging-x.html ├── dom-paging-y.html ├── dom-snapping.html ├── dom.html ├── easyscroller.html ├── index.html └── native.html ├── package-lock.json ├── package.json ├── rollup.config.js ├── scripts └── build-demos.js ├── scroller-1.3.0-dist.zip ├── src ├── Animate.js ├── EasyScroller.js ├── Scroller.js ├── index.js ├── umd-full.js └── umd.js ├── test ├── index.html ├── qunit.css ├── qunit.js └── test.js ├── tests ├── Animate.test.js ├── EasyScroller.test.js ├── Scroller.test.js └── setup.js └── vite.config.js /.github/workflows/deploy-demos.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Demos to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | workflow_dispatch: # Allow manual triggering 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | 12 | environment: 13 | name: github-pages 14 | url: ${{ steps.deployment.outputs.page_url }} 15 | 16 | permissions: 17 | contents: read 18 | pages: write 19 | id-token: write 20 | 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v4 24 | 25 | - name: Setup Node.js 26 | uses: actions/setup-node@v4 27 | with: 28 | node-version: '18' 29 | cache: 'npm' 30 | 31 | - name: Install dependencies 32 | run: npm ci 33 | 34 | - name: Build project and demos 35 | run: npm run build 36 | 37 | - name: Setup Pages 38 | uses: actions/configure-pages@v4 39 | 40 | - name: Upload artifact 41 | uses: actions/upload-pages-artifact@v3 42 | with: 43 | path: './dist/demo' 44 | 45 | - name: Deploy to GitHub Pages 46 | id: deployment 47 | uses: actions/deploy-pages@v4 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # macOS 2 | .DS_Store 3 | .DS_Store? 4 | ._* 5 | .Spotlight-V100 6 | .Trashes 7 | 8 | # Node.js 9 | node_modules/ 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Build output 15 | dist/ 16 | build/ 17 | out/ 18 | 19 | # Environment variables 20 | .env 21 | .env.local 22 | .env.development.local 23 | .env.test.local 24 | .env.production.local 25 | 26 | # Logs 27 | logs 28 | *.log 29 | 30 | # Runtime data 31 | pids 32 | *.pid 33 | *.seed 34 | *.pid.lock 35 | 36 | # Coverage directory used by tools like istanbul 37 | coverage/ 38 | .nyc_output/ 39 | *.lcov 40 | 41 | # IDEs and editors 42 | .vscode/ 43 | .idea/ 44 | *.swp 45 | *.swo 46 | *~ 47 | 48 | # OS generated files 49 | Thumbs.db 50 | ehthumbs.db 51 | 52 | # Temporary files 53 | *.tmp 54 | *.temp 55 | -------------------------------------------------------------------------------- /DEVELOPMENT.md: -------------------------------------------------------------------------------- 1 | # Development Guide 2 | 3 | Simple, unified development workflow for the Scroller library. 4 | 5 | ## Quick Start 6 | 7 | ### Development Mode (Hot Reloading) 8 | ```bash 9 | npm run dev 10 | ``` 11 | - Starts Vite dev server on `http://localhost:3000` 12 | - Demo pages default to loading from `src/` with hot reloading 13 | - Changes to source files automatically reload the browser 14 | 15 | ### Production Build 16 | ```bash 17 | npm run build 18 | ``` 19 | - Builds library bundles to `dist/` 20 | - Copies demo pages to `dist/demo/` with script tags updated to use built bundles 21 | 22 | ## How It Works 23 | 24 | ### Simple Script Loading 25 | Demo pages use a simple ES module script by default: 26 | 27 | ```html 28 | 29 | 33 | ``` 34 | 35 | During build, this gets replaced with: 36 | ```html 37 | 38 | 39 | ``` 40 | 41 | ### File Structure 42 | ``` 43 | demo/ 44 | ├── easyscroller.html # Default: loads from src/ 45 | ├── dom.html # Default: loads from src/ 46 | └── ... # All demos default to dev mode 47 | 48 | dist/ 49 | ├── scroller-full.umd.js # Built bundle 50 | └── demo/ # Production demo copies 51 | ├── easyscroller.html # Uses built bundle 52 | └── ... # All demos use built bundle 53 | ``` 54 | 55 | ## Development Workflow 56 | 57 | 1. **Start development**: `npm run dev` 58 | 2. **Edit source files**: Changes auto-reload 59 | 3. **Test production build**: `npm run build` 60 | 4. **View production demos**: Open `dist/demo/*.html` 61 | 62 | ## Scripts 63 | 64 | - `npm run dev` - Start dev server with hot reloading 65 | - `npm run build` - Build library + copy demos to dist/demo/ 66 | - `npm run build:lib` - Build library bundles only 67 | - `npm run build:demos` - Copy demos to dist/demo/ with updated script tags 68 | - `npm run build:watch` - Watch mode for library builds 69 | 70 | ## Benefits 71 | 72 | ✅ **Simple by default** - No complex detection logic 73 | ✅ **Dev mode first** - Demos default to loading from source 74 | ✅ **Hot reloading** - Instant feedback during development 75 | ✅ **Clean production builds** - Script replacement creates static demos 76 | ✅ **No duplication** - Single set of demo files -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Zynga Inc., http://zynga.com/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Zynga Scroller 2 | ============== 3 | 4 | A pure logic component for scrolling/zooming. It is independent of any specific kind of rendering or event system. 5 | 6 | The "demo" folder contains examples for usage with DOM and Canvas renderings which works both, on mouse and touch driven devices. 7 | 8 | 9 | Demos 10 | ----- 11 | 12 | See our demos online here: http://pbakaus.github.io/scroller/ 13 | 14 | 15 | Features 16 | -------- 17 | 18 | * Customizable enabling/disabling of scrolling for x-axis and y-axis 19 | * Deceleration (decelerates when user action ends in motion) 20 | * Bouncing (bounces back on the edges) 21 | * Paging (snap to full page width/height) 22 | * Snapping (snap to an user definable pixel grid) 23 | * Zooming (automatic centered zooming or based on a point in the view with configurable min/max zoom) 24 | * Locking (locks drag direction based on initial movement) 25 | * Pull-to-Refresh (Pull top out of the boundaries to start refresh of list) 26 | * Configurable regarding whether animation should be used. 27 | 28 | Options 29 | ------- 30 | 31 | These are the available options with their defaults. Options can be modified using the second constructor parameter or during runtime by modification of `scrollerObj.options.optionName`. 32 | 33 | * scrollingX = `true` 34 | * scrollingY = `true` 35 | * animating = `true` 36 | * animationDuration = `250` 37 | * bouncing = `true` 38 | * locking = `true` 39 | * paging = `false` 40 | * snapping = `false` 41 | * zooming = `false` 42 | * minZoom = `0.5` 43 | * maxZoom = `3` 44 | 45 | Installation 46 | ------------ 47 | 48 | **Modern (npm):** 49 | ```bash 50 | npm install scroller 51 | ``` 52 | 53 | **CDN (vanilla JS):** 54 | ```html 55 | 56 | 57 | 58 | 59 | 60 | ``` 61 | 62 | Usage 63 | ----- 64 | 65 | **ES6 Modules:** 66 | ```js 67 | import { Scroller } from 'scroller'; 68 | ``` 69 | 70 | **CommonJS:** 71 | ```js 72 | const { Scroller } = require('scroller'); 73 | ``` 74 | 75 | **Vanilla JS:** 76 | ```js 77 | // Available as global Scroller after loading script 78 | ``` 79 | 80 | Callback (first parameter of constructor) is required. Options are optional. Defaults are listed above. The created instance must have proper dimensions using a `setDimensions()` call. Afterwards you can pass in event data or manually control scrolling/zooming via the API. 81 | 82 | ```js 83 | var scrollerObj = new Scroller(function(left, top, zoom) { 84 | // apply coordinates/zooming 85 | }, { 86 | scrollingY: false 87 | }); 88 | 89 | // Configure to have an outer dimension of 1000px and inner dimension of 3000px 90 | scrollerObj.setDimensions(1000, 1000, 3000, 3000); 91 | ``` 92 | 93 | **EasyScroller (Simplified API):** 94 | 95 | EasyScroller provides a simplified, DOM-focused API that automatically handles scrolling and zooming for elements with data attributes. 96 | 97 | **Auto-initialization:** 98 | EasyScroller automatically initializes on elements with `data-scrollable` or `data-zoomable` attributes when the DOM is ready. 99 | 100 | ```html 101 | 102 |
data-scrollable or data-zoomable attributes.
108 | data-scrollable="true" data-zoomable="true"This area supports both scrolling and zooming! Try these interactions:
125 |This large content area extends beyond the visible container. Zoom out to see the full scope, or zoom in to see fine details of individual elements.
151 | 152 |The combination of scrolling and zooming provides the most flexible navigation experience. Zoom out for overview, zoom in for details!
155 |data-scrollable="y"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris consequat neque vel mi pellentesque laoreet. Praesent in nisi ut lacus fringilla fringilla id eget orci. Maecenas eget varius dolor. Pellentesque dignissim, libero at convallis aliquet, nibh mauris aliquam lacus, nec ornare libero arcu eget risus. Quisque quis nulla quis felis convallis feugiat sed tempus erat. Cras nec ante leo, vel aliquam dui. Vestibulum ut magna velit, eget luctus mi. Nullam eget sapien sit amet velit sagittis gravida ut in neque. Sed fermentum dui sed lorem malesuada nec adipiscing diam tempor. Etiam at augue ut ipsum scelerisque ullamcorper. Integer vehicula orci posuere sem tristique ac tempus odio facilisis. In mattis felis sed lacus consequat aliquet mollis lacus porta. Nullam ullamcorper risus et purus vulputate nec dignissim mauris imperdiet.
173 |Nam sem lorem, porttitor posuere elementum et, mattis non diam. Donec non augue odio, at pellentesque augue. Integer egestas, sapien lacinia ullamcorper suscipit, purus orci mollis nisl, eget vulputate elit libero vel diam. Suspendisse sodales nisl in est volutpat vitae tempus mauris vulputate.
174 |Pellentesque purus augue, scelerisque sit amet rutrum non, lobortis sed magna. Proin ultricies, nisl id cursus dignissim, odio erat feugiat erat, sed mollis libero nisl sit amet ante. Aliquam ante urna, ultricies id euismod sed, gravida ultrices neque. Curabitur viverra odio ultrices quam dapibus a cursus mi malesuada.
175 |Sed iaculis, felis non rhoncus accumsan, augue lectus condimentum ligula, in lacinia ipsum nibh id velit. Nam pellentesque, erat quis posuere vestibulum, tellus elit tristique lacus, ac elementum mauris felis at ipsum. Proin eget ante ante, nec faucibus turpis.
176 |Maecenas eget ante velit, vitae commodo ligula. In hac habitasse platea dictumst. Proin id lectus justo. Praesent sollicitudin justo eu urna rhoncus pellentesque. In blandit elit a dui pellentesque ut congue dui malesuada.
177 |data-scrollable="true"This content is wider than the container and can be scrolled horizontally and vertically. Try dragging in any direction to explore the content area.
190 |Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris consequat neque vel mi pellentesque laoreet. Praesent in nisi ut lacus fringilla fringilla id eget orci.
198 |Pellentesque dignissim, libero at convallis aliquet, nibh mauris aliquam lacus, nec ornare libero arcu eget risus. Quisque quis nulla quis felis convallis feugiat sed tempus erat.
199 |data-zoomable="true"This area can be zoomed and panned. Use your mouse wheel to zoom in and out!
217 | 218 |The content should remain visible and properly styled at all zoom levels. No more white screen issues!
239 | 240 |data-scrollable="true" data-zoomable="true"This demo combines zooming with panning for the best user experience.
259 | 260 |Zoom from cursor position + pan when zoomed = perfect navigation!
267 |data-zoomable="0.5-2"This area has zoom limits set between 0.5x and 2x.
285 |Notice how the zoom is constrained within the specified range. You cannot zoom out beyond 0.5x or zoom in beyond 2.0x.
290 |This is useful for maintaining readability while still allowing some zoom flexibility.
291 |"true" - Enable scrolling on both X and Y axes"x" - Enable scrolling on X-axis only"y" - Enable scrolling on Y-axis only"true" - Enable zooming with default range (0.5x to 3x)"min-max" - Enable zooming with custom range (e.g., "0.5-2" for 0.5x to 2x)data-scrollable="true" with data-zoomable for the best user experience. This enables proper zoom-from-cursor behavior and allows panning when zoomed in.
360 | Click on any demo in the sidebar to get started
199 |