Skip to content

Commit

Permalink
feat: dpr srcset options (#307)
Browse files Browse the repository at this point in the history
feat: dpr srcset options
  • Loading branch information
sylcastaing committed Dec 16, 2021
1 parent 5e6b3b6 commit 380abf0
Show file tree
Hide file tree
Showing 8 changed files with 311 additions and 12 deletions.
75 changes: 69 additions & 6 deletions README.md
Expand Up @@ -55,7 +55,7 @@ Depending on your module system, using @imgix/js-core is done a few different wa
### CommonJS

```js
const ImgixClient = require("@imgix/js-core");
const ImgixClient = require('@imgix/js-core');

const client = new ImgixClient({
domain: 'testing.imgix.net',
Expand All @@ -73,7 +73,7 @@ console.log(url); // => "https://testing.imgix.net/users/1.png?w=400&h=300&s=…
### ES6 Modules

```js
import ImgixClient from "@imgix/js-core";
import ImgixClient from '@imgix/js-core';

const client = new ImgixClient({
domain: 'testing.imgix.net',
Expand Down Expand Up @@ -144,6 +144,8 @@ https://testing.imgix.net/folder/image.jpg?w=1000&ixlib=js-...
- [**`minWidth`**](#minimum-and-maximum-width-ranges)
- [**`maxWidth`**](#minimum-and-maximum-width-ranges)
- [**`disableVariableQuality`**](#variable-qualities)
- [**`devicePixelRatios`**](#fixed-image-rendering)
- [**`variableQualities`**](#variable-qualities)

<!-- prettier-ignore-end -->

Expand Down Expand Up @@ -210,6 +212,38 @@ https://testing.imgix.net/image.jpg?h=800&ar=3%3A2&fit=crop&dpr=5&s=7c4b8adb733d

<!-- prettier-ignore-end -->

This library generate by default `1` to `5` dpr `srcset`.
You can control generated target ratios with `devicePixelRatios` parameters.

```js
const client = new ImgixClient({
domain: 'testing.imgix.net',
secureURLToken: 'my-token',
includeLibraryParam: false,
});

const srcset = client.buildSrcSet(
'image.jpg',
{
h: 800,
ar: '3:2',
fit: 'crop',
},
{
devicePixelRatios: [1, 2],
},
);

console.log(srcset);
```

Will result in a smaller srcset.

```html
https://testing.imgix.net/image.jpg?h=800&ar=3%3A2&fit=crop&dpr=1&s=3d754a157458402fd3e26977107ade74 1x,
https://testing.imgix.net/image.jpg?h=800&ar=3%3A2&fit=crop&dpr=2&s=a984ad1a81d24d9dd7d18195d5262c82 2x
```

For more information to better understand `srcset`, we highly recommend [Eric Portis' "Srcset and sizes" article](https://ericportis.com/posts/2014/srcset-sizes/) which goes into depth about the subject.

#### Custom Widths
Expand All @@ -225,7 +259,7 @@ const client = new ImgixClient({
const srcset = client.buildSrcSet(
'image.jpg',
{},
{ widths: [100, 500, 1000, 1800] }
{ widths: [100, 500, 1000, 1800] },
);

console.log(srcset);
Expand Down Expand Up @@ -286,7 +320,7 @@ const client = new ImgixClient({
const srcset = client.buildSrcSet(
'image.jpg',
{},
{ minWidth: 500, maxWidth: 2000 }
{ minWidth: 500, maxWidth: 2000 },
);

console.log(srcset);
Expand Down Expand Up @@ -327,9 +361,11 @@ const client = new ImgixClient({
});

const srcset = client.buildSrcSet('image.jpg', { w: 100 });

console.log(srcset);
```

will generate a srcset with the following `q` to `dpr` mapping:
Will generate a srcset with the following `q` to `dpr` mapping:

```html
https://testing.imgix.net/image.jpg?w=100&dpr=1&q=75 1x,
Expand All @@ -339,6 +375,33 @@ https://testing.imgix.net/image.jpg?w=100&dpr=4&q=23 4x,
https://testing.imgix.net/image.jpg?w=100&dpr=5&q=20 5x
```

Quality parameters is overridable for each `dpr` by passing `variableQualities` parameters.

```js
const client = new ImgixClient({
domain: 'testing.imgix.net',
includeLibraryParam: false,
});

const srcset = client.buildSrcSet(
'image.jpg',
{ w: 100 },
{ variableQualities: { 1: 45, 2: 30, 3: 20, 4: 15, 5: 10 } },
);

console.log(srcset);
```

Will generate the following custom `q` to `dpr` mapping:

```html
https://testing.imgix.net/image.jpg?w=100&dpr=1&q=45 1x,
https://testing.imgix.net/image.jpg?w=100&dpr=2&q=30 2x,
https://testing.imgix.net/image.jpg?w=100&dpr=3&q=20 3x,
https://testing.imgix.net/image.jpg?w=100&dpr=4&q=15 4x,
https://testing.imgix.net/image.jpg?w=100&dpr=5&q=10 5x
```

### Web Proxy Sources

If you are using a [Web Proxy Source](https://docs.imgix.com/setup/creating-sources/web-proxy), all you need to do is pass the full image URL you would like to proxy to `@imgix/js-core` as the path, and include a `secureURLToken` when creating the client. `@imgix/js-core` will then encode this full URL into a format that imgix will understand, thus creating a proxy URL for you.
Expand Down Expand Up @@ -376,6 +439,6 @@ new ImgixClient({
npm test
```


## License

[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fimgix%2Fimgix-core-js.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fimgix%2Fimgix-core-js?ref=badge_large)
9 changes: 7 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/constants.js
Expand Up @@ -18,6 +18,8 @@ export const DPR_QUALITIES = {
5: 20,
};

export const DEFAULT_DPR = [1, 2, 3, 4, 5];

export const DEFAULT_OPTIONS = {
domain: null,
useHTTPS: true,
Expand Down
18 changes: 16 additions & 2 deletions src/index.js
Expand Up @@ -6,6 +6,7 @@ import {
DOMAIN_REGEX,
DEFAULT_OPTIONS,
DPR_QUALITIES,
DEFAULT_DPR,
} from './constants.js';

import {
Expand All @@ -14,6 +15,8 @@ import {
validateAndDestructureOptions,
validateVariableQuality,
validateWidthTolerance,
validateDevicePixelRatios,
validateVariableQualities,
} from './validators.js';

export default class ImgixClient {
Expand Down Expand Up @@ -191,18 +194,29 @@ export default class ImgixClient {
}

_buildDPRSrcSet(path, params, options) {
const targetRatios = [1, 2, 3, 4, 5];
if (options.devicePixelRatios) {
validateDevicePixelRatios(options.devicePixelRatios);
}

const targetRatios = options.devicePixelRatios || DEFAULT_DPR;

const disableVariableQuality = options.disableVariableQuality || false;

if (!disableVariableQuality) {
validateVariableQuality(disableVariableQuality);
}

if (options.variableQualities) {
validateVariableQualities(options.variableQualities);
}

const qualities = { ...DPR_QUALITIES, ...options.variableQualities };

const withQuality = (path, params, dpr) => {
return `${this.buildURL(path, {
...params,
dpr: dpr,
q: params.q || DPR_QUALITIES[dpr],
q: params.q || qualities[dpr] || qualities[Math.floor(dpr)],
})} ${dpr}x`;
};

Expand Down
24 changes: 24 additions & 0 deletions src/validators.js
Expand Up @@ -71,3 +71,27 @@ export function validateVariableQuality(disableVariableQuality) {
);
}
}

export function validateDevicePixelRatios(devicePixelRatios) {
if (!Array.isArray(devicePixelRatios) || !devicePixelRatios.length) {
throw new Error(
'The devicePixelRatios argument can only be passed a valid non-empty array of integers',
);
} else {
const allValidDPR = devicePixelRatios.every(function (dpr) {
return typeof dpr === 'number' && dpr >= 1 && dpr <= 5;
});

if (!allValidDPR) {
throw new Error(
'The devicePixelRatios argument can only contain positive integer values between 1 and 5',
);
}
}
}

export function validateVariableQualities(variableQualities) {
if (typeof variableQualities !== 'object') {
throw new Error('The variableQualities argument can only be an object');
}
}

0 comments on commit 380abf0

Please sign in to comment.