necolas / react-native-web

Cross-platform React UI packages
https://necolas.github.io/react-native-web
MIT License
21.58k stars 1.78k forks source link

Setting background-blend-mode on <Image /> #2091

Open markymc opened 3 years ago

markymc commented 3 years ago

Is your feature request related to a problem? Please describe.

I need to set some unsupported properties on an <Image /> such as background-blend-mode and related values. It seems that any styles passed in aren't actually applied to the <View /> that renders the image, but a parent of it, so I see no clear way to do this with the current API.

Describe a solution you'd like

I'm not entirely sure of the best solution for this, other than perhaps explicitly supporting background-blend-mode as a style? However, in my use case I need it to be accompanied by opacity and backgroundColor, which are supported in the parent <View />, but are not useful to me there (as far as I can tell, but I'm not so experienced with CSS).

Describe alternatives you've considered

In the meantime, I've solved my problem by patch-packageing RNW:

diff --git a/node_modules/react-native-web/dist/exports/Image/index.js b/node_modules/react-native-web/dist/exports/Image/index.js
index dec9189..82568de 100644
--- a/node_modules/react-native-web/dist/exports/Image/index.js
+++ b/node_modules/react-native-web/dist/exports/Image/index.js
@@ -175,6 +175,7 @@ var Image = forwardRef(function (props, ref) {
       pointerEvents = props.pointerEvents,
       source = props.source,
       style = props.style,
+      imageInnerStyle = props.imageInnerStyle,
       rest = _objectWithoutPropertiesLoose(props, ["accessibilityLabel", "blurRadius", "defaultSource", "draggable", "onError", "onLayout", "onLoad", "onLoadEnd", "onLoadStart", "pointerEvents", "source", "style"]);

   if (process.env.NODE_ENV !== 'production') {
@@ -315,7 +316,7 @@ var Image = forwardRef(function (props, ref) {
       filter: filter
     }, backgroundSize != null && {
       backgroundSize: backgroundSize
-    }],
+    }, imageInnerStyle],
     suppressHydrationWarning: true
   }), hiddenImage, createTintColorSVG(tintColor, filterRef.current));
 });

So I can then do (inlined styles for this example):

<ImageBackground
  source={require('./image.png')}
  style={{ position: 'absolute', left: 0, top: 0, right: 0, height: 300 }}
  resizeMode="cover"
  imageInnerStyle={{
    opacity: 0.35,
    backgroundColor: myColor,
    backgroundBlendMode: 'luminosity',
  }}
/>

Additional context

Thanks!

dasbisu2b commented 1 month ago

thanks for help ing me