Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/danielgamage/lenti
Lenticular image viewer
https://github.com/danielgamage/lenti
canvas image-viewer lenticular slideshow
Last synced: about 1 month ago
JSON representation
Lenticular image viewer
- Host: GitHub
- URL: https://github.com/danielgamage/lenti
- Owner: danielgamage
- License: other
- Created: 2017-03-05T06:45:51.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2021-07-21T04:10:10.000Z (over 3 years ago)
- Last Synced: 2024-10-05T11:22:46.753Z (about 2 months ago)
- Topics: canvas, image-viewer, lenticular, slideshow
- Language: JavaScript
- Homepage: https://danielgamage.github.io/lenti/
- Size: 2.06 MB
- Stars: 10
- Watchers: 2
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# lenti [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Coverage percentage][coveralls-image]][coveralls-url]
> Lenticular image viewerLenti is an image viewer that mimicks the effect of lenticular printing. It displays images in a canvas element and binds events for mouse and accelerometer events, so just as you would rotate a card or print with lenticular lenses on it, you can tilt your phone to transition between images.
**[Demo][demo-page]**
## Installation
```sh
$ npm install --save lenti
```## Basic Usage
Lenti will accomodate any number of images in the container (be good to your RAM and don’t go wild, though).
```html
``````js
import Lenti from 'lenti'let lenticulars = document.querySelectorAll('[data-lenticular-list]')
let instances = []
// convert → array & loop through
;[...lenticulars].map((el, i) => {
// store instance in array for further manipulation
instances[i] = new Lenti({container: el, width: 1280, height: 720})
// initialize instance
instances[i].init()
})
```## Options
#### `container`
**Required**Specifies the HTMLElement (not selector) that contains the images.
#### `accelerometerEvents`
**default**: trueTurns tilt interaction on or off.
#### `mouseEvents`
**default**: trueTurns mouse hover interaction on or off.
#### `stripWidth`
**default**: 16The horizontal width (in pixels) of each lens strip.
#### `height` & `width`
**default**: 50The height and width of the canvas (in pixels). You **definitely should** match this to the value of your images (which should all be the same size)
#### `tiltMax`
**default**: 45
#### `tiltMin`
**default**: -45For the accelerometer event listener, define the max and min tiltable angle for interaction.
## Instance Methods
#### `Lenti.init()`
Runs setup functions.
#### `Lenti.bindEvents()`
#### `Lenti.destroy()`
Binds (`bindEvents`) or unbinds (`destroy`) events.
#### `Lenti.handleSizing()`
Measures the sizing of the box for further calculations. By default the event bindings will call this on resize. If you are resizing a container manually, you should probably fire this.
#### `Lenti.getBoxPosition()`
#### `Lenti.checkVisibility()`
This
#### `Lenti.redraw(balance)`
Refreshes the viewer for the given `balance`, where `balance` is a float from `0–1` that represents the position in the image sequence. A value of 0 will show the first image, and a value of 1 will show the last. See [custom events](#custom-events) for an example of this.
#### `Lenti.remap(value, inLow, inHigh, outLow, outHigh)`
Helper function to map values from one range to another. You'll likely use this to map values to the range `0–1` for `Lenti.redraw()`.## Custom events
Lenti doesn't make too many assumptions about your environment. You may turn off the default event handlers (see `accelerometerEvents` and `mouseEvents`) and make your own interaction system. Just send a value between 0–1 to your instance at `Lenti.redraw()`.In the following example, we show how a spring physics library ([rebound](https://github.com/facebook/rebound-js)) can be used as a sort of middleware in Lenti:
```js
import Lenti from 'lenti'
import rebound from 'rebound'let lenticulars = document.querySelectorAll('[data-lenticular-list]')
let instances = []
// convert → array & loop through
;[...lenticulars].map((el, i) => {
const image = el.querySelector('img')
// store instance in array for further manipulation
instances[i] = new Lenti({
container: el,
width: image.width,
height: image.height,
stripWidth: el.getAttribute('data-strip-width'),
mouseEvents: false // this is the key
})
let _this = instances[i]// set up spring
const springSystem = new rebound.SpringSystem();
const springConfig = [40, 9] // tension, friction
const balanceSpring = springSystem.createSpring(...springConfig);
balanceSpring.addListener({ onSpringUpdate: (balanceSpring) => {
_this.redraw(balanceSpring.getCurrentValue())
}})
// initialize instance
_this.init()// set initial value
balanceSpring.setEndValue(1)// bind mouse events
_this.canvas.addEventListener('mousemove', (e) => {
const balance = _this.remap(e.offsetX / _this.canvasWidth, 0, 1, 1, 0)
balanceSpring.setEndValue(balance)
})
})
```
After disabling the default mouse event handler, we set up a new event listener (`mousemove`), map the value of `e.offsetX / _this.canvasWidth` to the range 1–0 (just inverting the range here), and send the value to `balanceSpring`, which interpolates the value. We tell `balanceSpring` to send the spring value to our instance method at `Lenti.redraw()` as it updates. Check the [demo page][demo-page] to see this example in use.You can imagine that this example does not demonstrate the full flexibility you have here, and that you could, for instance, replace the default gamma-rotation accelerometer event with events for a different axis, use ambient light sensors to change the value, have timed animations driven by any arbitrary event, and so on.
## Cross-origin images
Because Lenti uses canvas to produce this effect, most browsers will be upset if you fetch an image from another origin. Be sure to set `crossorigin="anonymous"` on your images:```html
```## License
Apache-2.0 © [Daniel Gamage](https://danielgamage.com)
[npm-image]: https://badge.fury.io/js/lenti.svg
[npm-url]: https://npmjs.org/package/lenti
[travis-image]: https://travis-ci.org/danielgamage/lenti.svg?branch=master
[travis-url]: https://travis-ci.org/danielgamage/lenti
[daviddm-image]: https://david-dm.org/danielgamage/lenti.svg?theme=shields.io
[daviddm-url]: https://david-dm.org/danielgamage/lenti
[coveralls-image]: https://coveralls.io/repos/danielgamage/lenti/badge.svg
[coveralls-url]: https://coveralls.io/r/danielgamage/lenti
[demo-page]: https://danielgamage.github.io/lenti/