JavaScript library v3.0.6 Build status

Source code on GitHub
Package on npm

Lazy-loading responsive images. HTML5's picture element as well as srcset and sizes attributes. Our JavaScript library does all the heavy lifting for you. Works in browsers and Node.js.

Installation

Browser

Use our CDN for a fast-loading and always up-to-date library. Insert this line above the closing </body> tag in your HTML. It's 83 kB (24 kB gzipped).

<script src="https://tiny.pictures/tiny.pictures.min.js"></script>

This file will expose the library class as the global variable TinyPictures.

Node.js

npm install --save tiny.pictures-js

Just add var TinyPictures = require('tiny.pictures-js') to your code and use the factory class in the TinyPictures variable.

Demo

Start a local demo server with the following command:

npm run demo

Then point your browser to http://localhost:3000/ to see the SDK's functions in action.

Usage

Once the class is loaded and stored in a variable, you can instantiate it by supplying an options object.

var tinyPictures = new TinyPictures(options)

Example

var tinyPictures = new TinyPictures({
    // window is only necessary when run in a browser
    window: window,
    user: 'demo',
    protocol: 'http'
})

Options

window (Window)
Mandatory when used in a browser. The global window object.
user (string)
Mandatory. Your tiny.pictures user name.
overrideSourcesImages (string[]|string|boolean)
Optional. Default []. Use this to supply a set of replacement images that are used instead of images from non-public hosts such as localhost during development. Can be an array of publicly available image URLs, a string that specifies the desired type of image ('random', 'abstract', 'animals', 'business', 'cats', 'city', 'food', 'nightlife', 'fashion', 'people', 'nature', 'sports', 'technics', or 'transport'), or a boolean (true for 'random' and false for []).
overrideSourcesAlways (boolean)
Optional. Default false. Set to true to always replace the original source images by overrideSourcesImages, even if they were publicly available.
While being very useful and funny during development, this may have a serious impact on your employment status if used in production. Use with caution!
protocol ('https'|'http')
Optional. Default 'https'. Set to 'http' if you are running a non-TLS-encrypted website to save your users' devices from unnecessary computation time.
defaultBaseUrl (string)
Optional. Default ''. This value is used by the url function as the default baseUrl parameter.
namedSources ({name: string, url: string}[])
Optional. Default []. An array of objects describing the named sources you configured on your dashboard. Copy the array directly from there. If a source image URL starts with one of your named sources, you'll get a prettier tiny.pictures URL (e. g. https://demo.tiny.pictures/main/example1.jpg).
srcsetWidths (int[])
Optional. Default is a quite long list of image widths. This list is used whenever an img tag's srcset attribute is created.
lazySizesConfig (object)
Optional. Configuration object that is passed to the lazysizes library used for lazy loading and automatic sizes calculation.

API

url

This function converts any image URL to a tiny.pictures URL. You can specify image processing operations in the options object.

Function parameters

url (string)
URL of the original image.
options (object)
Optional. Default {}. Object containing the image processing options you'd like to be applied.
baseUrl (string)
Optional. No default. Base url that url gets resolved against, if url is a relative URL. Throws an error if not set and url is relative. Is set to the current page's URL (location.href) automatically in the browser.

Function returns

string

Examples

tinyPictures.url('https://tiny.pictures/image.jpg')
// 'https://demo.tiny.pictures/main/image.jpg'

tinyPictures.url('https://tiny.pictures/image.jpg', {width: 200})
// 'https://demo.tiny.pictures/main/image.jpg?width=200'

// In the browser when on page https://tiny.pictures/index.html:
tinyPictures.url('image.jpg', {width: 200})
// https://demo.tiny.pictures/main/image.jpg?width=200

tinyPictures.url('//other.domain/path/to/image.jpg', {width: 200})
// https://demo.tiny.pictures/?width=200&source=https%3A%2F%2Fother.domain%2Fpath%2Fto%2Fimage.jpg

// In Node.js:
tinyPictures.url('image.jpg', {width: 200})
// throws error

tinyPictures.url('image.jpg', {width: 200}, 'https://tiny.pictures/index.html')
// https://demo.tiny.pictures/main/image.jpg?width=200

unveil

This function automatically replaces URLs of img tags to tiny.pictures URLs. You can use and combine any image processing operation you like. Operations are specified as data-attributes (see below) in the image tag.

tiny.pictures can automatically calculate a srcset and sizes attribute that enables the browser to decide which image size to load for an optimal user experience on your website. See the data-tp-srcset and data-tp-sizes attributes below for details.

We automatically convert img elements to HTML5's picture elements in order to enable automatic support for the WebP image format. To disable this, behavior, use the convertToPictureElement parameter.

Please also consider using this function via our jQuery plugin for convenience.

Function parameters

img (DOM node)
Native DOM node of the image.
convertToPictureElement (boolean)
Optional. Default true. If true, the img element is wrapped in a picture element to enable automatic WebP support. If false, leaves the img element unwrapped.

Function returns

undefined

img tag attributes

data-tp-src (string)
URL of the original image. It gets transformed into a tiny.pictures URL and is put into the src attribute.
src (string)
Optional. No default. Fallback URL of the original image that is only used if data-tp-src is not set.
data-tp-options (JSON)
Optional. No default. JSON representation of an options object specifying the operations you'd like to apply. For example, to resize the image to a width of 200 pixels and flip the image, use data-tp-options='{"width": 200, "flip": true}' (note the single quotes).
data-tp-srcset ('{width}')
Optional. No default. Set to {width} (literally) to enable automatic srcset calculation. This only makes sense if you also set the sizes attribute manually or make use of the data-tp-sizes attribute described below.
data-tp-sizes ('auto')
Optional. No default. Set to auto (literally) to enable automatic sizes calculation. For details, see the documentation of the lazysizes library.

Examples

<img data-tp-src="https://tiny.pictures/example1.jpg">
<!-- Original source image url is used -->
<!-- src="https://demo.tiny.pictures/main/example1.jpg" -->

<img data-tp-src="https://tiny.pictures/example1.jpg" data-tp-options='{"width":200}'>
<!-- tiny.pictures url is used -->
<!-- src="https://demo.tiny.pictures/main/example1.jpg?width=200" -->

<img data-tp-src="https://tiny.pictures/example1.jpg" data-tp-srcset="{width}" sizes="100vw, (min-width: 800px) 50vw">
<!-- The browser decides which file to load based on the user's viewport width and display density -->
<!-- srcset="https://demo.tiny.pictures/main/example1.jpg?width=50 50w, https://demo.tiny.pictures/main/example1.jpg?width=75 75w, https://demo.tiny.pictures/main/example1.jpg?width=100 100w, https://demo.tiny.pictures/main/example1.jpg?width=120 120w, https://demo.tiny.pictures/main/example1.jpg?width=180 180w, https://demo.tiny.pictures/main/example1.jpg?width=360 360w, https://demo.tiny.pictures/main/example1.jpg?width=540 540w, https://demo.tiny.pictures/main/example1.jpg?width=720 720w, https://demo.tiny.pictures/main/example1.jpg?width=900 900w, https://demo.tiny.pictures/main/example1.jpg?width=1080 1080w, https://demo.tiny.pictures/main/example1.jpg?width=1296 1296w, https://demo.tiny.pictures/main/example1.jpg?width=1512 1512w, https://demo.tiny.pictures/main/example1.jpg?width=1728 1728w, https://demo.tiny.pictures/main/example1.jpg?width=1944 1944w, https://demo.tiny.pictures/main/example1.jpg?width=2160 2160w, https://demo.tiny.pictures/main/example1.jpg?width=2376 2376w, https://demo.tiny.pictures/main/example1.jpg?width=2592 2592w, https://demo.tiny.pictures/main/example1.jpg?width=2808 2808w, https://demo.tiny.pictures/main/example1.jpg?width=3024 3024w" -->

<img data-tp-src="https://tiny.pictures/example1.jpg" data-tp-srcset="{width}" data-tp-sizes="auto">
<!-- The browser decides which file to load based on the user's viewport width and display density -->
<!-- srcset="https://demo.tiny.pictures/main/example1.jpg?width=50 50w, https://demo.tiny.pictures/main/example1.jpg?width=75 75w, https://demo.tiny.pictures/main/example1.jpg?width=100 100w, https://demo.tiny.pictures/main/example1.jpg?width=120 120w, https://demo.tiny.pictures/main/example1.jpg?width=180 180w, https://demo.tiny.pictures/main/example1.jpg?width=360 360w, https://demo.tiny.pictures/main/example1.jpg?width=540 540w, https://demo.tiny.pictures/main/example1.jpg?width=720 720w, https://demo.tiny.pictures/main/example1.jpg?width=900 900w, https://demo.tiny.pictures/main/example1.jpg?width=1080 1080w, https://demo.tiny.pictures/main/example1.jpg?width=1296 1296w, https://demo.tiny.pictures/main/example1.jpg?width=1512 1512w, https://demo.tiny.pictures/main/example1.jpg?width=1728 1728w, https://demo.tiny.pictures/main/example1.jpg?width=1944 1944w, https://demo.tiny.pictures/main/example1.jpg?width=2160 2160w, https://demo.tiny.pictures/main/example1.jpg?width=2376 2376w, https://demo.tiny.pictures/main/example1.jpg?width=2592 2592w, https://demo.tiny.pictures/main/example1.jpg?width=2808 2808w, https://demo.tiny.pictures/main/example1.jpg?width=3024 3024w" sizes="500px" -->

<script src="https://tiny.pictures/tiny.pictures.min.js"></script>
<script>
    var tinyPictures = new TinyPictures({
        window: window,
        user: 'demo'
    })
    var list = document.getElementsByTagName('img')
    for (var i = 0; i < list.length; i++) {
        tinyPictures.unveil(list[i])
    }
</script>

Benefits

The following image is loaded with

<img data-tp-src="https://tiny.pictures/example1.jpg" data-tp-srcset="{width}" data-tp-sizes="auto">

Depending on the user's viewport and display density, the browser loads different images for the fastest possible load time and best user experience. Notice that mobile users may save up to 94.4 % bandwidth in this example.

URLSize
/?width=200&source=...8.5 kB
/?width=300&source=...16.7 kB
/?width=400&source=...27.6 kB
/?width=500&source=...42.2 kB
/?width=600&source=...57.9 kB
/?width=700&source=...78.2 kB
/?width=800&source=...98.7 kB
/?width=900&source=...122.0 kB
/?width=1000&source=...151.0 kB

Demo image loaded by the srcset attribute

For detailed insights into responsive images and why you should also use the sizes attribute, read Jason Grigsby's excellent Responsive Images 101 Series or the illustrative Srcset and sizes by Eric Portis.

unveilAll

This is a convenience function to execute unveil on all img tags.

Function parameters

None

Function returns

undefined

lazyload

This function does the same as the unveilAll function except that it defers image loading to when the user actually scrolls down to them. Set the tp-lazyload class to images you'd like to load lazily.

It sets the images' src attribute as soon as the user is about to scroll the image into view (300 pixels above).

Function parameters

None

Function returns

undefined

Examples

<img class="tp-lazyload" data-tp-src="https://tiny.pictures/example1.jpg">
<!-- Original source image url is used for lazy loading -->
<!-- class="tp-lazyloaded" src="https://demo.tiny.pictures/main/example1.jpg" -->

<img class="tp-lazyload" data-tp-src="https://tiny.pictures/example1.jpg" data-tp-options='{"width":200}'>
<!-- tiny.pictures url is used for lazy loading -->
<!-- class="tp-lazyloaded" src="https://demo.tiny.pictures/main/example1.jpg?width=200" -->

<img class="tp-lazyload" data-tp-src="https://tiny.pictures/example1.jpg" data-tp-srcset="{width}" sizes="100vw, (min-width: 800px) 50vw">
<!-- The browser decides which file to load based on the user's viewport width and display density -->
<!-- class="tp-lazyloaded" srcset="https://demo.tiny.pictures/main/example1.jpg?width=50 50w, https://demo.tiny.pictures/main/example1.jpg?width=75 75w, https://demo.tiny.pictures/main/example1.jpg?width=100 100w, https://demo.tiny.pictures/main/example1.jpg?width=120 120w, https://demo.tiny.pictures/main/example1.jpg?width=180 180w, https://demo.tiny.pictures/main/example1.jpg?width=360 360w, https://demo.tiny.pictures/main/example1.jpg?width=540 540w, https://demo.tiny.pictures/main/example1.jpg?width=720 720w, https://demo.tiny.pictures/main/example1.jpg?width=900 900w, https://demo.tiny.pictures/main/example1.jpg?width=1080 1080w, https://demo.tiny.pictures/main/example1.jpg?width=1296 1296w, https://demo.tiny.pictures/main/example1.jpg?width=1512 1512w, https://demo.tiny.pictures/main/example1.jpg?width=1728 1728w, https://demo.tiny.pictures/main/example1.jpg?width=1944 1944w, https://demo.tiny.pictures/main/example1.jpg?width=2160 2160w, https://demo.tiny.pictures/main/example1.jpg?width=2376 2376w, https://demo.tiny.pictures/main/example1.jpg?width=2592 2592w, https://demo.tiny.pictures/main/example1.jpg?width=2808 2808w, https://demo.tiny.pictures/main/example1.jpg?width=3024 3024w" -->

<img class="tp-lazyload" data-tp-src="https://tiny.pictures/example1.jpg" data-tp-srcset="{width}" data-tp-sizes="auto">
<!-- The browser decides which file to load based on the user's viewport width and display density -->
<!-- class="tp-lazyloaded" srcset="https://demo.tiny.pictures/main/example1.jpg?width=50 50w, https://demo.tiny.pictures/main/example1.jpg?width=75 75w, https://demo.tiny.pictures/main/example1.jpg?width=100 100w, https://demo.tiny.pictures/main/example1.jpg?width=120 120w, https://demo.tiny.pictures/main/example1.jpg?width=180 180w, https://demo.tiny.pictures/main/example1.jpg?width=360 360w, https://demo.tiny.pictures/main/example1.jpg?width=540 540w, https://demo.tiny.pictures/main/example1.jpg?width=720 720w, https://demo.tiny.pictures/main/example1.jpg?width=900 900w, https://demo.tiny.pictures/main/example1.jpg?width=1080 1080w, https://demo.tiny.pictures/main/example1.jpg?width=1296 1296w, https://demo.tiny.pictures/main/example1.jpg?width=1512 1512w, https://demo.tiny.pictures/main/example1.jpg?width=1728 1728w, https://demo.tiny.pictures/main/example1.jpg?width=1944 1944w, https://demo.tiny.pictures/main/example1.jpg?width=2160 2160w, https://demo.tiny.pictures/main/example1.jpg?width=2376 2376w, https://demo.tiny.pictures/main/example1.jpg?width=2592 2592w, https://demo.tiny.pictures/main/example1.jpg?width=2808 2808w, https://demo.tiny.pictures/main/example1.jpg?width=3024 3024w" sizes="500px" -->

<script src="https://tiny.pictures/tiny.pictures.min.js"></script>
<script>
    var tinyPictures = new TinyPictures({
        window: window,
        user: 'demo'
    })
    tinyPictures.lazyload()
</script>

jQuery

You may register tiny.pictures as a jQuery plugin. This creates a tinyPictures function, that executes the unveil function for all matching DOM nodes.

Example

<img data-tp-src="https://tiny.pictures/example.jpg" data-tp-options='{"width":200}'>
<script src="jQuery.js"></script>
<script src="https://tiny.pictures/tiny.pictures.min.js"></script>
<script>
    var tinyPictures = new TinyPictures({
        window: window,
        user: 'demo'
    })
    tinyPictures.registerJQueryPlugin($)
    $('img').tinyPictures({"width":200})
</script>
<!-- src="https://demo.tiny.pictures/main/example.jpg?width=200" -->

AngularJS (a.k.a. Angular 1)

If the SDK is loaded after AngularJS, it automatically registers a tiny.pictures module and a filter called tinyPicturesUrl, that exposes the url function for use in templates.

Example

<script src="angular.js"></script>
<script src="https://tiny.pictures/tiny.pictures.min.js"></script>
<script>
    var tinyPictures = new TinyPictures({
        window: window,
        user: 'demo'
    })
    tinyPictures.registerAngularJsModule(angular)
    angular.module('yourApp', ['tiny.pictures'])
</script>
…
<img ng-src="{{ item.imageUrl | tinyPicturesUrl: {width: 200, quality: 90} }}">

Angular (a.k.a. Angular 2)

With Angular 2 and above, you may just import the library in your component files and use its functions directly. The example below also shows a simple pipe based on the url function.

Example

import { Component, Pipe, PipeTransform } from '@angular/core'
import TinyPictures from 'tiny.pictures-js/browser'

const imageUrl = 'https://tiny.pictures/example1.jpg'
const tinyPictures = new TinyPictures({
    window: window,
    user: 'demo'
})

@Component({
    selector: 'my-component',
    template: '<h1>Nice images</h1>' +
              '<img src="' + tinyPictures.url(imageUrl) + '">' +
              '<img src="imageUrl | tinyPicturesUrl">'
})
export class MyComponent {
    imageUrl: string = imageUrl
}

@Pipe({
    name: 'tinyPicturesUrl'
})
export class TinyPicturesUrlPipe implements PipeTransform {
    transform(...args): string {
        return tinyPictures.url(...args)
    }
 }