[Android] Some weird behaviours when testing with the HueRotate example
Toan-Anh opened this issue · 6 comments
library version
yarn list v0.27.5
├─ gl-react-native@2.47.0
├─ gl-react@2.3.1
├─ react-native@0.48.4
└─ react@16.0.0-alpha.12
I was trying out HueRotate example on Android and there were a few problems.
The HueRotate component was copied directly from here, and this was my render
function:
render() {
return (
<View>
<Surface width={300} height={200} backgroundColor="transparent">
<HueRotate hue={Math.PI}>
<Image
style={{ width: 256, height: 244 }}
source={{ uri: 'http://i.imgur.com/qVxHrkY.jpg' }}
/>
</HueRotate>
</Surface>
{/* <Text>Some text</Text> */}
</View>
);
}
The Surface
seemed to be alright, but there was another image rendered right below the Surface
Now if I uncomment the <Text>Some text</Text>
part, the text is also rendered right below the Surface
, overlapping the duplicated image.
Messing around a bit more, I put a View
component right above the Surface
, which means my render
function is now:
render() {
return (
<View>
<View
style={{ width: 50, height: 50, backgroundColor: 'teal' }}
/>
<Surface width={300} height={200} backgroundColor="transparent">
<HueRotate hue={Math.PI}>
<Image
style={{ width: 256, height: 244 }}
source={{ uri: 'http://i.imgur.com/qVxHrkY.jpg' }}
/>
</HueRotate>
</Surface>
<Text>Some text</Text>
</View>
);
}
If I replace the added View
with an Image
or a Text
component, the result is similar, i.e. the Image
or the Text
gets its hue changed and rendered to the surface in place of the actual child of HueRotate
.
I added in a few more components to test and it seems to me that the very first component will always be the one appearing on the surface.
Am I missing something, or is this a problem with the library?
I'm not sure but this sounds like a React Native bug, probably related to the fact RN Android don't support well the overflow hidden
as in iOS.
we rely on this to hide the underlying content : https://github.com/gre/gl-react-native-v2/blob/master/src/makeSurface.js#L21
I have limited time to fix this right now but I can accept PR, otherwise expect I only address this in a few weeks :s
Yeah, it might have something to do with the overflow property, I guess.
What do you think about the wrong child rendering on the surface though? I mean in the second screenshot I posted, the correct result should still be the image of the wolf similar to the first screenshot, not the hue-changed teal View
component, right?
I think the image is not loaded when the rendering happened? you need to hook to onLoad to trigger a redraw.
it's not recommended to use <Image>
, prefer direclty pass the image URL, or otherwise use gl-react-image
I don't think the problem is because the image is not loaded at all, since I tried to force a redraw with onLoad, but the result is still the same.
Furthermore, I tested with a simple Text
component instead of the image just now and the result is still
the same, i.e. the very first component (teal View
) gets rendered onto the surface instead of the child Text
, and the text is visible right below the surface.
@gre I re-wrote the shader to strip all the effects and try to log out what is being passed in as the GL.Node children:
import React from 'react';
import GL from 'gl-react';
const GLSL = `
varying vec2 uv;
uniform sampler2D tex;
void main() {
gl_FragColor = vec4(texture2D(tex, uv).rgb, 1.0);
}
`;
const shaders = GL.Shaders.create({
shader: {
frag: GLSL
}
});
module.exports = GL.createComponent(
({ children: tex }) => {
console.log(tex);
return <GL.Node shader={shaders.shader} uniforms={{ tex }} />
},
{ displayName: 'HueRotate' }
);
The result is that the children property of GL.Node is indeed the actual child I'm expecting, but the one that gets rendered to the surface is the very first component on my screen instead, whether it is an Image
, Text
, or View
. Not that this helps much though.
I'll try this with a lower React Native version tomorrow since I'm suspecting it might be the cause.
Testing with lower React Native versions also produces similar results, and I have also tested on a number of devices and emulator.
If I pass the image URL directly to the GL.Node (which is, of course, the recommended way), everything seems fine, so this is not much of an issue with that case. However, other components such as Text
or View
won't be rendered correctly to the surface.