DEV Community

Cover image for Thinking in "GIF" with React
egfx
egfx

Posted on • Updated on

Thinking in "GIF" with React

Coding a GIF (without a doubt) isn't something you've heard of before. But wouldn't you like to login to Slack tomorrow and send that "Homer Simpson backing up into a hedge" gif (again) with something more? Just imagine, for a moment, that random gifs and other images could be magically enhanced with logic. Where each individual "piece" of content as a "whole" would collectively make up more then the sum of it's parts.

Thinking in "GIF"


Thinking in GIF

Figure 1.0: A "GIF" can be thought to be made up of more then the sum of it's parts.


Actually the concept isn't new to GIF's. The trend in web development has been to think about building structured blocks of functionality made of components. Today this idea has been embraced by every major frontend framework and most popularly in frameworks that use React as a foundation.


But what's thinking in GIF with React?


*

Exactly as it sounds "Thinking in GIF" allows us to break down the GIF into a holistic collection of it's parts, and thankfully thinking in GIF with React isn't as far flung a concept as you'd first imagine. React is a component based framework. And since we're talking about awesome old school tech like gif. Let's also discuss EnyoJS. A stellar frontend framework that inspired the React DOM component architecture under the hood. This kind of black magic, block structured thinking that Enyo first introduced fits nicely with gif.com.ai (your GIF coding platform).

enyo.kind({
  name: 'OG.MyComponent'
  kind: enyo.Component
});

var widget = new OG.MyComponent();
Enter fullscreen mode Exit fullscreen mode

Figure 1.0: Original EnyoJS - DOM components were called "Kinds" in Enyo.

Enyo introduced a concept called "Kinds". The way to think about the kind is everything that makes up a widget on a page gets put into a component tree. You write out these components in pure JS and then bootstrap them onto one or more DOM elements.

Component Component Component
HTML
JS
CSS
HTML
JS
CSS
HTML
JS
CSS
⤿  DOM Element DOM Element DOM Element  ⤾

Now with this concept firmly in mind; let's transplant ourselves into gif thinking mode and say we live in an alternate meme universe and among Shiba Inu's who spin cats and burgers in concentric circles. Developers in this land use only one IDE and that is LimeText™.


const kind = React.createElement;

ReactDOM.render(
  kind(Widget, document.querySelector('[data-master]'))

Enter fullscreen mode Exit fullscreen mode

Figure 2.0: We can convert React components and treat them like Enyo "Kinds".

We are able to resurface our beloved "Kind" by commandeering an existing widget we already had open. We will use a Shiba Inu pup for the task and turn him into a React component. What an honor!


Image description

Figure 2.1: DOM Elements can be copied and pasted into the HTML content in LimeText™ IDE.

As you can see we gave this wonderful Shiba Inu widget an additional react-container element.

Let's add an additional (dog). These dogs won't be explicitly connected to React but will be used to spice up our GIF in other ways. And we will talk to the other two widgets, the Cat and Burger images that we pre-loaded, with code.

Our react-container DOM element will be the container for our program logic. And we will use both img tags as visual GIF decorators.

Let's click on the JS tab...

const SPEED = 0;

const kind  = React.createElement,
container = "react-container";

const tags  = {
    cat     : document.querySelector('[data-cat]'),
    burger  : document.querySelector('[data-burger]')
}

class Main extends React.Component {
    constructor(props){
        super(props)
    }

    componentDidMount() {
        alert("say cheeze!")
    }

    render() {
        const kinds = [];
        Object.keys(tags).map(function(key, index) {
            const targets = { 
                key : index, 
                tag : tags[key].tagName.toLowerCase(), 
                src : tags[key].src, 
                SPEED
            }
            kinds.push(kind(Spin, targets))
        });
        return kinds
    }
}
Enter fullscreen mode Exit fullscreen mode

Figure 2.2: A DOM element becomes our "logic" container and provides a way to work with the gif canvas.

Because our Shiba Inu (react-container) widget is being used as a container for any gif logic. We will let it recursively call out to itself. It alerts a dialog right over our canvas just to know that it's been loaded. In this JS tab - we're free to change the contents of our container component or even change what the container component is defined as.

const Spin = function(props) {
    const [speed, go] = React.useState(props.SPEED);    
    const startSpin = function() {
        go(speed + 1)
    };
    React.useEffect(function() {
        startSpin()
    }, []);
    return kind(props.tag, { style : { animation : `spin ${speed}s linear infinite` }, src : props.src })
}
Enter fullscreen mode Exit fullscreen mode
Figure 2.3: Our "Spin" hook makes our cat and burger spin in circles.

Next we will add Spin to our Cat and Burger widgets. To do this we will create a React Hook. The Spin React hook lets you dynamically change speed through a stateful property. We just added +1 speed to the initial speed given.

#gifcanvas [data-cat] {
    display: none;
}
#gifcanvas [data-burger] {
    display: none;
}
Enter fullscreen mode Exit fullscreen mode
Figure 2.4: We hid the placeholder images because they aren't needed in the final gif.

Finishing up we hid the original Cat and Burger images with CSS when they are presented in the canvas. The reason for this is that these (images) are only being used as placeholders. We injected their data into react-container and then we hid the DOM elements so they wouldn't be seen in the actual gif.


Top comments (0)