react-native-svg
react-native-svg copied to clipboard
Inconsistent rendering of opacity in <G> element on Android and iOS
Question
Hi,
When using the <G> element with an opacity attribute, the rendering of nested elements inside the <G> element is inconsistent between Android and iOS platforms.
To Reproduce Here's a minimal code snippet that reproduces the issue:
import { Svg, G, Circle, Rect } from "react-native-svg";
export function Overlap() {
return (
<Svg>
<G opacity={0.5} translateX={100} translateY={200}>
<Circle r="40" fill="black" />
<Rect width="80" height="60" fill="green" />
</G>
</Svg>
)
}
The left one is on Android emulator (Pixel_6_Pro_API_33), the right one is on iOS simulator (iPhone 14 Pro)
How can I achieve the iOS result (the contents of the group to first be composited and then the result to be lowered in opacity) on Android?
Thank you!
+1
Hello @uier, Here is an example showcasing the use of the View component. I suspect that the bug is related to React Native.
import { View } from 'react-native';
const App = () => {
return (
<View style={{ width: '100%', height: '100%', opacity: 0.7 }}>
<View style={{ width: 100, height: 100, backgroundColor: 'red' }}></View>
<View
style={{
width: 100,
height: 100,
backgroundColor: 'green',
transform: [{ translateY: -50 }],
}}></View>
</View>
);
};
For me overlapping parts with opacity still (with https://github.com/software-mansion/react-native-svg/pull/2417) render differently on Android than in iOS.
<svg width="158" height="92" viewBox="0 0 158 92" fill="none" xmlns="http://www.w3.org/2000/svg">
<filter id="constantOpacity">
<feComponentTransfer>
<feFuncA type="table" tableValues="0 .5 .5" />
</feComponentTransfer>
</filter>
<path d="M54 -16H179V109L14 117C14 117 -8.99996 89 6.00002 44C21 -1 54 -16 54 -16Z" fill="white" fill-opacity="0.13"/>
<g filter="url(#constantOpacity)">
<path d="M120.469 59.942C118.549 61.8163 117.451 64.5134 117.726 67.3934C118.137 72.3306 122.663 75.942 127.6 75.942H136.286V96.382C136.286 105.845 128.56 113.571 119.097 113.571H66.6172C57.1543 113.571 49.4286 105.845 49.4286 96.382V50.6164C49.4286 41.1535 57.1543 33.4277 66.6172 33.4277H119.097C128.56 33.4277 136.286 41.1535 136.286 50.6164V57.1992H127.051C124.491 57.1992 122.16 58.2048 120.469 59.942Z" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" opacity="0.7"/>
<path d="M49.4286 54.7312V33.84C49.4286 28.4 52.7657 23.5541 57.84 21.6341L94.1372 7.91979C99.8057 5.77122 105.886 9.97706 105.886 16.0571V33.4284" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" opacity="0.7"/>
<path d="M141.126 61.8629V71.2803C141.126 73.7946 139.115 75.8515 136.555 75.9429H127.595C122.657 75.9429 118.132 72.3315 117.72 67.3944C117.446 64.5144 118.543 61.8172 120.463 59.9429C122.155 58.2058 124.486 57.2002 127.046 57.2002H136.555C139.115 57.2916 141.126 59.3486 141.126 61.8629Z" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" opacity="0.7"/>
<path d="M70 52.8569H102" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" opacity="0.7"/>
</g>
</svg>
EDIT: Filter is not respected. Found another issue: https://github.com/software-mansion/react-native-svg/issues/2362