├── .babelrc ├── .gitignore ├── .npmignore ├── README.md ├── lib ├── index.js └── style.css ├── package.json ├── src └── index.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets" : [ "env", "react" ] 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | src 3 | webpack.config.js 4 | .babelrc 5 | .gitignore -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-rain-animation 2 | A stateful rain animation component for your react project. No SVG animations no jQuery, no additional dependencies. Addapted from raichu26's [codepen](https://codepen.io/alemesre/pen/hAxGg?q=css%20rain&limit=all&order=popularity&depth=everything&show_forks=false). Live demo [here](https://willnickerson.github.io/react-rain-demo) 3 | 4 | 5 | ## Installation 6 | 7 | To install this Component, run `yarn add react-rain-animation` or `npm install react-rain-animation`. 8 | 9 | ## Usage 10 | 11 | ##Simple 12 | 13 | To use the component, In your react Application just import the component and styles. Also make sure to specify the numDrops property, as it is required. 14 | 15 | ```javascript 16 | import React from 'react'; 17 | import ReactRain from 'react-rain-animation'; 18 | 19 | // import all the styles 20 | import "react-rain-animation/lib/style.css"; 21 | 22 | 23 | const MyComponent = (props) => { 24 | 25 | return ( 26 | 29 | 30 | } 31 | 32 | export default MyComponent; 33 | 34 | 35 | ``` 36 | 37 | ###With Changing State 38 | 39 | To have user input change the number of drops rendered, include this component and some sort of input component (this example uses react-canvas-knob) as sibblings inside of a parent component. 40 | 41 | To avoid the "Maximum call stack size exceded" error, make sure to have 2 separate handlers (i.e. onChange and onChaneEnd). This way, the number of drops does not have to update every time the input value changes, but rather when the user has finished changing the input. 42 | 43 | 44 | ```javascript 45 | 46 | import React, { Component } from 'react'; 47 | import ReactRain from 'react-rain-animation'; 48 | import Knob from 'react-canvas-knob'; 49 | import 'react-rain-animation/lib/style.css'; 50 | 51 | const initVal = 25; 52 | 53 | class MyComponent extends Component { 54 | constructor(props) { 55 | super(props); 56 | 57 | this.state = { 58 | numDrops: initVal, 59 | knobValue: initVal 60 | }; 61 | } 62 | 63 | handleChange = newValue => { 64 | this.setState({ knobValue: newValue }); 65 | } 66 | 67 | onChangeEnd = () => { 68 | console.log(this.state.numDrops); 69 | this.setState({ numDrops: this.state.knobValue }); 70 | } 71 | 72 | render() { 73 | return ( 74 |
75 | 76 | 77 | 82 |
83 | ); 84 | } 85 | } 86 | 87 | export default MyComponent; 88 | 89 | 90 | ``` 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):"object"==typeof exports?exports.CodeHighlight=t(require("react")):e.CodeHighlight=t(e.react)}(this,function(e){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n 50 | ); 51 | } 52 | } 53 | 54 | Rain.propTypes = { 55 | numDrops: PropTypes.number.isRequired 56 | }; 57 | 58 | export default Rain; -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const path = require('path'); 3 | 4 | const BUILD_DIR = path.resolve(__dirname, 'lib'); 5 | const APP_DIR = path.resolve(__dirname, 'src'); 6 | 7 | const WebpackConfig = { 8 | 9 | entry: APP_DIR + '/index.js', 10 | 11 | output: { 12 | path: BUILD_DIR, 13 | filename: 'index.js', 14 | libraryTarget: 'umd', 15 | library: 'CodeHighlight' 16 | }, 17 | 18 | module: { 19 | rules: [ 20 | { 21 | loader: 'babel-loader', 22 | test: /.js$/, 23 | exclude: /node_modules/, 24 | include: APP_DIR, 25 | options: { 26 | presets: ['env', 'react'] 27 | } 28 | }, 29 | { 30 | test: /\.css$/, 31 | exclude: /node_modules/, 32 | loaders: ['style-loader', 'css-loader'], 33 | }, 34 | ], 35 | }, 36 | 37 | } 38 | // webpack production config. 39 | if (process.env.NODE_ENV === 'production') { 40 | 41 | WebpackConfig.externals = { 42 | 'react': 'react', 43 | 'react-dom': 'react-dom' 44 | }; 45 | 46 | WebpackConfig.plugins = [ 47 | new webpack.optimize.AggressiveMergingPlugin(), 48 | new webpack.optimize.UglifyJsPlugin({ 49 | beautify: false, 50 | mangle: { 51 | screw_ie8: true, 52 | }, 53 | compress: { 54 | warnings: false, 55 | screw_ie8: true 56 | }, 57 | comments: false 58 | }), 59 | ]; 60 | 61 | } 62 | 63 | 64 | module.exports = WebpackConfig; 65 | --------------------------------------------------------------------------------