diff --git a/packages/examples/pages/image/index.js b/packages/examples/pages/image/index.js
index 77cc927a..d894bab9 100644
--- a/packages/examples/pages/image/index.js
+++ b/packages/examples/pages/image/index.js
@@ -98,6 +98,17 @@ export default function ImagePage() {
+
+
+
+ Tint color
+
+
+
+ Tint color
+
+
+
);
}
diff --git a/packages/react-native-web/src/exports/Image/__tests__/__snapshots__/index-test.js.snap b/packages/react-native-web/src/exports/Image/__tests__/__snapshots__/index-test.js.snap
index bf1367a0..101048bb 100644
--- a/packages/react-native-web/src/exports/Image/__tests__/__snapshots__/index-test.js.snap
+++ b/packages/react-native-web/src/exports/Image/__tests__/__snapshots__/index-test.js.snap
@@ -329,25 +329,8 @@ exports[`components/Image prop "style" removes other unsupported View styles 1`]
>
#tint');"
/>
-
`;
@@ -378,7 +361,7 @@ exports[`components/Image prop "style" supports "tintcolor" property (convert to
>
#tint');"
/>

-
`;
diff --git a/packages/react-native-web/src/exports/Image/index.js b/packages/react-native-web/src/exports/Image/index.js
index 7cbde9f5..c2c50a36 100644
--- a/packages/react-native-web/src/exports/Image/index.js
+++ b/packages/react-native-web/src/exports/Image/index.js
@@ -20,6 +20,7 @@ import PixelRatio from '../PixelRatio';
import StyleSheet from '../StyleSheet';
import TextAncestorContext from '../Text/TextAncestorContext';
import View from '../View';
+import processColor from '../processColor';
export type { ImageProps };
@@ -28,23 +29,9 @@ const LOADED = 'LOADED';
const LOADING = 'LOADING';
const IDLE = 'IDLE';
-let _filterId = 0;
const svgDataUriPattern = /^(data:image\/svg\+xml;utf8,)(.*)/;
-function createTintColorSVG(tintColor, id) {
- return tintColor && id != null ? (
-
- ) : null;
-}
-
-function getFlatStyle(style, blurRadius, filterId) {
+function getFlatStyle(style, blurRadius) {
const flatStyle = { ...StyleSheet.flatten(style) };
const { filter, resizeMode, shadowOffset, tintColor } = flatStyle;
@@ -65,8 +52,26 @@ function getFlatStyle(style, blurRadius, filterId) {
filters.push(`drop-shadow(${shadowString})`);
}
}
- if (tintColor && filterId != null) {
- filters.push(`url(#tint-${filterId})`);
+ if (tintColor) {
+ const colorInt = processColor(tintColor);
+ if (colorInt != null) {
+ const r = (colorInt >> 16) & 255;
+ const g = (colorInt >> 8) & 255;
+ const b = colorInt & 255;
+ const a = ((colorInt >> 24) & 255) / 255;
+ const alpha = a.toFixed(2);
+ const matrix = `0 0 0 0 ${r / 255} 0 0 0 0 ${g / 255} 0 0 0 0 ${b / 255} 0 0 0 ${alpha} 0`;
+ // NOTE: Safari doesn't support inline SVG filters (reported 2012)
+ // https://bugs.webkit.org/show_bug.cgi?id=104169
+ const svgFilter =
+ "url('data:image/svg+xml," +
+ '#tint')";
+ filters.push(svgFilter);
+ }
}
if (filters.length > 0) {
@@ -85,7 +90,7 @@ function getFlatStyle(style, blurRadius, filterId) {
delete flatStyle.overlayColor;
delete flatStyle.resizeMode;
- return [flatStyle, resizeMode, _filter, tintColor];
+ return [flatStyle, resizeMode, _filter];
}
function resolveAssetDimensions(source) {
@@ -182,14 +187,9 @@ const Image: React.AbstractComponent>
const [layout, updateLayout] = React.useState({});
const hasTextAncestor = React.useContext(TextAncestorContext);
const hiddenImageRef = React.useRef(null);
- const filterRef = React.useRef(_filterId++);
const requestRef = React.useRef(null);
const shouldDisplaySource = state === LOADED || (state === LOADING && defaultSource == null);
- const [flatStyle, _resizeMode, filter, tintColor] = getFlatStyle(
- style,
- blurRadius,
- filterRef.current
- );
+ const [flatStyle, _resizeMode, filter] = getFlatStyle(style, blurRadius);
const resizeMode = props.resizeMode || _resizeMode || 'cover';
const selectedSource = shouldDisplaySource ? source : defaultSource;
const displayImageUri = resolveAssetUri(selectedSource);
@@ -293,10 +293,8 @@ const Image: React.AbstractComponent>
{ backgroundImage, filter },
backgroundSize != null && { backgroundSize }
]}
- suppressHydrationWarning={true}
/>
{hiddenImage}
- {createTintColorSVG(tintColor, filterRef.current)}
);
}