Gaëtan Renaudeau 36a702f2e8 add docs
2015-08-27 14:37:18 +02:00

1.8 KiB

Hue Rotate on Text+Image

gl-react-native not only allows to add effects on top of images but also on top of any content. This example shows the Hue rotation effect on top of texts and image.

<HueRotate
  width={256}
  height={180}
  hue={hue}>
  <Image style={{ width: 256, height: 244 }} source={{ uri: "http://i.imgur.com/qVxHrkY.jpg" }}/>
  <Text style={styles.demoText1}>Throw me to the wolves</Text>
  <Text style={styles.demoText2}>{text}</Text>
</HueRotate>

Implementation

const React = require("react-native");
const GL = require("gl-react-native");

const shaders = GL.Shaders.create({
  hueRotate: {
    frag: `
precision highp float;
varying vec2 uv;
uniform sampler2D tex;
uniform float hue;

const mat3 rgb2yiq = mat3(0.299, 0.587, 0.114, 0.595716, -0.274453, -0.321263, 0.211456, -0.522591, 0.311135);
const mat3 yiq2rgb = mat3(1.0, 0.9563, 0.6210, 1.0, -0.2721, -0.6474, 1.0, -1.1070, 1.7046);

void main() {
  vec3 yColor = rgb2yiq * texture2D(tex, uv).rgb;
  float originalHue = atan(yColor.b, yColor.g);
  float finalHue = originalHue + hue;
  float chroma = sqrt(yColor.b*yColor.b+yColor.g*yColor.g);
  vec3 yFinalColor = vec3(yColor.r, chroma * cos(finalHue), chroma * sin(finalHue));
  gl_FragColor = vec4(yiq2rgb*yFinalColor, 1.0);
}
    `
  }
});

class HueRotate extends React.Component {
  render () {
    const { width, height, hue, children } = this.props;
    return <GL.View
      shader={shaders.hueRotate}
      width={width}
      height={height}
      uniforms={{ hue }}>
      <GL.Target uniform="tex">{children}</GL.Target>
    </GL.View>;
  }
}

The GL.Target describes which texture uniform is used for the rasterization of its children content.

Note how powerful it is to compose React Components that way.