Browse Source

fix the child draw matrix/transformation rendering issues

Oleksandr Kucherenko 5 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,8 +4,10 @@ import android.app.Activity;
4 4
 import android.graphics.Bitmap;
5 5
 import android.graphics.Canvas;
6 6
 import android.graphics.Color;
7
+import android.graphics.Matrix;
7 8
 import android.graphics.Point;
8 9
 import android.graphics.Rect;
10
+import android.graphics.RectF;
9 11
 import android.net.Uri;
10 12
 import android.support.annotation.IntDef;
11 13
 import android.support.annotation.NonNull;
@@ -14,6 +16,7 @@ import android.util.Base64;
14 16
 import android.view.TextureView;
15 17
 import android.view.View;
16 18
 import android.view.ViewGroup;
19
+import android.view.ViewParent;
17 20
 import android.widget.ScrollView;
18 21
 
19 22
 import com.facebook.react.bridge.Promise;
@@ -328,6 +331,8 @@ public class ViewShot implements UIBlock {
328 331
         for (final View child : childrenList) {
329 332
             // skip any child that we don't know how to process
330 333
             if (!(child instanceof TextureView)) continue;
334
+            // skip all invisible to user child views
335
+            if (child.getVisibility() != View.VISIBLE) continue;
331 336
 
332 337
             final TextureView tvChild = (TextureView) child;
333 338
             tvChild.setOpaque(false);
@@ -338,12 +343,16 @@ public class ViewShot implements UIBlock {
338 343
             final int childWidth = child.getWidth();
339 344
             final int childHeight = child.getHeight();
340 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 348
             // get re-usable bitmap
344 349
             final Bitmap childBitmapBuffer = tvChild.getBitmap(getBitmapForScreenshot(child.getWidth(), child.getHeight()));
350
+
351
+            c.save();
352
+            c.setMatrix(concatMatrix(view, child));
345 353
             // due to re-use of bitmaps for screenshot, we can get bitmap that is bigger in size than requested
346 354
             c.drawBitmap(childBitmapBuffer, source, destination, null);
355
+            c.restore();
347 356
             recycleBitmap(childBitmapBuffer);
348 357
         }
349 358
 
@@ -371,6 +380,23 @@ public class ViewShot implements UIBlock {
371 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 400
     @NonNull
375 401
     private Point getParentOffsets(@NonNull final View view, @NonNull final View child) {
376 402
         int left = 0;

+ 27
- 1
example/App.js View File

@@ -9,7 +9,8 @@ import {
9 9
   TextInput,
10 10
   Picker,
11 11
   Slider,
12
-  WebView
12
+  WebView,
13
+  ART
13 14
 } from "react-native";
14 15
 import SvgUri from "react-native-svg-uri";
15 16
 import omit from "lodash/omit";
@@ -148,6 +149,8 @@ export default class App extends Component {
148 149
             />
149 150
             <Btn label="📷 All (ScrollView)" onPress={this.snapshot("full")} />
150 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 154
             <Btn label="📷 GL React" onPress={this.snapshot("gl")} />
152 155
             <Btn label="📷 MapView" onPress={this.snapshot("mapview")} />
153 156
             <Btn label="📷 WebView" onPress={this.snapshot("webview")} />
@@ -169,6 +172,7 @@ export default class App extends Component {
169 172
               <Picker.Item label="PNG" value="png" />
170 173
               <Picker.Item label="JPEG" value="jpeg" />
171 174
               <Picker.Item label="WEBM (android only)" value="webm" />
175
+              <Picker.Item label="RAW (android only)" value="raw" />
172 176
               <Picker.Item label="INVALID" value="_invalid_" />
173 177
             </Picker>
174 178
           </View>
@@ -239,6 +243,7 @@ export default class App extends Component {
239 243
             >
240 244
               <Picker.Item label="tmpfile" value="tmpfile" />
241 245
               <Picker.Item label="base64" value="base64" />
246
+              <Picker.Item label="zip-base64 (Android Only)" value="zip-base64" />
242 247
               <Picker.Item label="data URI" value="data-uri" />
243 248
               <Picker.Item label="INVALID" value="_invalid_" />
244 249
             </Picker>
@@ -258,6 +263,24 @@ export default class App extends Component {
258 263
         <View ref="empty" collapsable={false} />
259 264
         <View style={styles.experimental} ref="complex" collapsable={false}>
260 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 284
           <View ref="svg" collapsable={false}>
262 285
             <SvgUri
263 286
               width={200}
@@ -327,6 +350,9 @@ const styles = StyleSheet.create({
327 350
     fontSize: 16,
328 351
     margin: 10
329 352
   },
353
+  experimentalTransform: {
354
+    transform: [{ rotate: '180deg' }]
355
+  },
330 356
   p1: {
331 357
     marginBottom: 10,
332 358
     flexDirection: "row",