react-text-swap-animation 0.1.0 → 0.2.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/.eslintrc.js +42 -42
- package/.github/workflows/node.js.yml +18 -11
- package/README.md +2 -5
- package/dist/components/TextSwap.js +27 -33
- package/dist/components/constants.js +1 -1
- package/dist/components/index.css +32 -28
- package/dist/components/index.js +6 -15
- package/dist/index.js +0 -3
- package/dist/utils.js +1 -6
- package/package.json +8 -16
- package/src/index.js +9 -9
- package/src/lib/components/TextSwap.jsx +5 -5
- package/src/lib/components/index.css +32 -28
- package/src/lib/components/index.jsx +1 -1
- package/.idea/modules.xml +0 -8
- package/.idea/react-text-swap-animation.iml +0 -12
- package/.idea/vcs.xml +0 -6
- package/.idea/watcherTasks.xml +0 -4
package/.eslintrc.js
CHANGED
|
@@ -1,74 +1,74 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
extends: [
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
'react-app',
|
|
4
|
+
'react-app/jest',
|
|
5
5
|
],
|
|
6
6
|
rules: {
|
|
7
|
-
indent: [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
quotes: [0,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
indent: ['warn', 4],
|
|
8
|
+
'react/jsx-indent': ['warn', 4],
|
|
9
|
+
'react/jsx-indent-props': ['warn', 4],
|
|
10
|
+
quotes: [0, 'double', { avoidEscape: true }],
|
|
11
|
+
'quote-props': ['error', 'as-needed'],
|
|
12
|
+
'jsx-quotes': [2, 'prefer-double'],
|
|
13
|
+
'no-undef': 2,
|
|
14
|
+
'id-length': 0,
|
|
15
|
+
'max-len': 0,
|
|
16
|
+
'brace-style': [
|
|
17
17
|
1,
|
|
18
|
-
|
|
19
|
-
{ allowSingleLine: true
|
|
18
|
+
'stroustrup',
|
|
19
|
+
{ allowSingleLine: true },
|
|
20
20
|
],
|
|
21
21
|
curly: 2,
|
|
22
|
-
|
|
22
|
+
'no-use-before-define': [
|
|
23
23
|
1,
|
|
24
|
-
|
|
24
|
+
'nofunc',
|
|
25
25
|
],
|
|
26
|
-
|
|
26
|
+
'no-unused-vars': [
|
|
27
27
|
1,
|
|
28
28
|
{
|
|
29
|
-
args:
|
|
29
|
+
args: 'none',
|
|
30
30
|
ignoreRestSiblings: true,
|
|
31
31
|
},
|
|
32
32
|
],
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
'arrow-body-style': 0,
|
|
34
|
+
'no-unused-expressions': [
|
|
35
35
|
2,
|
|
36
|
-
{ allowShortCircuit: true
|
|
36
|
+
{ allowShortCircuit: true },
|
|
37
37
|
],
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
'object-curly-spacing': ['warn', 'always', { objectsInObjects: true }],
|
|
39
|
+
'object-curly-newline': ['warn', { multiline: true }],
|
|
40
|
+
'prefer-const': 'warn',
|
|
41
|
+
'no-restricted-syntax': [
|
|
42
42
|
1,
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
'WithStatement',
|
|
44
|
+
'DebuggerStatement',
|
|
45
45
|
],
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
'no-underscore-dangle': 0,
|
|
47
|
+
'react/jsx-boolean-value': 0,
|
|
48
|
+
'react/jsx-first-prop-new-line': 0,
|
|
49
|
+
'react/jsx-no-bind': 0,
|
|
50
|
+
'react/no-did-mount-set-state': 0,
|
|
51
|
+
'react/prefer-stateless-function': 0,
|
|
52
|
+
'react/jsx-one-expression-per-line': [0],
|
|
53
53
|
// Allow jsx tags inside .js files.
|
|
54
|
-
|
|
54
|
+
'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
|
|
55
55
|
// Disable props spreading (<App {...props} />) warning.
|
|
56
|
-
|
|
56
|
+
'react/jsx-props-no-spreading': 0,
|
|
57
57
|
// Throw warning instead of error when using array index as a key.
|
|
58
|
-
|
|
58
|
+
'react/no-array-index-key': 1,
|
|
59
59
|
// Allow using (props) => <Component /> and ({propName}) => <Component /> syntax.
|
|
60
|
-
|
|
60
|
+
'react/destructuring-assignment': 'off',
|
|
61
61
|
// Disable <Fragment> => <> replacement. Feel free to change
|
|
62
|
-
|
|
62
|
+
'react/jsx-fragments': 'off',
|
|
63
63
|
// Allow modules with named exports only.
|
|
64
|
-
|
|
64
|
+
'import/prefer-default-export': 0,
|
|
65
65
|
// Throw warning when <a href="#"> or <a href="javascript:void(0)"> are used. Use <button> instead.
|
|
66
|
-
|
|
66
|
+
'jsx-a11y/anchor-is-valid': ['off', { aspects: ['invalidHref'] }],
|
|
67
67
|
},
|
|
68
68
|
// DeprecationWarning: The 'ecmaFeatures' config file property is deprecated and has no effect. (found in ".eslintrc.js")
|
|
69
69
|
// ecmaFeatures: {
|
|
70
70
|
// jsx: true,
|
|
71
71
|
// modules: true,
|
|
72
72
|
// },
|
|
73
|
-
parser:
|
|
73
|
+
parser: 'babel-eslint',
|
|
74
74
|
};
|
|
@@ -20,20 +20,27 @@ jobs:
|
|
|
20
20
|
# The type of runner that the job will run on
|
|
21
21
|
runs-on: ubuntu-latest
|
|
22
22
|
|
|
23
|
+
strategy:
|
|
24
|
+
matrix:
|
|
25
|
+
node-version: [ 14.x, 16.x, 18.x ]
|
|
26
|
+
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
|
27
|
+
|
|
23
28
|
# Steps represent a sequence of tasks that will be executed as part of the job
|
|
24
29
|
steps:
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
30
|
+
- uses: actions/checkout@v3
|
|
31
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
32
|
+
uses: actions/setup-node@v3
|
|
33
|
+
with:
|
|
34
|
+
node-version: ${{ matrix.node-version }}
|
|
35
|
+
cache: 'npm'
|
|
28
36
|
# Runs a single command using the runners shell
|
|
29
37
|
- name: Run a one-line script
|
|
30
38
|
run: echo Building now...
|
|
31
39
|
|
|
32
|
-
- name:
|
|
33
|
-
run:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
run: echo DONE!
|
|
40
|
+
# - name: Install python2
|
|
41
|
+
# run: apt update && DEBIAN_FRONTEND=noninteractive apt install -y python2 make g++
|
|
42
|
+
# - name: Test python2
|
|
43
|
+
# run: python2 --version
|
|
44
|
+
# - run: npm install sass node-sass@4.14.1
|
|
45
|
+
- run: npm i
|
|
46
|
+
- run: npm run build-fresh --if-present
|
package/README.md
CHANGED
|
@@ -5,16 +5,13 @@ A React component to use CSS animations to swap letters in 2 words.
|
|
|
5
5
|
|
|
6
6
|
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.
|
|
7
7
|
|
|
8
|
-
[](https://github.com/scottcanoni/react-text-swap-animation/actions)
|
|
9
|
-
[](https://www.npmjs.com/package/react-text-swap-animation)
|
|
10
|
-
[](https://www.npmjs.com/package/react-text-swap-animation)
|
|
11
|
-
[](https://bundlephobia.com/result?p=react-text-swap-animation)
|
|
12
|
-
|
|
13
8
|
Install
|
|
14
9
|
----
|
|
15
10
|
|
|
16
11
|
`yarn add react-text-swap-animation`
|
|
12
|
+
|
|
17
13
|
or
|
|
14
|
+
|
|
18
15
|
`npm install react-text-swap-animation`
|
|
19
16
|
|
|
20
17
|
Demo
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
require("core-js/modules/es.symbol.description.js");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
7
|
exports.default = TextSwap;
|
|
7
|
-
|
|
8
8
|
require("core-js/modules/web.dom-collections.iterator.js");
|
|
9
|
-
|
|
10
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
-
|
|
12
10
|
var _utils = require("../utils");
|
|
13
|
-
|
|
14
11
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
15
|
-
|
|
16
12
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
17
|
-
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
23
|
-
|
|
13
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
14
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
15
|
+
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; }
|
|
16
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
17
|
+
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); }
|
|
24
18
|
/**
|
|
25
19
|
* Render and animate from one word to another word and back again.
|
|
26
20
|
*
|
|
@@ -59,28 +53,28 @@ function TextSwap(_ref) {
|
|
|
59
53
|
// Find a matching destination character to execute the swap with
|
|
60
54
|
let destLetterIndex = [...words[1]].findIndex((destLetter, srcIndex) => {
|
|
61
55
|
return destLetter.toLowerCase() === letter.toLowerCase() && destLettersPairedByIndex[srcIndex] !== true;
|
|
62
|
-
});
|
|
56
|
+
});
|
|
63
57
|
|
|
58
|
+
// If no matching character
|
|
64
59
|
if (destLetterIndex === -1) {
|
|
65
60
|
// Find a space to swap with
|
|
66
61
|
destLetterIndex = [...words[1]].findIndex((destLetter, srcIndex) => {
|
|
67
62
|
return destLetter === ' ' && destLettersPairedByIndex[srcIndex] !== true;
|
|
68
|
-
});
|
|
63
|
+
});
|
|
69
64
|
|
|
65
|
+
// If there was no space, find first non-used space
|
|
70
66
|
if (destLetterIndex === -1) {
|
|
71
67
|
destLetterIndex = [...words[1]].findIndex((destLetter, srcIndex) => {
|
|
72
68
|
return destLettersPairedByIndex[srcIndex] !== true;
|
|
73
69
|
});
|
|
74
70
|
}
|
|
75
71
|
}
|
|
76
|
-
|
|
77
72
|
if (destLetterIndex === -1) {
|
|
78
73
|
throw new Error("Not sure how to animate since all source letters were paired already, disappear maybe?");
|
|
79
74
|
}
|
|
80
|
-
|
|
81
75
|
destLettersPairedByIndex[destLetterIndex] = true; // mark this source paired/used
|
|
82
|
-
// If the text wraps then the offset left isn't correct.
|
|
83
76
|
|
|
77
|
+
// If the text wraps then the offset left isn't correct.
|
|
84
78
|
const swap = {
|
|
85
79
|
id: (0, _utils.uuidv4)(),
|
|
86
80
|
// for a unique key
|
|
@@ -110,7 +104,6 @@ function TextSwap(_ref) {
|
|
|
110
104
|
swaps.push(swap);
|
|
111
105
|
});
|
|
112
106
|
setAnimations(swaps);
|
|
113
|
-
|
|
114
107
|
const animateFunc = () => {
|
|
115
108
|
swaps.forEach((swap, i) => {
|
|
116
109
|
// Animate each character towards the destination
|
|
@@ -120,53 +113,57 @@ function TextSwap(_ref) {
|
|
|
120
113
|
playing: true,
|
|
121
114
|
disappear: false
|
|
122
115
|
});
|
|
123
|
-
|
|
124
116
|
if (swap.src.letter !== ' ' && swap.dest.letter === ' ') {
|
|
125
117
|
updateAnimation(i, {
|
|
126
118
|
disappear: true
|
|
127
119
|
});
|
|
128
120
|
}
|
|
129
|
-
}, forwardStartTime);
|
|
121
|
+
}, forwardStartTime);
|
|
130
122
|
|
|
123
|
+
// Halfway towards the destination, switch to the destination letter
|
|
131
124
|
setTimeout(() => {
|
|
132
|
-
if (swap.src.letter !== ' ' && swap.dest.letter === ' ') {
|
|
125
|
+
if (swap.src.letter !== ' ' && swap.dest.letter === ' ') {
|
|
126
|
+
// do nothing
|
|
133
127
|
} else {
|
|
134
128
|
updateAnimation(i, {
|
|
135
129
|
letter: swap.dest.letter
|
|
136
130
|
});
|
|
137
131
|
}
|
|
138
|
-
}, forwardStartTime + 500);
|
|
132
|
+
}, forwardStartTime + 500);
|
|
139
133
|
|
|
134
|
+
// Animate each character back to their original location
|
|
140
135
|
const reverseStartTime = (0, _utils.randomMinMax)(randomReverseMin, randomReverseMax);
|
|
141
136
|
setTimeout(() => {
|
|
142
137
|
updateAnimation(i, {
|
|
143
138
|
playing: false,
|
|
144
139
|
disappear: false
|
|
145
140
|
});
|
|
146
|
-
|
|
147
141
|
if (swap.dest.letter !== ' ' && swap.src.letter === ' ') {
|
|
148
142
|
updateAnimation(i, {
|
|
149
143
|
disappear: true
|
|
150
144
|
});
|
|
151
145
|
}
|
|
152
|
-
}, reverseStartTime);
|
|
146
|
+
}, reverseStartTime);
|
|
153
147
|
|
|
148
|
+
// Half way back to the initial location, switch to the initial letter
|
|
154
149
|
setTimeout(() => {
|
|
155
|
-
if (swap.dest.letter !== ' ' && swap.src.letter === ' ') {
|
|
150
|
+
if (swap.dest.letter !== ' ' && swap.src.letter === ' ') {
|
|
151
|
+
// do nothing
|
|
156
152
|
} else {
|
|
157
153
|
updateAnimation(i, {
|
|
158
154
|
letter: swap.src.letter
|
|
159
155
|
});
|
|
160
156
|
}
|
|
161
157
|
}, reverseStartTime + 500);
|
|
162
|
-
});
|
|
158
|
+
});
|
|
163
159
|
|
|
160
|
+
// Repeat forever
|
|
164
161
|
setTimeout(() => {
|
|
165
162
|
animateFunc();
|
|
166
163
|
}, loopAnimation);
|
|
167
|
-
};
|
|
168
|
-
|
|
164
|
+
};
|
|
169
165
|
|
|
166
|
+
// Start the process
|
|
170
167
|
setTimeout(() => {
|
|
171
168
|
animateFunc();
|
|
172
169
|
}, waitToStart);
|
|
@@ -193,7 +190,7 @@ function TextSwap(_ref) {
|
|
|
193
190
|
}, letter);
|
|
194
191
|
})), /*#__PURE__*/_react.default.createElement("div", {
|
|
195
192
|
className: "word word-animation"
|
|
196
|
-
}, swapAnimations.map(
|
|
193
|
+
}, swapAnimations.map(renderedLetter => {
|
|
197
194
|
const {
|
|
198
195
|
id,
|
|
199
196
|
letter,
|
|
@@ -202,8 +199,7 @@ function TextSwap(_ref) {
|
|
|
202
199
|
src,
|
|
203
200
|
dest
|
|
204
201
|
} = renderedLetter;
|
|
205
|
-
let letterStyles
|
|
206
|
-
|
|
202
|
+
let letterStyles;
|
|
207
203
|
if (playing) {
|
|
208
204
|
const left = "".concat(dest.rect.x, "px");
|
|
209
205
|
letterStyles = {
|
|
@@ -215,11 +211,9 @@ function TextSwap(_ref) {
|
|
|
215
211
|
left
|
|
216
212
|
};
|
|
217
213
|
}
|
|
218
|
-
|
|
219
214
|
if (disappear) {
|
|
220
215
|
letterStyles.opacity = 0;
|
|
221
216
|
}
|
|
222
|
-
|
|
223
217
|
return /*#__PURE__*/_react.default.createElement("span", {
|
|
224
218
|
key: id,
|
|
225
219
|
className: "letter",
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.DEFAULT_WORDS = exports.DEFAULT_ANIMATION_OPTIONS = void 0;
|
|
7
7
|
const DEFAULT_WORDS = ['Text Swap Animation', 'Antitoxin Swamp Tea'];
|
|
8
|
+
|
|
8
9
|
/**
|
|
9
10
|
* @typedef AnimationOptions Timing options for when to start, how fast to animate forwards, backwards, and when to loop.
|
|
10
11
|
* @property {number} randomStartMin The minimum amount of time to randomly wait before starting to animate each letter
|
|
@@ -16,7 +17,6 @@ const DEFAULT_WORDS = ['Text Swap Animation', 'Antitoxin Swamp Tea'];
|
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
19
|
/** @type AnimationOptions */
|
|
19
|
-
|
|
20
20
|
exports.DEFAULT_WORDS = DEFAULT_WORDS;
|
|
21
21
|
const DEFAULT_ANIMATION_OPTIONS = {
|
|
22
22
|
randomStartMin: 500,
|
|
@@ -1,28 +1,32 @@
|
|
|
1
|
-
.text-swap {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
z-index: 10;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
1
|
+
.text-swap {
|
|
2
|
+
color: #fff;
|
|
3
|
+
flex: 0 0 auto;
|
|
4
|
+
align-self: center;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
margin: 0 auto;
|
|
8
|
+
text-align: left;
|
|
9
|
+
text-transform: uppercase;
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
padding: 0;
|
|
13
|
+
position: relative; }
|
|
14
|
+
|
|
15
|
+
.text-swap .word {
|
|
16
|
+
position: relative; }
|
|
17
|
+
|
|
18
|
+
.text-swap .word.hidden {
|
|
19
|
+
position: absolute;
|
|
20
|
+
visibility: hidden;
|
|
21
|
+
z-index: -9000; }
|
|
22
|
+
|
|
23
|
+
.text-swap .word .letter {
|
|
24
|
+
white-space: pre;
|
|
25
|
+
z-index: 10;
|
|
26
|
+
display: inline-block; }
|
|
27
|
+
|
|
28
|
+
.text-swap .word-animation .letter {
|
|
29
|
+
z-index: 10;
|
|
30
|
+
position: absolute;
|
|
31
|
+
/*transition: all, 2s, cubic-bezier(0.1, 0.7, 1.0, 0.1), 2s;*/
|
|
32
|
+
transition: all, 2s, ease-in-out, 2s; }
|
package/dist/components/index.js
CHANGED
|
@@ -4,25 +4,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = Loader;
|
|
7
|
-
|
|
7
|
+
require("core-js/modules/es.symbol.description.js");
|
|
8
8
|
var _react = _interopRequireDefault(require("react"));
|
|
9
|
-
|
|
10
9
|
var _useFontFaceObserver = _interopRequireDefault(require("use-font-face-observer"));
|
|
11
|
-
|
|
12
10
|
var _TextSwap = _interopRequireDefault(require("./TextSwap"));
|
|
13
|
-
|
|
14
11
|
var _constants = require("./constants");
|
|
15
|
-
|
|
16
12
|
require("./index.css");
|
|
17
|
-
|
|
18
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
-
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
25
|
-
|
|
14
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
15
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
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
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
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); }
|
|
26
19
|
/**
|
|
27
20
|
* @typedef FontToObserve A description of an embedded font to observe and wait until loaded.
|
|
28
21
|
* @property {string} [family] The font-family: Roboto, Inter, Open Sans, etc
|
|
@@ -44,9 +37,7 @@ function Loader(_ref) {
|
|
|
44
37
|
animationOptions = {},
|
|
45
38
|
fontToObserve
|
|
46
39
|
} = _ref;
|
|
47
|
-
|
|
48
40
|
const animOptions = _objectSpread(_objectSpread({}, _constants.DEFAULT_ANIMATION_OPTIONS), animationOptions);
|
|
49
|
-
|
|
50
41
|
const isFontLoaded = (0, _useFontFaceObserver.default)(fontToObserve ? [fontToObserve] : []);
|
|
51
42
|
let word1 = words[0];
|
|
52
43
|
let word2 = words[1];
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _index = _interopRequireDefault(require("./components/index"));
|
|
9
|
-
|
|
10
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
9
|
var _default = _index.default;
|
|
13
10
|
exports.default = _default;
|
package/dist/utils.js
CHANGED
|
@@ -5,13 +5,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.randomMinMax = randomMinMax;
|
|
7
7
|
exports.uuidv4 = uuidv4;
|
|
8
|
-
|
|
9
8
|
require("core-js/modules/es.regexp.exec.js");
|
|
10
|
-
|
|
11
9
|
require("core-js/modules/es.string.replace.js");
|
|
12
|
-
|
|
13
10
|
require("core-js/modules/es.regexp.to-string.js");
|
|
14
|
-
|
|
15
11
|
/**
|
|
16
12
|
* Get a random number between `min` and `max`
|
|
17
13
|
* @param {number} min The minimum number you want to include in the random output
|
|
@@ -23,11 +19,10 @@ function randomMinMax() {
|
|
|
23
19
|
let max = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100;
|
|
24
20
|
return Math.floor(Math.random() * (max - min)) + min;
|
|
25
21
|
}
|
|
26
|
-
|
|
27
22
|
function uuidv4() {
|
|
28
23
|
return 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
29
24
|
const r = Math.random() * 16 | 0,
|
|
30
|
-
|
|
25
|
+
v = c === 'x' ? r : r & 0x3 | 0x8;
|
|
31
26
|
return v.toString(16);
|
|
32
27
|
});
|
|
33
28
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-text-swap-animation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.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",
|
|
@@ -10,14 +10,10 @@
|
|
|
10
10
|
"analyze": "source-map-explorer 'build/static/js/*.js'",
|
|
11
11
|
"start-js": "react-scripts start",
|
|
12
12
|
"start": "npm-run-all -p watch-css start-js",
|
|
13
|
-
"start-old": "react-scripts start",
|
|
14
|
-
"build-old": "react-scripts build",
|
|
15
|
-
"build-rm": "rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files",
|
|
16
13
|
"build": "del /Q dist\\* && NODE_ENV=production babel src/lib --out-dir dist --copy-files",
|
|
17
|
-
"build-
|
|
18
|
-
"build-css": "
|
|
19
|
-
"watch-css": "
|
|
20
|
-
"test": "react-scripts test",
|
|
14
|
+
"build-fresh": "NODE_ENV=production babel src/lib --out-dir dist --copy-files",
|
|
15
|
+
"build-css": "sass src/:src/",
|
|
16
|
+
"watch-css": "sass --watch src/:src/",
|
|
21
17
|
"eject": "react-scripts eject"
|
|
22
18
|
},
|
|
23
19
|
"repository": {
|
|
@@ -37,24 +33,20 @@
|
|
|
37
33
|
"use-font-face-observer": "^1.1.39"
|
|
38
34
|
},
|
|
39
35
|
"peerDependencies": {
|
|
40
|
-
"core-js": "^3.18.3",
|
|
41
36
|
"react": "^17.0.2",
|
|
42
37
|
"react-dom": "^17.0.2"
|
|
43
38
|
},
|
|
44
39
|
"devDependencies": {
|
|
45
|
-
"@babel/cli": "^7.
|
|
46
|
-
"@babel/core": "^7.
|
|
40
|
+
"@babel/cli": "^7.20.7",
|
|
41
|
+
"@babel/core": "^7.20.12",
|
|
47
42
|
"@babel/polyfill": "^7.12.1",
|
|
48
43
|
"@babel/preset-env": "^7.15.6",
|
|
49
44
|
"@babel/preset-react": "^7.14.5",
|
|
50
|
-
"@testing-library/jest-dom": "^5.11.4",
|
|
51
|
-
"@testing-library/react": "^11.1.0",
|
|
52
|
-
"@testing-library/user-event": "^12.1.10",
|
|
53
|
-
"node-sass-chokidar": "^1.5.0",
|
|
54
45
|
"npm-run-all": "^4.1.5",
|
|
55
46
|
"react": "^17.0.2",
|
|
56
47
|
"react-dom": "^17.0.2",
|
|
57
|
-
"react-scripts": "4.0.3"
|
|
48
|
+
"react-scripts": "4.0.3",
|
|
49
|
+
"sass": "^1.57.1"
|
|
58
50
|
},
|
|
59
51
|
"eslintConfig": {
|
|
60
52
|
"extends": "react-app"
|
package/src/index.js
CHANGED
|
@@ -11,20 +11,20 @@ ReactDOM.render(
|
|
|
11
11
|
|
|
12
12
|
<TextSwap fontToObserve={{ family: 'Open Sans' }} />
|
|
13
13
|
|
|
14
|
-
<br/>
|
|
15
|
-
<br/>
|
|
14
|
+
<br />
|
|
15
|
+
<br />
|
|
16
16
|
|
|
17
|
-
<TextSwap fontToObserve={{ family: 'Open Sans' }} words={[
|
|
17
|
+
<TextSwap fontToObserve={{ family: 'Open Sans' }} words={['a witty saying', 'proves nothing']} />
|
|
18
18
|
|
|
19
|
-
<br/>
|
|
20
|
-
<br/>
|
|
19
|
+
<br />
|
|
20
|
+
<br />
|
|
21
21
|
|
|
22
|
-
<TextSwap fontToObserve={{ family: 'Open Sans' }} words={[
|
|
22
|
+
<TextSwap fontToObserve={{ family: 'Open Sans' }} words={['don\'t be sad it\'s over', 'be happy that it happened']} />
|
|
23
23
|
|
|
24
|
-
<br/>
|
|
25
|
-
<br/>
|
|
24
|
+
<br />
|
|
25
|
+
<br />
|
|
26
26
|
|
|
27
|
-
<TextSwap fontToObserve={{ family: 'Open Sans' }} words={[
|
|
27
|
+
<TextSwap fontToObserve={{ family: 'Open Sans' }} words={['debit card', 'bad credit']} />
|
|
28
28
|
</div>
|
|
29
29
|
</React.StrictMode>,
|
|
30
30
|
document.getElementById('root'),
|
|
@@ -20,7 +20,7 @@ export default function TextSwap({ words, animationOptions }) {
|
|
|
20
20
|
newState[i] = {
|
|
21
21
|
...prevState[i],
|
|
22
22
|
...update,
|
|
23
|
-
}
|
|
23
|
+
};
|
|
24
24
|
|
|
25
25
|
return newState;
|
|
26
26
|
});
|
|
@@ -43,7 +43,7 @@ export default function TextSwap({ words, animationOptions }) {
|
|
|
43
43
|
// Find a matching destination character to execute the swap with
|
|
44
44
|
let destLetterIndex = [...words[1]].findIndex((destLetter, srcIndex) => {
|
|
45
45
|
return destLetter.toLowerCase() === letter.toLowerCase()
|
|
46
|
-
|
|
46
|
+
&& destLettersPairedByIndex[srcIndex] !== true;
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
// If no matching character
|
|
@@ -106,7 +106,7 @@ export default function TextSwap({ words, animationOptions }) {
|
|
|
106
106
|
}
|
|
107
107
|
}, forwardStartTime);
|
|
108
108
|
|
|
109
|
-
//
|
|
109
|
+
// Halfway towards the destination, switch to the destination letter
|
|
110
110
|
setTimeout(() => {
|
|
111
111
|
if (swap.src.letter !== ' ' && swap.dest.letter === ' ') {
|
|
112
112
|
// do nothing
|
|
@@ -170,10 +170,10 @@ export default function TextSwap({ words, animationOptions }) {
|
|
|
170
170
|
</div>
|
|
171
171
|
<div className="word word-animation">
|
|
172
172
|
{
|
|
173
|
-
swapAnimations.map((renderedLetter
|
|
173
|
+
swapAnimations.map((renderedLetter) => {
|
|
174
174
|
const { id, letter, playing, disappear, src, dest } = renderedLetter;
|
|
175
175
|
|
|
176
|
-
let letterStyles
|
|
176
|
+
let letterStyles;
|
|
177
177
|
if (playing) {
|
|
178
178
|
const left = `${dest.rect.x}px`;
|
|
179
179
|
letterStyles = { left };
|
|
@@ -1,28 +1,32 @@
|
|
|
1
|
-
.text-swap {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
z-index: 10;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
1
|
+
.text-swap {
|
|
2
|
+
color: #fff;
|
|
3
|
+
flex: 0 0 auto;
|
|
4
|
+
align-self: center;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
margin: 0 auto;
|
|
8
|
+
text-align: left;
|
|
9
|
+
text-transform: uppercase;
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
padding: 0;
|
|
13
|
+
position: relative; }
|
|
14
|
+
|
|
15
|
+
.text-swap .word {
|
|
16
|
+
position: relative; }
|
|
17
|
+
|
|
18
|
+
.text-swap .word.hidden {
|
|
19
|
+
position: absolute;
|
|
20
|
+
visibility: hidden;
|
|
21
|
+
z-index: -9000; }
|
|
22
|
+
|
|
23
|
+
.text-swap .word .letter {
|
|
24
|
+
white-space: pre;
|
|
25
|
+
z-index: 10;
|
|
26
|
+
display: inline-block; }
|
|
27
|
+
|
|
28
|
+
.text-swap .word-animation .letter {
|
|
29
|
+
z-index: 10;
|
|
30
|
+
position: absolute;
|
|
31
|
+
/*transition: all, 2s, cubic-bezier(0.1, 0.7, 1.0, 0.1), 2s;*/
|
|
32
|
+
transition: all, 2s, ease-in-out, 2s; }
|
|
@@ -20,7 +20,7 @@ import './index.css';
|
|
|
20
20
|
* @param {FontToObserve} [fontToObserve] A description of an embedded font to observe and wait until loaded.
|
|
21
21
|
* @returns {JSX.Element|null}
|
|
22
22
|
*/
|
|
23
|
-
export default function Loader
|
|
23
|
+
export default function Loader({ words = DEFAULT_WORDS, animationOptions = {}, fontToObserve }) {
|
|
24
24
|
const animOptions = {
|
|
25
25
|
...DEFAULT_ANIMATION_OPTIONS,
|
|
26
26
|
...animationOptions,
|
package/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/.idea/react-text-swap-animation.iml" filepath="$PROJECT_DIR$/.idea/react-text-swap-animation.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<module type="WEB_MODULE" version="4">
|
|
3
|
-
<component name="NewModuleRootManager">
|
|
4
|
-
<content url="file://$MODULE_DIR$">
|
|
5
|
-
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
6
|
-
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
7
|
-
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
8
|
-
</content>
|
|
9
|
-
<orderEntry type="inheritedJdk" />
|
|
10
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
|
11
|
-
</component>
|
|
12
|
-
</module>
|
package/.idea/vcs.xml
DELETED
package/.idea/watcherTasks.xml
DELETED