react-native-morph-card 0.1.14 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -114,55 +114,86 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
|
|
|
114
114
|
val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
|
|
115
115
|
val canvas = Canvas(bitmap)
|
|
116
116
|
|
|
117
|
-
// Track
|
|
118
|
-
data class
|
|
119
|
-
val
|
|
117
|
+
// Track Fresco views to restore rounding after capture
|
|
118
|
+
data class FrescoState(val view: View, val hierarchy: Any, val roundingParams: Any)
|
|
119
|
+
val frescoStates = mutableListOf<FrescoState>()
|
|
120
|
+
// Track views whose clipToOutline was disabled
|
|
121
|
+
val clippedViews = mutableListOf<View>()
|
|
120
122
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
var savedRounding: Any? = null
|
|
124
|
-
|
|
125
|
-
Log.d(TAG, "captureSnapshot: visiting ${view.javaClass.name} clipToOutline=$hadClip size=${view.width}x${view.height}")
|
|
123
|
+
// Map of Fresco views to their hierarchy (for drawing drawable directly)
|
|
124
|
+
val frescoViews = mutableMapOf<View, Any>()
|
|
126
125
|
|
|
126
|
+
fun prepareView(view: View) {
|
|
127
127
|
// Disable outline clipping
|
|
128
|
-
if (
|
|
128
|
+
if (view.clipToOutline) {
|
|
129
|
+
clippedViews.add(view)
|
|
129
130
|
view.clipToOutline = false
|
|
130
131
|
}
|
|
131
132
|
|
|
132
|
-
//
|
|
133
|
-
// Uses reflection to avoid a compile-time dependency on Fresco.
|
|
133
|
+
// Detect Fresco DraweeView and disable rounding
|
|
134
134
|
try {
|
|
135
135
|
val getHierarchy = view.javaClass.getMethod("getHierarchy")
|
|
136
136
|
val hierarchy = getHierarchy.invoke(view)
|
|
137
137
|
if (hierarchy != null) {
|
|
138
|
-
Log.d(TAG, "captureSnapshot: found hierarchy ${hierarchy.javaClass.name}")
|
|
139
138
|
val getRounding = hierarchy.javaClass.getMethod("getRoundingParams")
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (savedRounding != null) {
|
|
139
|
+
val rounding = getRounding.invoke(hierarchy)
|
|
140
|
+
if (rounding != null) {
|
|
143
141
|
val roundingClass = Class.forName("com.facebook.drawee.generic.RoundingParams")
|
|
144
142
|
val setRounding = hierarchy.javaClass.getMethod("setRoundingParams", roundingClass)
|
|
145
143
|
setRounding.invoke(hierarchy, null)
|
|
146
|
-
|
|
144
|
+
frescoStates.add(FrescoState(view, hierarchy, rounding))
|
|
145
|
+
frescoViews[view] = hierarchy
|
|
146
|
+
Log.d(TAG, "captureSnapshot: disabled Fresco rounding on ${view.width}x${view.height}")
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
|
-
} catch (
|
|
150
|
-
Log.d(TAG, "captureSnapshot: reflection skip for ${view.javaClass.simpleName}: ${e.javaClass.simpleName}")
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (hadClip || savedRounding != null) {
|
|
154
|
-
savedStates.add(ViewState(view, hadClip, savedRounding))
|
|
155
|
-
}
|
|
149
|
+
} catch (_: Exception) {}
|
|
156
150
|
|
|
157
151
|
if (view is ViewGroup) {
|
|
158
152
|
for (i in 0 until view.childCount) {
|
|
159
|
-
|
|
153
|
+
prepareView(view.getChildAt(i))
|
|
160
154
|
}
|
|
161
155
|
}
|
|
162
156
|
}
|
|
163
157
|
|
|
164
158
|
for (i in 0 until childCount) {
|
|
165
|
-
|
|
159
|
+
prepareView(getChildAt(i))
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Draw children. For Fresco views, draw the top-level drawable directly
|
|
163
|
+
// (since the internal drawable is rebuilt when roundingParams changes).
|
|
164
|
+
fun drawView(view: View, c: Canvas) {
|
|
165
|
+
val hierarchy = frescoViews[view]
|
|
166
|
+
if (hierarchy != null) {
|
|
167
|
+
try {
|
|
168
|
+
val getTopDrawable = hierarchy.javaClass.getMethod("getTopLevelDrawable")
|
|
169
|
+
val drawable = getTopDrawable.invoke(hierarchy) as? android.graphics.drawable.Drawable
|
|
170
|
+
if (drawable != null) {
|
|
171
|
+
drawable.setBounds(0, 0, view.width, view.height)
|
|
172
|
+
drawable.invalidateSelf()
|
|
173
|
+
drawable.draw(c)
|
|
174
|
+
Log.d(TAG, "captureSnapshot: drew Fresco drawable directly ${view.width}x${view.height}")
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
} catch (_: Exception) {}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (view is ViewGroup) {
|
|
181
|
+
// Draw background
|
|
182
|
+
view.background?.let { bg ->
|
|
183
|
+
bg.setBounds(0, 0, view.width, view.height)
|
|
184
|
+
bg.draw(c)
|
|
185
|
+
}
|
|
186
|
+
for (i in 0 until view.childCount) {
|
|
187
|
+
val child = view.getChildAt(i)
|
|
188
|
+
if (child.visibility != VISIBLE) continue
|
|
189
|
+
c.save()
|
|
190
|
+
c.translate(child.left.toFloat(), child.top.toFloat())
|
|
191
|
+
drawView(child, c)
|
|
192
|
+
c.restore()
|
|
193
|
+
}
|
|
194
|
+
} else {
|
|
195
|
+
view.draw(c)
|
|
196
|
+
}
|
|
166
197
|
}
|
|
167
198
|
|
|
168
199
|
for (i in 0 until childCount) {
|
|
@@ -170,26 +201,21 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
|
|
|
170
201
|
if (child.visibility != VISIBLE) continue
|
|
171
202
|
canvas.save()
|
|
172
203
|
canvas.translate(child.left.toFloat(), child.top.toFloat())
|
|
173
|
-
child
|
|
204
|
+
drawView(child, canvas)
|
|
174
205
|
canvas.restore()
|
|
175
206
|
}
|
|
176
207
|
|
|
177
|
-
// Restore
|
|
178
|
-
for (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
val setRounding = hierarchy.javaClass.getMethod("setRoundingParams", roundingClass)
|
|
189
|
-
setRounding.invoke(hierarchy, state.roundingParams)
|
|
190
|
-
}
|
|
191
|
-
} catch (_: Exception) {}
|
|
192
|
-
}
|
|
208
|
+
// Restore clipToOutline
|
|
209
|
+
for (view in clippedViews) {
|
|
210
|
+
view.clipToOutline = true
|
|
211
|
+
}
|
|
212
|
+
// Restore Fresco rounding params
|
|
213
|
+
for (state in frescoStates) {
|
|
214
|
+
try {
|
|
215
|
+
val roundingClass = Class.forName("com.facebook.drawee.generic.RoundingParams")
|
|
216
|
+
val setRounding = state.hierarchy.javaClass.getMethod("setRoundingParams", roundingClass)
|
|
217
|
+
setRounding.invoke(state.hierarchy, state.roundingParams)
|
|
218
|
+
} catch (_: Exception) {}
|
|
193
219
|
}
|
|
194
220
|
|
|
195
221
|
return bitmap
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-morph-card",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "Native card-to-modal morph transition for React Native. iOS App Store-style expand animation.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|