Skip to content

Commit 73383ea

Browse files
committed
Document new asset system
1 parent 4ac3c4a commit 73383ea

File tree

3 files changed

+62
-37
lines changed

3 files changed

+62
-37
lines changed

Libraries/Image/Image.ios.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ var warning = require('warning');
3434
* including network images, static resources, temporary local images, and
3535
* images from local disk, such as the camera roll.
3636
*
37+
* See [Images Guide](http://facebook.github.io/react-native/guides/images.html)
38+
*
3739
* Example usage:
3840
*
3941
* ```
@@ -42,7 +44,7 @@ var warning = require('warning');
4244
* <View>
4345
* <Image
4446
* style={styles.icon}
45-
* source={require('image!myIcon')}
47+
* source={require('./myIcon.png')}
4648
* />
4749
* <Image
4850
* style={styles.logo}
@@ -59,7 +61,7 @@ var Image = React.createClass({
5961
/**
6062
* `uri` is a string representing the resource identifier for the image, which
6163
* could be an http address, a local file path, or the name of a static image
62-
* resource (which should be wrapped in the `require('image!name')` function).
64+
* resource (which should be wrapped in the `require('./name.png')` function).
6365
*/
6466
source: PropTypes.oneOfType([
6567
PropTypes.shape({

docs/Image.md renamed to docs/Images.md

Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,77 @@
1-
## Static Resources
1+
---
2+
id: images
3+
title: Images
4+
layout: docs
5+
category: Guides
6+
permalink: docs/images.html
7+
next: gesture-responder-system
8+
---
29

3-
Over the course of a project, it is not uncommon to add and remove many images and accidentally end up shipping images you are no longer using in the app. In order to fight this, we need to find a way to know statically which images are being used in the app. To do that, we introduced a marker on require. The only allowed way to refer to an image in the bundle is to literally write `require('image!name-of-the-asset')` in the source.
10+
## Static Image Resources
11+
12+
As of 0.14 release, React Native provides a unified way of managing images in your iOS and Android apps. To add a static image to your app, place it somewhere in your source code tree and reference it like this:
413

514
```javascript
6-
// GOOD
7-
<Image source={require('image!my-icon')} />
15+
<Image source={require('./my-icon.png')} />
16+
```
817

9-
// BAD
10-
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
11-
<Image source={require('image!' + icon)} />
18+
Image name is resolved the same way JS modules are resolved. In the example above the packager will look for `my-icon.png` in the same folder as the component that requires it. Also if you have `my-icon.ios.png` and `my-icon.android.png`, the packager will pick the file depending on the platform you are running on.
1219

13-
// GOOD
14-
var icon = this.props.active ? require('image!my-icon-active') : require('image!my-icon-inactive');
15-
<Image source={icon} />
20+
You can also use `@2x`, `@3x`, etc. suffix in the file name to provide images for different screen densities. For example, if you have the following file structure:
21+
22+
```
23+
.
24+
├── button.js
25+
└── img
26+
├── check@2x.png
27+
└── check@3x.png
28+
```
29+
30+
And `button.js` code contains
31+
32+
```javascript
33+
<Image source={require('./img/check.png')} />
1634
```
1735

18-
When your entire codebase respects this convention, you're able to do interesting things like automatically packaging the assets that are being used in your app. Note that in the current form, nothing is enforced, but it will be in the future.
36+
Packager will bundle and server image corresponding to device's screen density, e.g. on iPhone 5s `check@2x.png` will be used, on Nexus 5 – `check@3x.png`. If there is no image matching screen density, closest best option will be selected.
1937

20-
### Adding Static Resources to your iOS App using Images.xcassets
38+
Here are some benefits that you get:
2139

22-
![](/react-native/img/StaticImageAssets.png)
40+
1. Same system on iOS and Android
41+
2. Images live in the same folder as your JS code. Components are self-contained.
42+
3. No global namespace, i.e. you don't have worry about name collisions.
43+
4. Only the images that are actually used will be packaged into your app.
44+
5. Adding and changing images doesn't require app recompilation, just refresh simulator as you normally do.
45+
6. Packager knows image size, no need to duplicate it in the code.
46+
7. Images can be distributed via [npm](https://www.npmjs.com/) packages.
2347

24-
> **NOTE**: App build required for new resources
25-
>
26-
> Any time you add a new resource to `Images.xcassets` you will need to re-build your app through Xcode before you can use it - a reload from within the simulator is not enough.
48+
Note that in order for this to work, image name in `require` has to be known statically.
2749

28-
*This process is currently being improved, a much better workflow will be available shortly.*
50+
```javascript
51+
// GOOD
52+
<Image source={require('./my-icon.png')} />
2953

30-
> **NOTE**: PNG images are required when loading with `require('image!my-icon')`
31-
>
32-
> At this time, only PNG images are supported in iOS. There is an [issue](https://github.com/facebook/react-native/issues/646) that is currently addressing this bug. In the meantime a quick fix is to rename your files to my-icon.png or to use the `uri` property like: `source={{ uri: 'my-icon' }}` instead of `require()`.
54+
// BAD
55+
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
56+
<Image source={require('./' + icon + '.png')} />
3357

34-
### Adding Static Resources to your Android app
58+
// GOOD
59+
var icon = this.props.active ? require('./my-icon-active.png') : require('./my-icon-inactive.png');
60+
<Image source={icon} />
61+
```
3562

36-
Add your images as [bitmap drawables](http://developer.android.com/guide/topics/resources/drawable-resource.html#Bitmap) to the android project (`<yourapp>/android/app/src/main/res`). To provide different resolutions of your assets, check out [using configuration qualifiers](http://developer.android.com/guide/practices/screens_support.html#qualifiers). Normally, you will want to put your assets in the following directories (create them under `res` if they don't exist):
63+
## Images From Hybrid App's Resources
3764

38-
* `drawable-mdpi` (1x)
39-
* `drawable-hdpi` (1.5x)
40-
* `drawable-xhdpi` (2x)
41-
* `drawable-xxhdpi` (3x)
65+
If you are building a hybrid app (some UIs in React Native, some UIs in platform code) you can still use images that are already bundled into the app (via Xcode asset catalogs or Android drawable folder):
4266

43-
If you're missing a resolution for your asset, Android will take the next best thing and resize it for you.
67+
```javascript
68+
<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />
69+
```
4470

45-
> **NOTE**: App build required for new resources
46-
>
47-
> Any time you add a new resource to your drawables you will need to re-build your app by running `react-native run-android` before you can use it - reloading the JS is not enough.
71+
Note that this approach provides no safety checks. It's up to you to guarantee that those images are available in the application. Also you have to specify image dimensions manually.
4872

49-
*This process is currently being improved, a much better workflow will be available shortly.*
5073

51-
## Network Resources
74+
## Network Images
5275

5376
Many of the images you will display in your app will not be available at compile time, or you will want to load some dynamically to keep the binary size down. Unlike with static resources, *you will need to manually specify the dimensions of your image.*
5477

@@ -61,7 +84,7 @@ Many of the images you will display in your app will not be available at compile
6184
<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}} />
6285
```
6386

64-
## Local Filesystem Resources
87+
## Local Filesystem Images
6588

6689
See [CameraRoll](/react-native/docs/cameraroll.html) for an example of
6790
using local resources that are outside of `Images.xcassets`.
@@ -90,7 +113,7 @@ In React Native, one interesting decision is that the `src` attribute is named `
90113
<Image source={{uri: 'something.jpg'}} />
91114
```
92115

93-
On the infrastructure side, the reason is that it allows us to attach metadata to this object. For example if you are using `require('image!icon')`, then we add an `isStatic` attribute to flag it as a local file (don't rely on this fact, it's likely to change in the future!). This is also future proofing, for example we may want to support sprites at some point, instead of outputting `{uri: ...}`, we can output `{uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}` and transparently support spriting on all the existing call sites.
116+
On the infrastructure side, the reason is that it allows us to attach metadata to this object. For example if you are using `require('./my-icon.png')`, then we add information about it's actual location and size (don't rely on this fact, it might change in the future!). This is also future proofing, for example we may want to support sprites at some point, instead of outputting `{uri: ...}`, we can output `{uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}` and transparently support spriting on all the existing call sites.
94117

95118
On the user side, this lets you annotate the object with useful attributes such as the dimension of the image in order to compute the size it's going to be displayed in. Feel free to use it as your data structure to store more information about your image.
96119

docs/Style.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: Style
44
layout: docs
55
category: Guides
66
permalink: docs/style.html
7-
next: gesture-responder-system
7+
next: images
88
---
99

1010
React Native doesn't implement CSS but instead relies on JavaScript to let you style your application. This has been a controversial decision and you can read through those slides for the rationale behind it.

0 commit comments

Comments
 (0)