expo-image 1.10.0 → 1.10.2
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.
- package/CHANGELOG.md +16 -0
- package/README.md +27 -17
- package/android/build.gradle +2 -3
- package/android/src/main/java/com/caverock/androidsvg/SVGStyler.kt +86 -4
- package/android/src/main/java/expo/modules/image/ImageViewWrapperTarget.kt +1 -1
- package/android/src/main/java/expo/modules/image/drawing/OutlineProvider.kt +13 -2
- package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashDecoder.kt +6 -4
- package/expo-module.config.json +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,22 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 1.10.2 — 2024-01-10
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- [Android] Fixed the issue with the application of tint color when an element does not have a style assigned to it. ([#26251](https://github.com/expo/expo/pull/26251) by [@lukmccall](https://github.com/lukmccall))
|
|
18
|
+
- [Android] Fixed the tint color was applied to the mask element. ([#26323](https://github.com/expo/expo/pull/26323) by [@lukmccall](https://github.com/lukmccall))
|
|
19
|
+
- [Android] Fixed the tint color wasn't applied to the root element. ([#26339](https://github.com/expo/expo/pull/26339) by [@lukmccall](https://github.com/lukmccall))
|
|
20
|
+
|
|
21
|
+
### 💡 Others
|
|
22
|
+
|
|
23
|
+
- Replace deprecated `com.facebook.react:react-native:+` Android dependency with `com.facebook.react:react-android`. ([#26237](https://github.com/expo/expo/pull/26237) by [@kudo](https://github.com/kudo))
|
|
24
|
+
|
|
25
|
+
## 1.10.1 — 2023-12-19
|
|
26
|
+
|
|
27
|
+
_This version does not introduce any user-facing changes._
|
|
28
|
+
|
|
13
29
|
## 1.10.0 — 2023-12-12
|
|
14
30
|
|
|
15
31
|
### 🎉 New features
|
package/README.md
CHANGED
|
@@ -21,34 +21,44 @@ A cross-platform, performant image component for React Native and Expo.
|
|
|
21
21
|
|
|
22
22
|
## Supported image formats
|
|
23
23
|
|
|
24
|
-
| Format | Android | iOS |
|
|
25
|
-
| :--------: | :-----: | :-: |
|
|
26
|
-
| WebP | ✅ | ✅ |
|
|
27
|
-
| PNG / APNG | ✅ | ✅ |
|
|
28
|
-
| AVIF | ✅ | ✅ |
|
|
29
|
-
| HEIC | ✅ | ✅ |
|
|
30
|
-
| JPEG | ✅ | ✅ |
|
|
31
|
-
| GIF | ✅ | ✅ |
|
|
32
|
-
| SVG | ✅ | ✅ |
|
|
33
|
-
| ICO | ✅ | ✅ |
|
|
34
|
-
| ICNS | ❌ | ✅ |
|
|
24
|
+
| Format | Android | iOS | Web |
|
|
25
|
+
| :--------: | :-----: | :-: | :--------------------------------------------: |
|
|
26
|
+
| WebP | ✅ | ✅ | ✅ |
|
|
27
|
+
| PNG / APNG | ✅ | ✅ | ✅ |
|
|
28
|
+
| AVIF | ✅ | ✅ | ⏳ [~87% adoption](https://caniuse.com/avif) |
|
|
29
|
+
| HEIC | ✅ | ✅ | ❌ [not adopted yet](https://caniuse.com/heif) |
|
|
30
|
+
| JPEG | ✅ | ✅ | ✅ |
|
|
31
|
+
| GIF | ✅ | ✅ | ✅ |
|
|
32
|
+
| SVG | ✅ | ✅ | ✅ |
|
|
33
|
+
| ICO | ✅ | ✅ | ✅ |
|
|
34
|
+
| ICNS | ❌ | ✅ | ❌ |
|
|
35
35
|
|
|
36
36
|
# API documentation
|
|
37
37
|
|
|
38
|
-
- [Documentation for the latest release](https://docs.expo.dev/versions/
|
|
38
|
+
- [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/image/)
|
|
39
39
|
|
|
40
|
-
# Installation
|
|
40
|
+
# Installation in managed Expo projects
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
> It is not available with Snack yet.
|
|
42
|
+
For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/image/).
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
# Installation in bare React Native projects
|
|
45
|
+
|
|
46
|
+
For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
|
|
47
|
+
|
|
48
|
+
### Add the package to your npm dependencies
|
|
46
49
|
|
|
47
50
|
```
|
|
48
51
|
npx expo install expo-image
|
|
49
|
-
npx pod-install
|
|
50
52
|
```
|
|
51
53
|
|
|
54
|
+
### Configure for iOS
|
|
55
|
+
|
|
56
|
+
Run `npx pod-install` after installing the npm package.
|
|
57
|
+
|
|
58
|
+
### Configure for Android
|
|
59
|
+
|
|
60
|
+
No additional setup necessary.
|
|
61
|
+
|
|
52
62
|
# Contributing
|
|
53
63
|
|
|
54
64
|
Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).
|
package/android/build.gradle
CHANGED
|
@@ -67,7 +67,7 @@ android {
|
|
|
67
67
|
namespace "expo.modules.image"
|
|
68
68
|
defaultConfig {
|
|
69
69
|
versionCode 1
|
|
70
|
-
versionName "1.10.
|
|
70
|
+
versionName "1.10.2"
|
|
71
71
|
consumerProguardFiles("proguard-rules.pro")
|
|
72
72
|
|
|
73
73
|
buildConfigField("boolean", "ALLOW_GLIDE_LOGS", project.properties.get("EXPO_ALLOW_GLIDE_LOGS", "false"))
|
|
@@ -108,8 +108,7 @@ dependencies {
|
|
|
108
108
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
implementation 'com.facebook.react:react-native:+' // From node_modules
|
|
111
|
+
implementation 'com.facebook.react:react-android'
|
|
113
112
|
|
|
114
113
|
api "com.github.bumptech.glide:glide:${GLIDE_VERSION}"
|
|
115
114
|
kapt "com.github.bumptech.glide:compiler:${GLIDE_VERSION}"
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
package com.caverock.androidsvg
|
|
2
2
|
|
|
3
|
+
import com.caverock.androidsvg.SVG.SPECIFIED_COLOR
|
|
4
|
+
import com.caverock.androidsvg.SVG.SPECIFIED_FILL
|
|
5
|
+
import com.caverock.androidsvg.SVG.SvgElementBase
|
|
6
|
+
|
|
3
7
|
internal fun replaceColor(paint: SVG.SvgPaint?, newColor: Int) {
|
|
4
8
|
if (paint is SVG.Colour && paint !== SVG.Colour.TRANSPARENT) {
|
|
5
9
|
paint.colour = newColor
|
|
@@ -19,15 +23,88 @@ internal fun replaceStyles(style: SVG.Style?, newColor: Int) {
|
|
|
19
23
|
replaceColor(style.viewportFill, newColor)
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
internal fun
|
|
23
|
-
if (element
|
|
26
|
+
internal fun hasStyle(element: SvgElementBase): Boolean {
|
|
27
|
+
if (element.style == null && element.baseStyle == null) {
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
val style = element.style
|
|
32
|
+
val hasColorInStyle = style != null &&
|
|
33
|
+
(
|
|
34
|
+
style.color != null || style.fill != null || style.stroke != null ||
|
|
35
|
+
style.stroke != null || style.stopColor != null || style.solidColor != null
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
if (hasColorInStyle) {
|
|
39
|
+
return true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
val baseStyle = element.baseStyle ?: return false
|
|
43
|
+
return baseStyle.color != null || baseStyle.fill != null || baseStyle.stroke != null ||
|
|
44
|
+
baseStyle.viewportFill != null || baseStyle.stopColor != null || baseStyle.solidColor != null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
internal fun defineStyles(element: SvgElementBase, newColor: Int, hasStyle: Boolean) {
|
|
48
|
+
if (hasStyle) {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
val style = if (element.style != null) {
|
|
53
|
+
element.style
|
|
54
|
+
} else {
|
|
55
|
+
SVG.Style().also {
|
|
56
|
+
element.style = it
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
val color = SVG.Colour(newColor)
|
|
61
|
+
when (element) {
|
|
62
|
+
is SVG.Path,
|
|
63
|
+
is SVG.Circle,
|
|
64
|
+
is SVG.Ellipse,
|
|
65
|
+
is SVG.Rect,
|
|
66
|
+
is SVG.SolidColor,
|
|
67
|
+
is SVG.Line,
|
|
68
|
+
is SVG.Polygon,
|
|
69
|
+
is SVG.PolyLine -> {
|
|
70
|
+
style.apply {
|
|
71
|
+
fill = color
|
|
72
|
+
|
|
73
|
+
specifiedFlags = SPECIFIED_FILL
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
is SVG.TextPath -> {
|
|
78
|
+
style.apply {
|
|
79
|
+
this.color = color
|
|
80
|
+
|
|
81
|
+
specifiedFlags = SPECIFIED_COLOR
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
internal fun applyTintColor(element: SVG.SvgObject, newColor: Int, parentDefinesStyle: Boolean) {
|
|
88
|
+
// We want to keep the colors in the mask as they control the visibility of the element to which the mask is applied.
|
|
89
|
+
if (element is SVG.Mask) {
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
val definesStyle = if (element is SvgElementBase) {
|
|
94
|
+
val hasStyle = parentDefinesStyle || hasStyle(element)
|
|
95
|
+
|
|
24
96
|
replaceStyles(element.baseStyle, newColor)
|
|
25
97
|
replaceStyles(element.style, newColor)
|
|
98
|
+
defineStyles(element, newColor, hasStyle)
|
|
99
|
+
|
|
100
|
+
hasStyle
|
|
101
|
+
} else {
|
|
102
|
+
parentDefinesStyle
|
|
26
103
|
}
|
|
27
104
|
|
|
28
105
|
if (element is SVG.SvgContainer) {
|
|
29
106
|
for (child in element.children) {
|
|
30
|
-
applyTintColor(child, newColor)
|
|
107
|
+
applyTintColor(child, newColor, definesStyle)
|
|
31
108
|
}
|
|
32
109
|
}
|
|
33
110
|
}
|
|
@@ -35,9 +112,14 @@ internal fun applyTintColor(element: SVG.SvgObject, newColor: Int) {
|
|
|
35
112
|
fun applyTintColor(svg: SVG, newColor: Int) {
|
|
36
113
|
val root = svg.rootElement
|
|
37
114
|
|
|
115
|
+
svg.cssRules?.forEach { rule ->
|
|
116
|
+
replaceStyles(rule.style, newColor)
|
|
117
|
+
}
|
|
118
|
+
replaceStyles(root.baseStyle, newColor)
|
|
38
119
|
replaceStyles(root.style, newColor)
|
|
120
|
+
val hasStyle = hasStyle(root)
|
|
39
121
|
|
|
40
122
|
for (child in root.children) {
|
|
41
|
-
applyTintColor(child, newColor)
|
|
123
|
+
applyTintColor(child, newColor, hasStyle)
|
|
42
124
|
}
|
|
43
125
|
}
|
|
@@ -30,7 +30,7 @@ import kotlin.math.max
|
|
|
30
30
|
* of implementing the transition between bitmaps.
|
|
31
31
|
*/
|
|
32
32
|
class ImageViewWrapperTarget(
|
|
33
|
-
private val imageViewHolder: WeakReference<ExpoImageViewWrapper
|
|
33
|
+
private val imageViewHolder: WeakReference<ExpoImageViewWrapper>
|
|
34
34
|
) : Target<Drawable> {
|
|
35
35
|
/**
|
|
36
36
|
* Whether the target has a main, non-placeholder source
|
|
@@ -15,11 +15,22 @@ import expo.modules.image.ifYogaUndefinedUse
|
|
|
15
15
|
|
|
16
16
|
class OutlineProvider(private val mContext: Context) : ViewOutlineProvider() {
|
|
17
17
|
enum class BorderRadiusConfig {
|
|
18
|
-
ALL,
|
|
18
|
+
ALL,
|
|
19
|
+
TOP_LEFT,
|
|
20
|
+
TOP_RIGHT,
|
|
21
|
+
BOTTOM_RIGHT,
|
|
22
|
+
BOTTOM_LEFT,
|
|
23
|
+
TOP_START,
|
|
24
|
+
TOP_END,
|
|
25
|
+
BOTTOM_START,
|
|
26
|
+
BOTTOM_END
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
enum class CornerRadius {
|
|
22
|
-
TOP_LEFT,
|
|
30
|
+
TOP_LEFT,
|
|
31
|
+
TOP_RIGHT,
|
|
32
|
+
BOTTOM_RIGHT,
|
|
33
|
+
BOTTOM_LEFT
|
|
23
34
|
}
|
|
24
35
|
|
|
25
36
|
private var mLayoutDirection = View.LAYOUT_DIRECTION_LTR
|
|
@@ -96,10 +96,12 @@ object ThumbhashDecoder {
|
|
|
96
96
|
hash[2] = (header24 shr 16).toByte()
|
|
97
97
|
hash[3] = header16.toByte()
|
|
98
98
|
hash[4] = (header16 shr 8).toByte()
|
|
99
|
-
if (hasAlpha)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
if (hasAlpha) {
|
|
100
|
+
hash[5] = (
|
|
101
|
+
Math.round(15.0f * a_channel!!.dc)
|
|
102
|
+
or (Math.round(15.0f * a_channel.scale) shl 4)
|
|
103
|
+
).toByte()
|
|
104
|
+
}
|
|
103
105
|
|
|
104
106
|
// Write the varying factors
|
|
105
107
|
var ac_index = 0
|
package/expo-module.config.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-image",
|
|
3
3
|
"title": "Expo Image",
|
|
4
|
-
"version": "1.10.
|
|
4
|
+
"version": "1.10.2",
|
|
5
5
|
"description": "A cross-platform, performant image component for React Native and Expo with Web support",
|
|
6
6
|
"main": "build/index.js",
|
|
7
7
|
"types": "build/index.d.ts",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"expo": "*"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "ca014bf2516c7644ef303f4c21fdd68de4d99f76"
|
|
39
39
|
}
|