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 ![alt tag](https://raw.githubusercontent.com/ggomaeng/react-native-magazine-listview/master/inspiration.gif) By Frederik Røssell from dribbble.com https://dribbble.com/shots/3058788-Digital-magazine-mockup ###Demo ![alt tag](https://raw.githubusercontent.com/ggomaeng/react-native-magazine-listview/master/demo.gif) ## 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', }, });