├── .babelrc ├── .editorconfig ├── .gitignore ├── .npmignore ├── LICENSE.txt ├── README.md ├── __tests__ ├── Animation.test.js ├── Reveal.test.js ├── __snapshots__ │ ├── Animation.test.js.snap │ ├── Reveal.test.js.snap │ └── index.test.js.snap ├── in-and-out │ ├── Bounce.test.js │ ├── Fade.test.js │ ├── Flip.test.js │ ├── LightSpeed.test.js │ ├── Roll.test.js │ ├── Rotate.test.js │ ├── Slide.test.js │ ├── Zoom.test.js │ └── __snapshots__ │ │ ├── Bounce.test.js.snap │ │ ├── Fade.test.js.snap │ │ ├── Flip.test.js.snap │ │ ├── LightSpeed.test.js.snap │ │ ├── Roll.test.js.snap │ │ ├── Rotate.test.js.snap │ │ ├── Slide.test.js.snap │ │ └── Zoom.test.js.snap ├── index.test.js └── simple │ ├── Flash.test.js │ ├── HeadShake.test.js │ ├── Jello.test.js │ ├── Jump.test.js │ ├── Pulse.test.js │ ├── RubberBand.test.js │ ├── Shake.test.js │ ├── Spin.test.js │ ├── Swing.test.js │ ├── Tada.test.js │ ├── Wobble.test.js │ └── __snapshots__ │ ├── Flash.test.js.snap │ ├── HeadShake.test.js.snap │ ├── Jello.test.js.snap │ ├── Jump.test.js.snap │ ├── Pulse.test.js.snap │ ├── RubberBand.test.js.snap │ ├── Shake.test.js.snap │ ├── Spin.test.js.snap │ ├── Swing.test.js.snap │ ├── Tada.test.js.snap │ └── Wobble.test.js.snap ├── gulpfile.js ├── package-lock.json ├── package.json └── src ├── Animation.js ├── Reveal.js ├── RevealBase.js ├── in-and-out ├── Bounce.js ├── Fade.js ├── Flip.js ├── LightSpeed.js ├── Roll.js ├── Rotate.js ├── Slide.js └── Zoom.js ├── lib ├── HamburgerIcon.js ├── Step.js ├── Stepper.js ├── debounce.js ├── globals.js ├── hamburger.js ├── index.js ├── makeCarousel.js ├── responsive.js ├── swipedetect.js ├── throttle.js ├── withReveal.js └── wrap.js └── simple ├── Flash.js ├── HeadShake.js ├── Jello.js ├── Jump.js ├── Pulse.js ├── RubberBand.js ├── Shake.js ├── Spin.js ├── Swing.js ├── Tada.js └── Wobble.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react", "es2015", "stage-3"], 3 | "plugins": ["add-module-exports"], 4 | } 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | npm-debug.log 4 | /RevealBase.js 5 | /makeCarousel.js 6 | /swipedetect.js 7 | /hamburger.js 8 | /responsive.js 9 | /withReveal.js 10 | /HamburgerIcon.js 11 | /Animation.js 12 | /Spin.js 13 | /Bounce.js 14 | /Fade.js 15 | /Flash.js 16 | /HeadShake.js 17 | /Jello.js 18 | /Jump.js 19 | /Pulse.js 20 | /Roll.js 21 | /RubberBand.js 22 | /Shake.js 23 | /Slide.js 24 | /Swing.js 25 | /Tada.js 26 | /Wobble.js 27 | /Flip.js 28 | /Reveal.js 29 | /Rotate.js 30 | /LightSpeed.js 31 | /Stepper.js 32 | /Step.js 33 | /Zoom.js 34 | /index.js 35 | /globals.js 36 | /debounce.js 37 | /throttle.js 38 | /wrap.js 39 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .babelrc 2 | .gitignore 3 | .git 4 | gulpfile.js 5 | npm-debug.log 6 | node_modules 7 | __tests__ 8 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2018 Roman Nosov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Reveal 2 | 3 | [React Reveal](https://www.react-reveal.com/) is 4 | an animation framework for React. It's MIT licensed, has a tiny footprint 5 | and written specifically for React in ES6. It can be used to create various cool reveal 6 | on scroll animations in your application. 7 | If you liked this package, don't forget to star 8 | the [Github repository](https://github.com/rnosov/react-reveal). 9 | 10 | ## Live Examples 11 | 12 | A number of simple effect examples: 13 | - [Fade](https://www.react-reveal.com/examples/common/fade/) 14 | - [Flip](https://www.react-reveal.com/examples/common/flip/) 15 | - [Rotate](https://www.react-reveal.com/examples/common/rotate/) 16 | - [Zoom](https://www.react-reveal.com/examples/common/zoom/) 17 | - [Bounce](https://www.react-reveal.com/examples/common/bounce/) 18 | - [Roll](https://www.react-reveal.com/examples/common/roll/) 19 | 20 | Also, there are more complicated examples of [animated form errors](https://www.react-reveal.com/examples/advanced/form/) and a [todo app](https://www.react-reveal.com/examples/advanced/todo/). 21 | 22 | ## Search Engine Visibility 23 | 24 | `react-reveal` is regularly checked against googlebot in the Google Search Console to make sure that googlebot can see the content in the revealed elements. 25 | 26 | ## Full Documentation 27 | 28 | For a full documentation please visit [online docs](https://www.react-reveal.com/docs/). 29 | 30 | ## Installation 31 | 32 | In the command prompt run: 33 | 34 | ```sh 35 | npm install react-reveal --save 36 | ``` 37 | 38 | Alternatively you may use `yarn`: 39 | 40 | ```sh 41 | yarn add react-reveal 42 | ``` 43 | 44 | ## Quick Start 45 | 46 | Import effects from [React Reveal](https://www.npmjs.com/package/react-reveal) to your project. Lets try `Zoom` effect first: 47 | 48 | ```javascript 49 | import Zoom from 'react-reveal/Zoom'; 50 | ``` 51 | 52 | Place the following code somewhere in your `render` method: 53 | 54 | ```jsx 55 | 56 |

Markup that will be revealed on scroll

57 |
58 | ``` 59 | 60 | You should see zooming animation that reveals text inside the tag. You can change this text to any JSX you want. If you place this code further down the page you'll see that it'd appear as you scroll down. 61 | 62 | ## Revealing React Components 63 | 64 | You may just wrap your custom React component with the effect of your choosing like so: 65 | 66 | ```jsx 67 | 68 | 69 | 70 | ``` 71 | 72 | In such case, in the resulting `` HTML markup will be wrapped in a `div` tag. If you would rather have a different HTML tag then wrap `` in a tag of your choosing: 73 | 74 | ```jsx 75 | 76 |
77 | 78 |
79 |
80 | ``` 81 | 82 | or if you want to customize `div` props: 83 | 84 | ```jsx 85 | 86 |
87 | 88 |
89 |
90 | ``` 91 | 92 | ## Revealing Images 93 | 94 | If you want to reveal an image you can wrap `img` tag with with the desired `react-reveal` effect: 95 | 96 | ```jsx 97 | 98 | 99 | 100 | ``` 101 | 102 | It would be a very good idea to specify width and height of any image you wish to reveal. 103 | 104 | ## Children 105 | 106 | `react-reveal` will attach a reveal effect to each child it gets. In other words, 107 | 108 | ```jsx 109 | 110 |
First Child
111 |
Second Child
112 |
113 | ``` 114 | 115 | will be equivalent to: 116 | 117 | ```jsx 118 | 119 |
First Child
120 |
121 | 122 |
Second Child
123 |
124 | ``` 125 | 126 | If you don't want this to happen, you should wrap multiple children in a `div` tag: 127 | 128 | ```jsx 129 | 130 |
131 |
First Child
132 |
Second Child
133 |
134 |
135 | ``` 136 | 137 | 138 | ## Server Side Rendering 139 | 140 | `react-reveal` supports server side rendering out of the box. In some cases, when the javascript bundle arrives much later than the HTML&CSS it might cause a flickering. To prevent this `react-reveal` will not apply reveal effects on the initial load. 141 | Another option is to apply gentle fadeout effect on the initial render. You can force it on all `react-reveal` elements by placing the following code somewhere near the entry point of your app: 142 | 143 | ```jsx 144 | import config from 'react-reveal/globals'; 145 | 146 | config({ ssrFadeout: true }); 147 | ``` 148 | 149 | Or you you can do it on a per element basis using `ssrFadeout` prop: 150 | 151 | ```jsx 152 |

Content

153 | ``` 154 | 155 | One last option is to use `ssrReveal` prop. If enabled, this option will suppress both flickering and `ssrFadeout` effect. The unfortunate drawback of this option is that the revealed content will appear hidden to Googlebot and to anyone with javascript switched off. So it will makes sense for images and/or headings which are duplicated elsewhere on the page. 156 | 157 | ## Forking This Package 158 | 159 | Clone the this repository using the following command: 160 | 161 | ```sh 162 | git clone https://github.com/rnosov/react-reveal.git 163 | ``` 164 | 165 | In the cloned directory, you can run following commands: 166 | 167 | ```sh 168 | npm install 169 | ``` 170 | 171 | Installs required node modules 172 | 173 | ```sh 174 | npm run build 175 | ``` 176 | 177 | Builds the package for production to the `dist` folder 178 | 179 | ```sh 180 | npm test 181 | ``` 182 | 183 | Runs tests 184 | 185 | ## License 186 | 187 | Copyright © 2018 Roman Nosov. Project source code is licensed under the MIT license. 188 | -------------------------------------------------------------------------------- /__tests__/Animation.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Animation Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Animation from '../Animation'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | 19 | describe('Animation', () => { 20 | it('renders a initial view', () => { 21 | const content = shallow( 22 | 23 |
Test test
24 |
25 | ); 26 | expect(content.html()).toMatchSnapshot(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /__tests__/Reveal.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * React Reveal Test Suite 3 | * 4 | * Copyright © Roman Nosov 2016, 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Reveal from '../Reveal'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | 19 | describe('Reveal', () => { 20 | it('renders a initial view', () => { 21 | const content = shallow( 22 | 23 |
Test test
24 |
25 | ); 26 | expect(content.html()).toMatchSnapshot(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /__tests__/__snapshots__/Animation.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Animation renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/__snapshots__/Reveal.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Reveal renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/__snapshots__/index.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`index renders a initial view 1`] = `"
Zoom Test test
Fade Test test
Flip Test test
Rotate Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/in-and-out/Bounce.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Bounce Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Bounce from '../../Bounce'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Bounce', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/in-and-out/Fade.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fade Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Fade from '../../Fade'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Fade', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/in-and-out/Flip.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Flip Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Flip from '../../Flip'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | 19 | describe('Flip', () => { 20 | it('renders a initial view', () => { 21 | const content = shallow( 22 | 23 |
Test test
24 |
25 | ); 26 | expect(content.html()).toMatchSnapshot(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /__tests__/in-and-out/LightSpeed.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * LightSpeed Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import LightSpeed from '../../LightSpeed'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('LightSpeed', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/in-and-out/Roll.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Roll Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Roll from '../../Roll'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Roll', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/in-and-out/Rotate.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Rotate Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Rotate from '../../Rotate'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | 19 | describe('Rotate', () => { 20 | it('renders a initial view', () => { 21 | const content = shallow( 22 | 23 |
Test test
24 |
25 | ); 26 | expect(content.html()).toMatchSnapshot(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /__tests__/in-and-out/Slide.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Slide Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Slide from '../../Slide'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Slide', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/in-and-out/Zoom.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Zoom Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Zoom from '../../Zoom'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Zoom', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/in-and-out/__snapshots__/Bounce.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Bounce renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/in-and-out/__snapshots__/Fade.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Fade renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/in-and-out/__snapshots__/Flip.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Flip renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/in-and-out/__snapshots__/LightSpeed.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`LightSpeed renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/in-and-out/__snapshots__/Roll.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Roll renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/in-and-out/__snapshots__/Rotate.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Rotate renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/in-and-out/__snapshots__/Slide.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Slide renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/in-and-out/__snapshots__/Zoom.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Zoom renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/index.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * index Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Reveal, { Zoom, Fade, Flip, Rotate } from '../'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | // 18 | // 19 | 20 | describe('index', () => { 21 | it('renders a initial view', () => { 22 | const content = shallow( 23 |
24 |
Zoom Test test
25 |
Fade Test test
26 |
Flip Test test
27 |
Rotate Test test
28 |
29 | ); 30 | expect(content.html()).toMatchSnapshot(); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /__tests__/simple/Flash.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Flash Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Flash from '../../Flash'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Flash', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/HeadShake.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * HeadShake Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import HeadShake from '../../HeadShake'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('HeadShake', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/Jello.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Jello Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Jello from '../../Jello'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Jello', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/Jump.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Jump Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Jump from '../../Jump'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Jump', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/Pulse.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Pulse Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Pulse from '../../Pulse'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Pulse', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/RubberBand.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * RubberBand Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import RubberBand from '../../RubberBand'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('RubberBand', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/Shake.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Shake Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Shake from '../../Shake'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Shake', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/Spin.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Spin Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Spin from '../../Spin'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Spin', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/Swing.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Swing Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Swing from '../../Swing'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Swing', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/Tada.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Tada Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Tada from '../../Tada'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Tada', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/Wobble.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Wobble Component Test Suite 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | import Wobble from '../../Wobble'; 10 | 11 | import React from 'react'; 12 | import { shallow } from 'enzyme'; 13 | import { configure } from 'enzyme'; 14 | import Adapter from 'enzyme-adapter-react-16'; 15 | 16 | configure({ adapter: new Adapter() }); 17 | 18 | describe('Wobble', () => { 19 | it('renders a initial view', () => { 20 | const content = shallow( 21 | 22 |
Test test
23 |
24 | ); 25 | expect(content.html()).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/Flash.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Flash renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/HeadShake.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`HeadShake renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/Jello.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Jello renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/Jump.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Jump renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/Pulse.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Pulse renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/RubberBand.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`RubberBand renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/Shake.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Shake renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/Spin.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Spin renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/Swing.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Swing renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/Tada.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Tada renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /__tests__/simple/__snapshots__/Wobble.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Wobble renders a initial view 1`] = `"
Test test
"`; 4 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const babel = require('gulp-babel'); 3 | const uglify = require('gulp-uglify'); 4 | const clean = require('gulp-clean'); 5 | const flatten = require('gulp-flatten'); 6 | const replace = require('gulp-replace'); 7 | 8 | gulp.task('build', () => 9 | gulp.src('./src/**/*.js') 10 | .pipe(flatten()) 11 | .pipe(replace("from './lib/", "from './")) 12 | .pipe(replace("from './in-and-out/", "from './")) 13 | .pipe(replace("from '../RevealBase';", "from './RevealBase';")) 14 | .pipe(replace("from '../lib/globals';", "from './globals';")) 15 | .pipe(replace("from '../lib/wrap';", "from './wrap';")) 16 | .pipe(babel()) 17 | .pipe(uglify()) 18 | .pipe(gulp.dest('./')) 19 | ); 20 | 21 | gulp.task('clean', function () { 22 | return gulp.src([ 23 | './index.js', 24 | './RevealBase.js', 25 | './hamburger.js', 26 | './withReveal.js', 27 | './responsive.js', 28 | './HamburgerIcon.js', 29 | './makeCarousel.js', 30 | './swipedetect.js', 31 | './Animation.js', 32 | './Stepper.js', 33 | './Step.js', 34 | './globals.js', 35 | './debounce.js', 36 | './throttle.js', 37 | './Bounce.js', 38 | './Fade.js', 39 | './Flash.js', 40 | './HeadShake.js', 41 | './Jello.js', 42 | './Jump.js', 43 | './Pulse.js', 44 | './Roll.js', 45 | './RubberBand.js', 46 | './Shake.js', 47 | './Slide.js', 48 | './Swing.js', 49 | './Tada.js', 50 | './Wobble.js', 51 | './Flip.js', 52 | './Reveal.js', 53 | './Rotate.js', 54 | './LightSpeed.js', 55 | './Spin.js', 56 | './Zoom.js', 57 | './wrap.js', 58 | ], {read: false}).pipe(clean()); 59 | }); 60 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-reveal", 3 | "version": "1.2.2", 4 | "author": "Roman Nosov ", 5 | "description": "Really simple way to add reveal on scroll animation to your React app.", 6 | "license": "MIT", 7 | "keywords": [ 8 | "react", 9 | "reveal", 10 | "reactreveal", 11 | "scroll" 12 | ], 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/rnosov/react-reveal" 16 | }, 17 | "bugs": { 18 | "url": "https://github.com/rnosov/react-reveal/issues" 19 | }, 20 | "homepage": "https://www.react-reveal.com", 21 | "main": "./index.js", 22 | "dependencies": { 23 | "prop-types": "^15.5.10" 24 | }, 25 | "peerDependencies": { 26 | "react": "^15.3.0 || ^16.0.0" 27 | }, 28 | "devDependencies": { 29 | "babel-cli": "^6.14.0", 30 | "babel-core": "^6.11.4", 31 | "babel-jest": "^15.0.0", 32 | "babel-plugin-add-module-exports": "^0.2.1", 33 | "babel-plugin-react-transform": "^2.0.2", 34 | "babel-plugin-transform-runtime": "^6.12.0", 35 | "babel-preset-es2015": "^6.9.0", 36 | "babel-preset-react": "^6.5.0", 37 | "babel-preset-stage-0": "^6.5.0", 38 | "enzyme": "^3.1.0", 39 | "enzyme-adapter-react-16": "^1.1.1", 40 | "gulp": "^3.9.1", 41 | "gulp-babel": "^6.1.2", 42 | "gulp-clean": "^0.3.2", 43 | "gulp-flatten": "^0.3.1", 44 | "gulp-replace": "^0.6.1", 45 | "gulp-uglify": "^2.0.0", 46 | "jest": "^22.1.4", 47 | "jest-cli": "^22.4.3", 48 | "react": "^16.2.0", 49 | "react-dom": "^16.2.0", 50 | "react-test-renderer": "^16.2.0", 51 | "uglify-js": "^2.7.3" 52 | }, 53 | "scripts": { 54 | "build": "./node_modules/gulp/bin/gulp.js build", 55 | "test": "jest .", 56 | "prepare": "npm run build && npm run test -- -u;", 57 | "clean": "./node_modules/gulp/bin/gulp.js clean" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Animation.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Animation Component For react-reveal 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import React from 'react'; 11 | import { element, instanceOf, object } from 'prop-types'; 12 | import Stepper from './lib/Stepper'; 13 | 14 | const 15 | propTypes = { 16 | steps: instanceOf(Stepper).isRequired, 17 | children: element.isRequired, 18 | }, 19 | defaultProps = { 20 | 21 | }, 22 | childContextTypes = { 23 | stepper: object, 24 | }; 25 | 26 | class Animation extends React.Component { 27 | 28 | constructor(props) { 29 | super(props); 30 | this.stepper = props.steps; 31 | } 32 | 33 | getChildContext() { 34 | return { stepper: this.stepper }; 35 | } 36 | 37 | static step(...args) { 38 | return new Stepper().step(...args); 39 | } 40 | 41 | render() { 42 | const { steps, children, ...props } = this.props; 43 | return React.cloneElement(React.Children.only(children), props); 44 | } 45 | 46 | } 47 | 48 | Animation.propTypes = propTypes; 49 | Animation.defaultProps = defaultProps; 50 | Animation.childContextTypes = childContextTypes; 51 | export default Animation; 52 | -------------------------------------------------------------------------------- /src/Reveal.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Reveal React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import { bool, string, number, object, oneOf, oneOfType } from 'prop-types'; 11 | import { defaults } from './lib/globals'; 12 | import wrap from './lib/wrap'; 13 | import Fade from './in-and-out/Fade'; 14 | 15 | const 16 | propTypes = { 17 | in: object, 18 | out: oneOfType([object, oneOf([ false ]) ]), 19 | effect: string, 20 | effectOut: string, 21 | duration: number, 22 | timeout: number, 23 | delay: number, 24 | count: number, 25 | forever: bool, 26 | durationOut: number, 27 | delayOut: number, 28 | countOut: number, 29 | foreverOut: bool, 30 | }, 31 | defaultProps = { 32 | ...defaults, 33 | durationOut: defaults.duration , 34 | delayOut: defaults.delay, 35 | countOut: defaults.count, 36 | foreverOut: defaults.forever, 37 | inEffect: Fade(defaults), 38 | outEffect: Fade({ out: true, ...defaults }), 39 | }; 40 | 41 | 42 | 43 | function Reveal({ children, timeout, duration, delay, count, forever, durationOut, delayOut, countOut, foreverOut, effect, effectOut, inEffect, outEffect, ...props}) { 44 | 45 | function factory(reverse) { 46 | return reverse 47 | ? effectOut ? { duration: durationOut, delay: delayOut, count: countOut, forever: foreverOut, className: effectOut, style: {} } : outEffect 48 | : effect ? { duration: timeout === undefined ? duration : timeout, delay, count, forever, className: effect, style: {} } : inEffect; 49 | } 50 | 51 | return wrap(props, factory(false), factory(true), children); 52 | } 53 | 54 | Reveal.propTypes = propTypes; 55 | Reveal.defaultProps = defaultProps; 56 | export default Reveal; 57 | -------------------------------------------------------------------------------- /src/RevealBase.js: -------------------------------------------------------------------------------- 1 | /* 2 | * RevealBase Component For react-reveal 3 | * 4 | * Copyright © Roman Nosov 2016, 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import React from 'react'; 11 | import { string, object, number, bool, func, oneOfType, oneOf, shape, element } from 'prop-types'; 12 | import { namespace, ssr, disableSsr, globalHide, hideAll, cascade, collapseend, fadeOutEnabled, observerMode, raf } from './lib/globals'; 13 | //import Step from './lib/Step'; 14 | //import throttle from './lib/throttle'; 15 | 16 | const 17 | inOut = shape({ 18 | make: func, 19 | duration: number.isRequired, 20 | delay: number.isRequired, 21 | forever: bool, 22 | count: number.isRequired, 23 | style: object.isRequired, 24 | reverse: bool, 25 | }), 26 | propTypes = { 27 | //when: any, 28 | //spy: any, 29 | //margin: number, 30 | collapse: bool,// oneOfType([bool, shape({ tag: string, props: object })]), 31 | collapseEl: element, 32 | cascade: bool, 33 | wait: number, 34 | // step: oneOfType([instanceOf(Step), string]), 35 | force: bool, 36 | disabled: bool, 37 | appear: bool, 38 | enter: bool, 39 | exit: bool, 40 | fraction: number, 41 | //children: element.isRequired, 42 | refProp: string, 43 | innerRef: func, 44 | onReveal: func, 45 | //onEnter: func, 46 | //onEntering: func, 47 | //onEntered: func, 48 | //onExit: func, 49 | //onExiting: func, 50 | //onExited: func, 51 | unmountOnExit: bool, 52 | mountOnEnter: bool, 53 | inEffect: inOut.isRequired, 54 | outEffect: oneOfType([ inOut, oneOf([ false ]) ]).isRequired, 55 | ssrReveal: bool, 56 | collapseOnly: bool, 57 | ssrFadeout: bool, 58 | }, 59 | defaultProps = { 60 | fraction: 0.2, 61 | //when: true, 62 | refProp: 'ref', 63 | //margin: 0, 64 | }, 65 | //, 66 | //contextTypes = { 67 | // stepper: object, 68 | //}; 69 | 70 | contextTypes = { 71 | transitionGroup: object, 72 | }; 73 | 74 | //childContextTypes = { 75 | // transitionGroup: ()=>{}, 76 | //}; 77 | 78 | class RevealBase extends React.Component { 79 | 80 | //getChildContext() { 81 | // return { transitionGroup: null }; // allows for nested Transitions 82 | //} 83 | 84 | constructor(props, context) { 85 | super(props, context); 86 | this.isOn = props.when !== undefined ? !!props.when : true; 87 | this.state = { 88 | collapse: props.collapse //&& (props.appear || (context.transitionGroup&&!context.transitionGroup.isMounting)) 89 | ? RevealBase.getInitialCollapseStyle(props) 90 | : void 0, 91 | style: { 92 | opacity: (!this.isOn||props.ssrReveal) && props.outEffect ? 0 : void 0, 93 | //visibility: props.when ? 'visible' : 'hidden', 94 | }, 95 | }; 96 | this.savedChild = false; 97 | //this.isListener = false; 98 | this.isShown = false; 99 | //this.ticking = false; 100 | //this.observerMode = observerMode && !this.props.disableObserver; 101 | if (!observerMode) { 102 | this.revealHandler = this.makeHandler(this.reveal); 103 | this.resizeHandler = this.makeHandler(this.resize); 104 | } 105 | else 106 | this.handleObserve = this.handleObserve.bind(this); 107 | //this.revealHandler = myThrottle(this.reveal.bind(this, false)); 108 | //this.revealHandler = rafThrottle(this.reveal.bind(this, false)); 109 | //this.revealHandler = rafThrottle(throttle(this.reveal.bind(this, false), 66)); 110 | //this.revealHandler = throttle(rafThrottle(this.reveal.bind(this, false)), 66); 111 | //this.resizeHandler = throttle(this.resize.bind(this), 500); 112 | this.saveRef = this.saveRef.bind(this); 113 | } 114 | 115 | 116 | saveRef(node) { 117 | if (this.childRef) 118 | this.childRef(node); 119 | if (this.props.innerRef) 120 | this.props.innerRef(node); 121 | if (this.el !== node) { //probably redundant check 122 | this.el = node && ('offsetHeight' in node) ? node : undefined; 123 | this.observe(this.props, true); 124 | } 125 | } 126 | 127 | invisible() { 128 | if (!this || !this.el) 129 | return; 130 | this.savedChild = false; 131 | if (!this.isShown) { 132 | this.setState( { hasExited: true, collapse: this.props.collapse?{...this.state.collapse, visibility: 'hidden'}: null, style: { /*...this.state.style, visibility: 'hidden'*/opacity: 0}/*, collapsing: false */}); 133 | //if (this.props.onExited) 134 | // this.props.onExited(this.el); 135 | if (!observerMode && this.props.collapse) 136 | window.document.dispatchEvent(collapseend); 137 | } 138 | } 139 | 140 | animationEnd(func, cascade, { forever, count, delay, duration }) { 141 | if (forever) 142 | return; 143 | //const el = this.finalEl || this.el; 144 | const handler = () => { 145 | if (!this || !this.el) 146 | return; 147 | this.animationEndTimeout = void 0; 148 | //el.removeEventListener('animationend', handler); 149 | func.call(this); 150 | }; 151 | this.animationEndTimeout = window.setTimeout(handler, delay+(duration+(cascade?duration:0)*count)); 152 | //el.addEventListener('animationend', handler); 153 | //this.animationEndEl = el; 154 | //this.animationEndHandler = handler; 155 | } 156 | 157 | getDimensionValue() { 158 | return this.el.offsetHeight + parseInt(window.getComputedStyle(this.el, null).getPropertyValue('margin-top'),10) + parseInt(window.getComputedStyle(this.el, null).getPropertyValue('margin-bottom'), 10); 159 | } 160 | // //const delta = this.props.duration>>2, 161 | // // duration = delta, 162 | // // delay = this.props.delay + (this.isOn ? 0 : this.props.duration - delta) 163 | 164 | collapse(state, props, inOut) { 165 | const total = inOut.duration + (props.cascade ? inOut.duration : 0), 166 | height = this.isOn ? this.getDimensionValue() : 0; 167 | let duration, delay; 168 | if (props.collapseOnly) { 169 | duration = inOut.duration/3; 170 | delay = inOut.delay; 171 | } 172 | else { 173 | let delta1 = total>>2, delta2 = delta1>>1; 174 | duration = delta1; // + (props.when ? 0 : delta2), 175 | delay = inOut.delay + (this.isOn ? 0 : total - delta1 - delta2); 176 | state.style.animationDuration = `${total - delta1 + (this.isOn ? delta2 : -delta2)}ms`; 177 | state.style.animationDelay = `${inOut.delay + (this.isOn ? delta1 - delta2 : 0)}ms`; 178 | } 179 | //const delta = total>>2, 180 | // duration = props.when ? delta : total - delta, 181 | // delay = inOut.delay + (props.when ? 0 : delta); 182 | //duration = total; 183 | //delay = inOut.delay; 184 | state.collapse = { 185 | height, 186 | transition: `height ${duration}ms ease ${delay}ms`,// padding ${duration}ms ease ${delay}ms, border ${duration}ms ease ${delay}ms`, 187 | overflow: props.collapseOnly ? 'hidden' : undefined, 188 | //margin: 0, padding: 0, border: '1px solid transparent', 189 | //boxSizing: 'border-box', 190 | }; 191 | return state; 192 | } 193 | 194 | animate(props) { 195 | if (!this || !this.el) 196 | return; 197 | this.unlisten(); 198 | if (this.isShown === this.isOn) 199 | return; 200 | this.isShown = this.isOn; 201 | const leaving = !this.isOn && props.outEffect, 202 | inOut = props[leaving ? 'outEffect' : 'inEffect']; 203 | //collapse = 'collapse' in props; 204 | let animationName = (('style' in inOut) && inOut.style.animationName) || void 0; 205 | let state; 206 | if (!props.collapseOnly) 207 | { 208 | if ((props.outEffect||this.isOn) && inOut.make) 209 | animationName = inOut.make; 210 | //animationName = inOut.make(leaving, props); 211 | //animationName = (!leaving && this.enterAnimation) || inOut.make(leaving, props); 212 | state = {/* status: leaving ? 'exiting':'entering',*/ 213 | hasAppeared: true, 214 | hasExited: false, 215 | collapse: undefined, 216 | style: { 217 | ...inOut.style, 218 | animationDuration: `${inOut.duration}ms`, 219 | animationDelay: `${inOut.delay}ms`, 220 | animationIterationCount: inOut.forever ? 'infinite' : inOut.count, 221 | opacity: 1, 222 | //visibility: 'visible', 223 | animationName, 224 | }, 225 | className: inOut.className 226 | }; 227 | } 228 | else 229 | state = { hasAppeared: true, hasExited: false, style: {opacity: 1}}; 230 | this.setState( props.collapse ? this.collapse(state, props, inOut) : state ); 231 | if (leaving) { 232 | this.savedChild = React.cloneElement(this.getChild()); 233 | this.animationEnd( this.invisible, props.cascade, inOut); 234 | } 235 | else 236 | this.savedChild = false; 237 | //if (collapse) 238 | // this.animationEnd( () => this.setState({ collapse: void 0 }), props.cascade, inOut); 239 | this.onReveal(props); 240 | } 241 | 242 | onReveal(props) { 243 | if (props.onReveal && this.isOn) { 244 | if (this.onRevealTimeout) 245 | this.onRevealTimeout = window.clearTimeout(this.onRevealTimeout); 246 | props.wait ? this.onRevealTimeout = window.setTimeout(props.onReveal, props.wait) : props.onReveal(); 247 | //props.wait ? this.onRevealTimeout = window.setTimeout( this.isOn ? (() => props.onReveal(true)):(() => props.onReveal(false)), props.wait) : props.onReveal( this.isOn ); 248 | } 249 | } 250 | 251 | componentWillUnmount() { 252 | this.unlisten(); 253 | ssr && disableSsr(); 254 | } 255 | 256 | handleObserve( [entry], observer ) { 257 | if (entry.intersectionRatio>0) { 258 | observer.disconnect(); 259 | this.observer = null; 260 | this.reveal(this.props, true); 261 | } 262 | } 263 | 264 | observe(props, update = false) { 265 | if (!this.el) return; 266 | if (observerMode) { 267 | if (this.observer) { 268 | if (update) 269 | this.observer.disconnect(); 270 | else return; 271 | } 272 | else if (update) return; 273 | this.observer = new IntersectionObserver(this.handleObserve, {threshold: props.fraction} ); 274 | this.observer.observe(this.el); 275 | } 276 | } 277 | 278 | reveal(props, inView = false) { 279 | if (!globalHide) 280 | hideAll(); 281 | if (!this||!this.el) return; 282 | if (!props) 283 | props = this.props; 284 | if (ssr) 285 | disableSsr(); 286 | if ( this.isOn && this.isShown && props.spy !== undefined ){ 287 | this.isShown = false; 288 | this.setState({ style: {} }); 289 | window.setTimeout( () => this.reveal(props), 200 ); 290 | } 291 | else if ( inView || this.inViewport(props) || props.force ) 292 | this.animate(props); 293 | else 294 | observerMode?this.observe(props):this.listen(); 295 | } 296 | 297 | componentDidMount() { 298 | if (!this.el || this.props.disabled) 299 | return; 300 | if (!this.props.collapseOnly) { 301 | if ('make' in this.props.inEffect) 302 | this.props.inEffect.make(false, this.props); 303 | if (this.props.when !== undefined && this.props.outEffect && 'make' in this.props.outEffect) 304 | this.props.outEffect.make(true, this.props); 305 | } 306 | const parentGroup = this.context.transitionGroup; 307 | const appear = parentGroup && !parentGroup.isMounting ? !('enter' in this.props && this.props.enter === false) : this.props.appear; 308 | if (this.isOn && (((this.props.when !== undefined || this.props.spy !== undefined) && !appear) 309 | || (ssr && !fadeOutEnabled && !this.props.ssrFadeout && this.props.outEffect && !this.props.ssrReveal && (RevealBase.getTop(this.el) < window.pageYOffset + window.innerHeight))) 310 | ) { 311 | this.isShown = true; 312 | this.setState({ 313 | hasAppeared: true, 314 | collapse: this.props.collapse ? { height: this.getDimensionValue() } : this.state.collapse, 315 | style: { opacity: 1,} 316 | }); 317 | this.onReveal(this.props); 318 | return; 319 | } 320 | if ( ssr && ( fadeOutEnabled || this.props.ssrFadeout )&& this.props.outEffect && (RevealBase.getTop(this.el) < window.pageYOffset + window.innerHeight)) { 321 | this.setState({ style: { opacity: 0, transition: 'opacity 1000ms 1000ms' } }); 322 | window.setTimeout( () => this.reveal(this.props, true), 2000); 323 | return; 324 | } 325 | if(this.isOn) 326 | this.props.force ? this.animate(this.props) : this.reveal(this.props); 327 | // return this.animate(this.props); 328 | // 329 | // this.reveal(this.props); 330 | } 331 | 332 | cascade(children) { 333 | let newChildren; 334 | if (typeof children === 'string') { 335 | newChildren = children.split("").map( (ch, index) => {ch} ); 336 | //reverse = this.props.reverse; 337 | } 338 | else 339 | newChildren = React.Children.toArray(children); 340 | //if (newChildren.length === 1) 341 | // return newChildren; 342 | let { duration, reverse } = this.props[this.isOn || !this.props.outEffect ?'inEffect':'outEffect'], 343 | count = newChildren.length, 344 | total = duration*2; 345 | //reverse = false; 346 | if (this.props.collapse) { 347 | total = parseInt(this.state.style.animationDuration, 10); 348 | duration = total/2; 349 | } 350 | let i = reverse ? count : 0; 351 | //let i = 0; 352 | newChildren = newChildren.map( child => 353 | typeof child === 'object' && child //&& 'type' in child && typeof child.type === 'string' 354 | ? React.cloneElement(child,{ 355 | style: { 356 | ...child.props.style, 357 | ...this.state.style, 358 | animationDuration: Math.round(cascade( reverse ? i-- : i++ /*i++*/,0 , count, duration, total)) + 'ms', 359 | }, 360 | //ref: i === count? (el => this.finalEl = el) : void 0, 361 | }) 362 | : child ); 363 | return newChildren; 364 | } 365 | 366 | static getInitialCollapseStyle(props) { 367 | return { 368 | height: 0, 369 | visibility: props.when ? void 0 : 'hidden', 370 | }; 371 | } 372 | 373 | componentWillReceiveProps (props) { 374 | if (props.when !== undefined) 375 | this.isOn = !!props.when; 376 | if (props.fraction !== this.props.fraction) 377 | this.observe(props, true); 378 | if (!this.isOn && props.onExited && ('exit' in props) && props.exit === false ) { 379 | props.onExited(); 380 | return; 381 | } 382 | if (props.disabled) 383 | return; 384 | if (props.collapse && !this.props.collapse) { 385 | this.setState({ style: { }, collapse: RevealBase.getInitialCollapseStyle(props)}); 386 | this.isShown = false; 387 | } 388 | if ( (props.when !== this.props.when) || (props.spy !== this.props.spy)) 389 | this.reveal(props); 390 | if (this.onRevealTimeout&& !this.isOn) 391 | this.onRevealTimeout = window.clearTimeout(this.onRevealTimeout); 392 | } 393 | 394 | getChild() { 395 | if (this.savedChild && !this.props.disabled) 396 | return this.savedChild; 397 | if (typeof this.props.children === 'object') { 398 | const child = React.Children.only(this.props.children); 399 | return (('type' in child) && typeof child.type === 'string') || this.props.refProp !== 'ref' 400 | ? child 401 | :
{child}
; 402 | } 403 | else 404 | return
{this.props.children}
; 405 | } 406 | 407 | render() { 408 | let mount; 409 | if (!this.state.hasAppeared) 410 | mount = !this.props.mountOnEnter || this.isOn; 411 | else 412 | mount = !this.props.unmountOnExit || !this.state.hasExited || this.isOn; 413 | const child = this.getChild(); 414 | //if (this.props.disabled) 415 | // return child; 416 | if (typeof child.ref === 'function') 417 | this.childRef = child.ref; 418 | let 419 | newChildren = false, 420 | { style, className, children } = child.props; 421 | let 422 | newClass = this.props.disabled ? className : `${ this.props.outEffect ? namespace : '' }${ this.state.className ? ' ' + this.state.className : '' }${ className ? ' ' + className : '' }`||void 0, 423 | newStyle; 424 | if (typeof this.state.style.animationName === 'function') // todo: needs refactotoring 425 | this.state.style.animationName = this.state.style.animationName(!this.isOn ,this.props); 426 | if (this.props.cascade && !this.props.disabled && children && this.state.style.animationName) { 427 | newChildren = this.cascade(children); 428 | newStyle = { ...style, opacity: 1 }; 429 | } 430 | else 431 | newStyle = this.props.disabled ? style : { ...style, ...this.state.style }; 432 | const props = { ...this.props.props, className: newClass, style: newStyle, [this.props.refProp]: this.saveRef }; 433 | //if (this.props.collapse && !this.props.disabled) 434 | // props.key = 1; 435 | const el = React.cloneElement(child, props, mount ? newChildren||children : undefined); 436 | if ( this.props.collapse !== undefined ) 437 | return this.props.collapseEl 438 | ? React.cloneElement(this.props.collapseEl, { style: {...this.props.collapseEl.style, ...(this.props.disabled ? undefined : this.state.collapse)}, children: (el) }) 439 | :
; 440 | //return
; 441 | return el; 442 | } 443 | 444 | makeHandler(handler) { 445 | const update = () => { 446 | handler.call(this, this.props); 447 | this.ticking = false; 448 | }; 449 | return () => { 450 | if (!this.ticking) { 451 | raf(update); 452 | this.ticking = true; 453 | } 454 | }; 455 | } 456 | 457 | static getTop(el) { 458 | while (el.offsetTop === void 0) 459 | el = el.parentNode; 460 | let top = el.offsetTop; 461 | for (;el.offsetParent; top += el.offsetTop) 462 | el = el.offsetParent; 463 | return top; 464 | } 465 | 466 | inViewport(props) { 467 | if (!this.el || window.document.hidden) return false; 468 | const h = this.el.offsetHeight, 469 | delta = window.pageYOffset/* - props.margin */- RevealBase.getTop(this.el), 470 | tail = Math.min(h, window.innerHeight) * ( globalHide ? props.fraction : 0 ); 471 | return ( delta > tail - window.innerHeight ) && ( delta < h - tail ); 472 | } 473 | 474 | resize(props) { 475 | if (!this||!this.el||!this.isOn) 476 | return; 477 | if ( this.inViewport(props) ) { 478 | this.unlisten(); 479 | this.isShown = this.isOn; 480 | this.setState({ hasExited: !this.isOn, hasAppeared: true, collapse: undefined, style: { opacity: this.isOn || !props.outEffect ? 1 : 0 } }); 481 | this.onReveal(props); 482 | //if (this.props.onReveal && this.isOn) 483 | // this.props.wait ? this.onRevealTimeout = window.setTimeout(this.props.onReveal, this.props.wait) : this.props.onReveal(); 484 | } 485 | } 486 | 487 | listen() { 488 | if (!observerMode && !this.isListener) { 489 | this.isListener = true; 490 | window.addEventListener('scroll', this.revealHandler, { passive: true }); 491 | window.addEventListener('orientationchange', this.revealHandler, { passive: true }); 492 | window.document.addEventListener('visibilitychange', this.revealHandler, { passive: true }); 493 | window.document.addEventListener('collapseend', this.revealHandler, { passive: true }); 494 | window.addEventListener('resize', this.resizeHandler, { passive: true }); 495 | } 496 | } 497 | 498 | unlisten() { 499 | if (!observerMode && this.isListener) { 500 | window.removeEventListener('scroll', this.revealHandler, { passive: true }); 501 | window.removeEventListener('orientationchange', this.revealHandler, { passive: true }); 502 | window.document.removeEventListener('visibilitychange', this.revealHandler, { passive: true }); 503 | window.document.removeEventListener('collapseend', this.revealHandler, { passive: true }); 504 | window.removeEventListener('resize', this.resizeHandler, { passive: true }); 505 | this.isListener = false; 506 | } 507 | if(this.onRevealTimeout) 508 | this.onRevealTimeout = window.clearTimeout(this.onRevealTimeout); 509 | if (this.animationEndTimeout) 510 | this.animationEndTimeout = window.clearTimeout(this.animationEndTimeout); 511 | //if (this.animationEndHandler) 512 | // this.animationEndEl.removeEventListener('animationend', this.animationEndHandler); 513 | } 514 | 515 | } 516 | 517 | RevealBase.propTypes = propTypes; 518 | RevealBase.defaultProps = defaultProps; 519 | RevealBase.contextTypes = contextTypes; 520 | RevealBase.displayName = 'RevealBase'; 521 | //RevealBase.childContextTypes = childContextTypes; 522 | export default RevealBase; 523 | -------------------------------------------------------------------------------- /src/in-and-out/Bounce.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Bounce React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | out: bool, 18 | left: bool, 19 | right: bool, 20 | top: bool, 21 | bottom: bool, 22 | mirror: bool, 23 | opposite: bool, 24 | duration: number, 25 | timeout: number, 26 | delay: number, 27 | count: number, 28 | forever: bool, 29 | }; 30 | 31 | const lookup = {}; 32 | function make(reverse, { left, right, up, down, top, bottom, mirror, opposite, }) { 33 | const checksum = (left?1:0) | (right?2:0) | (top||down?4:0) | (bottom||up?8:0) | (mirror?16:0) | (opposite?32:0) | (reverse?64:0); 34 | if (lookup.hasOwnProperty(checksum)) 35 | return lookup[checksum]; 36 | if ( !mirror !== !(reverse&&opposite)) // Boolean XOR 37 | [left, right, top, bottom, up, down] = [right, left, bottom, top, down, up]; 38 | const 39 | transformX = left || right, 40 | transformY = top || bottom || up || down, 41 | transform = transformX || transformY; 42 | let rule, x0, y0, x20, y20, y40, x60, y60, x75, y75, x90, y90, x100, y100; 43 | if (reverse) { 44 | x20 = transformX ? ( right ?'-':'') + '20px' : 0; 45 | y20 = transformY ? ( up||bottom?'':'-') + '10px' : '0'; 46 | y40 = ( down||top ? '':'-') + '20px'; 47 | x100 = transformX ? ( left ? '-' :'' ) + '2000px':'0'; 48 | y100 = transformY ? ( down||top?'-':'') +'2000px':'0'; 49 | } 50 | else { 51 | x0 = transformX ? ((left?'-':'') + '3000px'):'0'; 52 | y0 = transformY ? ((down||top?'-':'') + '3000px'):'0'; 53 | x60 = transformX ? ((right?'-':'') + '25px'):'0'; 54 | y60 = transformY ? ((up||bottom?'-':'') + '25px'):'0'; 55 | x75 = transformX ? ((left?'-':'') + '10px'):'0'; 56 | y75 = transformY ? ((down||top?'-':'') + '10px'):'0'; 57 | x90 = transformX ? ((right?'-':'') + '5px'):'0'; 58 | y90 = transformY ? ((up||bottom?'-':'') + '5px'):'0'; 59 | } 60 | if (transform) 61 | rule = reverse 62 | ?` 63 | 20% { 64 | transform: translate3d(${x20}, ${y20}, 0); 65 | } 66 | ${ transformY 67 | ?`40%, 45% { 68 | opacity: 1; 69 | transform: translate3d(0, ${y40}, 0); 70 | }` 71 | :'' 72 | } 73 | to { 74 | opacity: 0; 75 | transform: translate3d(${x100}, ${y100}, 0); 76 | } 77 | ` 78 | :`from, 60%, 75%, 90%, to { 79 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 80 | } 81 | from { 82 | opacity: 0; 83 | transform: translate3d(${x0}, ${y0}, 0); 84 | } 85 | 60% { 86 | opacity: 1; 87 | transform: translate3d(${x60}, ${y60}, 0); 88 | } 89 | 75% { 90 | transform: translate3d(${x75}, ${y75}, 0); 91 | } 92 | 90% { 93 | transform: translate3d(${x90}, ${y90}, 0); 94 | } 95 | to { 96 | transform: none; 97 | }`; 98 | else 99 | rule = reverse 100 | ? `20% { 101 | transform: scale3d(.9, .9, .9); 102 | } 103 | 50%, 55% { 104 | opacity: 1; 105 | transform: scale3d(1.1, 1.1, 1.1); 106 | } 107 | to { 108 | opacity: 0; 109 | transform: scale3d(.3, .3, .3); 110 | }` 111 | : `from, 20%, 40%, 60%, 80%, to { 112 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 113 | } 114 | 0% { 115 | opacity: 0; 116 | transform: scale3d(.3, .3, .3); 117 | } 118 | 20% { 119 | transform: scale3d(1.1, 1.1, 1.1); 120 | } 121 | 40% { 122 | transform: scale3d(.9, .9, .9); 123 | } 124 | 60% { 125 | opacity: 1; 126 | transform: scale3d(1.03, 1.03, 1.03); 127 | } 128 | 80% { 129 | transform: scale3d(.97, .97, .97); 130 | } 131 | to { 132 | opacity: 1; 133 | transform: scale3d(1, 1, 1); 134 | }`; 135 | lookup[checksum] = animation(rule); 136 | return lookup[checksum]; 137 | } 138 | 139 | function Bounce({ children, out, forever, 140 | timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, ...props } = defaults) { 141 | const effect = { 142 | make, 143 | duration: timeout === undefined ? duration : timeout, 144 | delay, 145 | forever, 146 | count, 147 | style: { animationFillMode: 'both', }, 148 | reverse: props.left, 149 | }; 150 | return wrap(props, effect, effect, children); 151 | } 152 | 153 | Bounce.propTypes = propTypes; 154 | export default Bounce; 155 | -------------------------------------------------------------------------------- /src/in-and-out/Fade.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fade React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import { bool, number, string } from 'prop-types'; 11 | import { animation, defaults } from '../lib/globals'; 12 | import wrap from '../lib/wrap'; 13 | 14 | const 15 | propTypes = { 16 | out: bool, 17 | left: bool, 18 | right: bool, 19 | top: bool, 20 | bottom: bool, 21 | big: bool, 22 | mirror: bool, 23 | opposite: bool, 24 | duration: number, 25 | timeout: number, 26 | distance: string, 27 | delay: number, 28 | count: number, 29 | forever: bool, 30 | }; 31 | 32 | const lookup = {}; 33 | function make(reverse, { distance, left, right, up, down, top, bottom, big, mirror, opposite, }) { 34 | const checksum = (distance?distance.toString():0) + ( (left?1:0) | (right?2:0) | (top||down?4:0) | (bottom||up?8:0) | (mirror?16:0) | (opposite?32:0) | (reverse?64:0) | (big?128:0)); 35 | if (lookup.hasOwnProperty(checksum)) 36 | return lookup[checksum]; 37 | const transform = left||right||up||down||top||bottom; 38 | let x, y; 39 | if (transform) { 40 | if ( !mirror !== !(reverse&&opposite)) // Boolean XOR 41 | [left, right, top, bottom, up, down] = [right, left, bottom, top, down, up]; 42 | const dist = distance || (big ? '2000px' : '100%'); 43 | x = left ? '-' + dist : ( right ? dist : '0' ); 44 | y = down || top ? '-'+ dist : ( up || bottom ? dist : '0' ); 45 | } 46 | lookup[checksum] = animation( 47 | `${!reverse?'from':'to'} {opacity: 0;${ transform ? ` transform: translate3d(${x}, ${y}, 0);` : ''}} 48 | ${ reverse?'from':'to'} {opacity: 1;transform: none;} ` 49 | ); 50 | return lookup[checksum]; 51 | } 52 | 53 | function Fade({ children, out, forever, 54 | timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, ...props } = defaults, context = false) { 55 | const effect = { 56 | make, 57 | duration: timeout === undefined ? duration : timeout, 58 | delay, 59 | forever, 60 | count, 61 | style: { animationFillMode: 'both', }, 62 | reverse: props.left, 63 | }; 64 | return context ? wrap(props, effect, effect, children) : effect; 65 | } 66 | 67 | Fade.propTypes = propTypes; 68 | export default Fade; 69 | -------------------------------------------------------------------------------- /src/in-and-out/Flip.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Flip React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | out: bool, 18 | left: bool, 19 | right: bool, // y 20 | top: bool, // x 21 | bottom: bool, 22 | mirror: bool, 23 | opposite: bool, 24 | duration: number, 25 | timeout: number, 26 | delay: number, 27 | count: number, 28 | forever: bool, 29 | }; 30 | 31 | const lookup = {}; 32 | function make(reverse, { left, right, top, bottom, x, y, mirror, opposite, }) { 33 | const checksum = (left?1:0) | (right||y?2:0) | (top||x?4:0) | (bottom?8:0) | (mirror?16:0) | (opposite?32:0) | (reverse?64:0); 34 | if (lookup.hasOwnProperty(checksum)) 35 | return lookup[checksum]; 36 | if ( !mirror !== !(reverse&&opposite)) // Boolean XOR 37 | [left, right, top, bottom, x, y] = [right, left, bottom, top, y, x]; 38 | let rule; 39 | if (x||y||left||right||top||bottom) { 40 | const 41 | xval = x||top||bottom ? (bottom?'-':'') + '1' : '0', 42 | yval = y||right||left ? (left?'-':'') +'1' : '0'; 43 | if (!reverse) 44 | rule=`from { 45 | transform: perspective(400px) rotate3d(${xval}, ${yval}, 0, 90deg); 46 | animation-timing-function: ease-in; 47 | opacity: 0; 48 | } 49 | 40% { 50 | transform: perspective(400px) rotate3d(${xval}, ${yval}, 0, -20deg); 51 | animation-timing-function: ease-in; 52 | } 53 | 60% { 54 | transform: perspective(400px) rotate3d(${xval}, ${yval}, 0, 10deg); 55 | opacity: 1; 56 | } 57 | 80% { 58 | transform: perspective(400px) rotate3d(${xval}, ${yval}, 0, -5deg); 59 | } 60 | to { 61 | transform: perspective(400px); 62 | }`; 63 | else 64 | rule = `from { 65 | transform: perspective(400px); 66 | } 67 | 30% { 68 | transform: perspective(400px) rotate3d(${xval}, ${yval}, 0, -15deg); 69 | opacity: 1; 70 | } 71 | to { 72 | transform: perspective(400px) rotate3d(${xval}, ${yval}, 0, 90deg); 73 | opacity: 0; 74 | }`; 75 | } else 76 | rule = `from { 77 | transform: perspective(400px) rotate3d(0, 1, 0, -360deg); 78 | animation-timing-function: ease-out; 79 | opacity: ${!reverse?'0':'1'}; 80 | } 81 | 40% { 82 | transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); 83 | animation-timing-function: ease-out; 84 | } 85 | 50% { 86 | transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); 87 | animation-timing-function: ease-in; 88 | } 89 | to { 90 | transform: perspective(400px); 91 | animation-timing-function: ease-in; 92 | opacity: ${reverse?'0':'1'}; 93 | }`; 94 | lookup[checksum] = animation(rule); 95 | return lookup[checksum]; 96 | } 97 | 98 | function Flip({ children, out, forever, 99 | timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, ...props } = defaults) { 100 | const effect = { 101 | make, 102 | duration: timeout === undefined ? duration : timeout, 103 | delay, forever, count, 104 | style: { animationFillMode: 'both', backfaceVisibility: 'visible', }, 105 | }; 106 | return wrap(props, effect, effect, children); 107 | } 108 | 109 | Flip.propTypes = propTypes; 110 | export default Flip; 111 | -------------------------------------------------------------------------------- /src/in-and-out/LightSpeed.js: -------------------------------------------------------------------------------- 1 | /* 2 | * LightSpeed React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import wrap from '../lib/wrap'; 12 | import { bool, number } from 'prop-types'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | out: bool, 18 | left: bool, 19 | right: bool, 20 | mirror: bool, 21 | opposite: bool, 22 | duration: number, 23 | timeout: number, 24 | delay: number, 25 | count: number, 26 | forever: bool, 27 | }; 28 | 29 | const lookup = {}; 30 | function make(reverse, { left, right, mirror, opposite, }) { 31 | const checksum = (left?1:0) | (right?2:0) | (mirror?16:0) | (opposite?32:0) | (reverse?64:0); 32 | if (lookup.hasOwnProperty(checksum)) 33 | return lookup[checksum]; 34 | if ( !mirror !== !(reverse&&opposite)) // Boolean XOR 35 | [left, right] = [right, left]; 36 | const dist = '100%', 37 | x = left ? '-' + dist : ( right ? dist : '0' ); 38 | const rule = !reverse 39 | ? `from { 40 | transform: translate3d(${x}, 0, 0) skewX(-30deg); 41 | opacity: 0; 42 | } 43 | 60% { 44 | transform: skewX(20deg); 45 | opacity: 1; 46 | } 47 | 80% { 48 | transform: skewX(-5deg); 49 | opacity: 1; 50 | } 51 | to { 52 | transform: none; 53 | opacity: 1; 54 | }` 55 | : `from { 56 | opacity: 1; 57 | } 58 | to { 59 | transform: translate3d(${x}, 0, 0) skewX(30deg); 60 | opacity: 0; 61 | } 62 | `; 63 | lookup[checksum] = animation(rule); 64 | return lookup[checksum]; 65 | } 66 | 67 | function LightSpeed({ children, out, forever, 68 | timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, ...props } = defaults) { 69 | const effect = { 70 | make, 71 | duration: timeout === undefined ? duration : timeout, 72 | delay, forever, count, 73 | style: { animationFillMode: 'both', } 74 | }; 75 | const checksum = 0 + (props.left?1:0) + (props.right?10:0) + (props.mirror?10000:0) + (props.opposite?100000:0); 76 | return wrap(props, effect, effect, children); 77 | } 78 | 79 | LightSpeed.propTypes = propTypes; 80 | export default LightSpeed; 81 | -------------------------------------------------------------------------------- /src/in-and-out/Roll.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Roll React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * CSS effect originally authored by Nick Pettit - https://github.com/nickpettit/glide 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import wrap from '../lib/wrap'; 12 | import { bool, number } from 'prop-types'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | out: bool, 18 | left: bool, 19 | right: bool, 20 | top: bool, 21 | bottom: bool, 22 | big: bool, 23 | mirror: bool, 24 | opposite: bool, 25 | duration: number, 26 | timeout: number, 27 | delay: number, 28 | count: number, 29 | forever: bool, 30 | }; 31 | 32 | const lookup = {}; 33 | function make(reverse, { left, right, up, down, top, bottom, big, mirror, opposite, }) { 34 | const checksum = ( (left?1:0) | (right?2:0) | (top||down?4:0) | (bottom||up?8:0) | (mirror?16:0) | (opposite?32:0) | (reverse?64:0) | (big?128:0)); 35 | if (lookup.hasOwnProperty(checksum)) 36 | return lookup[checksum]; 37 | if ( !mirror !== !(reverse&&opposite)) // Boolean XOR 38 | [left, right, top, bottom, up, down] = [right, left, bottom, top, down, up]; 39 | const dist = big ? '2000px' : '100%', 40 | x = left ? '-' + dist : ( right ? dist : '0' ), 41 | y = down || top ? '-'+ dist : ( up || bottom ? dist : '0' ); 42 | lookup[checksum] = animation(` 43 | ${!reverse?'from':'to'} {opacity: 0;transform: translate3d(${x}, ${y}, 0) rotate3d(0, 0, 1, -120deg);} 44 | ${reverse?'from':'to'} {opacity: 1;transform: none} 45 | `); 46 | return lookup[checksum]; 47 | } 48 | 49 | function Roll({ children, out, forever, 50 | timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, ...props } = defaults) { 51 | const effect = { 52 | make, 53 | duration: timeout === undefined ? duration : timeout, 54 | delay, forever, count, 55 | style: { animationFillMode: 'both', } 56 | }; 57 | return wrap(props, effect, effect, children); 58 | } 59 | 60 | Roll.propTypes = propTypes; 61 | export default Roll; 62 | -------------------------------------------------------------------------------- /src/in-and-out/Rotate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Rotate React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | out: bool, 18 | left: bool, 19 | right: bool, 20 | top: bool, 21 | bottom: bool, 22 | mirror: bool, 23 | opposite: bool, 24 | duration: number, 25 | timeout: number, 26 | delay: number, 27 | count: number, 28 | forever: bool, 29 | }; 30 | 31 | const lookup = {}; 32 | function make(reverse, { left, right, up, down, top, bottom, mirror, opposite, }) { 33 | const checksum = (left?1:0) | (right?2:0) | (top||down?4:0) | (bottom||up?8:0) | (mirror?16:0) | (opposite?32:0) | (reverse?64:0); 34 | if (lookup.hasOwnProperty(checksum)) 35 | return lookup[checksum]; 36 | if ( !mirror !== !(reverse&&opposite)) // Boolean XOR 37 | [left, right, top, bottom, up, down] = [right, left, bottom, top, down, up]; 38 | let angle = '-200deg', origin = 'center'; 39 | if ( (down||top) && left ) angle = '-45deg'; 40 | if ( ((down||top) && right) || ((up||bottom) && left) ) angle = '45deg'; 41 | if ( (up||bottom) && right ) angle = '-90deg'; 42 | if ( left || right ) origin=( left ? 'left' : 'right' ) + ' bottom'; 43 | lookup[checksum] = animation(` 44 | ${!reverse?'from':'to'} { opacity: 0; transform-origin: ${origin}; transform: rotate3d(0, 0, 1, ${angle});} 45 | ${reverse?'from':'to'} { opacity: 1; transform-origin: ${origin}; transform: none;} 46 | `); 47 | return lookup[checksum]; 48 | } 49 | 50 | function Rotate({ children, out, forever, 51 | timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, ...props } = defaults) { 52 | const effect = { 53 | make, 54 | duration: timeout === undefined ? duration : timeout, 55 | delay, forever, count, 56 | style: { animationFillMode: 'both', } 57 | }; 58 | return wrap(props, effect, effect, children); 59 | } 60 | 61 | Rotate.propTypes = propTypes; 62 | export default Rotate; 63 | -------------------------------------------------------------------------------- /src/in-and-out/Slide.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Slide React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import { bool, number } from 'prop-types'; 11 | import wrap from '../lib/wrap'; 12 | import { animation, defaults } from '../lib/globals'; 13 | 14 | const 15 | propTypes = { 16 | out: bool, 17 | left: bool, 18 | right: bool, 19 | top: bool, 20 | bottom: bool, 21 | big: bool, 22 | mirror: bool, 23 | opposite: bool, 24 | duration: number, 25 | timeout: number, 26 | delay: number, 27 | count: number, 28 | forever: bool, 29 | }; 30 | 31 | const lookup = {}; 32 | function make(reverse, { left, right, up, down, top, bottom, big, mirror, opposite, }) { 33 | const checksum = ( (left?1:0) | (right?2:0) | (top||down?4:0) | (bottom||up?8:0) | (mirror?16:0) | (opposite?32:0) | (reverse?64:0) | (big?128:0)); 34 | if (lookup.hasOwnProperty(checksum)) 35 | return lookup[checksum]; 36 | const transform = left||right||up||down||top||bottom; 37 | let x, y; 38 | if (transform) { 39 | if ( !mirror !== !(reverse&&opposite)) // Boolean XOR 40 | [left, right, top, bottom, up, down] = [right, left, bottom, top, down, up]; 41 | const dist = big ? '2000px' : '100%'; 42 | x = left ? '-' + dist : ( right ? dist : '0' ); 43 | y = down || top ? '-'+ dist : ( up || bottom ? dist : '0' ); 44 | } 45 | lookup[checksum] = animation( 46 | `${!reverse?'from':'to'} {${ transform ? ` transform: translate3d(${x}, ${y}, 0);` : ''}} 47 | ${ reverse?'from':'to'} {transform: none;} ` 48 | ); 49 | return lookup[checksum]; 50 | } 51 | 52 | function Slide({ children, out, forever, 53 | timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, ...props } = defaults) { 54 | const effect = { 55 | make, 56 | duration: timeout === undefined ? duration : timeout, 57 | delay, 58 | forever, 59 | count, 60 | style: { animationFillMode: 'both', }, 61 | reverse: props.left, 62 | }; 63 | return wrap(props, effect, effect, children); 64 | } 65 | 66 | Slide.propTypes = propTypes; 67 | export default Slide; 68 | -------------------------------------------------------------------------------- /src/in-and-out/Zoom.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Zoom React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | out: bool, 18 | left: bool, 19 | right: bool, 20 | top: bool, 21 | bottom: bool, 22 | mirror: bool, 23 | opposite: bool, 24 | duration: number, 25 | timeout: number, 26 | delay: number, 27 | count: number, 28 | forever: bool, 29 | }; 30 | 31 | const lookup = {}; 32 | function make(reverse, { left, right, up, down, top, bottom, mirror, opposite, }) { 33 | const checksum = (left?1:0) | (right?2:0) | (top||down?4:0) | (bottom||up?8:0) | (mirror?16:0) | (opposite?32:0) | (reverse?64:0); 34 | if (lookup.hasOwnProperty(checksum)) 35 | return lookup[checksum]; 36 | if ( !mirror !== !(reverse&&opposite)) // Boolean XOR 37 | [left, right, top, bottom, up, down] = [right, left, bottom, top, down, up]; 38 | const 39 | transformX = left || right, 40 | transformY = top || bottom || up || down, 41 | transform = transformX || transformY; 42 | let rule, x1, y1, x2, y2; 43 | if (transform) { 44 | if (reverse) { 45 | x1 = transformX ? ( left ? '' : '-' ) + '42px' : '0'; 46 | y1 = transformY ? ( down||top ? '-' : '' ) + '60px' : '0'; 47 | x2 = transformX ? ( right ? '' : '-' ) + '2000px' : '0'; 48 | y2 = transformY ? ( up||bottom ? '' : '-' ) + '2000px' : '0'; 49 | rule =`40% { 50 | opacity: 1; 51 | transform: scale3d(.475, .475, .475) translate3d(${x1}, ${y1}, 0); 52 | } 53 | to { 54 | opacity: 0; 55 | transform: scale(.1) translate3d(${x2}, ${y2}, 0); 56 | transform-origin: ${transformY ? `center bottom` : `${left?'left':'right'} center`}; 57 | }`; 58 | } 59 | else { 60 | x1 = transformX ? ( left ? '-' : '' ) + '1000px' : '0'; 61 | y1 = transformY ? ( down||top ? '-' : '' ) + '1000px' : '0'; 62 | x2 = transformX ? ( right ? '-' : '' ) + '10px' : '0'; 63 | y2 = transformY ? ( up||bottom ? '-' : '' ) + '60px' : '0'; 64 | rule =`from { 65 | opacity: 0; 66 | transform: scale3d(.1, .1, .1) translate3d(${x1}, ${y1}, 0); 67 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 68 | } 69 | 60% { 70 | opacity: 1; 71 | transform: scale3d(.475, .475, .475) translate3d(${x2}, ${y2}, 0); 72 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 73 | }`; 74 | } 75 | } 76 | else 77 | rule = `${!reverse?'from':'to'} {opacity: 0; transform: scale3d(.1, .1, .1);} ${reverse?'from':'to'} { opacity: 1; transform: none;}`; 78 | lookup[checksum] = animation(rule); 79 | return lookup[checksum]; 80 | } 81 | 82 | function Zoom({ children, out, forever, 83 | timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, ...props } = defaults) { 84 | const effect = { 85 | make, 86 | duration: timeout === undefined ? duration : timeout, 87 | delay, forever, count, 88 | style: { animationFillMode: 'both', }, 89 | reverse: props.left, 90 | }; 91 | return wrap(props, effect, effect, children); 92 | } 93 | 94 | Zoom.propTypes = propTypes; 95 | export default Zoom; 96 | -------------------------------------------------------------------------------- /src/lib/HamburgerIcon.js: -------------------------------------------------------------------------------- 1 | /* 2 | * HamburgerIcon Component Service For react-reveal 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * SVG animation adapted from https://codepen.io/cwmanning/pen/zaCHB 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import React from 'react'; 12 | 13 | function HamburgerIcon( toggle, animation, handleClick, 14 | { color = '#fff', size = 28, style, ...props} = { color: '#fff', size: 28, style: { backgroundColor: '#808080' }} ) { 15 | const 16 | common = { opacity: 1, stroke: color, transition: 'transform 0.3s' }, 17 | flip = ` 18 | 15% { 19 | opacity: 0.8; 20 | transform: translateZ(0) scale(0.8) rotateZ(0); 21 | } 22 | 30% { 23 | transform: translateZ(0) scale(0.8) rotateZ(0); 24 | } 25 | 100% { 26 | opacity: 1; 27 | transform: translateZ(0) scale(1) rotateZ(405deg); 28 | } 29 | `, 30 | hamburger = { 31 | cursor: 'pointer', 32 | animationName: !toggle ? void 0 : animation(flip), 33 | animationDuration: !toggle ? void 0 : '900ms', 34 | animationFillMode: !toggle ? void 0 : 'forwards', 35 | }, 36 | a = { ...common, transform: !toggle?void 0:'translate(0, 7px)' }, 37 | b = { ...common, transform: !toggle?'rotate(0deg)':'translate(20px, -4px) rotate(90deg)' }, 38 | c = { ...common, transform: !toggle?void 0:'translate(0, -7px)' }; 39 | //viewBox="0 0 24 16" 40 | return ( 41 |
42 | 43 | 44 | 45 | 46 | 47 |
48 | ); 49 | } 50 | 51 | export default HamburgerIcon; 52 | -------------------------------------------------------------------------------- /src/lib/Step.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Step Auxiliary Class 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | class Step { 11 | 12 | constructor(name, after = 1000) { 13 | this.after = after; 14 | this.name = name; 15 | this.chain = []; 16 | } 17 | 18 | push(api) { 19 | if (this.start) { 20 | api.step = this.index; 21 | api.start = this.start; 22 | } 23 | this.chain.push(api); 24 | } 25 | 26 | } 27 | 28 | export default Step; -------------------------------------------------------------------------------- /src/lib/Stepper.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Stepper Auxiliary Class 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import Step from './Step'; 11 | 12 | class Stepper { 13 | 14 | constructor() { 15 | this.steps = []; 16 | this.stepMap = {}; 17 | this.hasStarted = false; 18 | this.isTriggered = false; 19 | this.runs = 1; 20 | this.totalRuns = 0; 21 | this.start = this.start.bind(this); 22 | this.next = this.next.bind(this); 23 | } 24 | 25 | step(name, after = 1000) { 26 | const step = new Step(name, after); 27 | step.start = this.start; 28 | step.index = this.steps.push(step) - 1; 29 | this.stepMap[name] = step; 30 | return this; 31 | } 32 | 33 | //if (process.env.NODE_ENV !== 'production') 34 | // throw new Error(`Animation step ${name} is missing`); 35 | //else { 36 | //} 37 | is(name) { 38 | return this.get(name); 39 | } 40 | 41 | get(name) { 42 | if (name in this.stepMap)//.hasOwnProperty(name)) 43 | return this.stepMap[name]; 44 | else console.warn(`Animation step ${name} is missing`); 45 | } 46 | 47 | 48 | start(step) { 49 | if (this.hasStarted) { 50 | this.runs = 2; 51 | } 52 | if(this.isTriggered) { 53 | if ( step < this.trigger ) 54 | this.trigger = step; 55 | return; 56 | } 57 | this.isTriggered = true; 58 | this.trigger = step; 59 | window.setTimeout(this.init.bind(this), 50); 60 | } 61 | 62 | init() { 63 | this.hasStarted = true; 64 | this.head = this.trigger; 65 | this.tail = this.head === 0 ? this.steps.length - 1 : this.head - 1; 66 | this.next(); 67 | } 68 | 69 | stop() { 70 | this.hasStarted = false; 71 | this.isTriggered = false; 72 | } 73 | 74 | next() { 75 | let onceRevealed = false; 76 | for (let i = 0, len = this.steps[this.head].chain.length; i < len; i++) { 77 | const api = this.steps[this.head].chain[i]; 78 | if (!api.isShown&&api.start&&api.inViewport()) { 79 | onceRevealed = true; 80 | delete api.start; 81 | api.animate(api.props); 82 | } 83 | } 84 | if (this.head === this.tail) { 85 | this.runs--; 86 | this.totalRuns++; 87 | if (this.totalRuns>100) 88 | return; 89 | if (this.runs <= 0) 90 | return this.stop(); 91 | } 92 | const prev = this.head; 93 | this.head++; 94 | if (this.head >= this.steps.length) 95 | this.head = 0; 96 | //console.log('head:',this.head,'runs', this.runs,'total', this.totalRuns) ; 97 | if (onceRevealed) 98 | window.setTimeout(this.next, this.steps[prev].after); 99 | else this.next(); 100 | } 101 | 102 | } 103 | 104 | export default Stepper; 105 | -------------------------------------------------------------------------------- /src/lib/debounce.js: -------------------------------------------------------------------------------- 1 | // Returns a function, that, as long as it continues to be invoked, will not 2 | // be triggered. The function will be called after it stops being called for 3 | // N milliseconds. If `immediate` is passed, trigger the function on the 4 | // leading edge, instead of the trailing. 5 | export default function debounce(func, wait, immediate) { 6 | var timeout; 7 | return function() { 8 | var context = this, args = arguments; 9 | var later = function() { 10 | timeout = null; 11 | if (!immediate) func.apply(context, args); 12 | }; 13 | var callNow = immediate && !timeout; 14 | clearTimeout(timeout); 15 | timeout = setTimeout(later, wait); 16 | if (callNow) func.apply(context, args); 17 | }; 18 | }; 19 | 20 | // Copyright (c) 2009-2017 Jeremy Ashkenas, DocumentCloud and Investigative 21 | // Reporters & Editors 22 | // 23 | // Permission is hereby granted, free of charge, to any person 24 | // obtaining a copy of this software and associated documentation 25 | // files (the "Software"), to deal in the Software without 26 | // restriction, including without limitation the rights to use, 27 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 28 | // copies of the Software, and to permit persons to whom the 29 | // Software is furnished to do so, subject to the following 30 | // conditions: 31 | // 32 | // The above copyright notice and this permission notice shall be 33 | // included in all copies or substantial portions of the Software. 34 | // 35 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 36 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 37 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 38 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 39 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 40 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 41 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 42 | // OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/lib/globals.js: -------------------------------------------------------------------------------- 1 | /* 2 | * React-reveal Global Helpers 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | //import {version} from 'react'; 11 | 12 | export const namespace = 'react-reveal';//, is16 = parseInt(version, 10) >= 16; 13 | export const defaults = { duration: 1000, delay: 0, count: 1, }; 14 | 15 | export let 16 | ssr = true, 17 | observerMode = false, 18 | raf = cb => window.setTimeout(cb, 66), 19 | disableSsr = () => ssr = false, 20 | fadeOutEnabled = false, 21 | ssrFadeout = (enable = false) => fadeOutEnabled = enable, 22 | globalHide = false, 23 | ie10 = false, 24 | collapseend; 25 | let counter = 1, effectMap = {}, sheet = false, name = `${namespace}-${Math.floor(Math.random() * 1000000000000000)}-`; 26 | 27 | export function insertRule(rule) { 28 | try { 29 | return sheet.insertRule(rule, sheet.cssRules.length); 30 | } 31 | catch(e){ 32 | console.warn('react-reveal - animation failed'); 33 | } 34 | } 35 | 36 | export function cascade(i, start, end, duration, total) { 37 | const minv = Math.log(duration), maxv = Math.log(total), scale = (maxv-minv) / (end-start); 38 | return Math.exp(minv + scale*(i-start)); 39 | } 40 | 41 | export function animation(effect) { 42 | if (!sheet) return ''; 43 | const rule = `@keyframes ${name + counter}{${effect}}`; 44 | const effectId = effectMap[effect]; 45 | if (!effectId){ 46 | insertRule(rule); 47 | effectMap[effect] = counter; 48 | return `${name}${counter++}`; 49 | } 50 | return `${name}${effectId}`; 51 | } 52 | 53 | export function hideAll() { 54 | if(globalHide) 55 | return; 56 | globalHide = true; 57 | window.removeEventListener('scroll', hideAll, true); 58 | insertRule(`.${namespace} { opacity: 0; }`); 59 | window.removeEventListener('orientationchange', hideAll, true); 60 | window.document.removeEventListener('visibilitychange', hideAll); 61 | } 62 | 63 | //navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom") 64 | if (typeof window !== 'undefined' && window.name !== 'nodejs' && window.document && typeof navigator !== 'undefined') { // are we in browser? 65 | observerMode = 'IntersectionObserver' in window 66 | && 'IntersectionObserverEntry' in window // bypassing 67 | && 'intersectionRatio' in window.IntersectionObserverEntry.prototype // inclomplete implementations 68 | && (/\{\s*\[native code\]\s*\}/).test('' + IntersectionObserver); // and buggy polyfills 69 | raf = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || raf; 70 | ssr = window.document.querySelectorAll('div[data-reactroot]').length>0; // are we prerendered? 71 | if (navigator.appVersion.indexOf("MSIE 10") !== -1) 72 | ie10 = true; 73 | //if (ssr && 'serviceWorker' in navigator && navigator.serviceWorker.controller) //cached by service worker? 74 | // ssr = false; 75 | //console.log(Date.now() - window.performance.timing.domLoading<500); 76 | if (ssr && 'performance' in window 77 | && 'timing' in window.performance 78 | && 'domContentLoadedEventEnd' in window.performance.timing 79 | && window.performance.timing.domLoading 80 | && Date.now() - window.performance.timing.domLoading<300) 81 | ssr = false; 82 | if (ssr) 83 | window.setTimeout(disableSsr, 1500); 84 | if (!observerMode) { 85 | collapseend = document.createEvent('Event'); 86 | collapseend.initEvent('collapseend', true, true); 87 | } 88 | let element = document.createElement('style'); 89 | document.head.appendChild(element); 90 | if (element.sheet && element.sheet.cssRules && element.sheet.insertRule) { 91 | sheet = element.sheet; 92 | window.addEventListener('scroll', hideAll, true); 93 | window.addEventListener("orientationchange", hideAll, true); 94 | window.document.addEventListener("visibilitychange", hideAll); 95 | } 96 | } 97 | 98 | export default function config({ ssrFadeout }) { 99 | fadeOutEnabled = ssrFadeout; 100 | } 101 | -------------------------------------------------------------------------------- /src/lib/hamburger.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Hamburger Higher Order Component For react-reveal 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import React from 'react'; 11 | import responsive from './responsive'; 12 | import makeIcon from './HamburgerIcon'; 13 | import { animation } from './globals'; 14 | import Fade from './Fade'; 15 | 16 | function hamburger(WrappedComponent, config = {} ) { 17 | 18 | let responsiveNode; 19 | 20 | function icon(iconProps) { 21 | if (!responsiveNode || responsiveNode.state.match) 22 | return void 0; 23 | return makeIcon(responsiveNode.state.isClicked, animation, responsiveNode.handleClick, iconProps); 24 | } 25 | 26 | if ('duration' in config) 27 | config.duration*=3; 28 | const ResponsiveComponent = responsive(WrappedComponent, { ...config, effect: }); 29 | 30 | return function(props) { 31 | return ( 32 | responsiveNode = node } 37 | /> 38 | ); 39 | } 40 | 41 | } 42 | 43 | export default hamburger; 44 | -------------------------------------------------------------------------------- /src/lib/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Reveal'; 2 | export { default as Fade } from './Fade'; 3 | //export { default as makeCarousel } from './makeCarousel'; 4 | //export { default as hamburger } from './hamburger'; 5 | //export { default as responsive } from './responsive'; 6 | //export { default as withReveal } from './withReveal'; 7 | //export { default as HamburgerIcon } from './HamburgerIcon'; 8 | //export { default as Spin } from './Spin'; 9 | export { default as Bounce } from './Bounce'; 10 | //export { default as Flash } from './Flash'; 11 | //export { default as HeadShake } from './HeadShake'; 12 | //export { default as Jello } from './Jello'; 13 | //export { default as Jump } from './Jump'; 14 | //export { default as Pulse } from './Pulse'; 15 | export { default as Roll } from './Roll'; 16 | //export { default as RubberBand } from './RubberBand'; 17 | //export { default as Shake } from './Shake'; 18 | export { default as Slide } from './Slide'; 19 | //export { default as Swing } from './Swing'; 20 | //export { default as Tada } from './Tada'; 21 | //export { default as Wobble } from './Wobble'; 22 | export { default as Flip } from './Flip'; 23 | export { default as Reveal } from './Reveal'; 24 | export { default as Rotate } from './Rotate'; 25 | export { default as LightSpeed } from './LightSpeed'; 26 | export { default as Zoom } from './Zoom'; 27 | -------------------------------------------------------------------------------- /src/lib/makeCarousel.js: -------------------------------------------------------------------------------- 1 | /* 2 | * makeCarousel Higher Order Component For react-reveal 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import React from 'react'; 11 | import { number, node, bool} from 'prop-types'; 12 | import swipedetect from './swipedetect'; 13 | 14 | function makeCarousel(WrappedComponent, config = {}) { 15 | 16 | //const { wait = 5000, maxTurns = 2, } = config; 17 | 18 | return class extends React.Component { 19 | 20 | static get propTypes() { 21 | return { 22 | children: node.isRequired, 23 | defaultWait: number, 24 | maxTurns: number, 25 | swipe: bool, 26 | }; 27 | } 28 | 29 | static get defaultProps() { 30 | return { 31 | defaultWait: config.defaultWait || 5000, 32 | maxTurns: config.maxTurns || 5, 33 | swipe: config.swipe || true, 34 | }; 35 | } 36 | 37 | constructor(props) { 38 | super(props); 39 | this.state = { 40 | //next: React.Children.count(this.props.children) - 1, 41 | current: 0, 42 | next: 1, 43 | backwards: false, 44 | swap: false, 45 | appear: false, 46 | }; 47 | this.turn = 0; 48 | this.stop = false; 49 | this.handleReveal = this.handleReveal.bind(this); 50 | this.handleSwipe = this.handleSwipe.bind(this); 51 | this.target = this.target.bind(this); 52 | } 53 | 54 | target({currentTarget}) { 55 | this.move(+currentTarget.getAttribute('data-position')); 56 | } 57 | 58 | handleReveal() { 59 | if (this.turn >= this.props.maxTurns) 60 | return; 61 | this.move(this.state.current + 1); 62 | } 63 | 64 | componentWillUnmount() { 65 | this.turn = -1; 66 | } 67 | 68 | move(newPos) { 69 | if (this.turn<0 || newPos === this.state.current) 70 | return; 71 | let pos = newPos; 72 | const count = React.Children.count(this.props.children); 73 | if (newPos >= count) { 74 | this.turn++ 75 | pos = 0; 76 | } 77 | else if (newPos < 0) 78 | pos = count -1; 79 | this.setState({ 80 | current: pos, 81 | next: this.state.current, 82 | backwards: newPos; 115 | after =
; 116 | case 1: 117 | before = arr[0]; 118 | after = arr[0]; 119 | default: 120 | before = arr[swap ? next : current]; 121 | after = arr[swap ? current : next]; 122 | } 123 | 124 | if (typeof before !== 'object') 125 | before =
{before}
; 126 | if (typeof after !== 'object') 127 | after =
{after}
; 128 | 129 | return ( 130 | this.beforeNode = node } key={1} style={{ position: 'absolute', left: 0, top: 0, width: '100%', height: '100%', zIndex: swap ? 1 : 2 }}> 137 | 150 |
, 151 |
this.afterNode = node } style={{ position: 'absolute', left: 0, top: 0, width: '100%', height: '100%', zIndex: swap ? 2 : 1 }}> 152 | 165 |
166 | ]} 167 | /> 168 | ); 169 | } 170 | 171 | }; 172 | } 173 | 174 | export default makeCarousel; 175 | -------------------------------------------------------------------------------- /src/lib/responsive.js: -------------------------------------------------------------------------------- 1 | /* 2 | * responsive Higher Order Component For react-reveal 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import React from 'react'; 11 | import withReveal from './withReveal'; 12 | 13 | function responsive( WrappedComponent, {effect, breakpoint = '768px', ...rest } = { breakpoint: '768px' } ) { 14 | 15 | const RevealedComponent = withReveal(WrappedComponent, effect); 16 | 17 | return class extends React.Component { 18 | 19 | constructor(props) { 20 | super(props); 21 | this.mql = false; 22 | this.handleChange = this.handleChange.bind(this); 23 | this.handleClick = this.handleClick.bind(this); 24 | this.state = { 25 | match : true, 26 | isClicked: false, 27 | }; 28 | } 29 | 30 | handleChange(e) { 31 | this.setState({ match: e.matches, isClicked: false }); 32 | } 33 | 34 | handleClick() { 35 | this.setState({ isClicked: !this.state.isClicked }); 36 | } 37 | 38 | newQuery(query) { 39 | this.unlisten(); 40 | if ('matchMedia' in window) { 41 | this.mql = window.matchMedia(`(min-width: ${breakpoint})`); 42 | this.handleChange(this.mql); 43 | this.mql.addListener(this.handleChange); 44 | } 45 | } 46 | 47 | unlisten() { 48 | if (this.mql) 49 | this.mql.removeListener(this.handleChange); 50 | } 51 | 52 | componentWillUnmount() { 53 | this.unlisten(); 54 | } 55 | 56 | componentDidMount() { 57 | this.newQuery(this.props.query); 58 | } 59 | 60 | componentWillReceiveProps({ query }) { 61 | this.newQuery(query); 62 | } 63 | 64 | render() { 65 | return ( 66 | 76 | ); 77 | } 78 | 79 | }; 80 | } 81 | 82 | export default responsive; 83 | -------------------------------------------------------------------------------- /src/lib/swipedetect.js: -------------------------------------------------------------------------------- 1 | //// credit: http://www.javascriptkit.com/javatutors/touchevents2.shtml 2 | // var supportsPassive = false; 3 | // try { 4 | // var opts = Object.defineProperty({}, 'passive', { 5 | // get: function() { 6 | // supportsPassive = true; 7 | // } 8 | // }); 9 | // window.addEventListener("testPassive", null, opts); 10 | // window.removeEventListener("testPassive", null, opts); 11 | // } catch (e) {} 12 | export default function swipedetect(el, callback){ 13 | 14 | var touchsurface = el, 15 | swipedir, 16 | startX, 17 | startY, 18 | distX, 19 | distY, 20 | threshold = 150, //required min distance traveled to be considered swipe 21 | restraint = 100, // maximum distance allowed at the same time in perpendicular direction 22 | allowedTime = 300, // maximum time allowed to travel that distance 23 | elapsedTime, 24 | startTime, 25 | handleswipe = callback || function(swipedir){} 26 | 27 | 28 | 29 | // Use our detect's results. passive applied if supported, capture will be false either way. 30 | //elem.addEventListener('touchstart', fn, supportsPassive ? { passive: true } : false); 31 | 32 | touchsurface.addEventListener('touchstart', function(e){ 33 | var touchobj = e.changedTouches[0]; 34 | swipedir = 'none'; 35 | //dist = 0; 36 | startX = touchobj.pageX; 37 | startY = touchobj.pageY; 38 | startTime = new Date().getTime(); // record time when finger first makes contact with surface 39 | //e.preventDefault(); 40 | }, { passive: true })//supportsPassive ? { passive: true } : false) 41 | 42 | //touchsurface.addEventListener('touchmove', function(e){ 43 | // e.preventDefault() // prevent scrolling when inside DIV 44 | //}, false) 45 | 46 | touchsurface.addEventListener('touchend', function(e){ 47 | var touchobj = e.changedTouches[0] 48 | distX = touchobj.pageX - startX // get horizontal dist traveled by finger while in contact with surface 49 | distY = touchobj.pageY - startY // get vertical dist traveled by finger while in contact with surface 50 | elapsedTime = new Date().getTime() - startTime // get time elapsed 51 | if (elapsedTime <= allowedTime){ // first condition for awipe met 52 | if (Math.abs(distX) >= threshold && Math.abs(distY) <= restraint){ // 2nd condition for horizontal swipe met 53 | swipedir = (distX < 0)? 'left' : 'right' // if dist traveled is negative, it indicates left swipe 54 | } 55 | else if (Math.abs(distY) >= threshold && Math.abs(distX) <= restraint){ // 2nd condition for vertical swipe met 56 | swipedir = (distY < 0)? 'up' : 'down' // if dist traveled is negative, it indicates up swipe 57 | } 58 | } 59 | handleswipe(swipedir) 60 | //e.preventDefault() 61 | }, { passive: true })//supportsPassive ? { passive: true } : false) 62 | } 63 | -------------------------------------------------------------------------------- /src/lib/throttle.js: -------------------------------------------------------------------------------- 1 | export default function throttle(callback, wait, context = this) { 2 | let timeout = null 3 | let callbackArgs = null 4 | 5 | const later = () => { 6 | callback.apply(context, callbackArgs) 7 | timeout = null 8 | } 9 | 10 | return function() { 11 | if (!timeout) { 12 | callbackArgs = arguments 13 | timeout = setTimeout(later, wait) 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/lib/withReveal.js: -------------------------------------------------------------------------------- 1 | /* 2 | * withReveal Auxiliary Function For Making react-reveal Higher Order Components 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import React from 'react'; 11 | 12 | function withReveal(WrappedComponent, effect) { 13 | let refProp = undefined; 14 | if (typeof WrappedComponent === 'function' && typeof WrappedComponent.styledComponentId === 'string') 15 | refProp = "innerRef"; 16 | return function({ 17 | force, 18 | mountOnEnter, 19 | unmountOnExit, 20 | opposite, 21 | mirror, 22 | wait, 23 | onReveal, 24 | in: inProp, 25 | when, 26 | spy, 27 | collapse, 28 | onExited, 29 | enter, 30 | exit, 31 | appear, 32 | //disableObserver, 33 | ...props 34 | }) { 35 | return ( 36 | 56 | 57 | 58 | ); 59 | } 60 | 61 | } 62 | 63 | export default withReveal; 64 | -------------------------------------------------------------------------------- /src/lib/wrap.js: -------------------------------------------------------------------------------- 1 | /* 2 | * React-reveal Wrap Helper 3 | * 4 | * Copyright © Roman Nosov 2018 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE.txt file in the root directory of this source tree. 8 | */ 9 | 10 | import React from 'react'; 11 | import RevealBase from '../RevealBase'; 12 | 13 | export default function wrap(props, inEffect, outEffect, children) { 14 | if ('in' in props) 15 | props.when = props.in; 16 | if (React.Children.count(children) < 2) 17 | return 18 | children = React.Children.map(children, child => 19 | 20 | ); 21 | return 'Fragment' in React ? {children} : {children}; 22 | } 23 | -------------------------------------------------------------------------------- /src/simple/Flash.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Flash React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | from, 50%, to { 26 | opacity: 1; 27 | } 28 | 29 | 25%, 75% { 30 | opacity: 0; 31 | } 32 | `; 33 | 34 | let name = false; 35 | function make() { 36 | return name || (name = animation(rule)); 37 | } 38 | 39 | function Flash({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 40 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; 41 | return wrap(props, effect, false, children, true); 42 | } 43 | 44 | Flash.propTypes = propTypes; 45 | export default Flash; 46 | -------------------------------------------------------------------------------- /src/simple/HeadShake.js: -------------------------------------------------------------------------------- 1 | /* 2 | * HeadShake React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | 0% { 26 | transform: translateX(0); 27 | } 28 | 29 | 6.5% { 30 | transform: translateX(-6px) rotateY(-9deg); 31 | } 32 | 33 | 18.5% { 34 | transform: translateX(5px) rotateY(7deg); 35 | } 36 | 37 | 31.5% { 38 | transform: translateX(-3px) rotateY(-5deg); 39 | } 40 | 41 | 43.5% { 42 | transform: translateX(2px) rotateY(3deg); 43 | } 44 | 45 | 50% { 46 | transform: translateX(0); 47 | } 48 | `; 49 | 50 | let name = false; 51 | function make() { 52 | return name || (name = animation(rule)); 53 | } 54 | 55 | 56 | function HeadShake({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 57 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; return wrap(props, effect, false, children, true); 58 | } 59 | 60 | 61 | HeadShake.propTypes = propTypes; 62 | export default HeadShake; 63 | -------------------------------------------------------------------------------- /src/simple/Jello.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Jello React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | from, 11.1%, to { 26 | transform: none; 27 | } 28 | 29 | 22.2% { 30 | transform: skewX(-12.5deg) skewY(-12.5deg); 31 | } 32 | 33 | 33.3% { 34 | transform: skewX(6.25deg) skewY(6.25deg); 35 | } 36 | 37 | 44.4% { 38 | transform: skewX(-3.125deg) skewY(-3.125deg); 39 | } 40 | 41 | 55.5% { 42 | transform: skewX(1.5625deg) skewY(1.5625deg); 43 | } 44 | 45 | 66.6% { 46 | transform: skewX(-0.78125deg) skewY(-0.78125deg); 47 | } 48 | 49 | 77.7% { 50 | transform: skewX(0.390625deg) skewY(0.390625deg); 51 | } 52 | 53 | 88.8% { 54 | transform: skewX(-0.1953125deg) skewY(-0.1953125deg); 55 | } 56 | `; 57 | 58 | let name = false; 59 | function make() { 60 | return name || (name = animation(rule)); 61 | } 62 | 63 | 64 | function Jello({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 65 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; 66 | return wrap(props, effect, false, children, true); 67 | } 68 | 69 | Jello.propTypes = propTypes; 70 | export default Jello; 71 | -------------------------------------------------------------------------------- /src/simple/Jump.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Jump React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | from, 20%, 53%, 80%, to { 26 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 27 | transform: translate3d(0,0,0); 28 | } 29 | 30 | 40%, 43% { 31 | animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); 32 | transform: translate3d(0, -30px, 0); 33 | } 34 | 35 | 70% { 36 | animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); 37 | transform: translate3d(0, -15px, 0); 38 | } 39 | 40 | 90% { 41 | transform: translate3d(0, -4px, 0); 42 | } 43 | `; 44 | 45 | let name = false; 46 | function make() { 47 | return name || (name = animation(rule)); 48 | } 49 | 50 | 51 | function Jump({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 52 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; 53 | return wrap(props, effect, false, children, true); 54 | } 55 | 56 | 57 | Jump.propTypes = propTypes; 58 | export default Jump; 59 | -------------------------------------------------------------------------------- /src/simple/Pulse.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Pulse React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | from { 26 | transform: scale3d(1, 1, 1); 27 | } 28 | 29 | 50% { 30 | transform: scale3d(1.05, 1.05, 1.05); 31 | } 32 | 33 | to { 34 | transform: scale3d(1, 1, 1); 35 | } 36 | `; 37 | 38 | let name = false; 39 | function make() { 40 | return name || (name = animation(rule)); 41 | } 42 | 43 | 44 | function Pulse({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 45 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; 46 | return wrap(props, effect, false, children, true); 47 | } 48 | 49 | Pulse.propTypes = propTypes; 50 | export default Pulse; 51 | -------------------------------------------------------------------------------- /src/simple/RubberBand.js: -------------------------------------------------------------------------------- 1 | /* 2 | * RubberBand React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | from { 26 | transform: scale3d(1, 1, 1); 27 | } 28 | 29 | 30% { 30 | transform: scale3d(1.25, 0.75, 1); 31 | } 32 | 33 | 40% { 34 | transform: scale3d(0.75, 1.25, 1); 35 | } 36 | 37 | 50% { 38 | transform: scale3d(1.15, 0.85, 1); 39 | } 40 | 41 | 65% { 42 | transform: scale3d(.95, 1.05, 1); 43 | } 44 | 45 | 75% { 46 | transform: scale3d(1.05, .95, 1); 47 | } 48 | 49 | to { 50 | transform: scale3d(1, 1, 1); 51 | } 52 | `; 53 | 54 | let name = false; 55 | function make() { 56 | return name || (name = animation(rule)); 57 | } 58 | 59 | 60 | function RubberBand({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 61 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; 62 | return wrap(props, effect, false, children, true); 63 | } 64 | 65 | RubberBand.propTypes = propTypes; 66 | export default RubberBand; 67 | -------------------------------------------------------------------------------- /src/simple/Shake.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Shake React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | from, to { 26 | transform: translate3d(0, 0, 0); 27 | } 28 | 29 | 10%, 30%, 50%, 70%, 90% { 30 | transform: translate3d(-10px, 0, 0); 31 | } 32 | 33 | 20%, 40%, 60%, 80% { 34 | transform: translate3d(10px, 0, 0); 35 | } 36 | `; 37 | 38 | let name = false; 39 | function make() { 40 | return name || (name = animation(rule)); 41 | } 42 | 43 | 44 | function Shake({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 45 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; 46 | return wrap(props, effect, false, children, true); 47 | } 48 | 49 | Shake.propTypes = propTypes; 50 | export default Shake; 51 | -------------------------------------------------------------------------------- /src/simple/Spin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Spin React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | from { 26 | transform: rotate(360deg); 27 | animation-timing-function: linear; 28 | } 29 | 30 | to { 31 | transform: rotate(0deg); 32 | } 33 | `; 34 | 35 | let name = false; 36 | function make() { 37 | return name || (name = animation(rule)); 38 | } 39 | 40 | 41 | function Spin({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 42 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; 43 | return wrap(props, effect, false, children, true); 44 | } 45 | 46 | Spin.propTypes = propTypes; 47 | export default Spin; 48 | -------------------------------------------------------------------------------- /src/simple/Swing.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Swing React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | 20% { 26 | transform: rotate3d(0, 0, 1, 15deg); 27 | } 28 | 29 | 40% { 30 | transform: rotate3d(0, 0, 1, -10deg); 31 | } 32 | 33 | 60% { 34 | transform: rotate3d(0, 0, 1, 5deg); 35 | } 36 | 37 | 80% { 38 | transform: rotate3d(0, 0, 1, -5deg); 39 | } 40 | 41 | to { 42 | transform: rotate3d(0, 0, 1, 0deg); 43 | } 44 | `; 45 | 46 | let name = false; 47 | function make() { 48 | return name || (name = animation(rule)); 49 | } 50 | 51 | 52 | function Swing({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 53 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; 54 | return wrap(props, effect, false, children, true); 55 | } 56 | 57 | 58 | Swing.propTypes = propTypes; 59 | export default Swing; 60 | -------------------------------------------------------------------------------- /src/simple/Tada.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Tada React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | from { 26 | transform: scale3d(1, 1, 1); 27 | } 28 | 29 | 10%, 20% { 30 | transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); 31 | } 32 | 33 | 30%, 50%, 70%, 90% { 34 | transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); 35 | } 36 | 37 | 40%, 60%, 80% { 38 | transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); 39 | } 40 | 41 | to { 42 | transform: scale3d(1, 1, 1); 43 | } 44 | `; 45 | 46 | let name = false; 47 | function make() { 48 | return name || (name = animation(rule)); 49 | } 50 | 51 | 52 | function Tada({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 53 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; 54 | return wrap(props, effect, false, children, true); 55 | } 56 | 57 | Tada.propTypes = propTypes; 58 | export default Tada; 59 | 60 | -------------------------------------------------------------------------------- /src/simple/Wobble.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Wobble React Component 3 | * 4 | * Copyright © Roman Nosov 2017 5 | * Original CSS Effect - Copyright (c) 2016 Daniel Eden 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE.txt file in the root directory of this source tree. 9 | */ 10 | 11 | import { bool, number } from 'prop-types'; 12 | import wrap from '../lib/wrap'; 13 | import { animation, defaults } from '../lib/globals'; 14 | 15 | const 16 | propTypes = { 17 | duration: number, 18 | timeout: number, 19 | delay: number, 20 | count: number, 21 | forever: bool, 22 | }; 23 | 24 | const rule = ` 25 | from { 26 | transform: none; 27 | } 28 | 29 | 15% { 30 | transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); 31 | } 32 | 33 | 30% { 34 | transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); 35 | } 36 | 37 | 45% { 38 | transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); 39 | } 40 | 41 | 60% { 42 | transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); 43 | } 44 | 45 | 75% { 46 | transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); 47 | } 48 | 49 | to { 50 | transform: none; 51 | } 52 | `; 53 | 54 | let name = false; 55 | function make() { 56 | return name || (name = animation(rule)); 57 | } 58 | 59 | 60 | function Wobble({ children, out, timeout, duration = defaults.duration, delay = defaults.delay, count = defaults.count, forever, ...props } = defaults) { 61 | const effect = { make, duration: timeout === undefined ? duration : timeout, delay, forever, count, style: { animationFillMode: 'both', } }; 62 | return wrap(props, effect, false, children, true); 63 | } 64 | 65 | Wobble.propTypes = propTypes; 66 | export default Wobble; 67 | --------------------------------------------------------------------------------