0.3.2 • Published 5 months ago

lenti v0.3.2

Weekly downloads
2
License
-
Repository
github
Last release
5 months ago

lenti v0.3.2


Lenti 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

Installation

npm install --save lenti

Usage

Lenti will accomodate any number of images in the container.

<div data-lenticular-list="true">
  <img src="./images/sample_a_1.png" alt="Left-facing view of object" width="1280" height="720" />
  <img src="./images/sample_a_2.png" alt="Center-left-facing view of object" width="1280" height="720" />
  <img src="./images/sample_a_3.png" alt="Center-facing view of object" width="1280" height="720" />
  <img src="./images/sample_a_4.png" alt="Center-right-facing view of object" width="1280" height="720" />
  <img src="./images/sample_a_5.png" alt="Right-facing view of object" width="1280" height="720" />
</div>
import {Lenti, bindGyroscopeXY, bindMouseXY} from "lenti"

const container = document.querySelector("[data-lenticular-list]")
const canvas = document.createElement("canvas") // programmatically creating canvas. could also just put it in the HTML
container.appendChild(canvas)
const lenti = new Lenti({
  container,
  canvas,
  images: Array.from(container.querySelectorAll("img")),
  uiAdapters: [bindMouseXY({eventRoot: window}), bindGyroscopeXY()]
})

Browser Support

Lenti relies on WebGPU for buttery-smooth framerates on modern computers. Unflagged browser support below:

Thanks to Ire for their Can I Use Embed

API

Lenti

Lenti

TODOs:

Constructors

new Lenti()
new Lenti(options: {
  canvas: HTMLCanvasElement;
  images: HTMLImageElement[];
  oversampling: number;
  samplerSettings: GPUSamplerDescriptor;
  uiAdapters: UIAdapter[];
 } & Partial<{
  lensDarkening: number;
  lensDistortion: number;
  stripWidth: number;
  transition: number;
  viewX: number;
  viewY: number;
 }>): Lenti
Parameters
options

{ canvas: HTMLCanvasElement; images: HTMLImageElement[]; oversampling: number; samplerSettings: GPUSamplerDescriptor; uiAdapters: UIAdapter[]; } & Partial\<{ lensDarkening: number; lensDistortion: number; stripWidth: number; transition: number; viewX: number; viewY: number; }>

Returns

Lenti

Properties

PropertyTypeDefault valueDescription
canvasHTMLCanvasElementnullThe output (rendered) canvas
images( | HTMLCanvasElement | HTMLOrSVGImageElement | HTMLVideoElement | ImageBitmap | OffscreenCanvas | ImageData)[][]Image elements to pull textures from. Also supports ImageData.
inputs{ lensDarkening: number; lensDistortion: number; stripWidth: number; transition: number; viewX: number; viewY: number; }undefined-
inputs.lensDarkeningnumberundefinedAmount of darkening to apply near the virtual off-axis parts of the lenticule
inputs.lensDistortionnumberundefinedAmount of y-axis distortion applied to the lenticule simulate vertical off-axis viewing
inputs.stripWidthnumberundefinedImage-space width of the strip placed in an interlaced array under the lenticule
inputs.transitionnumberundefinedAmount of virtual warping to apply to the transition from left–right
inputs.viewXnumberundefined0: Leftmost image, 1: Rightmost image
inputs.viewYnumberundefined0: Top distortion, 1: Bottom distortion
isVisiblebooleanfalseWhether the canvas is visible in the viewport
oversamplingnumber2Canvas oversampling
uiAdapterCleanupCallbacksUIAdapterCleanupCallback[][]-
uiAdaptersUIAdapter[]undefinedUI adapters connect user input to the shader settings, custom adapters can be made Default [bindMouseXY(), bindGyroscopeXY()]

Accessors

imageAspectRatio
Get Signature
get imageAspectRatio(): number
Returns

number

Methods

createTextureFromImage()
createTextureFromImage(imageData: ImageData): Promise<GPUTexture>
Parameters
imageData

ImageData

Returns

Promise\[`GPUTexture`](https://developer.mozilla.org/docs/Web/API/GPUTexture)\


destroy()
destroy(): void

Destroys the instance and cleans up resources

Returns

void


error()
error(e: Error): void

Common Lenti errors may be fired from here

Parameters
e

Error

Returns

void


init()
init(): Promise<void>
Returns

Promise\<void>


render()
render(): void

Renders the current state of the instance

Returns

void


update()
update(updates: Partial<{
  lensDarkening: number;
  lensDistortion: number;
  stripWidth: number;
  transition: number;
  viewX: number;
  viewY: number;
 }>): void

Updates the instance state with a subset of Lenti's state

Parameters
updates

Partial\<{ lensDarkening: number; lensDistortion: number; stripWidth: number; transition: number; viewX: number; viewY: number; }>

Returns

void


bindGyroscopeXYOptions

Properties

PropertyTypeDescription
userGestureElement?HTMLElementSome browsers require user gesture before requesting permission. This is the element that will require click if so. By default, this is the Lenti instance's canvas element, but it can be a button or other interactive element.
xBounds[number, number]Range of angles in object-space x-rotation
yBounds[number, number]Range of angles in object-space y-rotation

Degree

type Degree = number;

A number representing degrees (typically -360, 360)


NormalizedNumber

type NormalizedNumber = number;

A number in the range 0, 1


PositiveInteger

type PositiveInteger = number;

A positive integer

Managing User Interaction

UIAdapter()

type UIAdapter = (lentiInstance: Lenti) => UIAdapterCleanupCallback | void;

UI Adapaters listen for events on a page and can access Lenti properties throughout the instance lifecycle.

UIAdapters expect a Lenti instance to be passed to them, and can be used to bind user input to shader settings.

In practice, this can be as simple as:

// Sets the lensDarkening based on the amount of daylight when the page loads
new Lenti({uiAdapters: [function bindDaylight(lentiInstance: Lenti) => {
  lentiInstance.inputs.lensDarkening = 0.5
})]})

Parameters

lentiInstance

Lenti

Returns

UIAdapterCleanupCallback | void


UIAdapterCleanupCallback()

type UIAdapterCleanupCallback = () => void;

UIAdapterCleanupCallback is a function that is called when a Lenti instance is destroyed.

Some cases might be usage in a single-page application where the Lenti instance is created and destroyed multiple times as a user navigates the site.

Returns

void


UIAdapterFactory()

type UIAdapterFactory = (options?: any) => UIAdapter;

UIAdapterFactory is an initializing function that is passed options for the UIAdapater it contains.

If you want your UIAdapter to be reusable and configurable, you can create a UIAdapterFactory that returns the UIAdapter.

// Sets the lensDarkening based on the amount of daylight when the page loads
const bindDaylightFactory = (options: {daylight: number}) => {
  return function bindDaylight(lentiInstance: Lenti) => {
    lentiInstance.inputs.lensDarkening = 1 - options.daylight
  }
}

new Lenti({uiAdapters: [bindDaylightFactory({daylight: 0.5})]})

Parameters

options?

any

Returns

UIAdapter


bindGyroscopeXY()

function bindGyroscopeXY(options: bindGyroscopeXYOptions): UIAdapter

Drives viewX/viewY based on the device viewing angle

Parameters

options

bindGyroscopeXYOptions = ...

Returns

UIAdapter


bindMouseXY()

function bindMouseXY(options: {
  eventRoot:   | HTMLElement
     | Window
     | Document;
 }): UIAdapter

Drives viewX/viewY based on the mouse position on the element, in the browser window, or in another element (like a touchstrip element)

Parameters

options
eventRoot

| HTMLElement | Window | Document

The element that the mouse will be tracked on

Returns

UIAdapter

0.3.0

5 months ago

0.3.2

5 months ago

0.2.1

8 years ago

0.2.0

8 years ago

0.1.0

8 years ago

0.0.0

8 years ago