ink-text-animation
Version:
A text animation component for Ink
110 lines (83 loc) • 2.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ink = require('ink');
var _chalkAnimation = require('chalk-animation');
var _chalkAnimation2 = _interopRequireDefault(_chalkAnimation);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const delays = {
rainbow: 15,
pulse: 16,
glitch: 55,
radar: 50,
neon: 500
};
class TextAnimation extends _ink.Component {
constructor(props, context) {
super(props, context);
this.timeout = null;
this.animation = _chalkAnimation2.default[props.name]('').stop();
this.state = {
frame: ''
};
}
componentDidMount() {
this.start();
}
componentWillReceiveProps(nextProps) {
const { name } = nextProps;
if (name !== this.props.name) {
this.animation = _chalkAnimation2.default[name]('').stop();
}
}
componentWillUnmount() {
this.stop();
}
start() {
const { name, speed } = this.props;
this.update();
// Using `setTimeout` instead of `setInterval` since the animation can change, thus its delay.
this.timeout = setTimeout(() => {
this.start();
}, delays[name] / speed);
}
update() {
const text = (0, _ink.renderToString)((0, _ink.h)(
'span',
null,
this.props.children
));
// There's probably some clashing between `chalk-animation` and Ink's rendering mechanism
// (which uses `log-update`). The solution is to remove the ANSI escape sequence at the
// start of the frame that we're getting from `chalk-animation` that tells the terminal to
// clear the lines.
const frame = this.animation.replace(text).frame().replace(/^\u001B\[(\d)F\u001B\[G\u001B\[2K/, ''); // eslint-disable-line no-control-regex
this.setState({
frame
});
}
stop() {
clearTimeout(this.timeout);
this.timeout = null;
}
render() {
return (0, _ink.h)(
'span',
null,
this.state.frame
);
}
}
TextAnimation.defaultProps = {
name: 'rainbow',
speed: 1
};
TextAnimation.propTypes = {
children: _propTypes2.default.oneOfType([_propTypes2.default.node, _propTypes2.default.string]).isRequired,
name: _propTypes2.default.oneOf(['rainbow', 'pulse', 'glitch', 'radar', 'neon']),
speed: _propTypes2.default.number
};
exports.default = TextAnimation;