Repository: ggomaeng/react-native-magazine-listview
Branch: master
Commit: 2ce20829950a
Files: 6
Total size: 10.3 KB
Directory structure:
gitextract_806nzrp7/
├── README.md
├── exp.json
├── main.js
├── package.json
└── src/
├── components/
│ └── digital-magazine.js
└── index.js
================================================
FILE CONTENTS
================================================
================================================
FILE: README.md
================================================
# react-native-magazine-listview
A pure javascript magazine listview for React Native framework.
###Inspiration

By Frederik Røssell from dribbble.com
https://dribbble.com/shots/3058788-Digital-magazine-mockup
###Demo

## Try it out
Try it with Exponent: https://getexponent.com/@sungwoopark95/react-native-digital-magazine
## Run it locally
To install, there are two steps:
1. Install Exponent XDE [following this
guide](https://docs.getexponent.com/versions/latest/introduction/installation.html).
Also install the Exponent app on your phone if you want to test it on
your device, otherwise you don't need to do anything for the simulator.
2. Clone this repo and run `npm install`
```bash
git clone https://github.com/ggomaeng/react-native-magazine-listview.git magazineListview
cd magazineListview
npm install
```
3. Open the project with Exponent XDE and run it.
================================================
FILE: exp.json
================================================
{
"name": "react-native-digital-magazine",
"description": "An empty new project",
"slug": "react-native-digital-magazine",
"sdkVersion": "11.0.0",
"version": "1.0.0",
"orientation": "portrait",
"primaryColor": "#cccccc",
"iconUrl": "https://s3.amazonaws.com/exp-brand-assets/ExponentEmptyManifest_192.png",
"notification": {
"iconUrl": "https://s3.amazonaws.com/exp-us-standard/placeholder-push-icon-blue-circle.png",
"color": "#000000"
},
"loading": {
"iconUrl": "https://s3.amazonaws.com/exp-brand-assets/ExponentEmptyManifest_192.png",
"hideExponentText": false
},
"packagerOpts": {
"assetExts": ["ttf", "mp4"]
}
}
================================================
FILE: main.js
================================================
import Exponent from 'exponent';
import Main from './src/index';
Exponent.registerRootComponent(Main);
================================================
FILE: package.json
================================================
{
"name": "react-native-digital-magazine",
"version": "0.0.0",
"description": "Hello Exponent!",
"author": null,
"private": true,
"main": "main.js",
"dependencies": {
"exponent": "~11.0.2",
"@exponent/vector-icons": "~2.0.3",
"react": "~15.3.2",
"react-native": "git+https://github.com/exponentjs/react-native#sdk-11.0.3"
}
}
================================================
FILE: src/components/digital-magazine.js
================================================
/**
* Created by ggoma on 2016. 11. 25..
*/
import Exponent from 'exponent';
import React, {Component} from 'react';
import {
Animated,
View,
Text,
Image,
Dimensions,
ListView,
StyleSheet
} from 'react-native';
const {width, height} = Dimensions.get('window');
const midpoint = width / 2;
export default class DigitalMagazine extends Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(props.items),
opacity: new Animated.Value(1),
images: props.images.reverse(), //to stack the images in right order
opacity_values : props.images.map(() => {
return new Animated.Value(1)
}),
text_opacity : props.images.map(() => {
return new Animated.Value(1)
}),
};
this.page = props.images.length - 1; //backwards
this.offset = 0;
this._renderRow = this._renderRow.bind(this);
this.handleScroll = this.handleScroll.bind(this);
}
_renderRow(row) {
var {page, publisher, title, author, highlight, color} = row;
return (
{publisher}
{highlight}{title}
{author}
)
}
handleScroll (event) {
var e = event.nativeEvent;
var currentOffset = e.contentOffset.x;
var offset_ratio = (currentOffset / width);
if(currentOffset > this.offset) {
if(!Number.isInteger(offset_ratio) && offset_ratio > 0 ) {
var page = Math.floor(offset_ratio);
// console.log('scrolling right on page', page);
var stack = Math.abs(page - this.state.opacity_values.length + 1);
// console.log('position on stack', stack);
//make current slide fade to 0
if(stack != 0) { //check last page
this.state.opacity_values[stack].setValue(Math.abs((currentOffset - ( width * (page +1) )) / width));
//set current page to 0
this.state.text_opacity[page].setValue(Math.abs((currentOffset - ( width * (page +1) )) / width));
//set next page to 1 from 0
this.state.text_opacity[page + 1].setValue(Math.abs((currentOffset - ( width * (page) )) / width));
}
}
} else {
if(!Number.isInteger(offset_ratio) && offset_ratio > 0) {
var page = Math.ceil(offset_ratio);
// console.log('scrolling left on page', page);
var stack = Math.abs(page - this.state.opacity_values.length + 1);
// console.log('position on stack', stack);
if(this.state.opacity_values[stack + 1] != null && page < this.state.opacity_values.length) {
//make previous slide fade to 1 -- remember, here uses math.ceil
this.state.opacity_values[stack + 1].setValue(Math.abs(currentOffset - ( width * page )) / width);
//set left page to 1
this.state.text_opacity[page - 1].setValue(Math.abs((currentOffset - ( width * (page) )) / width));
//set current page from 1 to 0
this.state.text_opacity[page].setValue(Math.abs(currentOffset - (width * (page-1) )) / width);
}
}
}
this.offset = currentOffset;
}
renderImages() {
var {images, opacity_values} = this.state;
return images.map((image, i) => {
return
})
}
render() {
var {images, page, opacity} = this.state;
return (
{this.renderImages()}
)
}
}
var styles = StyleSheet.create({
img: {
width: width,
height: height,
position: 'absolute',
}
})
================================================
FILE: src/index.js
================================================
/**
* Created by ggoma on 2016. 11. 25..
*/
import Exponent from 'exponent';
import React from 'react';
import {
StyleSheet,
Text,
View,
} from 'react-native';
import DigitalMagazine from './components/digital-magazine';
export default class App extends React.Component {
state = {
appIsReady: false,
}
async componentWillMount() {
try {
await Exponent.Font.loadAsync({cursive: require('../assets/dancingscript.ttf')});
this.setState({appIsReady: true});
} catch(e) {
// console.warn(
// 'There was an error caching assets (see: main.js), perhaps due to a ' +
// 'network timeout, so we skipped caching. Reload the app to try again.'
// );
// console.log(e.message);
}
}
render() {
if (!this.state.appIsReady) {
return (
);
}
return (
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});