Skip to content

Commit

Permalink
tint color support (DylanVann#2)
Browse files Browse the repository at this point in the history
* add image color support
  • Loading branch information
millibeckers authored and oisu committed Aug 25, 2018
1 parent 47965fa commit ab03eb2
Show file tree
Hide file tree
Showing 6 changed files with 308 additions and 2 deletions.
83 changes: 83 additions & 0 deletions ReactNativeFastImageExample/FastImage/FastImageExamples.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React from 'react'
import { ScrollView, StatusBar, StyleSheet, Text, View } from 'react-native'
import Icon from './Icons/Icon'
import Section from './Section'
import PriorityExample from './PriorityExample'
import GifExample from './GifExample'
import BorderRadiusExample from './BorderRadiusExample'
import FeatureText from './FeatureText'
import ProgressExample from './ProgressExample'
import PreloadExample from './PreloadExample'
import StatusBarUnderlay, { STATUS_BAR_HEIGHT } from './StatusBarUnderlay'
import TintColorExample from './TintColorExample';

const FastImageExample = () => (
<View style={styles.container}>
<StatusBar
translucent
barStyle="dark-content"
backgroundColor="transparent"
/>
<ScrollView
style={styles.scrollContainer}
contentContainerStyle={styles.scrollContentContainer}
>
<View style={styles.contentContainer}>
<Section>
<Text style={styles.titleText}>🚩 FastImage</Text>
<FeatureText text="Tap images to reload examples." />
</Section>
<PriorityExample />
<GifExample />
<BorderRadiusExample />
<ProgressExample />
<TintColorExample />
<PreloadExample />
</View>
</ScrollView>
<StatusBarUnderlay />
</View>
)

FastImageExample.navigationOptions = {
tabBarLabel: 'FastImage Example',
tabBarIcon: props => (
<Icon
name="ios-information-circle-outline"
focusedName="ios-information-circle"
{...props}
/>
),
}

const styles = StyleSheet.create({
titleText: {
fontWeight: '900',
marginBottom: 20,
color: '#222',
},
contentContainer: {
marginTop: 20,
marginBottom: 20,
},
image: {
flex: 1,
height: 100,
backgroundColor: '#ddd',
margin: 10,
},
container: {
flex: 1,
alignItems: 'stretch',
backgroundColor: '#fff',
},
scrollContainer: {
marginTop: STATUS_BAR_HEIGHT,
},
scrollContentContainer: {
alignItems: 'stretch',
flex: 0,
},
})

export default FastImageExample
62 changes: 62 additions & 0 deletions ReactNativeFastImageExample/FastImage/TintColorExample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react'
import { PixelRatio, StyleSheet, View } from 'react-native'
import withCacheBust from './withCacheBust'
import FastImage from 'react-native-fast-image'
import Section from './Section'
import SectionFlex from './SectionFlex'
import FeatureText from './FeatureText'

const getImageUrl = (id, width, height) =>
`https://source.unsplash.com/${id}/${width}x${height}`
const IMAGE_SIZE = 1024
const IMAGE_SIZE_PX = PixelRatio.getPixelSizeForLayoutSize(IMAGE_SIZE)
const IMAGE_URLS = [
getImageUrl('x58soEovG_M', IMAGE_SIZE_PX, IMAGE_SIZE_PX),
getImageUrl('yPI7myL5eWY', IMAGE_SIZE_PX, IMAGE_SIZE_PX),
getImageUrl('S7VCcp6KCKE', IMAGE_SIZE, IMAGE_SIZE),
]

const PriorityExample = ({ onPressReload, bust }) => (
<View>
<Section>
<FeatureText text="Images with image color" />
</Section>
<SectionFlex onPress={onPressReload}>
<FastImage
style={styles.image}
imageColor={'green'}
source={{
uri: IMAGE_URLS[0] + bust,
priority: FastImage.priority.low,
}}
/>
<FastImage
style={styles.image}
imageColor={'#9324c3'}
source={{
uri: IMAGE_URLS[1],
priority: FastImage.priority.normal,
}}
/>
<FastImage
style={styles.image}
imageColor={'rgba(0,0,0,0.5)'}
source={{
uri: IMAGE_URLS[2] + bust,
priority: FastImage.priority.high,
}}
/>
</SectionFlex>
</View>
)

const styles = StyleSheet.create({
image: {
flex: 1,
height: 100,
backgroundColor: '#ddd',
margin: 10,
},
})

export default withCacheBust(PriorityExample)
143 changes: 143 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {
Platform,
View,
Image,
NativeModules,
requireNativeComponent,
ViewPropTypes,
StyleSheet,
} from 'react-native'

const resolveAssetSource = require('react-native/Libraries/Image/resolveAssetSource')

const FastImageViewNativeModule = NativeModules.FastImageView

const useLocalImage = source => {
// No source.
if (!source) return true
// No uri.
if (!source.uri) return true
// Is a local Android image.
if (source.uri.startsWith('file://')) return true
if (source.uri.startsWith('content://')) return true
// We have a remote source.
return false
}

class FastImage extends Component {
setNativeProps(nativeProps) {
this._root.setNativeProps(nativeProps)
}

captureRef = e => (this._root = e)

render() {
const {
source,
imageColor,
onLoadStart,
onProgress,
onLoad,
onError,
onLoadEnd,
style,
children,
...props
} = this.props

// If there's no source or source uri just fallback to Image.
if (useLocalImage(source)) {
return (
<Image
ref={this.captureRef}
{...props}
tintColor={imageColor}
style={style}
source={source}
onLoadStart={onLoadStart}
onProgress={onProgress}
onLoad={onLoad}
onError={onError}
onLoadEnd={onLoadEnd}
/>
)
}

const resolvedSource = resolveAssetSource(source)

return (
<View style={[style, styles.imageContainer]} ref={this.captureRef}>
<FastImageView
{...props}
style={StyleSheet.absoluteFill}
imageColor={imageColor}
source={resolvedSource}
onFastImageLoadStart={onLoadStart}
onFastImageProgress={onProgress}
onFastImageLoad={onLoad}
onFastImageError={onError}
onFastImageLoadEnd={onLoadEnd}
/>
{children && <View style={StyleSheet.absoluteFill}>{children}</View>}
</View>
)
}
}

const styles = StyleSheet.create({
imageContainer: {
overflow: 'hidden',
},
})

FastImage.resizeMode = {
contain: 'contain',
cover: 'cover',
stretch: 'stretch',
center: 'center',
}

FastImage.priority = {
low: 'low',
normal: 'normal',
high: 'high',
}

FastImage.preload = sources => {
FastImageViewNativeModule.preload(sources)
}

FastImage.defaultProps = {
resizeMode: FastImage.resizeMode.cover,
}

const FastImageSourcePropType = PropTypes.shape({
uri: PropTypes.string,
headers: PropTypes.objectOf(PropTypes.string),
priority: PropTypes.oneOf(Object.keys(FastImage.priority)),
})

FastImage.propTypes = {
...ViewPropTypes,
imageColor: PropTypes.any,
source: PropTypes.oneOfType([FastImageSourcePropType, PropTypes.number]),
onLoadStart: PropTypes.func,
onProgress: PropTypes.func,
onLoad: PropTypes.func,
onError: PropTypes.func,
onLoadEnd: PropTypes.func,
}

const FastImageView = requireNativeComponent('FastImageView', FastImage, {
nativeOnly: {
onFastImageLoadStart: true,
onFastImageProgress: true,
onFastImageLoad: true,
onFastImageError: true,
onFastImageLoadEnd: true,
},
})

export default FastImage
1 change: 1 addition & 0 deletions ios/FastImage/FFFastImageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
@property (nonatomic, copy) RCTDirectEventBlock onFastImageLoadEnd;
@property (nonatomic, assign) RCTResizeMode resizeMode;
@property (nonatomic, strong) FFFastImageSource *source;
@property (nonatomic, strong) UIColor *imageColor;

@end

16 changes: 16 additions & 0 deletions ios/FastImage/FFFastImageView.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ - (void)sendOnLoad:(UIImage *)image {
};
if (_onFastImageLoad) {
_onFastImageLoad(onLoadEvent);
- (void)setImageColor:(UIColor *)imageColor
{
if (imageColor != nil) {
_imageColor = imageColor;
self.tintColor = self.imageColor;
super.image = [super.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
}
}

- (void)setImage:(UIImage *)image
{
if (self.imageColor != nil) {
self.tintColor = self.imageColor;
super.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
} else {
super.image = image;
}
}

Expand Down
5 changes: 3 additions & 2 deletions ios/FastImage/FFFastImageViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@ - (FFFastImageView*)view {
RCT_EXPORT_VIEW_PROPERTY(onFastImageError, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageLoad, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageLoadEnd, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(imageColor, UIColor)

RCT_EXPORT_METHOD(preload:(nonnull NSArray<FFFastImageSource *> *)sources)
{
NSMutableArray *urls = [NSMutableArray arrayWithCapacity:sources.count];

[sources enumerateObjectsUsingBlock:^(FFFastImageSource * _Nonnull source, NSUInteger idx, BOOL * _Nonnull stop) {
[source.headers enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString* header, BOOL *stop) {
[[SDWebImageDownloader sharedDownloader] setValue:header forHTTPHeaderField:key];
}];
[urls setObject:source.url atIndexedSubscript:idx];
}];

[[SDWebImagePrefetcher sharedImagePrefetcher] prefetchURLs:urls];
}

Expand Down

0 comments on commit ab03eb2

Please sign in to comment.