Skip to content

Commit 2346c13

Browse files
authored
Merge pull request #247 from CSSSR/feat/COM-3172
[COM-3172]: add avif support
2 parents 361e608 + 93d924b commit 2346c13

6 files changed

Lines changed: 41 additions & 20 deletions

File tree

example/react-entry.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { PictureSmart } from '../src/react';
44
import { backgroundCssSmart } from '../src/utils/backgroundCss';
55
import { getOriginal } from '../src/utils';
66

7-
// Adds 'webp' class to html element if the browser supports webp.
8-
import '../src/utils/webpDetector';
7+
// Adds 'webp' or 'avif' class to html element if the browser supports it.
8+
import '../src/utils/imgSupportDetector';
99

1010
const oneImageForAllBreakpoints = require.context('./images/oneImageForAllBreakpoints');
1111
const differentBreakpoints = require.context('./images/differentBreakpoints');

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@csssr/csssr.images",
3-
"version": "3.3.2",
3+
"version": "3.3.3",
44
"description": "Utilities for Webpack and React to simplify images workflow",
55
"main": "dist/index.js",
66
"types": "dist",

src/utils/backgroundCss.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@ const breakpointMedia = (media: string | null): ((nestedCss: string) => string)
99
};
1010

1111
const getSelector = (selector: string, extension: string) => {
12-
return extension === 'webp' ? `html.webp ${selector}` : selector;
12+
if (extension === 'avif') {
13+
return `html.avif ${selector}`;
14+
}
15+
16+
if (extension === 'webp') {
17+
return `html.webp ${selector}`;
18+
}
19+
20+
return selector;
1321
};
1422

1523
const srcSetCss = (selector: string, sources: ExtensionSrcSet[]): string => {

src/utils/imgSupportDetector.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// https://avif.io/blog/tutorials/use-avif-in-css/
2+
3+
function imgSupportDetector () {
4+
const avif = new Image();
5+
avif.src = "data:image/avif;base64,AAAAFGZ0eXBhdmlmAAAAAG1pZjEAAACgbWV0YQAAAAAAAAAOcGl0bQAAAAAAAQAAAB5pbG9jAAAAAEQAAAEAAQAAAAEAAAC8AAAAGwAAACNpaW5mAAAAAAABAAAAFWluZmUCAAAAAAEAAGF2MDEAAAAARWlwcnAAAAAoaXBjbwAAABRpc3BlAAAAAAAAAAQAAAAEAAAADGF2MUOBAAAAAAAAFWlwbWEAAAAAAAAAAQABAgECAAAAI21kYXQSAAoIP8R8hAQ0BUAyDWeeUy0JG+QAACANEkA=";
6+
avif.onload = () => { document.documentElement.classList.add("avif") };
7+
8+
// before we remove `generateAvif` flag, we want to detect webp support even if avif support is present
9+
const webp = new Image();
10+
webp.src = "data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==";
11+
webp.onload = () => { document.documentElement.classList.add("webp") };
12+
}
13+
14+
imgSupportDetector();

src/utils/webpDetector.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/webpack/loader.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export type LoaderOptions = {
1919
disable: boolean;
2020
imagesHost: string;
2121
host: string;
22+
generateAvif: boolean;
2223
};
2324
originalPixelRatio: Dpr;
2425
};
@@ -68,7 +69,7 @@ export const loader = function (this: webpack.loader.LoaderContext, source: stri
6869
(a, b, imagePath) => imagePath,
6970
);
7071

71-
let webpSrcSet: SrcSet, originalExtensionSrcSet: SrcSet, data: OrderedBreakpointSource;
72+
let avifSrcSet: SrcSet, webpSrcSet: SrcSet, originalExtensionSrcSet: SrcSet, data: OrderedBreakpointSource;
7273
// Disables picture processing, srcSet is generated only for the original image type
7374
if (options.imgproxy.disable) {
7475
data = {
@@ -86,6 +87,7 @@ export const loader = function (this: webpack.loader.LoaderContext, source: stri
8687
};
8788
} else {
8889
const buildUrlsForPixelRatios = getImgproxyUrlBuilder(options.imgproxy);
90+
avifSrcSet = buildUrlsForPixelRatios(pixelRatios, outputImagePath, 'avif');
8991
webpSrcSet = buildUrlsForPixelRatios(pixelRatios, outputImagePath, 'webp');
9092
originalExtensionSrcSet = buildUrlsForPixelRatios(
9193
pixelRatios,
@@ -107,6 +109,18 @@ export const loader = function (this: webpack.loader.LoaderContext, source: stri
107109
},
108110
],
109111
};
112+
113+
if (options.imgproxy.generateAvif) {
114+
data.srcSets.unshift({
115+
extension: 'avif',
116+
srcSet: avifSrcSet,
117+
})
118+
119+
imageUrls.push(
120+
...(Object.values(avifSrcSet) as string[]),
121+
);
122+
}
123+
110124
// Add links to images via imgproxy to the global object
111125
imageUrls.push(
112126
...(Object.values(webpSrcSet) as string[]),

0 commit comments

Comments
 (0)