5.md 2.27 KB
Newer Older
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
# Touch Responsive

This example shows a simple rendering that responds to touch events (one finger only).

![](5.gif)

```html
<OneFingerResponse
  width={256}
  height={180}
/>
```

## Implementation

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

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

uniform float pressed;
uniform vec2 position;

void main () {
  float dist = pow(1.0 - distance(position, uv), 4.0);
  float edgeDistX = pow(1.0 - distance(position.x, uv.x), 24.0);
  float edgeDistY = pow(1.0 - distance(position.y, uv.y), 24.0);
  gl_FragColor = pressed * vec4(0.8 * dist + edgeDistX, 0.7 * dist + edgeDistY, 0.6 * dist, 1.0);
}
    `
  }
});

class OneFingerResponse extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      pressed: 0,
      position: [ 0, 0 ]
    };
    this.onTouchStart = this.onTouchStart.bind(this);
    this.onTouchEnd = this.onTouchEnd.bind(this);
    this.onTouchMove = this.onTouchMove.bind(this);
  }
  onTouchStart (evt) {
    this.setState({
      pressed: 1
    });
    this.onTouchMove(evt);
  }
  onTouchMove (evt) {
    const { width, height } = this.props;
    const { locationX, locationY } = evt.nativeEvent;
    this.setState({
      position: [
        Math.max(0, Math.min(locationX/width, 1)),
        Math.max(0, Math.min(1-locationY/height, 1))
      ]
    });
  }
  onTouchEnd () {
    this.setState({
      pressed: 0
    });
  }
  render () {
    const { width, height } = this.props;
    const { pressed, position } = this.state;
    return <GL.View
      onStartShouldSetResponderCapture={() => true}
      onMoveShouldSetResponderCapture={() => true}
      onResponderTerminationRequest={() => false}
      onResponderGrant={this.onTouchStart}
      onResponderMove={this.onTouchMove}
      onResponderRelease={this.onTouchEnd}
      onResponderTerminate={this.onTouchEnd}
      width={width}
      height={height}
      shader={shaders.oneFingerResponse}
      uniforms={{ pressed, position }}
    />;
  }
}
```

The GLSL code shown here is a bit more advanced, we recommend you to take a look at the [GLSL specification](https://www.opengl.org/documentation/glsl/) to learn what the primitive function are doing.