Skip to content

Instantly share code, notes, and snippets.

@josh-stevens
Created February 14, 2019 16:40
Show Gist options
  • Save josh-stevens/2ce09f7f923433032afafcb70163c8f3 to your computer and use it in GitHub Desktop.
Save josh-stevens/2ce09f7f923433032afafcb70163c8f3 to your computer and use it in GitHub Desktop.
Cool text scramble effect (use Roboto Mono 100 + #FAFAFA + #757575 for colors
import React, { Component, Fragment } from 'react';
const chars = '!<>-_\\/[]{}-=+*^?#________';
class TextScramble extends Component {
constructor(props) {
super(props);
this.string = props.children;
this.length = this.string.length;
this.queue = [];
this.frame = 0;
for (let i = 0; i < this.length; i++) {
const from = '';
const to = this.string[i];
const start = Math.floor(Math.random() * 40);
const end = start + Math.floor(Math.random() * 40);
this.queue.push({ from, to, start, end });
}
}
state = {
output: ''
}
componentDidMount() {
this.update();
}
update = () => {
let output = '';
let complete = 0;
for (let i = 0, n = this.queue.length; i< n; i++) {
let { from, to, start, end, char } = this.queue[i];
if (this.frame >= end) {
complete++;
output += to;
} else if (this.frame >= start) {
if (!char || Math.random() < 0.28) {
char = this.randomChar();
this.queue[i].char = char;
}
output += char;
} else {
output += from;
}
}
this.setState({ output });
if (complete !== this.queue.length) {
this.frameRequest = requestAnimationFrame(this.update);
this.frame++;
}
}
randomChar = () => chars[Math.floor(Math.random() * chars.length)];
render() {
return (
<Fragment>
{this.state.output}
</Fragment>
);
}
}
export default TextScramble;
@josh-stevens
Copy link
Author

@josh-stevens
Copy link
Author

Could still add a "setText" function to cycle through different lines

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment