Touch Responsive
This example shows a simple rendering that responds to touch events (one finger only).
<OneFingerResponse width={256} height={180} />
Implementation
const React = require("react-native");
const GL = require("gl-react");
const {Surface} = 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 <Surface
onStartShouldSetResponderCapture={() => true}
onMoveShouldSetResponderCapture={() => true}
onResponderTerminationRequest={() => false}
onResponderGrant={this.onTouchStart}
onResponderMove={this.onTouchMove}
onResponderRelease={this.onTouchEnd}
onResponderTerminate={this.onTouchEnd}
width={width}
height={height}>
<GL.Node
shader={shaders.oneFingerResponse}
uniforms={{ pressed, position }}
/>
</Surface>;
}
}
The GLSL code shown here is a bit more advanced, we recommend you to take a look at the GLSL specification to learn what the primitive function are doing.