react-text-swap-animation 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,22 +45,19 @@ To control the animation speed and timing, you can pass an object of `animationO
45
45
  randomReverseMax: 6000,
46
46
  loopAnimation: 20000,
47
47
  waitToStart: 5000,
48
+ transitionDuration: 2000,
49
+ timingFunction: 'ease-in-out',
48
50
  }} />
49
51
  ```
50
52
 
51
53
  If you are using an embedded font and need to wait for it to load before animating,
52
- then you should specify the `fontToObserve` object with the font family name and/or other font specifics.
54
+ then you should specify the `fontToObserve` property with the font family name.
53
55
 
54
56
  ```js
55
- <TextSwap fontToObserve={{ family: 'Open Sans' }} />
57
+ <TextSwap fontToObserve="Open Sans" />
56
58
  ```
57
59
  ```js
58
- <TextSwap fontToObserve={{
59
- family: 'Roboto',
60
- weight: 600,
61
- style: 'italic',
62
- stretch: 'expanded',
63
- }} />
60
+ <TextSwap fontToObserve="Roboto" />
64
61
  ```
65
62
 
66
63
  API
@@ -69,43 +66,25 @@ API
69
66
  ### Props
70
67
 
71
68
  | Prop | Type | Default | Description |
72
- | :----------------- | :----- | :------------------------------------------------| :------------------------------------------------------ |
69
+ | :----------------- | :----- |:-------------------------------------------------| :------------------------------------------------------ |
73
70
  | `words` | array | `['Text Swap Animation', 'Antitoxin Swamp Tea']` | An array containing exactly 2 words which are an anagram of each other. |
74
71
  | `animationOptions` | object | `AnimationOptions` | Timing options for when to start, how fast to animate forwards, backwards, and when to loop (optional). |
75
- | `fontToObserve` | object | `FontToObserve` | A description of an embedded font to observe and wait until loaded. If not specified, animation will loaded immediately (optional). |
72
+ | `fontToObserve` | string | | The name of an embedded font to wait until loaded. If not specified, animation will loaded immediately (optional). |
76
73
 
77
74
  #### AnimationOptions
78
75
 
79
- | Property | Type | Default | Description |
80
- | :----------------- | :----- | :------ | :-------------------------------------------------------------------------------------------- |
81
- | `randomStartMin` | number | `0` | The minimum amount of time to randomly wait before starting to animate each letter |
82
- | `randomStartMax` | number | `3000` | The maximum amount of time to randomly wait before starting to animate each letter |
83
- | `randomReverseMin` | number | `6000` | The minimum amount of time to randomly wait before starting to animate each letter in reverse |
84
- | `randomReverseMax` | number | `9000` | The maximum amount of time to randomly wait before starting to animate each letter in reverse |
85
- | `loopAnimation` | number | `12000` | The amount of time for each full loop of the animation |
86
- | `waitToStart` | number | `0` | The amount of time to wait before beginning the animation on start up |
87
-
88
- #### FontToObserve
89
-
90
- This object is passed along to [Font Face Observer](https://github.com/iamskok/use-font-face-observer)
91
-
92
- | Property | Type | Description |
93
- | :---------| :--------------- | :------------------------------------------------------- |
94
- | `family` | string | The font-family: `Roboto`, `Inter`, `Open Sans`, etc |
95
- | `weight` | string or number | The font-weight: `normal`, `bold`, `800`, etc |
96
- | `style` | string | The font-style: `normal`, `italic`, `oblique` |
97
- | `stretch` | string | The font stretch: `normal`, `condensed`, `expanded`, etc |
98
-
99
- Styling
100
- ----
101
-
102
- You can use the CSS transition property to adjust the speed and duration of the animation completely. Can you find a neat transition animation? Please share! :)
76
+ All time values are in # of milliseconds. The randomness allows a nice jumble effect. You can use any values you want to create some fascinating animations.
103
77
 
104
- ```css
105
- .text-swap .word .letter {
106
- transition: all, 2s, cubic-bezier(0.1, 0.7, 1.0, 0.1), 2s;
107
- }
108
- ```
78
+ | Property | Type | Default | Description |
79
+ | :------------------- | :----- | :------------ |:--------------------------------------------------------------------------------------------------------------------------------------|
80
+ | `randomStartMin` | number | `0` | The minimum amount of time to randomly wait before starting to animate each letter. |
81
+ | `randomStartMax` | number | `3000` | The maximum amount of time to randomly wait before starting to animate each letter. Should be `>= randomStartMin`. |
82
+ | `randomReverseMin` | number | `6000` | The minimum amount of time to randomly wait before starting to animate each letter in reverse. |
83
+ | `randomReverseMax` | number | `9000` | The maximum amount of time to randomly wait before starting to animate each letter in reverse. Should be `>= randomReverseMin`. |
84
+ | `loopAnimation` | number | `12000` | The amount of time to wait before starting the next full loop of the animation. Should be `>= randomReverseMax + transitionDuration`. |
85
+ | `waitToStart` | number | `0` | The amount of time to wait before beginning the animation on start up the first time. |
86
+ | `transitionDuration` | number | `1000` | How long should it take for a letter to move to its next position. Should be `<= randomReverseMin - randomStartMax`. |
87
+ | `timingFunction` | string | `ease-in-out` | What [timing function](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timing-function) should be used for the animation. |
109
88
 
110
89
  Run Locally
111
90
  ----
@@ -117,10 +96,17 @@ To run demo locally:
117
96
 
118
97
  and a browser will open to the demo.
119
98
 
99
+ If you receive `Invalid hook call` errors because you are linking this module, you may need to point this library's React to your app's installed React so there is only one copy.
100
+
101
+ ```
102
+ npm link ../my-app/node_modules/react
103
+ npm link ../my-app/node_modules/react-dom
104
+ ```
105
+
120
106
  Future Ideas
121
107
  ----
122
108
 
123
- - Supply different animation easing.
109
+ - Supply different animation easing. Done!
124
110
 
125
111
 
126
112
  License
@@ -44,7 +44,9 @@ function TextSwap(_ref) {
44
44
  randomReverseMin,
45
45
  randomReverseMax,
46
46
  loopAnimation,
47
- waitToStart
47
+ waitToStart,
48
+ transitionDuration,
49
+ timingFunction
48
50
  } = animationOptions;
49
51
  (0, _react.useEffect)(() => {
50
52
  const swaps = [];
@@ -167,13 +169,12 @@ function TextSwap(_ref) {
167
169
  setTimeout(() => {
168
170
  animateFunc();
169
171
  }, waitToStart);
170
- }, [lettersRefs1, lettersRefs2, loopAnimation, updateAnimation, randomReverseMax, randomReverseMin, randomStartMax, randomStartMin, waitToStart, words]);
172
+ }, [lettersRefs1, lettersRefs2, loopAnimation, updateAnimation, randomReverseMax, randomReverseMin, randomStartMax, randomStartMin, waitToStart, transitionDuration, timingFunction, words]);
171
173
  return /*#__PURE__*/_react.default.createElement("div", {
172
174
  className: "text-swap"
173
175
  }, /*#__PURE__*/_react.default.createElement("div", {
174
176
  className: "word word-1 hidden"
175
177
  }, [...words[0]].map((letter, i) => {
176
- // eslint-disable-next-line react/no-array-index-key
177
178
  return /*#__PURE__*/_react.default.createElement("span", {
178
179
  ref: lettersRefs1.current[i],
179
180
  className: "letter",
@@ -182,7 +183,6 @@ function TextSwap(_ref) {
182
183
  })), /*#__PURE__*/_react.default.createElement("div", {
183
184
  className: "word word-2 hidden"
184
185
  }, [...words[1]].map((letter, i) => {
185
- // eslint-disable-next-line react/no-array-index-key
186
186
  return /*#__PURE__*/_react.default.createElement("span", {
187
187
  ref: lettersRefs2.current[i],
188
188
  className: "letter",
@@ -199,17 +199,19 @@ function TextSwap(_ref) {
199
199
  src,
200
200
  dest
201
201
  } = renderedLetter;
202
- let letterStyles;
202
+ let letterStyles = {
203
+ transition: "left ".concat(transitionDuration, "ms ").concat(timingFunction, ", top ").concat(transitionDuration, "ms ").concat(timingFunction)
204
+ };
203
205
  if (playing) {
204
206
  const left = "".concat(dest.rect.x, "px");
205
- letterStyles = {
207
+ letterStyles = _objectSpread(_objectSpread({}, letterStyles), {}, {
206
208
  left
207
- };
209
+ });
208
210
  } else {
209
211
  const left = "".concat(src.rect.x, "px");
210
- letterStyles = {
212
+ letterStyles = _objectSpread(_objectSpread({}, letterStyles), {}, {
211
213
  left
212
- };
214
+ });
213
215
  }
214
216
  if (disappear) {
215
217
  letterStyles.opacity = 0;
@@ -8,22 +8,26 @@ const DEFAULT_WORDS = ['Text Swap Animation', 'Antitoxin Swamp Tea'];
8
8
 
9
9
  /**
10
10
  * @typedef AnimationOptions Timing options for when to start, how fast to animate forwards, backwards, and when to loop.
11
- * @property {number} randomStartMin The minimum amount of time to randomly wait before starting to animate each letter
12
- * @property {number} randomStartMax The maximum amount of time to randomly wait before starting to animate each letter
13
- * @property {number} randomReverseMin The minimum amount of time to randomly wait before starting to animate each letter in reverse
14
- * @property {number} randomReverseMax The maximum amount of time to randomly wait before starting to animate each letter in reverse
15
- * @property {number} loopAnimation The amount of time for each full loop of the animation
16
- * @property {number} waitToStart The amount of time to wait before beginning the animation on start up
11
+ * @property {number} randomStartMin The minimum amount of time to randomly wait before starting to animate each letter.
12
+ * @property {number} randomStartMax The maximum amount of time to randomly wait before starting to animate each letter. Should be `>= randomStartMin`.
13
+ * @property {number} randomReverseMin The minimum amount of time to randomly wait before starting to animate each letter in reverse.
14
+ * @property {number} randomReverseMax The maximum amount of time to randomly wait before starting to animate each letter in reverse. Should be `>= randomReverseMin`.
15
+ * @property {number} loopAnimation The amount of time to wait before starting the next full loop of the animation. Should be `>= randomReverseMax + transitionDuration`.
16
+ * @property {number} waitToStart The amount of time to wait before beginning the animation on start up the first time.
17
+ * @property {number} transitionDuration How long should it take for a letter to move to its next position. Should be `<= randomReverseMin - randomStartMax`.
18
+ * @property {string} timingFunction What [timing function](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timing-function) should be used for the animation.
17
19
  */
18
20
 
19
21
  /** @type AnimationOptions */
20
22
  exports.DEFAULT_WORDS = DEFAULT_WORDS;
21
23
  const DEFAULT_ANIMATION_OPTIONS = {
22
- randomStartMin: 500,
23
- randomStartMax: 500,
24
- randomReverseMin: 8000,
25
- randomReverseMax: 8000,
24
+ randomStartMin: 0,
25
+ randomStartMax: 3000,
26
+ randomReverseMin: 6000,
27
+ randomReverseMax: 9000,
26
28
  loopAnimation: 12000,
27
- waitToStart: 0
29
+ waitToStart: 0,
30
+ transitionDuration: 1000,
31
+ timingFunction: 'ease-in-out'
28
32
  };
29
33
  exports.DEFAULT_ANIMATION_OPTIONS = DEFAULT_ANIMATION_OPTIONS;
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = Loader;
7
7
  require("core-js/modules/es.symbol.description.js");
8
8
  var _react = _interopRequireDefault(require("react"));
9
- var _useFontFaceObserver = _interopRequireDefault(require("use-font-face-observer"));
9
+ var _useFonts = _interopRequireDefault(require("./useFonts"));
10
10
  var _TextSwap = _interopRequireDefault(require("./TextSwap"));
11
11
  var _constants = require("./constants");
12
12
  require("./index.css");
@@ -16,19 +16,11 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
16
16
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
17
17
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
18
18
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
19
- /**
20
- * @typedef FontToObserve A description of an embedded font to observe and wait until loaded.
21
- * @property {string} [family] The font-family: Roboto, Inter, Open Sans, etc
22
- * @property {string|number} [weight] The font-weight: normal, bold, 800, etc
23
- * @property {string} [style] The font-style: normal, italic, oblique
24
- * @property {string} [stretch] The font stretch: normal, condensed, expanded, etc
25
- */
26
-
27
19
  /**
28
20
  * Render and animate from one word to another word and back again.
29
21
  * @param {[string]} [words] The 2 words to animate between.
30
22
  * @param {AnimationOptions} [animationOptions] Timing options for when to start, how fast to animate forwards, backwards, and when to loop.
31
- * @param {FontToObserve} [fontToObserve] A description of an embedded font to observe and wait until loaded.
23
+ * @param {string} [fontToObserve] A description of an embedded font to observe and wait until loaded.
32
24
  * @returns {JSX.Element|null}
33
25
  */
34
26
  function Loader(_ref) {
@@ -37,8 +29,8 @@ function Loader(_ref) {
37
29
  animationOptions = {},
38
30
  fontToObserve
39
31
  } = _ref;
32
+ const isFontLoaded = (0, _useFonts.default)(fontToObserve);
40
33
  const animOptions = _objectSpread(_objectSpread({}, _constants.DEFAULT_ANIMATION_OPTIONS), animationOptions);
41
- const isFontLoaded = (0, _useFontFaceObserver.default)(fontToObserve ? [fontToObserve] : []);
42
34
  let word1 = words[0];
43
35
  let word2 = words[1];
44
36
  const maxLength = Math.max(word1.length, word2.length);
@@ -32,8 +32,7 @@
32
32
  .letter {
33
33
  z-index: 10;
34
34
  position: absolute;
35
- /*transition: all, 2s, cubic-bezier(0.1, 0.7, 1.0, 0.1), 2s;*/
36
- transition: all, 2s, ease-in-out, 2s;
35
+ transition: left 2s ease-in-out, top 2s ease-in-out;
37
36
  }
38
37
  }
39
38
  }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = useFonts;
7
+ require("core-js/modules/web.dom-collections.iterator.js");
8
+ require("core-js/modules/es.promise.js");
9
+ var _react = require("react");
10
+ function useFonts() {
11
+ for (var _len = arguments.length, fontNames = new Array(_len), _key = 0; _key < _len; _key++) {
12
+ fontNames[_key] = arguments[_key];
13
+ }
14
+ const [isLoaded, setIsLoaded] = (0, _react.useState)(false);
15
+ (0, _react.useEffect)(() => {
16
+ // Inspired by https://stackoverflow.com/a/60138011
17
+ if (!document || !document.fonts) {
18
+ // eslint-disable-next-line no-console
19
+ console.warn('Browser does not support document.fonts API');
20
+ setIsLoaded(true);
21
+ return;
22
+ }
23
+ Promise.all(fontNames.map(fontName => document.fonts.load("16px \"".concat(fontName, "\"")))).then(() => {
24
+ setIsLoaded(true);
25
+ });
26
+ }, [fontNames]);
27
+ return isLoaded;
28
+ }
29
+ ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-text-swap-animation",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "author": "Scott Canoni",
5
5
  "description": "A React component to use CSS animations to swap letters in 2 words. The text is animated in position after calculating initial and final positions of each letter. Words which are anagrams will animate well, but you can use any words or phrases.",
6
6
  "license": "WTFPL",
@@ -29,8 +29,7 @@
29
29
  "rearrange"
30
30
  ],
31
31
  "dependencies": {
32
- "core-js": "^3.18.3",
33
- "use-font-face-observer": "^1.1.39"
32
+ "core-js": "^3.18.3"
34
33
  },
35
34
  "peerDependencies": {
36
35
  "react": "^17.0.2 || ^18.2.0",
package/src/index.js CHANGED
@@ -9,22 +9,35 @@ ReactDOM.render(
9
9
  <h1>React Text Swap Animation</h1>
10
10
  <h2>Demo</h2>
11
11
 
12
- <TextSwap fontToObserve={{ family: 'Open Sans' }} />
12
+ <TextSwap fontToObserve="Open Sans" />
13
13
 
14
14
  <br />
15
15
  <br />
16
16
 
17
- <TextSwap fontToObserve={{ family: 'Open Sans' }} words={['a witty saying', 'proves nothing']} />
17
+ <TextSwap fontToObserve="Open Sans" words={['a witty saying', 'proves nothing']} />
18
18
 
19
19
  <br />
20
20
  <br />
21
21
 
22
- <TextSwap fontToObserve={{ family: 'Open Sans' }} words={['don\'t be sad it\'s over', 'be happy that it happened']} />
22
+ <TextSwap fontToObserve="Open Sans" words={['don\'t be sad it\'s over', 'be happy that it happened']} />
23
23
 
24
24
  <br />
25
25
  <br />
26
26
 
27
- <TextSwap fontToObserve={{ family: 'Open Sans' }} words={['debit card', 'bad credit']} />
27
+ <TextSwap fontToObserve="Open Sans" words={['debit card', 'bad credit']} />
28
+ <br />
29
+ <br />
30
+
31
+ <TextSwap fontToObserve="Open Sans" words={['debit card', 'bad credit']} animationOptions={{
32
+ randomStartMin: 0,
33
+ randomStartMax: 3000,
34
+ randomReverseMin: 12000,
35
+ randomReverseMax: 12000,
36
+ loopAnimation: 20000,
37
+ waitToStart: 0,
38
+ transitionDuration: 4000,
39
+ timingFunction: 'cubic-bezier(0.2,-2,0.8,2)'
40
+ }} />
28
41
  </div>
29
42
  </React.StrictMode>,
30
43
  document.getElementById('root'),
@@ -1,3 +1,4 @@
1
+ /* eslint-disable react/no-array-index-key */
1
2
  import React, { createRef, useCallback, useEffect, useRef, useState } from 'react';
2
3
  import { randomMinMax, uuidv4 } from '../utils';
3
4
 
@@ -33,6 +34,8 @@ export default function TextSwap({ words, animationOptions }) {
33
34
  randomReverseMax,
34
35
  loopAnimation,
35
36
  waitToStart,
37
+ transitionDuration,
38
+ timingFunction,
36
39
  } = animationOptions;
37
40
 
38
41
  useEffect(() => {
@@ -148,14 +151,13 @@ export default function TextSwap({ words, animationOptions }) {
148
151
  animateFunc();
149
152
  }, waitToStart);
150
153
 
151
- }, [lettersRefs1, lettersRefs2, loopAnimation, updateAnimation, randomReverseMax, randomReverseMin, randomStartMax, randomStartMin, waitToStart, words]);
154
+ }, [lettersRefs1, lettersRefs2, loopAnimation, updateAnimation, randomReverseMax, randomReverseMin, randomStartMax, randomStartMin, waitToStart, transitionDuration, timingFunction, words]);
152
155
 
153
156
  return (
154
157
  <div className="text-swap">
155
158
  <div className="word word-1 hidden">
156
159
  {
157
160
  [...words[0]].map((letter, i) => {
158
- // eslint-disable-next-line react/no-array-index-key
159
161
  return <span ref={lettersRefs1.current[i]} className="letter" key={`${i}${letter}`}>{letter}</span>;
160
162
  })
161
163
  }
@@ -163,7 +165,6 @@ export default function TextSwap({ words, animationOptions }) {
163
165
  <div className="word word-2 hidden">
164
166
  {
165
167
  [...words[1]].map((letter, i) => {
166
- // eslint-disable-next-line react/no-array-index-key
167
168
  return <span ref={lettersRefs2.current[i]} className="letter" key={`${i}${letter}`}>{letter}</span>;
168
169
  })
169
170
  }
@@ -173,14 +174,14 @@ export default function TextSwap({ words, animationOptions }) {
173
174
  swapAnimations.map((renderedLetter) => {
174
175
  const { id, letter, playing, disappear, src, dest } = renderedLetter;
175
176
 
176
- let letterStyles;
177
+ let letterStyles = { transition: `left ${transitionDuration}ms ${timingFunction}, top ${transitionDuration}ms ${timingFunction}` };
177
178
  if (playing) {
178
179
  const left = `${dest.rect.x}px`;
179
- letterStyles = { left };
180
+ letterStyles = { ...letterStyles, left };
180
181
  }
181
182
  else {
182
183
  const left = `${src.rect.x}px`;
183
- letterStyles = { left };
184
+ letterStyles = { ...letterStyles, left };
184
185
  }
185
186
 
186
187
  if (disappear) {
@@ -2,20 +2,24 @@ export const DEFAULT_WORDS = ['Text Swap Animation', 'Antitoxin Swamp Tea'];
2
2
 
3
3
  /**
4
4
  * @typedef AnimationOptions Timing options for when to start, how fast to animate forwards, backwards, and when to loop.
5
- * @property {number} randomStartMin The minimum amount of time to randomly wait before starting to animate each letter
6
- * @property {number} randomStartMax The maximum amount of time to randomly wait before starting to animate each letter
7
- * @property {number} randomReverseMin The minimum amount of time to randomly wait before starting to animate each letter in reverse
8
- * @property {number} randomReverseMax The maximum amount of time to randomly wait before starting to animate each letter in reverse
9
- * @property {number} loopAnimation The amount of time for each full loop of the animation
10
- * @property {number} waitToStart The amount of time to wait before beginning the animation on start up
5
+ * @property {number} randomStartMin The minimum amount of time to randomly wait before starting to animate each letter.
6
+ * @property {number} randomStartMax The maximum amount of time to randomly wait before starting to animate each letter. Should be `>= randomStartMin`.
7
+ * @property {number} randomReverseMin The minimum amount of time to randomly wait before starting to animate each letter in reverse.
8
+ * @property {number} randomReverseMax The maximum amount of time to randomly wait before starting to animate each letter in reverse. Should be `>= randomReverseMin`.
9
+ * @property {number} loopAnimation The amount of time to wait before starting the next full loop of the animation. Should be `>= randomReverseMax + transitionDuration`.
10
+ * @property {number} waitToStart The amount of time to wait before beginning the animation on start up the first time.
11
+ * @property {number} transitionDuration How long should it take for a letter to move to its next position. Should be `<= randomReverseMin - randomStartMax`.
12
+ * @property {string} timingFunction What [timing function](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timing-function) should be used for the animation.
11
13
  */
12
14
 
13
15
  /** @type AnimationOptions */
14
16
  export const DEFAULT_ANIMATION_OPTIONS = {
15
- randomStartMin: 500,
16
- randomStartMax: 500,
17
- randomReverseMin: 8000,
18
- randomReverseMax: 8000,
17
+ randomStartMin: 0,
18
+ randomStartMax: 3000,
19
+ randomReverseMin: 6000,
20
+ randomReverseMax: 9000,
19
21
  loopAnimation: 12000,
20
22
  waitToStart: 0,
23
+ transitionDuration: 1000,
24
+ timingFunction: 'ease-in-out',
21
25
  };
@@ -1,33 +1,24 @@
1
1
  import React from 'react';
2
- import useFontFaceObserver from 'use-font-face-observer';
2
+ import useFonts from './useFonts';
3
3
  import TextSwap from './TextSwap';
4
4
  import { DEFAULT_ANIMATION_OPTIONS, DEFAULT_WORDS } from './constants';
5
5
 
6
6
  import './index.css';
7
7
 
8
- /**
9
- * @typedef FontToObserve A description of an embedded font to observe and wait until loaded.
10
- * @property {string} [family] The font-family: Roboto, Inter, Open Sans, etc
11
- * @property {string|number} [weight] The font-weight: normal, bold, 800, etc
12
- * @property {string} [style] The font-style: normal, italic, oblique
13
- * @property {string} [stretch] The font stretch: normal, condensed, expanded, etc
14
- */
15
-
16
8
  /**
17
9
  * Render and animate from one word to another word and back again.
18
10
  * @param {[string]} [words] The 2 words to animate between.
19
11
  * @param {AnimationOptions} [animationOptions] Timing options for when to start, how fast to animate forwards, backwards, and when to loop.
20
- * @param {FontToObserve} [fontToObserve] A description of an embedded font to observe and wait until loaded.
12
+ * @param {string} [fontToObserve] A description of an embedded font to observe and wait until loaded.
21
13
  * @returns {JSX.Element|null}
22
14
  */
23
15
  export default function Loader({ words = DEFAULT_WORDS, animationOptions = {}, fontToObserve }) {
16
+ const isFontLoaded = useFonts(fontToObserve);
24
17
  const animOptions = {
25
18
  ...DEFAULT_ANIMATION_OPTIONS,
26
19
  ...animationOptions,
27
20
  };
28
21
 
29
- const isFontLoaded = useFontFaceObserver(fontToObserve ? [fontToObserve] : []);
30
-
31
22
  let word1 = words[0];
32
23
  let word2 = words[1];
33
24
  const maxLength = Math.max(word1.length, word2.length);
@@ -32,8 +32,7 @@
32
32
  .letter {
33
33
  z-index: 10;
34
34
  position: absolute;
35
- /*transition: all, 2s, cubic-bezier(0.1, 0.7, 1.0, 0.1), 2s;*/
36
- transition: all, 2s, ease-in-out, 2s;
35
+ transition: left 2s ease-in-out, top 2s ease-in-out;
37
36
  }
38
37
  }
39
38
  }
@@ -0,0 +1,22 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ export default function useFonts(...fontNames) {
4
+ const [isLoaded, setIsLoaded] = useState(false);
5
+
6
+ useEffect(() => {
7
+ // Inspired by https://stackoverflow.com/a/60138011
8
+ if (!document || !document.fonts) {
9
+ // eslint-disable-next-line no-console
10
+ console.warn('Browser does not support document.fonts API');
11
+ setIsLoaded(true);
12
+
13
+ return;
14
+ }
15
+
16
+ Promise.all(fontNames.map((fontName) => document.fonts.load(`16px "${fontName}"`))).then(() => {
17
+ setIsLoaded(true);
18
+ });
19
+ }, [fontNames]);
20
+
21
+ return isLoaded;
22
+ };