Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Added fade animation support #979

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ Headers to load the image with. e.g. `{ Authorization: 'someAuthToken' }`.

---

### `animation?: enum`

- `FastImage.animation.none` **(Default)** - No animation in image loading.
- `FastImage.animation.fade` - Fade in animation in image loading.

---

### `onLoadStart?: () => void`

Called when the image starts to load.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.dylanvann.fastimage;

public enum FastImageAnimation {
FADE,
NONE
}

Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ class FastImageViewConverter {
put("center", ScaleType.CENTER_INSIDE);
}};

private static final Map<String, FastImageAnimation> FAST_IMAGE_ANIMATION_MAP =
new HashMap<String, FastImageAnimation>() {{
put("fade", FastImageAnimation.FADE);
put("none", FastImageAnimation.NONE);
}};

// Resolve the source uri to a file path that android understands.
static @Nullable
FastImageSource getImageSource(Context context, @Nullable ReadableMap source) {
Expand Down Expand Up @@ -133,6 +139,10 @@ static ScaleType getScaleType(String propValue) {
return getValue("resizeMode", "cover", FAST_IMAGE_RESIZE_MODE_MAP, propValue);
}

static FastImageAnimation getAnimation(String propValue) {
return getValue("animation", "none", FAST_IMAGE_ANIMATION_MAP, propValue);
}

private static <T> T getValue(String propName, String defaultPropValue, Map<String, T> map, String propValue) {
if (propValue == null) propValue = defaultPropValue;
T value = map.get(propValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ public void setResizeMode(FastImageViewWithUrl view, String resizeMode) {
view.setScaleType(scaleType);
}

@ReactProp(name = "animation")
public void setAnimation(FastImageViewWithUrl view, String animation) {
final FastImageAnimation animationType = FastImageViewConverter.getAnimation(animation);
view.setAnimation(animationType);
}

@Override
public void onDropViewInstance(@NonNull FastImageViewWithUrl view) {
// This will cancel existing requests.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.Request;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
Expand All @@ -30,6 +31,7 @@ class FastImageViewWithUrl extends AppCompatImageView {
private boolean mNeedsReload = false;
private ReadableMap mSource = null;
private Drawable mDefaultSource = null;
private FastImageAnimation mAnimation = FastImageAnimation.NONE;

public GlideUrl glideUrl;

Expand All @@ -47,6 +49,10 @@ public void setDefaultSource(@Nullable Drawable source) {
mDefaultSource = source;
}

public void setAnimation(FastImageAnimation animation) {
mAnimation = animation;
}

private boolean isNullOrEmpty(final String url) {
return url == null || url.trim().isEmpty();
}
Expand Down Expand Up @@ -144,6 +150,10 @@ public void onAfterUpdate(
.placeholder(mDefaultSource) // show until loaded
.fallback(mDefaultSource)); // null will not be treated as error

if(mAnimation == FastImageAnimation.FADE) {
builder = builder.transition(DrawableTransitionOptions.withCrossFade());
}

if (key != null)
builder.listener(new FastImageRequestListener(key));

Expand Down
1 change: 1 addition & 0 deletions ios/FastImage/FFFastImageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
@property (nonatomic, strong) FFFastImageSource *source;
@property (nonatomic, strong) UIImage *defaultSource;
@property (nonatomic, strong) UIColor *imageColor;
@property (nonatomic, assign) NSString *animation;

@end

8 changes: 8 additions & 0 deletions ios/FastImage/FFFastImageView.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ - (void) setResizeMode: (RCTResizeMode)resizeMode {
}
}

- (void)setAnimation:(NSString*)animation {
if(_animation != animation) {
_animation = animation;
if([_animation isEqual: @"fade"])
self.sd_imageTransition = SDWebImageTransition.fadeTransition;
}
}

- (void) setOnFastImageLoadEnd: (RCTDirectEventBlock)onFastImageLoadEnd {
_onFastImageLoadEnd = onFastImageLoadEnd;
if (self.hasCompleted) {
Expand Down
1 change: 1 addition & 0 deletions ios/FastImage/FFFastImageViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ - (FFFastImageView*)view {
RCT_EXPORT_VIEW_PROPERTY(source, FFFastImageSource)
RCT_EXPORT_VIEW_PROPERTY(defaultSource, UIImage)
RCT_EXPORT_VIEW_PROPERTY(resizeMode, RCTResizeMode)
RCT_EXPORT_VIEW_PROPERTY(animation, NSString)
RCT_EXPORT_VIEW_PROPERTY(onFastImageLoadStart, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageProgress, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageError, RCTDirectEventBlock)
Expand Down
13 changes: 13 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ const resizeMode = {
center: 'center',
} as const

export type Animation = 'none' | 'fade'

const animation = {
none: 'none',
fade: 'fade'
} as const

export type Priority = 'low' | 'normal' | 'high'

const priority = {
Expand Down Expand Up @@ -84,6 +91,7 @@ export interface FastImageProps extends AccessibilityProps, ViewProps {
source?: Source | ImageRequireSource
defaultSource?: ImageRequireSource
resizeMode?: ResizeMode
animation?: Animation
fallback?: boolean

onLoadStart?(): void
Expand Down Expand Up @@ -167,6 +175,7 @@ function FastImageBase({
children,
// eslint-disable-next-line no-shadow
resizeMode = 'cover',
animation = 'none',
forwardedRef,
...props
}: FastImageProps & { forwardedRef: React.Ref<any> }) {
Expand Down Expand Up @@ -211,6 +220,7 @@ function FastImageBase({
onFastImageError={onError}
onFastImageLoadEnd={onLoadEnd}
resizeMode={resizeMode}
animation={animation}
/>
{children}
</View>
Expand All @@ -229,6 +239,7 @@ FastImageComponent.displayName = 'FastImage'

export interface FastImageStaticProperties {
resizeMode: typeof resizeMode
animation: typeof animation
priority: typeof priority
cacheControl: typeof cacheControl
preload: (sources: Source[]) => void
Expand All @@ -245,6 +256,8 @@ FastImage.cacheControl = cacheControl

FastImage.priority = priority

FastImage.animation = animation

FastImage.preload = (sources: Source[]) =>
NativeModules.FastImageView.preload(sources)

Expand Down