Skip to content

Commit a7ab961

Browse files
EvanBacondcalhoun
authored andcommitted
[fix] Image support for variable resolution images
Renders the asset scale which is closest to the window scale. Requires bundler integration. Close #1456 Co-authored-by: David Calhoun <[email protected]>
1 parent c8b73fa commit a7ab961

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

packages/react-native-web/src/exports/Image/__tests__/__snapshots__/index-test.js.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -317,14 +317,14 @@ exports[`components/Image prop "style" removes other unsupported View styles 1`]
317317
>
318318
<div
319319
class="css-view-1dbjc4n r-backgroundColor-1niwhzg r-backgroundPosition-vvn4in r-backgroundRepeat-u6sd8q r-backgroundSize-4gszlv r-bottom-1p0dtai r-height-1pi2tsx r-left-1d2f490 r-position-u8s1d r-right-zchlnj r-top-ipm5af r-width-13qz1uu r-zIndex-1wyyakw"
320-
style="filter: url(#tint-31);"
320+
style="filter: url(#tint-33);"
321321
/>
322322
<svg
323323
style="position: absolute; height: 0px; visibility: hidden; width: 0px;"
324324
>
325325
<defs>
326326
<filter
327-
id="tint-31"
327+
id="tint-33"
328328
>
329329
<feflood
330330
flood-color="blue"
@@ -366,7 +366,7 @@ exports[`components/Image prop "style" supports "tintcolor" property (convert to
366366
>
367367
<div
368368
class="css-view-1dbjc4n r-backgroundColor-1niwhzg r-backgroundPosition-vvn4in r-backgroundRepeat-u6sd8q r-backgroundSize-4gszlv r-bottom-1p0dtai r-height-1pi2tsx r-left-1d2f490 r-position-u8s1d r-right-zchlnj r-top-ipm5af r-width-13qz1uu r-zIndex-1wyyakw"
369-
style="background-image: url(https://google.com/favicon.ico); filter: url(#tint-30);"
369+
style="background-image: url(https://google.com/favicon.ico); filter: url(#tint-32);"
370370
/>
371371
<img
372372
alt=""
@@ -379,7 +379,7 @@ exports[`components/Image prop "style" supports "tintcolor" property (convert to
379379
>
380380
<defs>
381381
<filter
382-
id="tint-30"
382+
id="tint-32"
383383
>
384384
<feflood
385385
flood-color="red"

packages/react-native-web/src/exports/Image/__tests__/index-test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
/* eslint-env jasmine, jest */
22
/* eslint-disable react/jsx-no-bind */
33

4+
import * as AssetRegistry from '../../../modules/AssetRegistry';
45
import Image from '../';
56
import ImageLoader from '../../../modules/ImageLoader';
67
import ImageUriCache from '../ImageUriCache';
8+
import PixelRatio from '../../PixelRatio';
79
import React from 'react';
810
import { render } from '@testing-library/react';
911

@@ -200,6 +202,23 @@ describe('components/Image', () => {
200202
loadCallback();
201203
expect(container.firstChild).toMatchSnapshot();
202204
});
205+
206+
test('it correctly selects the source scale', () => {
207+
AssetRegistry.getAssetByID = jest.fn(() => ({
208+
httpServerLocation: 'static',
209+
name: 'img',
210+
scales: [1, 2, 3],
211+
type: 'png'
212+
}));
213+
214+
PixelRatio.get = jest.fn(() => 1.0);
215+
let { container } = render(<Image source={1} />);
216+
expect(container.querySelector('img').src).toBe('http://localhost/static/img.png');
217+
218+
PixelRatio.get = jest.fn(() => 2.2);
219+
({ container } = render(<Image source={1} />));
220+
expect(container.querySelector('img').src).toBe('http://localhost/static/[email protected]');
221+
});
203222
});
204223

205224
describe('prop "style"', () => {

packages/react-native-web/src/exports/Image/index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { getAssetByID } from '../../modules/AssetRegistry';
1818
import resolveShadowValue from '../StyleSheet/resolveShadowValue';
1919
import ImageLoader from '../../modules/ImageLoader';
2020
import ImageUriCache from './ImageUriCache';
21+
import PixelRatio from '../PixelRatio';
2122
import StyleSheet from '../StyleSheet';
2223
import TextAncestorContext from '../Text/TextAncestorContext';
2324
import View from '../View';
@@ -70,7 +71,14 @@ const resolveAssetUri = source => {
7071
if (typeof source === 'number') {
7172
// get the URI from the packager
7273
const asset = getAssetByID(source);
73-
const scale = asset.scales[0];
74+
let scale = asset.scales[0];
75+
if (asset.scales.length > 1) {
76+
const preferredScale = PixelRatio.get();
77+
// Get the scale which is closest to the preferred scale
78+
scale = asset.scales.reduce((prev, curr) =>
79+
Math.abs(curr - preferredScale) < Math.abs(prev - preferredScale) ? curr : prev
80+
);
81+
}
7482
const scaleSuffix = scale !== 1 ? `@${scale}x` : '';
7583
uri = asset ? `${asset.httpServerLocation}/${asset.name}${scaleSuffix}.${asset.type}` : '';
7684
} else if (typeof source === 'string') {

0 commit comments

Comments
 (0)