Permalink
Browse files

streamlining props

  • Loading branch information...
rnosov committed Oct 4, 2017
1 parent c3aa564 commit c3285e2f3882775012611610341964c7fa4c5fed
Showing with 54 additions and 59 deletions.
  1. +19 −26 README.md
  2. +1 −1 __tests__/__snapshots__/Reveal.test.js.snap
  3. +1 −1 package.json
  4. +33 −31 src/Reveal.js
View
@@ -26,7 +26,7 @@ yarn add react-reveal
### Quick Start
Import effects from [React Reveal](https://www.npmjs.com/package/react-reveal) in to your project.
Import effects from [React Reveal](https://www.npmjs.com/package/react-reveal) to your project.
```javascript
import { Fade, Flip, Rotate, Zoom } from 'react-reveal';
@@ -114,11 +114,20 @@ If several of Reveal effects are likely to happen simultaneously you might want
<Zoom delay={500} duration={3000}>
<p>Markup that will be revealed first</p>
</Zoom>
<Zoom delay={4000} duration={200}>
<Zoom delay={4000}>
<p>Markup that will be revealed a bit later</p>
</Zoom>
```
### Web Analytics
`react-reveal` can be used to generate events for web analytics tools (like Google analytics) in order to get fine grained reports. For example, you can log exactly whether a particular markup was seen by user:
```jsx
<Fade onReveal={ () => analyticsFunc('element revealed') }>
<p>Markup that will be revealed</p>
</Fade>
```
### Unwanted Scrollbars
@@ -180,42 +189,26 @@ If you already have animations effects in your CSS then just set effect property
```
### Reveal Properties
### Reveal Props
- `effect` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** or **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/object)** This prop could be either an object describing a desired reveal effect or a string containing CSS animation class (for example "animated fadeInUp" from animate.css). If you don't specify it a default fade in effect will apply. **Optional**.
- `duration` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Duration of the reveal animation in milliseconds. Ignored for effects based on CSS animation classes. Defaults to `1000` milliseconds. **Optional**.
- `delay` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Delay before the start of reveal animation in milliseconds. Can be handy if several reveals are happening at approximately same time and you want to space them out a bit. Defaults to `66` seconds ( small delay is used to throttle reveal events). Anything higher than that should be generally okay. **Optional**.
- `easing` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Easing function. Read more about [here](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-function). Defaults to `ease`. **Optional**.
- `wave` **[bool](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** or **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Can be used to create wave like animation effects. Makes sense if you're trying to Reveal a some kind of list and don't want reveal all items at once. If you set it to a number then this number will be a delay in milliseconds between each reveal. If you set to true then the delay will `200` milliseconds. Off by default. **Optional**.
- `tag` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** HTML tag which is used for Reveal container. Defaults to `div`. **Optional**.
- `className` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** CSS class name. **Optional**.
- `style` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/object)** Style Object. **Optional**.
- `fraction` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Fraction of the revealed element height that must be visible in order for reveal animation to trigger. Should be some value between 0 to 1. Defaults to `0.2` meaning that at least 20% of the element must be visible before the reveal. **Optional**.
- `ssr` **[bool](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Use this option to suppress flickering during server side rendering. Off by default. **Optional**.
- `onReveal` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)** Function called once the element is revealed. **Optional**.
- `easing` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Easing function. Read more about [here](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-function). Defaults to `ease`. **Optional**.
- `preventReveal` **[bool](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** If true then reveal will be suppressed even if element is in view. It is useful for building animation sequences. Off by default. **Optional**.
- `onReveal` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)** Function called once the element is revealed. **Optional**.
These props will work with both `<Reveal />` component and effect aliases ( `<Zoom />`, `<Rotate />`, etc ) as well.
These props will work with both `<Reveal />` component and effect aliases ( `<Fade />`, `<Rotate />`, etc ) as well.
### Children
You should pass at least one child to this component. If you don't do it then lorem ipsum placeholder text will be generated.
### Other Props
All props that do not belong to `Reveal` class will be passed down to a `div` tag (including `className` and `style`). For example:
```jsx
<div className="some-class">
<p>Markup that will be revealed on scroll</p>
</div>
```
Change `div` to `Reveal` and add a desired effect.
All other other props will be passed down
```jsx
<Reveal className="some-class">
<p>Markup that will be revealed on scroll</p>
</Reveal>
```
You should pass at least one child to this component. **Required**.
### Universal Rendering
@@ -1 +1 @@
exports[`Reveal renders a initial view 1`] = `"<div style=\"opacity: 0;\"><div>Test test</div></div>"`;
exports[`Reveal renders a initial view 1`] = `"<div style=\"visibility: hidden; opacity: 0;\"><div>Test test</div></div>"`;
View
@@ -1,6 +1,6 @@
{
"name": "react-reveal",
"version": "0.4.2",
"version": "0.5.0",
"author": "Roman Nosov <rnosov@gmail.com>",
"description": "Really simple way to add reveal on scroll animation to your React app.",
"license": "MIT",
View
@@ -7,28 +7,32 @@
* LICENSE.txt file in the root directory of this source tree.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { string, object, number, oneOfType, bool, func, node } from 'prop-types';
const
propTypes = {
effect: PropTypes.oneOfType([ PropTypes.string, PropTypes.object ]),
duration: PropTypes.number,
delay: PropTypes.number,
easing: PropTypes.string,
wave: PropTypes.oneOfType([ PropTypes.bool, PropTypes.number ]),
tag: PropTypes.string,
className: PropTypes.string,
style: PropTypes.object,
ssr: PropTypes.bool,
fraction: PropTypes.number,
onReveal: PropTypes.func,
effect: oneOfType([ string, object ]),
duration: number,
delay: number,
easing: string,
wave: oneOfType([ bool, number ]),
tag: string,
className: string,
style: object,
preventReveal: bool,
passProps: bool,
ssr: bool,
fraction: number,
onReveal: func,
children: node.isRequired,
},
defaultProps = {
duration: 1000,
easing: 'ease',
delay: 66,
fraction: 0.2,
tag: 'div',
passProps: true
};
class Reveal extends React.Component {
@@ -46,6 +50,7 @@ class Reveal extends React.Component {
handleReveal = () => {
this.revealTimeout = void 0;
if (this.props.preventReveal) return;
if (window.pageYOffset + window.innerHeight - this.refs.el.offsetHeight*this.props.fraction > Reveal.getTop(this.refs.el)) {
this.setState({ isHidden: false });
this.componentWillUnmount();
@@ -65,6 +70,11 @@ class Reveal extends React.Component {
window.removeEventListener('resize', this.revealThrottler, false);
}
componentWillReceiveProps(next) {
if (!next.preventReveal && next.preventReveal !== this.props.preventReveal)
this.revealThrottler();
}
componentDidMount() {
if (this.props.ssr)
if (window.pageYOffset + window.innerHeight > Reveal.getTop(this.refs.el))
@@ -78,16 +88,9 @@ class Reveal extends React.Component {
window.addEventListener('resize', this.revealThrottler, false);
}
static lorem() {
let lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ';
for (let i=0; i<4; i++)
lorem += lorem;
return <p>{lorem}</p>;
}
render() {
const { transition, tag, children, wave, duration, delay, easing, effect, style,
className, ssr, onReveal, fraction, ...props } = this.props;
preventReveal, passProps, className, ssr, onReveal, fraction, ...props } = this.props;
let TagName = tag, newStyle = {}, cls = className, isInline = !(typeof effect === 'string' || effect instanceof String);
if (this.state.isHidden)
newStyle = { visibility: 'hidden', opacity: 0, ...( isInline ? effect : {} ) };
@@ -99,19 +102,18 @@ class Reveal extends React.Component {
cls = className ? className + ' ' + this.props.effect : this.props.effect;
}
if (wave && isInline) {
let delaySum = 0, waveDelay = typeof wave === 'boolean' ? 200 : wave;
let delaySum = 0, waveDelay = typeof wave === 'boolean' ? 200 : wave;
return (
<TagName { ...props } style={style} className={className} ref="el">
<TagName {...( passProps ? props : {} )} style={style} className={className} ref="el">
{React.Children.map(children, child => {
if (newStyle.transition)
newStyle.transition = `all ${duration}ms ${easing} ${delaySum += waveDelay}ms`;
return React.cloneElement( child, {style: {...child.props.style, ...newStyle} });
}
)}
})}
</TagName>
);
}
else return <TagName { ...props } children={ children || Reveal.lorem() } style={{ ...style, ...newStyle }} className={cls} ref="el" />;
else return <TagName {...( passProps ? props : {} )} children={children} style={{ ...style, ...newStyle }} className={cls} ref="el" />;
}
}
@@ -121,17 +123,17 @@ Reveal.defaultProps = defaultProps;
export default Reveal;
export let
Fade = ({ left, right, up, down, big, ...props }) => {
const dist = big?'2000px':'100%';
return <Reveal {...props} effect={{ transform: `translate3d(${left?`-${dist}`:(right?dist:'0')}, ${down?`-${dist}`:(up?dist:'0')}, 0)` }} />;
const dist = big ? '2000px' : '100%';
return <Reveal passProps={false} {...props} effect={{ transform: `translate3d(${left?`-${dist}`:(right?dist:'0')}, ${down?`-${dist}`:(up?dist:'0')}, 0)` }} />;
},
Flip = ({ x, y, ...props }) => <Reveal {...props} effect={{ transform: `perspective(400px) rotate3d(${x?'1':'0'}, ${x?'0':'1'}, 0, ${x||y?'90deg':'-360deg'})` }} />,
Flip = ({ x, y, ...props }) => <Reveal passProps={false} {...props} effect={{ transform: `perspective(400px) rotate3d(${x?'1':'0'}, ${x?'0':'1'}, 0, ${x||y?'90deg':'-360deg'})` }} />,
Rotate = ({ left, right, up, down, ...props }) => {
let angle = '-200deg', origin = 'center';
if ( down && left ) angle = '-45deg';
if ( (down && right) || (up && left) ) angle = '45deg';
if ( up && right ) angle = '-90deg';
if ( left || right ) origin=(left?'left':'right')+' bottom';
return <Reveal {...props} effect={{ transform: `rotate3d(0, 0, 1, ${angle})`, transformOrigin: origin }} />
if ( left || right ) origin=( left ? 'left' : 'right' ) + ' bottom';
return <Reveal passProps={false} {...props} effect={{ transform: `rotate3d(0, 0, 1, ${angle})`, transformOrigin: origin }} />
},
Zoom = props => <Reveal {...props} effect={{ transform: 'scale3d(.3, .3, .3)' }} />
Zoom = props => <Reveal passProps={false} {...props} effect={{ transform: 'scale3d(.3, .3, .3)' }} />
;

0 comments on commit c3285e2

Please sign in to comment.