gre / react-native-view-shot

Snapshot a React Native view and save it to an image
https://github.com/gre/react-native-view-shot-example
MIT License
2.64k stars 344 forks source link

Components in different order on Android. ART #150

Open simomau opened 6 years ago

simomau commented 6 years ago

bug report

Version & Platform

├── react-native@0.54.2 
└── react-native-view-shot@2.3.0 

Platform: Android

Expected behavior

Taken image to be same as shown on screen

Actual behavior

ART element seems to be in wrong order on android. I have ART shape (green line) and then on top of it is orange box (View element). On left you'll see android emulator which has elements in wrong order in taken snapshot. And on right is iOS which is working as expected.

screen shot 2018-05-30 at 10 15 40

Steps to reproduce the behavior

import React, { Component } from 'react'
import { ART, Text, View, TouchableOpacity, Image, Dimensions } from 'react-native'
import ViewShot from 'react-native-view-shot'

const {
  Surface,
  Group,
  Shape
} = ART
class TestScreen extends Component {
  static navigationOptions = ({ navigation }) => ({
    header: null
  })
  constructor () {
    super()
    this.state = {
      image: null
    }
    this.viewshot = null
  }

  capture () {
    this.viewshot.capture().then((uri) => {
      console.warn(uri)
      this.setState({image: uri})
    })
  }

  render () {
    if (this.state.image) {
      Image.getSize(this.state.image, (width, height) => console.warn('Image size', width, height))
    }
    const {width, height} = Dimensions.get('window')
    return (
      <View style={{ width: width, height: height, justifyContent: 'center', alignItems: 'center' }}>
        <Text>View to capture</Text>
        <ViewShot options={{ format: 'jpg', quality: 1 }} ref={(c) => { this.viewshot = c }}>
          <View style={{height: 100, alignItems: 'center', justifyContent: 'center', backgroundColor: 'blue'}}>
            <Surface
              width={200}
              height={100}>
              <Group>
                <Shape
                  d='M 5 50, L320 50'
                  stroke={'lime'}
                  strokeWidth={10} />
              </Group>
            </Surface>
            <View style={{width: 10, height: 10, backgroundColor: 'orange', position: 'absolute', top: 50}} />
          </View>
        </ViewShot>
        <TouchableOpacity onPress={() => this.capture()}>
          <View style={{marginTop: 20, width: 200, height: 20, backgroundColor: 'violet'}}>
            <Text style={{textAlign: 'center'}}>Snapshot</Text>
          </View>
        </TouchableOpacity>
        <Text style={{marginTop: 20}}>Taken image</Text>
        <View style={{width: 360, height: 200}}>
          { this.state.image && <Image resizeMode={'contain'} style={{flex: 1}} source={{uri: this.state.image}} />}
        </View>
      </View>
    )}}

export default TestScreen
simomau commented 6 years ago

Any thoughts? I've been waiting quite long.

gre commented 6 years ago

@simomau can you give a try to 2.4.0 ? it's supposed to fix that

simomau commented 6 years ago

@gre I did test it with version 2.4.0 but issue still persists.

simomau commented 6 years ago

@gre Any news on this?

simomau commented 6 years ago

@gre I noticed that ARTs components some reason is drawn on top of every other component. I disabled view.draw method for testing in ViewShot.java and those ART components were still drawn and were in a final outcome. Don't know if this helps at all.

gre commented 5 years ago

I can't make @react-native-community/art working at all. it's not rendering anything 🤔

meanwhile, i've put that ART example into example project

gre commented 4 years ago

example project reproduce the problem if anyone want to help.

wibimaster commented 1 year ago

I got a similar problem, but with rive-react-native. Rive element is considered as TextureView, and it seems that ViewShot takes a bitmap of all elements, and THEN apply TextureView's above.

So, if I have something like this :

  <Rive [...] />
  <Text>hello</Text>

with an absolute positioning, on my screen I have the Text above the Rive, but on the screenshot the Rive is above the Text...

Is there a way to recreate elements in the good order ?

Thanks !