Skip to content

Commit 8590f6b

Browse files
committed
wip support of different originalPixelRatios
1 parent 873fcda commit 8590f6b

10 files changed

Lines changed: 171 additions & 61 deletions

File tree

example/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
Чтобы запустить этот пример,
44
нужно предварительно запустить imgproxy локально на 8080 порту командой
55
`docker run -e IMGPROXY_MAX_SRC_RESOLUTION=40 -p 8080:8080 -it darthsim/imgproxy`,
6-
затем выполнить `npm run run-example` из корня проекта
6+
затем выполнить `npm run dev` из корня проекта
77
и открыть в браузере http://localhost:8081/.

example/react-entry.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,33 @@ import { backgroundCssSmart } from '../src/utils/backgroundCss';
77
import '../src/utils/webpDetector'
88

99
const oneImageForAllBreakpoints = require.context('./images/oneImageForAllBreakpoints');
10-
const differentBreakpoints = require.context('./images/differentBreakpoints');
10+
// const differentBreakpoints = require.context('./images/differentBreakpoints');
11+
12+
const oneImageForAllBreakpointsWithoutResize = require.context('./images/oneImageForAllBreakpoints?dontresize');
1113

1214
ReactDOM.render(
1315
<div>
1416
<h1>Example usage of csssr.images</h1>
1517

1618
<h2>As picture tag</h2>
1719
<h3>One image for all resolutions</h3>
20+
<PictureSmart requireImages={oneImageForAllBreakpointsWithoutResize} alt="One image for all resolutions" />
1821
<PictureSmart requireImages={oneImageForAllBreakpoints} alt="One image for all resolutions" />
19-
<h3>Image with different breakpoints</h3>
20-
<PictureSmart requireImages={differentBreakpoints} alt="Image with different breakpoints" />
22+
{/*<h3>Image with different breakpoints</h3>*/}
23+
{/*<PictureSmart requireImages={differentBreakpoints} alt="Image with different breakpoints" />*/}
2124

2225

23-
<h2>As background css</h2>
24-
<h3>One image for all resolutions</h3>
25-
<div className="one-image-for-all-resolutions" style={{ width: '100%', height: '100%' }}>
26-
One image for all resolutions on background
27-
</div>
28-
<style>{backgroundCssSmart('.one-image-for-all-resolutions', oneImageForAllBreakpoints)}</style>
29-
<h3>Different breakpoints</h3>
30-
<div className="different-breakpoints" style={{ width: '100%', height: '100%' }}>
31-
Image with different breakpoints on background
32-
</div>
33-
<style>{backgroundCssSmart('.different-breakpoints', differentBreakpoints)}</style>
26+
{/*<h2>As background css</h2>*/}
27+
{/*<h3>One image for all resolutions</h3>*/}
28+
{/*<div className="one-image-for-all-resolutions" style={{ width: '100%', height: '100%' }}>*/}
29+
{/* One image for all resolutions on background*/}
30+
{/*</div>*/}
31+
{/*<style>{backgroundCssSmart('.one-image-for-all-resolutions', oneImageForAllBreakpoints)}</style>*/}
32+
{/*<h3>Different breakpoints</h3>*/}
33+
{/*<div className="different-breakpoints" style={{ width: '100%', height: '100%' }}>*/}
34+
{/* Image with different breakpoints on background*/}
35+
{/*</div>*/}
36+
{/*<style>{backgroundCssSmart('.different-breakpoints', differentBreakpoints)}</style>*/}
3437
</div>,
3538
document.getElementById('app'),
3639
);

example/webpack.config.ts

Lines changed: 82 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import path from 'path';
22
import webpack from 'webpack';
3+
const ip = require('ip')
34
import { Plugin } from '../src/webpack';
45

56
const config: webpack.Configuration = {
@@ -23,42 +24,93 @@ const config: webpack.Configuration = {
2324
},
2425
{
2526
test: /\.(jpe?g|png|gif)$/,
26-
use: [
27+
oneOf: [
2728
{
28-
loader: path.resolve(__dirname, '../src/index.ts'),
29-
options: {
30-
breakpoints: [
31-
{
32-
name: 'mobile',
33-
maxWidth: 767,
34-
},
35-
{
36-
name: 'tablet',
37-
minWidth: 768,
38-
maxWidth: 1279,
29+
resourceQuery: /dontresize/,
30+
// TODO reuse
31+
use: [
32+
{
33+
loader: path.resolve(__dirname, '../src/index.ts'),
34+
options: {
35+
breakpoints: [
36+
{
37+
name: 'mobile',
38+
maxWidth: 767,
39+
},
40+
{
41+
name: 'tablet',
42+
minWidth: 768,
43+
maxWidth: 1279,
44+
},
45+
{
46+
name: 'desktop',
47+
minWidth: 1280,
48+
},
49+
],
50+
imgproxy: {
51+
disable: false,
52+
imagesHost: process.env.HOST || `http://${ip.address()}:8081`,
53+
host: process.env.IMGPROXY_HOST || 'http://localhost:8080',
54+
},
55+
// TODO использовать originalPixelRatio
56+
shouldResize: false,
57+
// originalPixelRatio: '1x',
3958
},
40-
{
41-
name: 'desktop',
42-
minWidth: 1280,
59+
},
60+
{
61+
loader: 'file-loader',
62+
options: {
63+
publicPath: '/build',
64+
name:
65+
process.env.NODE_ENV === 'development'
66+
? '[path][name].[ext]'
67+
: '[path][name]-[hash:8].[ext]',
68+
esModule: false,
4369
},
44-
],
45-
imgproxy: {
46-
disable: false,
47-
imagesHost: process.env.HOST || 'http://192.168.1.134:8081',
48-
host: process.env.IMGPROXY_HOST || 'http://localhost:8080',
4970
},
50-
},
71+
],
5172
},
5273
{
53-
loader: 'file-loader',
54-
options: {
55-
publicPath: '/build',
56-
name:
57-
process.env.NODE_ENV === 'development'
58-
? '[path][name].[ext]'
59-
: '[path][name]-[hash:8].[ext]',
60-
esModule: false,
61-
},
74+
use: [
75+
{
76+
loader: path.resolve(__dirname, '../src/index.ts'),
77+
options: {
78+
breakpoints: [
79+
{
80+
name: 'mobile',
81+
maxWidth: 767,
82+
},
83+
{
84+
name: 'tablet',
85+
minWidth: 768,
86+
maxWidth: 1279,
87+
},
88+
{
89+
name: 'desktop',
90+
minWidth: 1280,
91+
},
92+
],
93+
imgproxy: {
94+
disable: false,
95+
imagesHost: process.env.HOST || `http://${ip.address()}:8081`,
96+
host: process.env.IMGPROXY_HOST || 'http://localhost:8080',
97+
},
98+
shouldResize: true,
99+
// originalPixelRatio: '3x',
100+
},
101+
},
102+
{
103+
loader: 'file-loader',
104+
options: {
105+
publicPath: '/build',
106+
name:
107+
process.env.NODE_ENV === 'development'
108+
? '[path][name].[ext]'
109+
: '[path][name]-[hash:8].[ext]',
110+
esModule: false,
111+
},
112+
},
113+
]
62114
},
63115
],
64116
},

package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"eslint-plugin-react": "^7.20.0",
3939
"file-loader": "^6.0.0",
4040
"http-server": "^0.12.3",
41+
"ip": "^1.1.5",
4142
"jest": "^26.0.1",
4243
"loader-utils": "^2.0.0",
4344
"prettier": "^2.0.5",

src/types.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
11
export type Dpr = '1x' | '2x' | '3x';
22

3+
// TODO поправить этот тип
4+
// export type SrcSet = {
5+
// '1x': string;
6+
// } | {
7+
// '1x': string;
8+
// '2x': string;
9+
// } | {
10+
// '1x': string;
11+
// '2x': string;
12+
// '3x': string;
13+
// };
314
export type SrcSet = {
4-
[dpr in Dpr]: string;
15+
'1x': string;
16+
'2x'?: string;
17+
'3x'?: string;
518
};
619

720
export type ExtensionSrcSet = {

src/utils/getOriginal.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { BreakpointSource } from '../types';
22

3-
export const getOriginal = (source: BreakpointSource): string =>
4-
source.srcSets[source.srcSets.length - 1].srcSet['3x'];
3+
export const getOriginal = (source: BreakpointSource): string => {
4+
// TODO здесь использовалось 3x изображение
5+
// Надо использовать самое большое по значению
6+
// или может быть сохранять где-то original раньше
7+
return source.srcSets[source.srcSets.length - 1].srcSet['1x']
8+
}

src/webpack/imgproxyUrlBuilder.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import Imgproxy from 'imgproxy';
2-
import { SrcSet } from '../types';
2+
import { Dpr, SrcSet } from '../types'
33

44
type ImgproxyUrlBuilderConfig = {
55
imagesHost: string;
66
host: string;
77
};
88

9-
export type BuildUrlsForAllPixelRatios = (imagePath: string, extension: string) => SrcSet;
9+
export type BuildUrlsForPixelRatios = (pixelRatios: Dpr[], imagePath: string, extension: string) => SrcSet;
1010

1111
export const getImgproxyUrlBuilder = ({
1212
imagesHost,
1313
host,
14-
}: ImgproxyUrlBuilderConfig): BuildUrlsForAllPixelRatios => {
14+
}: ImgproxyUrlBuilderConfig): BuildUrlsForPixelRatios => {
1515
const imgproxy = new Imgproxy({
1616
baseUrl: host,
1717
encode: false,
@@ -24,10 +24,21 @@ export const getImgproxyUrlBuilder = ({
2424
.generateUrl(imagesHost + imgPath, extension);
2525
};
2626

27-
return (imagePath: string, extension: string): SrcSet => ({
28-
'1x': buildImgproxyUrl(imagePath, 0.3333, extension),
29-
'2x': buildImgproxyUrl(imagePath, 0.6666, extension),
30-
// 0 здесь означает, что не будет никакого изменения размеров картинки
31-
'3x': buildImgproxyUrl(imagePath, 0, extension),
32-
});
27+
return (pixelRatios: Dpr[], imagePath: string, extension: string): SrcSet => {
28+
// TODO выводить коэффициенты сжатия (изменения размера) из количества элементов массива
29+
// или из значений массива
30+
// [1x, 2x] -> {1x: 0.5, 2x: 1}
31+
32+
if (pixelRatios.length === 1) {
33+
return {
34+
'1x': buildImgproxyUrl(imagePath, 1, extension),
35+
}
36+
}
37+
return {
38+
'1x': buildImgproxyUrl(imagePath, 0.3333, extension),
39+
'2x': buildImgproxyUrl(imagePath, 0.6666, extension),
40+
// 0 здесь означает, что не будет никакого изменения размеров картинки
41+
'3x': buildImgproxyUrl(imagePath, 0, extension),
42+
}
43+
};
3344
};

src/webpack/loader.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export type LoaderOptions = {
1919
imagesHost: string;
2020
host: string;
2121
};
22+
shouldResize: boolean;
2223
};
2324

2425
// Каждый импорт картинки проходит через этот лоадер и на выходе
@@ -29,6 +30,10 @@ export const loader = function (this: webpack.loader.LoaderContext, source: stri
2930

3031
validateOptions(schema, options, { name: 'Imgproxy responsive loader', baseDataPath: 'options' });
3132

33+
// TODO
34+
// Подготовить здесь массив с pixelRatios [1x 2x 3x] [1x 2x] [1x]
35+
// Я не уверен в каком порядке должны быть элементы массива
36+
3237
const breakpoints: Breakpoint[] = options.breakpoints;
3338

3439
// Такой результат приходит от file-loader 'module.exports = "/build/myImage/mobile.all-4b767a7b.png";'
@@ -66,6 +71,8 @@ export const loader = function (this: webpack.loader.LoaderContext, source: stri
6671
let webpSrcSet: SrcSet, originalExtensionSrcSet: SrcSet, data: OrderedBreakpointSource;
6772
// Отключает процессинг картинок, генерируется srcSet только для оригинального типа изображения
6873
if (options.imgproxy.disable) {
74+
// TODO пока не смотрим disable
75+
6976
originalExtensionSrcSet = {
7077
'1x': outputImagePath,
7178
'2x': outputImagePath,
@@ -82,9 +89,19 @@ export const loader = function (this: webpack.loader.LoaderContext, source: stri
8289
],
8390
};
8491
} else {
85-
const buildUrlsForAllPixelRatios = getImgproxyUrlBuilder(options.imgproxy);
86-
webpSrcSet = buildUrlsForAllPixelRatios(outputImagePath, 'webp');
87-
originalExtensionSrcSet = buildUrlsForAllPixelRatios(outputImagePath, originalExtension);
92+
const buildUrlsForPixelRatios = getImgproxyUrlBuilder(options.imgproxy);
93+
console.log(options.shouldResize)
94+
if (options.shouldResize) {
95+
// TODO убрать хардкод, вынести в опции лоадера?
96+
// originalRatio: 3x -> 3x 2x 1x
97+
// originalRatio: 2x -> 2x 1x
98+
// originalRatio: 1x -> 1x
99+
webpSrcSet = buildUrlsForPixelRatios(['1x', '2x', '3x'], outputImagePath, 'webp');
100+
originalExtensionSrcSet = buildUrlsForPixelRatios(['1x', '2x', '3x'], outputImagePath, originalExtension);
101+
} else {
102+
webpSrcSet = buildUrlsForPixelRatios(['1x'], outputImagePath, 'webp');
103+
originalExtensionSrcSet = buildUrlsForPixelRatios(['1x'], outputImagePath, originalExtension);
104+
}
88105
data = {
89106
order,
90107
breakpointMedia,
@@ -100,7 +117,7 @@ export const loader = function (this: webpack.loader.LoaderContext, source: stri
100117
],
101118
};
102119
// Добавляем ссылки на картинки через imgproxy в глобальный объект
103-
imageUrls.push(...Object.values(webpSrcSet), ...Object.values(originalExtensionSrcSet));
120+
imageUrls.push(...(Object.values(webpSrcSet) as string[]), ...(Object.values(originalExtensionSrcSet) as string[]));
104121
}
105122

106123
const result: OrderedBreakpointSource = data;

src/webpack/loaderOptionsSchema.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ export const schema: JSONSchema7 = {
4848
},
4949
],
5050
},
51+
shouldResize: {
52+
type: 'boolean',
53+
}
5154
},
5255
required: ['breakpoints', 'imgproxy'],
5356
additionalProperties: false,

0 commit comments

Comments
 (0)