30 | );
31 | }
32 | }
33 |
34 | TestWrapper.propTypes = {
35 | children: PropTypes.element,
36 | };
37 |
38 | export default TestWrapper;
39 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./ReactRevealText').default;
2 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | export const getRandoms = (length, threshold) => {
2 | const tooClose = (a, b) => Math.abs(a - b) < threshold;
3 |
4 | const result = [];
5 | let random;
6 |
7 | for (let i = 0; i < length; i += 1) {
8 | random = Math.random();
9 | if (i !== 0) {
10 | const prev = result[i - 1];
11 | while (tooClose(random, prev)) {
12 | random = Math.random();
13 | }
14 | }
15 | result.push(random);
16 | }
17 | return result;
18 | };
19 |
20 | export const randomToDelay = (random, min, max) => {
21 | const float = random * (max - min);
22 | return parseInt(float, 10) + min;
23 | };
24 |
--------------------------------------------------------------------------------
/stories/demo.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/no-unused-state */
2 | import React from 'react';
3 | import { storiesOf } from '@storybook/react';
4 | import { withInfo } from '@storybook/addon-info';
5 |
6 | import TestWrapper from '../src/TestWrapper';
7 | import ReactRevealText from '../src/index';
8 |
9 | export default () =>
10 | storiesOf('Demo', module)
11 | .add('Revealing Text', withInfo({
12 | propTables: false,
13 | inline: true,
14 | source: false,
15 | text: `
16 | A simple component for revealing text in a gradual way.
17 |
18 | Each letter gets a transition applied to it with a random distribution of delays so that they come into (and out of) view sporadically.
19 |
20 | This controlled component is great for landing pages and anywhere you need to show some kind of transition.
21 |
22 | Inspired by Adam Schwartz's [Magic of CSS](http://adamschwartz.co/magic-of-css/chapters/6-transitions/).
23 | `,
24 | })(() => {
25 | class Wrapper extends React.Component {
26 | constructor() {
27 | super();
28 | this.state = { show: false };
29 | }
30 |
31 | componentDidMount() {
32 | setTimeout(() => {
33 | this.setState({ show: true });
34 | }, 2000);
35 | }
36 |
37 | render() {
38 | const bgStyles = {
39 | background: 'linear-gradient(135deg, #723362, #9d223c)',
40 | padding: '36px',
41 | paddingTop: '48px',
42 | };
43 | const textStyles = {
44 | color: 'white',
45 | fontSize: '24px',
46 | lineHeight: '36px',
47 | fontFamily: 'sans-serif',
48 | textAlign: 'center',
49 | letterSpacing: '1em',
50 | paddingLeft: '1em', // to compensate for letter spacing
51 | };
52 | return (
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | );
61 | }
62 | }
63 |
64 | return (
65 |
66 | );
67 | }));
68 |
--------------------------------------------------------------------------------
/stories/documentation.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { storiesOf } from '@storybook/react';
3 | import { withInfo } from '@storybook/addon-info';
4 | import { withKnobs, text, boolean, object, number, select } from '@storybook/addon-knobs';
5 |
6 | import { setOptions } from '@storybook/addon-options';
7 |
8 | import TestWrapper from '../src/TestWrapper';
9 | import ReactRevealText from '../src/index';
10 |
11 | export default () =>
12 | storiesOf('Documentation', module)
13 | .addDecorator(withKnobs)
14 | .add('Basic Properties', withInfo({
15 | propTables: false,
16 | inline: true,
17 | text: `
18 | This component has many props that you can manipulate. Please see below and use the knobs panel on the right to experiment.
19 |
20 | Note that the component only re-renders when the \`show\` property has been changed.
21 |
22 | # Basic Properties
23 |
24 | **text** *(string)*
25 | You can set the text either by passing in text as children or by using the text property.
26 |
27 | **show** *(boolean)*
28 | This prop allows you to control what state the component is in. It allows you to hide or reveal the text.
29 |
30 | **className** *(string)*
31 | This prop allows you to set the className for the div surrounding the text.
32 |
33 | **style** *(object)*
34 | This prop allows you to pass in styles for the div surrounding the text.
35 | `,
36 | })(() => {
37 | setOptions({ showDownPanel: true });
38 | return (
39 |
53 | );
54 | }))
55 | .add('Transition Properties', withInfo({
56 | propTables: false,
57 | inline: true,
58 | text: `
59 | Each letter has its own randomly generated delay before its transition begins.
60 |
61 | # Transition Properties
62 |
63 | **transitionTime** *(integer)* [default: 1300]
64 | The time it takes for each letter's transition.
65 |
66 | **timingFunction** *(string)* [default: 'linear']
67 | The CSS transition-timing-function property. On this page, you are given a dropdown selection, but in practice (and in the sandbox), you can enter in any valid string.
68 |
69 | **delayMin** *(integer)* [default: 200]
70 | The minimum allowable delay before the transition for a letter is to begin.
71 |
72 | **delayMax** *(integer)* [default: 1200]
73 | The maximum allowable delay before the transition for a letter is to begin.
74 |
75 | **threshold** *(float)* [default: 0.2]
76 | The difference between the random numbers generated for each letter compared to the previous letter.
77 | Setting this higher will force the delays to be very different between each letter, spreading out the effect.
78 | Setting this lower will allow delays to be similar between letters, sometimes creating a chunking effect.
79 | `,
80 | })(() => {
81 | setOptions({ showDownPanel: true });
82 | const timingFnOptions = {
83 | linear: 'linear',
84 | ease: 'ease',
85 | 'ease-in': 'ease-in',
86 | 'ease-out': 'ease-out',
87 | 'ease-in-out': 'ease-in-out',
88 | 'step-start': 'step-end',
89 | };
90 | const thresholdOptions = {
91 | range: true,
92 | min: 0,
93 | max: 0.5,
94 | step: 0.1,
95 | };
96 | return (
97 |
98 |
105 | AMAZING TEXT!
106 |
107 |
108 | );
109 | }))
110 | .add('Sandbox', withInfo({
111 | propTables: false,
112 | inline: true,
113 | text: `
114 | This page has all the properties for you to play with.
115 |
116 | Note that you can input \`timingFunction\` as a string on the knobs tab.
117 | `,
118 | })(() => {
119 | setOptions({ showDownPanel: true });
120 | const thresholdOptions = {
121 | range: true,
122 | min: 0,
123 | max: 0.5,
124 | step: 0.1,
125 | };
126 | return (
127 |
128 |
147 |
148 | );
149 | }));
150 |
--------------------------------------------------------------------------------
/stories/examples.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { storiesOf } from '@storybook/react';
3 | import { withInfo } from '@storybook/addon-info';
4 |
5 | import ReactRevealText from '../src/index';
6 |
7 | export default () =>
8 | storiesOf('Examples', module)
9 | .add('1. Show on load', withInfo({
10 | propTables: false,
11 | inline: true,
12 | source: false,
13 | text: `
14 | Here is an example that will reveal the text once the component has been mounted.
15 |
16 | # Source
17 |
18 | ~~~jsx
19 | class Wrapper extends React.Component {
20 |
21 | constructor() {
22 | super();
23 | this.state = { show: false };
24 | }
25 |
26 | componentDidMount() {
27 | setTimeout(() => {
28 | this.setState({ show: true });
29 | }, 2000);
30 | }
31 |
32 | render() {
33 | return (
34 |