# lazySizes RIaS extension (Responsive image as a service / Responsive image on demand)

The RiaS plugin enables lazySizes to generate the best suitable image source based on an URL pattern. It works with pre-build images (i.e. grunt-responsive-images) as also with any third party (ReSrc, Pixtulate, mobify, WURFL's Image Tailor ...) or self hosted restful responsive image services (responsive image on demand).

In general the RIaS  plugin combines the simplicity of the famous Imager.js solution with the future power of native responsive images implementations and the webcomponent-like working of lazySizes' ``.lazyload`` elements (self-initialization, self-configuration and self-destroying).

In case the browser does support ``srcset`` the RIaS plugin will also produce a list of source candidates so that any current and future improvements (low bandwidth, metered bandwidth, user preferences, browser zoom etc.) to the native responsive image support is automatically exploited.

The RiaS plugin also allows art direction by combining placeholder URLs with a ``picture`` element.

## Basic/quick usage

* Add the RiaS plugin right before the lazySizes script or concat those scripts into your script bundle:

```html
<!-- include lazysizes + rias extension -->
<script src="../plugins/rias/ls.rias.js"></script>
<script src="../lazysizes.js"></script>
```


* Add the ``lazyload`` class and the ``data-sizes="auto"`` attribute to your image and include the placeholder ``{width}`` at the point, where your image service expects the requested width of the image.

```html
<img
	data-src="http://placehold.it/{width}"
	data-sizes="auto"
	class="lazyload"
	alt="" />

<img
    data-src="http://wit.wurfl.io/w_{width}/http://wurfl.io/assets/sunsetbeach.jpg"
	data-sizes="auto"
	class="lazyload"
	alt="" />
```

## [Demo](http://afarkas.github.io/lazysizes/rias/)
A [demo with markup and code examples can be seen here](http://afarkas.github.io/lazysizes/rias/).

## Configuration/Options

The RIaS plugin can be configured through the ``lazySizesConfig.rias`` option object, which should be configured before the lazySizes script.

```js
window.lazySizesConfig = window.lazySizesConfig || {};
window.lazySizesConfig.rias = window.lazySizesConfig.rias || {};

// configure available widths to replace with the {width} placeholder
window.lazySizesConfig.rias.widths = [320, 480, 640, 960];
window.lazySizesConfig.rias.absUrl = true;
```

or element specific and declarative with corresponding ``data-*`` attributes:

```html
<img
    data-widths="[160, 320]"
    data-absurl="false"
    data-src="http://placehold.it/{width}"
    data-sizes="auto"
    class="lazyload"
    alt="" />
```

or element specific and functional using the ``lazyriasmodifyoptions`` event.

```html
<script>
document.addEventListener('lazyriasmodifyoptions', function(event){
    // event.detail referes the placeholders/options and event.target the corresponding element
    event.detail.quality = (window.devicePixelRatio || 1) > 1.9 ? 50 : 80;
});
</script>
<img
    data-src="image-w{width}-q{quality}.jpg"
    data-sizes="auto"
    class="lazyload"
    alt="" />
```

All ``rias`` options can also be used as ``data-*`` attributes.

### URL generation and {placeholder}s

The url is dynamically generated by replacing placeholder values, which are enclosed by curly brackets.

All RiAS options can also be used as a {placeholder} inside the url.

### List of Options

* ``lazySizesConfig.rias.srcAttr`` (default: ``"data-src"``): The attribute, which should be transformed to ``src``/``srcset``. (The extension will also automatically check the ``lazySizesConfig.srcsetAttr`` and ``lazySizesConfig.srcAttr``)
* ``lazySizesConfig.rias.widths`` (``array of numbers``): The widths option reduces the calculated ``width`` to the allowed widths. The numeric width can also be simply mapped to a string (i.e.: small, medium, large) using the ``widthmap`` option. The default value is the following array: ``[180, 360, 540, 720, 900, 1080, 1296, 1512, 1728, 1944, 2160, 2376, 2592, 2808, 3024]``.
* ``lazySizesConfig.rias.widthmap`` (``{}``): The widthmap option allows you to simply transform a numeric width to a string.
    ```js
    window.lazySizesConfig = window.lazySizesConfig || {};
    window.lazySizesConfig.rias = window.lazySizesConfig.rias || {};

    window.lazySizesConfig.rias.widths = [320, 640, 940];
    window.lazySizesConfig.rias.widthmap = {
        320: 'small',
        640: 'medium',
        940: 'large'
   };
    ```
* ``lazySizesConfig.rias.modifyOptions`` (default: ``function`` noop ): A ``function`` that gets an data object passed with the options as the ``details`` and the corresponding ``img`` element as the ``target``. Can be used to modify existing options/placeholder values or to add new placeholder values. An event with the name ``lazyriasmodifyoptions`` is also fired at the element.
    ```html
    <script>
    window.lazySizesConfig = window.lazySizesConfig || {};
    window.lazySizesConfig.rias = window.lazySizesConfig.rias || {};
    window.lazySizesConfig.rias.modifyOptions = function(data){
        //create higher compressed images on HighDPI devices:
        data.detail.quality = (window.devicePixelRatio || 1) > 1.9 ? 50 : 80;
    };
    </script>
    <img
        data-src="image-w{width}-q{quality}.jpg"
        data-sizes="auto"
        class="lazyload"
        alt="" />
    ```

* ``lazySizesConfig.rias.absUrl`` (default: ``false``): Wether the value of the ``data-src`` attribute should be resolved to an absolute url. The value must not contain any placeholders in this case. Use in conjunction with ``prefix`` and/or ``postfix`` option.
    ```html
    <script>
        window.lazySizesConfig = window.lazySizesConfig || {};
        window.lazySizesConfig.rias = {
            prefix: 'http://wit.wurfl.io/w_{width}/',
            absUrl: true
        };
    </script>

    <img
        data-src="assets/sunsetbeach.jpg"
        data-sizes="auto"
        class="lazyload"
        alt="" />
    ```

* ``lazySizesConfig.rias.prefix`` (default: ``""``): A string, which is prepended to the generated src.
    ```html
    <script>
    window.lazySizesConfig = window.lazySizesConfig || {};
    window.lazySizesConfig.rias = {
        prefix: 'http://placehold.it/'
    };
    </script>
    <img
        data-src="{width}"
        data-sizes="auto"
        class="lazyload"
        alt="" />
    ```
* ``lazySizesConfig.rias.postfix`` (default: ``""`` ): A string, which is appended to the generated src.

With lazySizes + RIaS extension you have a script to rule them all. You won't need to include a script provided by a third party image on demand service.

### Dynamically calculating the height of image elements

You can provide a `apsectratio`  option which then will be used to dynamically replace `{height}` placeholders. 

```html
<img
    data-src="{width}x{height}}"
    data-aspectratio="2"
    data-sizes="auto"
    class="lazyload"
    alt="" />
```

In case your image has CSS defined width and height dimensions you can provide this dynamically:

```js
document.addEventListener('lazyriasmodifyoptions', function(e) {
    e.detail.aspectratio = e.target.offsetWidth / e.target.offsetHeight;
});
```
 

## Advanced Examples

### Embedding via CDN and combohandler

In case you want to use a CDN you can use jsDelivr's combohandler service:

```html
<script src="http://cdn.jsdelivr.net/g/lazysizes(lazysizes.min.js+plugins/rias/ls.rias.min.js)" async=""></script>
```

### Using art direction

In case you want to use art direction simply also use placeholder urls inside of your ``source[data-srcset]`` or ``source[data-src]`` attributes.

```html
<picture>
    <!--[if IE 9]><audio><![endif]-->
    <source
            data-srcset="http://placehold.it/{width}/1111ee/fff"
            media="(max-width: 500px)" />
    <source
            data-srcset="http://placehold.it/{width}/e8117f/fff"
            media="(max-width: 1090px)" />
    <source
            data-srcset="http://placehold.it/{width}/7D26CD/fff"
            media="(min-width: 1224px)" />
    <source
            data-srcset="http://placehold.it/{width}"
             />
    <!--[if IE 9]></audio><![endif]-->
    <img
        src="http://placehold.it/100"
        data-sizes="auto"
        class="lazyload"
        alt="" />
</picture>
```

### Using different ``widths`` options for different images
Often you will have different image formats with different allowed available ``widths``. This can be configured in two ways:

#### Descriptive way the ``data-widths`` attribute

```html
<img
        data-srcset="http://placehold.it/{width}"
        data-widths="[320, 480, 640]"
        data-sizes="auto"
        class="lazyload"
        alt="" />

<img
        data-srcset="http://placehold.it/{width}"
        data-widths="[640, 800, 960]"
        data-sizes="auto"
        class="lazyload"
        alt="" />

```

#### Scripted way using the ``lazyriasmodifyoptions`` event


```html
<script>
document.addEventListener('lazyriasmodifyoptions', (function(){
    var formats = {
        full: [640, 800, 960, 1280, 1600],
        content: [320, 480, 640]
    };
    return function(e){
       var format = e.target.getAttribute('data-format');
       if(formats[format]){
           e.detail.widths = formats[format];
       }
   };
})());
</script>

<img
    data-src="http://placehold.it/{width}"
    data-format="full"
    data-sizes="auto"
    class="lazyload"
    alt="" />

<img
    data-src="http://placehold.it/{width}"
    data-format="content"
    data-sizes="auto"
    class="lazyload"
    alt="" />
```

### Overriding existing placeholders or Extending new placeholders

The RIaS plugin is highly flexible in extending possible {placeholder} values. Each {placeholder} will be tried to be replaced by searching it in the ``lazySizesConfig.rias`` option object or by searching for a corresponding ``data-*`` attribute.

Additionally the ``modifyOptions`` callback or the equivalent ``lazyriasmodifyoptions`` event can be used to generate new or modify existing placeholders:

**Using ``data-*`` to override an existing placeholder:**

```html
<img
    data-widths="[160, 320]"
    data-src="http://placehold.it/{width}"
    data-sizes="auto"
    class="lazyload" />
```

**Using ``data-*`` to define a new placeholder:**

```html
<img
    data-custom="foo"
    data-src="http://placehold.it/{width}/{custom}"
    data-sizes="auto"
    class="lazyload" />
```

**Using the ``lazySizesConfig.rias`` object to define a new placeholder:**

```html
<script>
window.lazySizesConfig = window.lazySizesConfig || {};
window.lazySizesConfig.rias = {
    custom: 'test',
    dynCustom: function(elem, opts){
        return 'computed-something';
    }
};
</script>
<img
    data-src="http://placehold.it/{width}/{custom}/{dynCustom}"
    data-sizes="auto"
    class="lazyload"
    alt="" />
```

**Using the ``lazyriasmodifyoptions`` event to define or change a placeholder object:**

```html
<script>
document.addEventListener('lazyriasmodifyoptions', function(e){
    // change available widths and widthmap for .special-widths elements
    if($(e.target).is('.special-widths')){
        // (Note: With version 1.1.0 the ``details`` property will be renamed to ``detail``.)
        e.detail.widths = [320, 480, 600];
        e.detail.widthmap = {
              320: 'small',
              480: 'medium',
              600: 'large'
         };
    }

    //add new custom property with value 'foo'
    e.detail.custom = 'foo';

    e.detail.quality = (window.devicePixelRatio || 1) > 1.9 ? 50 : 80;
});
</script>
<img
    data-src="image-w{width}-w{custom}-q{quality}.jpg"
    data-sizes="auto"
    class="lazyload special-widths"
    alt="" />
```

### Tip: Constraining the pixel density for a generated ``srcset`` attribute.

In case you don't want to generate additional compressive images for high resolution displays you can combine the RIaS extension with the [optimumx extension](../optimumx) to constrain the maximum pixel density for the generated ``srcset`` list.

```html
<script src="http://cdn.jsdelivr.net/g/lazysizes(lazysizes.min.js+plugins/rias/ls.rias.min.js+plugins/optimumx/ls.optimumx.min.js)" async=""></script>


<img
    data-src="image-width-{width}.jpg"
    data-optimumx="1.6"
    data-sizes="auto"
    class="lazyload" />
```

