[
  {
    "path": ".eslintrc",
    "content": "{\n  \"parser\": \"babel-eslint\",\n  \"extends\": \"airbnb\",\n  \"env\": {\n    \"browser\": true,\n    \"node\": true,\n    \"mocha\": true\n  },\n  \"globals\": {\n    \"connect\": true\n  },\n  \"rules\": {\n    \"max-len\": 0,\n    \"no-console\": 0,\n    \"no-unused-expressions\": 0,\n    \"no-param-reassign\": 0,\n    \"no-unneeded-ternary\": 0,\n    \"arrow-body-style\": 0,\n    \"react/jsx-no-bind\": 0,\n    \"default-case\": 0,\n    \"prefer-template\": 0,\n    \"padded-blocks\": 0,\n    \"camelcase\": 0,\n    \"no-else-return\": 0,\n    \"func-names\": 0,\n    \"consistent-return\": 0,\n    \"array-callback-return\": 0,\n    \"no-confusing-arrow\": 0,\n    \"no-case-declaration\": 0,\n    \"react/jsx-closing-bracket-location\": 0,\n    \"no-empty\": 0,\n    \"react/prefer-stateless-function\": 0\n  },\n  \"plugins\": [\n    \"react\"\n  ]\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio\n\n*.iml\n\n## Directory-based project format:\n.idea/\n# if you remove the above rule, at least ignore the following:\n\n# User-specific stuff:\n# .idea/workspace.xml\n# .idea/tasks.xml\n# .idea/dictionaries\n\n# Sensitive or high-churn files:\n# .idea/dataSources.ids\n# .idea/dataSources.xml\n# .idea/sqlDataSources.xml\n# .idea/dynamic.xml\n# .idea/uiDesigner.xml\n\n# Gradle:\n# .idea/gradle.xml\n# .idea/libraries\n\n# Mongo Explorer plugin:\n# .idea/mongoSettings.xml\n\n## File-based project format:\n*.ipr\n*.iws\n\n## Plugin-specific files:\n\n# IntelliJ\n/out/\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\nnode_modules/\n.sass-cache/\nbower_components/\napp/bower_components\n.DS_Store\n.tmp\nios\n.yo-rc.json\n.jshintrc\n.gitattributes\n.editorconfig\n.babelrc\nnpm-debug.log"
  },
  {
    "path": "README.md",
    "content": "# React Parallax Component\n\nEasiest way to add scroll parallax effect on the component.\n\n![image](https://raw.githubusercontent.com/keske/react-parallax-component/master/src/example/images/example.gif?token=ABvV0pJZwvFAa0Nrvv6LRVqxkGZb8vhcks5Wgt1WwA%3D%3D)\n\n\n## Installation\n\n`npm install react-parallax-component`\n\n## Usage\n\n`import ParallaxComponent from 'react-parallax-component';`\n\n\n```javascript\n<ParallaxComponent\n  speed=\"0.003\"\n  width=\"300\"\n  top=\"40%\"\n  left=\"100\"\n>\n  <div>\n    Children component\n  </div>\n</ParallaxComponent>\n```\n\n### Props\n- `speed` _(String)_ - animation speed, default: `-0.03`\n- `width` _(String)_ - component width, default: `auto`\n- `height` _(String)_ - component height, default: `auto`\n- `top` _(String)_ - component top position, default: `inherit`\n- `left` _(String)_ - component left position, default: `inherit`\n- `right` _(String)_ - component top position, default: `inherit`\n\n## Development\n```\n$ npm install\n```\n\n## Run app\n```\n$ npm start\n```\nAnd open in browser: [http://localhost:4000](http://localhost:4000)\n\n## Build\n```\n$ npm run build\n```"
  },
  {
    "path": "index.html",
    "content": "<html>\n\n<head>\n  <meta charset=\"utf-8\">\n  <title>React Parallax Component Examples</title>\n</head>\n\n<body>\n  <div id=\"react-parallax-component-example\"></div>\n  <a\n    href=\"https://github.com/keske/react-parallax-component\"\n    style=\"\n      position: fixed;\n      top: 20px;\n      right: 20px;\n    \"\n  >\n    How to use\n  </a>\n</body>\n\n<script src=\"dist/bundle.js\"></script>\n\n</html>\n"
  },
  {
    "path": "index.js",
    "content": "var ParallaxComponent = require('./dist/index.min.js');\nmodule.exports = ParallaxComponent;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-parallax-component\",\n  \"version\": \"1.0.6\",\n  \"description\": \"Easiest way to add scroll parallax effect on the component\",\n  \"scripts\": {\n    \"start\": \"node server.js\",\n    \"lint\": \"eslint src\",\n    \"build\": \"webpack --verbose --colors --display-error-details --config webpack/prod.config.js\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/keske/react-parallax-component.git\"\n  },\n  \"keywords\": [\n    \"react\",\n    \"reactjs\",\n    \"parallax\",\n    \"animation\",\n    \"react-component\",\n    \"webpack\"\n  ],\n  \"author\": \"https://github.com/keske\",\n  \"contributors\": [\n    \"Jérémie Boulay (https://github.com/Jeremboo)\"\n  ],\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"autoprefixer\": \"^6.2.1\",\n    \"babel-core\": \"^5.4.7\",\n    \"babel-eslint\": \"^4.0.7\",\n    \"babel-loader\": \"^5.1.4\",\n    \"babel-runtime\": \"^5.5.5\",\n    \"css\": \"^2.2.1\",\n    \"css-loader\": \"^0.23.1\",\n    \"csswring\": \"^4.1.1\",\n    \"eslint\": \"^1.1.0\",\n    \"eslint-config-airbnb\": \"^0.1.0\",\n    \"eslint-plugin-react\": \"^3.2.3\",\n    \"express\": \"^4.13.3\",\n    \"extract-text-webpack-plugin\": \"^0.9.1\",\n    \"morgan\": \"^1.6.1\",\n    \"node-sass\": \"^3.4.2\",\n    \"postcss-loader\": \"^0.8.0\",\n    \"react-dom\": \"^0.14.3\",\n    \"react-hot-loader\": \"^1.3.0\",\n    \"sass\": \"^0.5.0\",\n    \"sass-loader\": \"^3.1.2\",\n    \"style\": \"0.0.3\",\n    \"style-loader\": \"^0.13.0\",\n    \"webpack\": \"^1.12.9\",\n    \"webpack-dev-middleware\": \"^1.4.0\",\n    \"webpack-hot-middleware\": \"^2.6.0\",\n    \"lodash.throttle\": \"^4.1.1\"\n  },\n  \"dependencies\": {\n    \"react\": \"^0.14.2\"\n  }\n}\n"
  },
  {
    "path": "server.js",
    "content": "var http = require('http');\nvar express = require('express');\nvar app = express();\n\napp.use(require('morgan')('short'));\n\n(function initWebpack() {\n  var webpack = require('webpack');\n  var webpackConfig = require('./webpack/dev.config');\n  var compiler = webpack(webpackConfig);\n\n  app.use(require('webpack-dev-middleware')(compiler, {\n    noInfo: true, publicPath: webpackConfig.output.publicPath,\n  }));\n\n  app.use(require('webpack-hot-middleware')(compiler, {\n    log: console.log, path: '/__webpack_hmr', heartbeat: 10 * 1000,\n  }));\n\n  app.use(express.static(__dirname + '/'));\n})();\n\napp.get('/', function root(req, res) {\n  res.sendFile(__dirname + '/index.html');\n});\n\nif (require.main === module) {\n  var server = http.createServer(app);\n  server.listen(process.env.PORT || 4000, function onListen() {\n    var address = server.address();\n    console.log('Listening on: %j', address);\n    console.log(' -> that probably means: http://localhost:%d', address.port);\n  });\n}\n"
  },
  {
    "path": "src/example/index.js",
    "content": "import React, { Component } from 'react';\nimport ReactDOM from 'react-dom';\n\n// Lib\nimport ParallaxComponent from '../';\n\n// Component styles\nimport styles from './styles';\n\nconst WORD = 'AWESOME REACT';\nconst random = (min, max) => Math.random() * (max - min) + min;\n\nexport default class ExamplePage extends Component {\n  render() {\n\n    const wrap = {\n      height: window.innerHeight * 10,\n    };\n\n    return (\n      <div\n        className={styles}\n        style={wrap}\n      >\n        {\n          WORD.split('').map((letter, index) =>\n            <ParallaxComponent\n              speed={random(0, 0.1) * ((random(0, 2) > 1) ? 1 : -1)}\n              top=\"40%\"\n              left={(index + 1) * 80}\n              key={index}\n            >\n              <span className=\"letter\">\n                {letter}\n              </span>\n            </ParallaxComponent>\n          )\n        }\n      </div>\n    );\n  }\n}\n\nReactDOM.render(\n  <ExamplePage />,\n  document.getElementById('react-parallax-component-example')\n);\n"
  },
  {
    "path": "src/example/styles/index.js",
    "content": "import 'style!./styles.scss';\nexport default require('./styles.scss').locals.styles;\n"
  },
  {
    "path": "src/example/styles/styles.scss",
    "content": "@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700,400italic,300italic&subset=latin,cyrillic-ext);\n\n:local(.styles) {\n  position: relative;\n\n  span.letter {\n    font-size: 60px;\n    font-weight: 600;\n    font-family: 'Open Sans', sans-serif;\n    text-align: center;\n    width: 80px;\n    display: inline-block;\n  }\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "import React, { Component } from 'react';\nimport throttle from 'lodash.throttle';\n\n// Component styles\nimport styles from './styles';\n\nexport default class ParallaxComponent extends Component {\n\n  static propTypes = {\n    children: React.PropTypes.node.isRequired,\n    speed: React.PropTypes.number,\n\n    // Style\n    style: React.PropTypes.object,\n    className: React.PropTypes.string,\n    width: React.PropTypes.oneOfType([\n      React.PropTypes.string,\n      React.PropTypes.number,\n    ]),\n    height: React.PropTypes.oneOfType([\n      React.PropTypes.string,\n      React.PropTypes.number,\n    ]),\n    top: React.PropTypes.oneOfType([\n      React.PropTypes.string,\n      React.PropTypes.number,\n    ]),\n    left: React.PropTypes.oneOfType([\n      React.PropTypes.string,\n      React.PropTypes.number,\n    ]),\n    right: React.PropTypes.oneOfType([\n      React.PropTypes.string,\n      React.PropTypes.number,\n    ]),\n  }\n\n  static defaultProps = {\n    width: 'auto',\n    height: 'auto',\n    top: 'inherit',\n    left: 'inherit',\n    right: 'inherit',\n    speed: -0.03,\n  }\n\n  constructor(props) {\n    super(props);\n\n    this.handleScroll = throttle(this.handleScroll.bind(this), 10);\n    this.parallaxElement;\n  }\n\n  componentDidMount() {\n    window.addEventListener('scroll', this.handleScroll);\n    this.handleScroll();\n  }\n\n  componentWillUnmount() {\n    window.removeEventListener('scroll', this.handleScroll);\n  }\n\n  getTop() {\n    const { top = 0 } = this.props;\n    const topString = top + '';\n\n    return topString.indexOf('%') > -1\n      ? window.innerHeight * (topString.replace('%', '') / 100)\n      : parseInt(top, 10);\n  }\n\n  handleScroll() {\n    const { speed } = this.props;\n\n    const top = this.getTop();\n\n    // Top positons\n    const pageTop = window.pageYOffset;\n    const newTop = (top - (pageTop * speed));\n\n    // Set new top position\n    this.parallaxElement.style.top = `${newTop}px`;\n  }\n\n  render() {\n    const { width, height, left, right, top, speed, style, children, className, ...rest } = this.props;\n    const ownStyle = {\n      width,\n      height,\n      left,\n      right,\n    };\n    return (\n      <div\n        className={`${styles} ${className}`}\n        ref={ref => this.parallaxElement = ref}\n        style={{ ...style, ...ownStyle }}\n        {...rest}\n      >\n          {children}\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "src/styles/index.js",
    "content": "import 'style!./styles.scss';\nexport default require('./styles.scss').locals.styles;\n"
  },
  {
    "path": "src/styles/styles.scss",
    "content": ":local(.styles) {\n  position: fixed;\n\n  img {\n    width: 100%;\n  }\n}\n"
  },
  {
    "path": "webpack/dev.config.js",
    "content": "var path = require('path');\nvar webpack = require('webpack');\nvar ExtractTextPlugin = require('extract-text-webpack-plugin');\nvar autoprefixer = require('autoprefixer');\nvar csswring = require('csswring');\n\nmodule.exports = {\n  devtool: 'cheap-module-eval-source-map',\n  entry: [\n    'webpack-hot-middleware/client',\n    './src/example/index',\n  ],\n\n  output: {\n    filename: 'bundle.js',\n    path: path.join(__dirname, '/dist/'),\n    publicPath: '/dist/',\n  },\n\n  plugins: [\n    new webpack.DefinePlugin({\n      __DEVELOPMENT__: true,\n    }),\n    new ExtractTextPlugin('bundle.css'),\n    new webpack.optimize.OccurenceOrderPlugin(),\n    new webpack.HotModuleReplacementPlugin(),\n    new webpack.NoErrorsPlugin(),\n  ],\n\n  resolve: {\n    extensions: ['', '.jsx', '.js', '.json'],\n    modulesDirectories: ['node_modules', 'src'],\n  },\n\n  module: {\n    loaders: [{\n      test: /\\.js$/,\n      loaders: ['react-hot', 'babel?stage=0&loose[]=es6.modules'],\n      exclude: /node_modules/,\n    }, {\n      test: /\\.scss$/,\n      loader: 'css?localIdentName=[path]!postcss-loader!sass',\n    }],\n  },\n\n  postcss: function() {\n    return [autoprefixer({\n      browsers: ['last 2 versions', 'safari 5', 'ie 9', 'ios 6', 'android 4']\n    }), csswring];\n  },\n};"
  },
  {
    "path": "webpack/prod.config.js",
    "content": "var path = require('path');\nvar webpack = require('webpack');\nvar ExtractTextPlugin = require('extract-text-webpack-plugin');\nvar autoprefixer = require('autoprefixer');\nvar csswring = require('csswring');\n\nmodule.exports = {\n  devtool: 'source-map',\n  entry: [\n    './src/',\n  ],\n\n  output: {\n    library: 'react-parallax-component',\n    libraryTarget: 'umd',\n    filename: '../dist/index.min.js',\n    path: __dirname,\n  },\n  plugins: [\n    new webpack.DefinePlugin({\n      'process.env': {\n        NODE_ENV: '\"production\"',\n      },\n      __DEVELOPMENT__: false,\n    }),\n    new ExtractTextPlugin('bundle.css'),\n    new webpack.optimize.DedupePlugin(),\n    new webpack.optimize.OccurenceOrderPlugin(),\n    new webpack.optimize.UglifyJsPlugin({\n      compress: {\n        warnings: false,\n      },\n    }),\n  ],\n\n  resolve: {\n    extensions: ['', '.jsx', '.js', '.json'],\n    modulesDirectories: ['node_modules', 'src'],\n  },\n\n  module: {\n    loaders: [{\n      test: /\\.js$/,\n      loaders: ['react-hot', 'babel?stage=0&loose[]=es6.modules'],\n      exclude: /node_modules/,\n    }, {\n      test: /\\.scss$/,\n      loader: 'css?localIdentName=[path]!postcss-loader!sass',\n    }],\n  },\n\n  postcss: function() {\n    return [autoprefixer({ browsers: ['last 2 versions', 'safari 5', 'ie 9', 'ios 6', 'android 4'] }), csswring];\n  },\n};\n"
  }
]