Vignette.js 2.23 KB
Newer Older
1 2 3
import React from "react-native";
import GL from "gl-react";
import {Surface} from "gl-react-native";
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
4 5 6 7 8 9 10 11 12 13 14 15 16

const shaders = GL.Shaders.create({
  imageVignette: {
    frag: `
precision highp float;
varying vec2 uv;

uniform float time;
uniform float amp;
uniform float freq;
uniform sampler2D texture;
uniform float moving;

17
uniform vec2 finger;
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
18

19
vec2 lookup (vec2 offset, float amp2) {
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
20
  return mod(
21
    uv + amp2 * amp * vec2(cos(freq*(uv.x+offset.x)+time),sin(freq*(uv.y+offset.x)+time)) + vec2(moving * time/10.0, 0.0),
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
22 23 24 25
    vec2(1.0));
}

void main() {
26 27
  float dist = distance(uv, finger);
  float amp2 = pow(1.0 - dist, 2.0);
28 29
  float colorSeparation = 0.02 * mix(amp2, 1.0, 0.5);
  vec2 orientation = vec2(1.0, 0.0);
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
30 31
  gl_FragColor = vec4(
    vec3(
32 33
    texture2D(texture, lookup(colorSeparation * orientation, amp2)).r,
    texture2D(texture, lookup(-colorSeparation * orientation, amp2)).g,
34 35
    texture2D(texture, lookup(vec2(0.0), amp2)).b),
    1.0-min(0.95, pow(1.8 * distance(uv, finger), 4.0) + 0.5 * pow(distance(fract(50.0 * uv.y), 0.5), 2.0)));
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
36 37 38 39 40 41
}
`
  }
});


42
class Vignette extends React.Component {
43 44 45 46 47 48 49 50 51 52 53 54 55
  constructor (props) {
    super(props);
    this.onResponderMove = this.onResponderMove.bind(this);
    this.state = {
      finger: [0.5, 0.5]
    };
  }
  onResponderMove (evt) {
    const { width, height } = this.props;
    const { locationX, locationY } = evt.nativeEvent;
    this.setState({ finger: [locationX/width, 1-locationY/height] });
  }

Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
56
  render () {
57
    const { width, height, time, source } = this.props;
58
    const { finger } = this.state;
59
    return <Surface
60 61
      width={width}
      height={height}
62
      backgroundColor="transparent"
63 64 65
      preload
      onStartShouldSetResponder={() => true}
      onMoveShouldSetResponder={() => true}
66
      onLoad={() => console.log("Vignette onLoad")}
67
      onProgress={e => console.log("Vignette onProgress", e.nativeEvent)}
68 69 70 71 72 73 74 75 76 77 78 79 80
      onResponderMove={this.onResponderMove}>
      <GL.Node
        shader={shaders.imageVignette}
        uniforms={{
          time: time,
          freq: 10 + 2 * Math.sin(0.7*time),
          texture: source,
          amp: 0.05 + Math.max(0, 0.03*Math.cos(time)),
          moving: 0,
          finger: finger
        }}
      />
    </Surface>;
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
81 82 83 84
  }
}

module.exports = Vignette;