Skip to content

Commit b7e9d6e

Browse files
author
Oleksandr Kucherenko
committed
fix the child draw matrix/transformation rendering issues
1 parent e394402 commit b7e9d6e

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

android/src/main/java/fr/greweb/reactnativeviewshot/ViewShot.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import android.graphics.Bitmap;
55
import android.graphics.Canvas;
66
import android.graphics.Color;
7+
import android.graphics.Matrix;
78
import android.graphics.Point;
89
import android.graphics.Rect;
10+
import android.graphics.RectF;
911
import android.net.Uri;
1012
import android.support.annotation.IntDef;
1113
import android.support.annotation.NonNull;
@@ -14,6 +16,7 @@
1416
import android.view.TextureView;
1517
import android.view.View;
1618
import android.view.ViewGroup;
19+
import android.view.ViewParent;
1720
import android.widget.ScrollView;
1821

1922
import com.facebook.react.bridge.Promise;
@@ -328,6 +331,8 @@ private Point captureViewImpl(@NonNull final View view, @NonNull final OutputStr
328331
for (final View child : childrenList) {
329332
// skip any child that we don't know how to process
330333
if (!(child instanceof TextureView)) continue;
334+
// skip all invisible to user child views
335+
if (child.getVisibility() != View.VISIBLE) continue;
331336

332337
final TextureView tvChild = (TextureView) child;
333338
tvChild.setOpaque(false);
@@ -338,12 +343,16 @@ private Point captureViewImpl(@NonNull final View view, @NonNull final OutputStr
338343
final int childWidth = child.getWidth();
339344
final int childHeight = child.getHeight();
340345
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);
342347

343348
// get re-usable bitmap
344349
final Bitmap childBitmapBuffer = tvChild.getBitmap(getBitmapForScreenshot(child.getWidth(), child.getHeight()));
350+
351+
c.save();
352+
c.setMatrix(concatMatrix(view, child));
345353
// due to re-use of bitmaps for screenshot, we can get bitmap that is bigger in size than requested
346354
c.drawBitmap(childBitmapBuffer, source, destination, null);
355+
c.restore();
347356
recycleBitmap(childBitmapBuffer);
348357
}
349358

@@ -371,6 +380,23 @@ private Point captureViewImpl(@NonNull final View view, @NonNull final OutputStr
371380
return resolution; // return image width and height
372381
}
373382

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+
374400
@NonNull
375401
private Point getParentOffsets(@NonNull final View view, @NonNull final View child) {
376402
int left = 0;

example/App.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
TextInput,
1010
Picker,
1111
Slider,
12-
WebView
12+
WebView,
13+
ART
1314
} from "react-native";
1415
import SvgUri from "react-native-svg-uri";
1516
import omit from "lodash/omit";
@@ -148,6 +149,8 @@ export default class App extends Component {
148149
/>
149150
<Btn label="📷 All (ScrollView)" onPress={this.snapshot("full")} />
150151
<Btn label="📷 SVG" onPress={this.snapshot("svg")} />
152+
<Btn label="📷 Transform" onPress={this.snapshot("transformParent")} />
153+
<Btn label="📷 Transform Child" onPress={this.snapshot("transform")} />
151154
<Btn label="📷 GL React" onPress={this.snapshot("gl")} />
152155
<Btn label="📷 MapView" onPress={this.snapshot("mapview")} />
153156
<Btn label="📷 WebView" onPress={this.snapshot("webview")} />
@@ -169,6 +172,7 @@ export default class App extends Component {
169172
<Picker.Item label="PNG" value="png" />
170173
<Picker.Item label="JPEG" value="jpeg" />
171174
<Picker.Item label="WEBM (android only)" value="webm" />
175+
<Picker.Item label="RAW (android only)" value="raw" />
172176
<Picker.Item label="INVALID" value="_invalid_" />
173177
</Picker>
174178
</View>
@@ -239,6 +243,7 @@ export default class App extends Component {
239243
>
240244
<Picker.Item label="tmpfile" value="tmpfile" />
241245
<Picker.Item label="base64" value="base64" />
246+
<Picker.Item label="zip-base64 (Android Only)" value="zip-base64" />
242247
<Picker.Item label="data URI" value="data-uri" />
243248
<Picker.Item label="INVALID" value="_invalid_" />
244249
</Picker>
@@ -258,6 +263,24 @@ export default class App extends Component {
258263
<View ref="empty" collapsable={false} />
259264
<View style={styles.experimental} ref="complex" collapsable={false}>
260265
<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>
261284
<View ref="svg" collapsable={false}>
262285
<SvgUri
263286
width={200}
@@ -327,6 +350,9 @@ const styles = StyleSheet.create({
327350
fontSize: 16,
328351
margin: 10
329352
},
353+
experimentalTransform: {
354+
transform: [{ rotate: '180deg' }]
355+
},
330356
p1: {
331357
marginBottom: 10,
332358
flexDirection: "row",

0 commit comments

Comments
 (0)