123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- import React, { Component } from "react";
- import {
- StyleSheet,
- Text,
- View,
- ScrollView,
- Image,
- Switch,
- TextInput,
- Picker,
- Slider,
- WebView
- } from "react-native";
- import omit from "lodash/omit";
- import { captureRef } from "react-native-view-shot";
- import { Surface } from "gl-react-native";
- import GL from "gl-react";
- import MapView from "react-native-maps";
- import Video from "react-native-video";
- import Btn from "./Btn";
-
- const catsSource = {
- uri: "https://i.imgur.com/5EOyTDQ.jpg"
- };
-
- const shaders = GL.Shaders.create({
- helloGL: {
- frag: `
- precision highp float;
- varying vec2 uv;
- uniform float blue;
- void main () {
- gl_FragColor = vec4(uv.x, uv.y, blue, 1.0);
- }`
- }
- });
-
- const HelloGL = GL.createComponent(
- ({ blue }) => <GL.Node shader={shaders.helloGL} uniforms={{ blue }} />,
- { displayName: "HelloGL" }
- );
-
- export default class App extends Component {
- state = {
- previewSource: catsSource,
- error: null,
- res: null,
- value: {
- format: "png",
- quality: 0.9,
- result: "tmpfile",
- snapshotContentContainer: false
- }
- };
-
- snapshot = refname => () =>
- captureRef(this.refs[refname], this.state.value)
- .then(
- res =>
- this.state.value.result !== "tmpfile"
- ? res
- : new Promise((success, failure) =>
- // just a test to ensure res can be used in Image.getSize
- Image.getSize(
- res,
- (width, height) => (
- console.log(res, width, height), success(res)
- ),
- failure
- )
- )
- )
- .then(res =>
- this.setState({
- error: null,
- res,
- previewSource: {
- uri:
- this.state.value.result === "base64"
- ? "data:image/" + this.state.value.format + ";base64," + res
- : res
- }
- })
- )
- .catch(
- error => (
- console.warn(error),
- this.setState({ error, res: null, previewSource: null })
- )
- );
-
- render() {
- const { value, previewSource, error, res } = this.state;
- const {
- format,
- quality,
- width,
- height,
- result,
- snapshotContentContainer
- } = value;
- return (
- <ScrollView
- ref="full"
- style={styles.root}
- contentContainerStyle={styles.container}
- >
- <View ref="header" style={styles.header}>
- <Text style={styles.title}>😃 ViewShot Example 😜</Text>
- <View style={styles.p1}>
- <Text style={styles.text}>This is a </Text>
- <Text style={styles.code}>react-native-view-shot</Text>
- <Text style={styles.text}> showcase.</Text>
- </View>
- <View style={styles.preview}>
- {error ? (
- <Text style={styles.previewError}>
- {"" + (error.message || error)}
- </Text>
- ) : (
- <Image
- fadeDuration={0}
- resizeMode="contain"
- style={styles.previewImage}
- source={previewSource}
- />
- )}
- </View>
- <Text numberOfLines={1} style={styles.previewUriText}>
- {res ? res.slice(0, 200) : ""}
- </Text>
- </View>
- <View ref="form" style={styles.form}>
- <View style={styles.btns}>
- <Btn
- label="😻 Reset"
- onPress={() => this.setState({ previewSource: catsSource })}
- />
- <Btn label="📷 Head Section" onPress={this.snapshot("header")} />
- <Btn label="📷 Form" onPress={this.snapshot("form")} />
- <Btn
- label="📷 Experimental Section"
- onPress={this.snapshot("complex")}
- />
- <Btn label="📷 All (ScrollView)" onPress={this.snapshot("full")} />
- <Btn label="📷 GL React" onPress={this.snapshot("gl")} />
- <Btn label="📷 MapView" onPress={this.snapshot("mapview")} />
- <Btn label="📷 WebView" onPress={this.snapshot("webview")} />
- <Btn label="📷 Video" onPress={this.snapshot("video")} />
- <Btn
- label="📷 Empty View (should crash)"
- onPress={this.snapshot("empty")}
- />
- </View>
- <View style={styles.field}>
- <Text style={styles.label}>Format</Text>
- <Picker
- style={styles.input}
- selectedValue={format}
- onValueChange={format =>
- this.setState({ value: { ...value, format } })}
- >
- <Picker.Item label="PNG" value="png" />
- <Picker.Item label="JPEG" value="jpeg" />
- <Picker.Item label="WEBM (android only)" value="webm" />
- <Picker.Item label="INVALID" value="_invalid_" />
- </Picker>
- </View>
- <View style={styles.field}>
- <Text style={styles.label}>Quality</Text>
- <Slider
- style={styles.input}
- value={quality}
- onValueChange={quality =>
- this.setState({ value: { ...value, quality } })}
- />
- <Text>{(quality * 100).toFixed(0)}%</Text>
- </View>
- <View style={styles.field}>
- <Text style={styles.label}>Size</Text>
- <Switch
- style={styles.switch}
- value={width !== undefined}
- onValueChange={checked =>
- this.setState({
- value: omit(
- {
- ...value,
- width: 300,
- height: 300
- },
- checked ? [] : ["width", "height"]
- )
- })}
- />
- {width !== undefined ? (
- <TextInput
- style={styles.inputText}
- value={"" + width}
- keyboardType="number-pad"
- onChangeText={txt =>
- !isNaN(txt) &&
- this.setState({
- value: { ...value, width: parseInt(txt, 10) }
- })}
- />
- ) : (
- <Text style={styles.inputText}>(auto)</Text>
- )}
- <Text>x</Text>
- {height !== undefined ? (
- <TextInput
- style={styles.inputText}
- value={"" + height}
- keyboardType="number-pad"
- onChangeText={txt =>
- !isNaN(txt) &&
- this.setState({
- value: { ...value, height: parseInt(txt, 10) }
- })}
- />
- ) : (
- <Text style={styles.inputText}>(auto)</Text>
- )}
- </View>
- <View style={styles.field}>
- <Text style={styles.label}>Result</Text>
- <Picker
- style={styles.input}
- selectedValue={result}
- onValueChange={result =>
- this.setState({ value: { ...value, result } })}
- >
- <Picker.Item label="tmpfile" value="tmpfile" />
- <Picker.Item label="base64" value="base64" />
- <Picker.Item label="data URI" value="data-uri" />
- <Picker.Item label="INVALID" value="_invalid_" />
- </Picker>
- </View>
- <View style={styles.field}>
- <Text style={styles.label}>snapshotContentContainer</Text>
- <Switch
- style={styles.switch}
- value={snapshotContentContainer}
- onValueChange={snapshotContentContainer =>
- this.setState({
- value: { ...value, snapshotContentContainer }
- })}
- />
- </View>
- </View>
- <View ref="empty" collapsable={false} />
- <View style={styles.experimental} ref="complex" collapsable={false}>
- <Text style={styles.experimentalTitle}>Experimental Stuff</Text>
- <Surface ref="gl" width={300} height={300}>
- <HelloGL blue={0.5} />
- </Surface>
- <MapView
- ref="mapview"
- initialRegion={{
- latitude: 37.78825,
- longitude: -122.4324,
- latitudeDelta: 0.0922,
- longitudeDelta: 0.0421
- }}
- style={{ width: 300, height: 300 }}
- />
- <View
- ref="webview"
- collapsable={false}
- style={{ width: 300, height: 300 }}
- >
- <WebView
- source={{
- uri: "https://github.com/gre/react-native-view-shot"
- }}
- />
- </View>
- <Video
- ref="video"
- style={{ width: 300, height: 300 }}
- source={require("./broadchurch.mp4")}
- volume={0}
- repeat
- />
- </View>
- </ScrollView>
- );
- }
- }
-
- const styles = StyleSheet.create({
- root: {
- flex: 1,
- backgroundColor: "#f6f6f6"
- },
- container: {
- paddingVertical: 20,
- backgroundColor: "#f6f6f6"
- },
- title: {
- fontSize: 20,
- textAlign: "center",
- margin: 10
- },
- experimental: {
- padding: 10,
- flexDirection: "column",
- alignItems: "center"
- },
- experimentalTitle: {
- fontSize: 16,
- margin: 10
- },
- p1: {
- marginBottom: 10,
- flexDirection: "row",
- flexWrap: "wrap",
- justifyContent: "center",
- alignItems: "center"
- },
- text: {
- color: "#333"
- },
- code: {
- fontWeight: "bold",
- color: "#000"
- },
- field: {
- flexDirection: "row",
- alignItems: "center",
- paddingVertical: 4,
- paddingHorizontal: 10
- },
- label: {
- minWidth: 80,
- fontStyle: "italic",
- color: "#888"
- },
- switch: {
- marginRight: 50
- },
- input: {
- flex: 1,
- marginHorizontal: 5
- },
- inputText: {
- flex: 1,
- marginHorizontal: 5,
- color: "red",
- textAlign: "center"
- },
- preview: {
- flexDirection: "row",
- alignItems: "center",
- justifyContent: "space-around"
- },
- previewImage: {
- width: 375,
- height: 300
- },
- previewUriText: {
- fontSize: 12,
- fontStyle: "italic",
- color: "#666",
- textAlign: "center",
- padding: 10,
- paddingBottom: 0
- },
- previewError: {
- width: 375,
- height: 300,
- paddingTop: 20,
- textAlign: "center",
- fontSize: 20,
- fontWeight: "bold",
- color: "#fff",
- backgroundColor: "#c00"
- },
- header: {
- backgroundColor: "#f6f6f6",
- borderColor: "#000",
- borderWidth: 1,
- paddingBottom: 20
- },
- form: {
- backgroundColor: "#fff"
- },
- btns: {
- flexDirection: "row",
- flexWrap: "wrap",
- alignItems: "center",
- justifyContent: "center",
- paddingVertical: 10,
- margin: 4
- }
- });
|