Browse Source

fix the child draw matrix/transformation rendering issues

Oleksandr Kucherenko 6 years ago
parent
commit
b7e9d6eae4
2 changed files with 54 additions and 2 deletions
  1. 27
    1
      android/src/main/java/fr/greweb/reactnativeviewshot/ViewShot.java
  2. 27
    1
      example/App.js

+ 27
- 1
android/src/main/java/fr/greweb/reactnativeviewshot/ViewShot.java View File

4
 import android.graphics.Bitmap;
4
 import android.graphics.Bitmap;
5
 import android.graphics.Canvas;
5
 import android.graphics.Canvas;
6
 import android.graphics.Color;
6
 import android.graphics.Color;
7
+import android.graphics.Matrix;
7
 import android.graphics.Point;
8
 import android.graphics.Point;
8
 import android.graphics.Rect;
9
 import android.graphics.Rect;
10
+import android.graphics.RectF;
9
 import android.net.Uri;
11
 import android.net.Uri;
10
 import android.support.annotation.IntDef;
12
 import android.support.annotation.IntDef;
11
 import android.support.annotation.NonNull;
13
 import android.support.annotation.NonNull;
14
 import android.view.TextureView;
16
 import android.view.TextureView;
15
 import android.view.View;
17
 import android.view.View;
16
 import android.view.ViewGroup;
18
 import android.view.ViewGroup;
19
+import android.view.ViewParent;
17
 import android.widget.ScrollView;
20
 import android.widget.ScrollView;
18
 
21
 
19
 import com.facebook.react.bridge.Promise;
22
 import com.facebook.react.bridge.Promise;
328
         for (final View child : childrenList) {
331
         for (final View child : childrenList) {
329
             // skip any child that we don't know how to process
332
             // skip any child that we don't know how to process
330
             if (!(child instanceof TextureView)) continue;
333
             if (!(child instanceof TextureView)) continue;
334
+            // skip all invisible to user child views
335
+            if (child.getVisibility() != View.VISIBLE) continue;
331
 
336
 
332
             final TextureView tvChild = (TextureView) child;
337
             final TextureView tvChild = (TextureView) child;
333
             tvChild.setOpaque(false);
338
             tvChild.setOpaque(false);
338
             final int childWidth = child.getWidth();
343
             final int childWidth = child.getWidth();
339
             final int childHeight = child.getHeight();
344
             final int childHeight = child.getHeight();
340
             final Rect source = new Rect(0, 0, childWidth, childHeight);
345
             final Rect source = new Rect(0, 0, childWidth, childHeight);
341
-            final Rect destination = new Rect(left, top, left + childWidth, top + childHeight);
346
+            final RectF destination = new RectF(left, top, left + childWidth, top + childHeight);
342
 
347
 
343
             // get re-usable bitmap
348
             // get re-usable bitmap
344
             final Bitmap childBitmapBuffer = tvChild.getBitmap(getBitmapForScreenshot(child.getWidth(), child.getHeight()));
349
             final Bitmap childBitmapBuffer = tvChild.getBitmap(getBitmapForScreenshot(child.getWidth(), child.getHeight()));
350
+
351
+            c.save();
352
+            c.setMatrix(concatMatrix(view, child));
345
             // due to re-use of bitmaps for screenshot, we can get bitmap that is bigger in size than requested
353
             // due to re-use of bitmaps for screenshot, we can get bitmap that is bigger in size than requested
346
             c.drawBitmap(childBitmapBuffer, source, destination, null);
354
             c.drawBitmap(childBitmapBuffer, source, destination, null);
355
+            c.restore();
347
             recycleBitmap(childBitmapBuffer);
356
             recycleBitmap(childBitmapBuffer);
348
         }
357
         }
349
 
358
 
371
         return resolution; // return image width and height
380
         return resolution; // return image width and height
372
     }
381
     }
373
 
382
 
383
+    /** Concat all the transformation matrix's from child to parent. */
384
+    @NonNull
385
+    private Matrix concatMatrix(@NonNull final View view, @NonNull final View child){
386
+        final Matrix transform = new Matrix();
387
+
388
+        View iterator = child;
389
+        do {
390
+
391
+            final Matrix m = iterator.getMatrix();
392
+            transform.preConcat(m);
393
+
394
+            iterator = (View)iterator.getParent();
395
+        } while( iterator != view );
396
+
397
+        return transform;
398
+    }
399
+
374
     @NonNull
400
     @NonNull
375
     private Point getParentOffsets(@NonNull final View view, @NonNull final View child) {
401
     private Point getParentOffsets(@NonNull final View view, @NonNull final View child) {
376
         int left = 0;
402
         int left = 0;

+ 27
- 1
example/App.js View File

9
   TextInput,
9
   TextInput,
10
   Picker,
10
   Picker,
11
   Slider,
11
   Slider,
12
-  WebView
12
+  WebView,
13
+  ART
13
 } from "react-native";
14
 } from "react-native";
14
 import SvgUri from "react-native-svg-uri";
15
 import SvgUri from "react-native-svg-uri";
15
 import omit from "lodash/omit";
16
 import omit from "lodash/omit";
148
             />
149
             />
149
             <Btn label="📷 All (ScrollView)" onPress={this.snapshot("full")} />
150
             <Btn label="📷 All (ScrollView)" onPress={this.snapshot("full")} />
150
             <Btn label="📷 SVG" onPress={this.snapshot("svg")} />
151
             <Btn label="📷 SVG" onPress={this.snapshot("svg")} />
152
+            <Btn label="📷 Transform" onPress={this.snapshot("transformParent")} />
153
+            <Btn label="📷 Transform Child" onPress={this.snapshot("transform")} />
151
             <Btn label="📷 GL React" onPress={this.snapshot("gl")} />
154
             <Btn label="📷 GL React" onPress={this.snapshot("gl")} />
152
             <Btn label="📷 MapView" onPress={this.snapshot("mapview")} />
155
             <Btn label="📷 MapView" onPress={this.snapshot("mapview")} />
153
             <Btn label="📷 WebView" onPress={this.snapshot("webview")} />
156
             <Btn label="📷 WebView" onPress={this.snapshot("webview")} />
169
               <Picker.Item label="PNG" value="png" />
172
               <Picker.Item label="PNG" value="png" />
170
               <Picker.Item label="JPEG" value="jpeg" />
173
               <Picker.Item label="JPEG" value="jpeg" />
171
               <Picker.Item label="WEBM (android only)" value="webm" />
174
               <Picker.Item label="WEBM (android only)" value="webm" />
175
+              <Picker.Item label="RAW (android only)" value="raw" />
172
               <Picker.Item label="INVALID" value="_invalid_" />
176
               <Picker.Item label="INVALID" value="_invalid_" />
173
             </Picker>
177
             </Picker>
174
           </View>
178
           </View>
239
             >
243
             >
240
               <Picker.Item label="tmpfile" value="tmpfile" />
244
               <Picker.Item label="tmpfile" value="tmpfile" />
241
               <Picker.Item label="base64" value="base64" />
245
               <Picker.Item label="base64" value="base64" />
246
+              <Picker.Item label="zip-base64 (Android Only)" value="zip-base64" />
242
               <Picker.Item label="data URI" value="data-uri" />
247
               <Picker.Item label="data URI" value="data-uri" />
243
               <Picker.Item label="INVALID" value="_invalid_" />
248
               <Picker.Item label="INVALID" value="_invalid_" />
244
             </Picker>
249
             </Picker>
258
         <View ref="empty" collapsable={false} />
263
         <View ref="empty" collapsable={false} />
259
         <View style={styles.experimental} ref="complex" collapsable={false}>
264
         <View style={styles.experimental} ref="complex" collapsable={false}>
260
           <Text style={styles.experimentalTitle}>Experimental Stuff</Text>
265
           <Text style={styles.experimentalTitle}>Experimental Stuff</Text>
266
+          <View ref="transformParent" collapsable={false}>
267
+              <View ref="transformInner" collapsable={false} style={styles.experimentalTransform}>
268
+                <Text ref="transform" >Transform</Text>
269
+                <ART.Surface ref="surface" width={20} height={20}>
270
+                    <ART.Text
271
+                            fill="#000000"
272
+                            font={{fontFamily:'Arial',fontSize: 6}}
273
+                            >Sample Text</ART.Text>
274
+                    <ART.Shape
275
+                            d='M2.876,10.6499757 L16.375,18.3966817 C16.715,18.5915989 17.011,18.4606545 17.125,18.3956822 C17.237,18.3307098 17.499,18.1367923 17.499,17.746958 L17.499,2.25254636 C17.499,1.86271212 17.237,1.66879457 17.125,1.6038222 C17.011,1.53884983 16.715,1.4079055 16.375,1.60282262 L2.876,9.34952866 C2.537,9.54544536 2.5,9.86930765 2.5,10.000252 C2.5,10.1301967 2.537,10.4550586 2.876,10.6499757 M16.749,20 C16.364,20 15.98,19.8990429 15.629,19.6971288 L2.13,11.9504227 L2.129,11.9504227 C1.422,11.5445953 1,10.8149056 1,10.000252 C1,9.18459879 1.422,8.45590864 2.129,8.04908162 L15.629,0.302375584 C16.332,-0.10245228 17.173,-0.10045313 17.876,0.306373884 C18.579,0.713200898 18.999,1.44089148 18.999,2.25254636 L18.999,17.746958 C18.999,18.5586129 18.579,19.2863035 17.876,19.6931305 C17.523,19.8970438 17.136,20 16.749,20'
276
+                            fill="blue"
277
+                            stroke="black"
278
+                            strokeWidth={0}
279
+                            >
280
+                    </ART.Shape>
281
+                </ART.Surface>
282
+              </View>
283
+          </View>
261
           <View ref="svg" collapsable={false}>
284
           <View ref="svg" collapsable={false}>
262
             <SvgUri
285
             <SvgUri
263
               width={200}
286
               width={200}
327
     fontSize: 16,
350
     fontSize: 16,
328
     margin: 10
351
     margin: 10
329
   },
352
   },
353
+  experimentalTransform: {
354
+    transform: [{ rotate: '180deg' }]
355
+  },
330
   p1: {
356
   p1: {
331
     marginBottom: 10,
357
     marginBottom: 10,
332
     flexDirection: "row",
358
     flexDirection: "row",