[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 <dpcalhoun@gmail.com>
This commit is contained in:
Evan Bacon
2019-07-31 13:41:53 -07:00
committed by Nicolas Gallagher
parent c8b73fa4e4
commit a7ab961d95
3 changed files with 32 additions and 5 deletions
@@ -317,14 +317,14 @@ exports[`components/Image prop "style" removes other unsupported View styles 1`]
> >
<div <div
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" 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"
style="filter: url(#tint-31);" style="filter: url(#tint-33);"
/> />
<svg <svg
style="position: absolute; height: 0px; visibility: hidden; width: 0px;" style="position: absolute; height: 0px; visibility: hidden; width: 0px;"
> >
<defs> <defs>
<filter <filter
id="tint-31" id="tint-33"
> >
<feflood <feflood
flood-color="blue" flood-color="blue"
@@ -366,7 +366,7 @@ exports[`components/Image prop "style" supports "tintcolor" property (convert to
> >
<div <div
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" 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"
style="background-image: url(https://google.com/favicon.ico); filter: url(#tint-30);" style="background-image: url(https://google.com/favicon.ico); filter: url(#tint-32);"
/> />
<img <img
alt="" alt=""
@@ -379,7 +379,7 @@ exports[`components/Image prop "style" supports "tintcolor" property (convert to
> >
<defs> <defs>
<filter <filter
id="tint-30" id="tint-32"
> >
<feflood <feflood
flood-color="red" flood-color="red"
@@ -1,9 +1,11 @@
/* eslint-env jasmine, jest */ /* eslint-env jasmine, jest */
/* eslint-disable react/jsx-no-bind */ /* eslint-disable react/jsx-no-bind */
import * as AssetRegistry from '../../../modules/AssetRegistry';
import Image from '../'; import Image from '../';
import ImageLoader from '../../../modules/ImageLoader'; import ImageLoader from '../../../modules/ImageLoader';
import ImageUriCache from '../ImageUriCache'; import ImageUriCache from '../ImageUriCache';
import PixelRatio from '../../PixelRatio';
import React from 'react'; import React from 'react';
import { render } from '@testing-library/react'; import { render } from '@testing-library/react';
@@ -200,6 +202,23 @@ describe('components/Image', () => {
loadCallback(); loadCallback();
expect(container.firstChild).toMatchSnapshot(); expect(container.firstChild).toMatchSnapshot();
}); });
test('it correctly selects the source scale', () => {
AssetRegistry.getAssetByID = jest.fn(() => ({
httpServerLocation: 'static',
name: 'img',
scales: [1, 2, 3],
type: 'png'
}));
PixelRatio.get = jest.fn(() => 1.0);
let { container } = render(<Image source={1} />);
expect(container.querySelector('img').src).toBe('http://localhost/static/img.png');
PixelRatio.get = jest.fn(() => 2.2);
({ container } = render(<Image source={1} />));
expect(container.querySelector('img').src).toBe('http://localhost/static/img@2x.png');
});
}); });
describe('prop "style"', () => { describe('prop "style"', () => {
+9 -1
View File
@@ -18,6 +18,7 @@ import { getAssetByID } from '../../modules/AssetRegistry';
import resolveShadowValue from '../StyleSheet/resolveShadowValue'; import resolveShadowValue from '../StyleSheet/resolveShadowValue';
import ImageLoader from '../../modules/ImageLoader'; import ImageLoader from '../../modules/ImageLoader';
import ImageUriCache from './ImageUriCache'; import ImageUriCache from './ImageUriCache';
import PixelRatio from '../PixelRatio';
import StyleSheet from '../StyleSheet'; import StyleSheet from '../StyleSheet';
import TextAncestorContext from '../Text/TextAncestorContext'; import TextAncestorContext from '../Text/TextAncestorContext';
import View from '../View'; import View from '../View';
@@ -70,7 +71,14 @@ const resolveAssetUri = source => {
if (typeof source === 'number') { if (typeof source === 'number') {
// get the URI from the packager // get the URI from the packager
const asset = getAssetByID(source); const asset = getAssetByID(source);
const scale = asset.scales[0]; let scale = asset.scales[0];
if (asset.scales.length > 1) {
const preferredScale = PixelRatio.get();
// Get the scale which is closest to the preferred scale
scale = asset.scales.reduce((prev, curr) =>
Math.abs(curr - preferredScale) < Math.abs(prev - preferredScale) ? curr : prev
);
}
const scaleSuffix = scale !== 1 ? `@${scale}x` : ''; const scaleSuffix = scale !== 1 ? `@${scale}x` : '';
uri = asset ? `${asset.httpServerLocation}/${asset.name}${scaleSuffix}.${asset.type}` : ''; uri = asset ? `${asset.httpServerLocation}/${asset.name}${scaleSuffix}.${asset.type}` : '';
} else if (typeof source === 'string') { } else if (typeof source === 'string') {