Hello The People of Greensock,
I've been working with a static site generator for react lately - Gatsby.js. One of the components has a menu animation attached. In development the animation works just fine, but when deployed it just doesn't trigger.
Code is bundled and minified with webpack.
The weird thing is, GSAP loads up properly, the console is clear, no errors. It's hard to investigate more since code after minification and bundling is hard to read in chrome dev tools. :/
I'm not sure if this is related to my GSAP setup, but if anyone could take a look at the code, it would be awesome.
This is the navAnimation itself:
import { TimelineLite, CSSPlugin, Power2, Power3 } from 'gsap';
import * as CSSRulePlugin from 'gsap/CSSRulePlugin';
const slideDownTl = new TimelineLite({ paused: true, initialRender: true });
const slideUpTl = new TimelineLite({ paused: true, initialRender: true });
// Document-object-aware variables
let menuBtn, menuList, shutter, shutterBf, shutterAft, menuSpans, menuSpansAfts;
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
document.addEventListener('DOMContentLoaded', function() {
// Menu Button
menuBtn = document.querySelector('.menu-btn');
// Menu List
menuList = document.querySelector('.list-nav');
// Shutter Variables
shutter = document.querySelector('.shutter');
shutterBf = CSSRulePlugin.getRule('.shutter:before');
shutterAft = CSSRulePlugin.getRule('.shutter:after');
// Menu Span Variables
menuSpans = document.querySelectorAll('.menu-span');
menuSpansAfts = CSSRulePlugin.getRule(
'.list-nav ul li .menu-link a .menu-span:after'
);
console.log('we passed window+document check!');
// slideDown Animation Timeline
slideDownTl
.set([shutterBf, shutterAft], {
cssRule: { y: '-120%' }
})
.set(menuBtn, { pointerEvents: `none` })
.set([menuList, shutter], {
visibility: 'visible'
})
.set(menuSpans, { y: '-200%' })
.timeScale(1.2)
.staggerTo(
[shutterBf, shutterAft],
1,
{
cssRule: { y: '0%' },
force3D: true,
rotation: 0.01,
ease: Power3.easeOut
},
0.3
)
.staggerTo(
menuSpans,
0.5,
{ y: '0%', ease: Power2.easeInOut },
0.1,
'-=0.7'
)
.set(menuBtn, { pointerEvents: `all` });
// slideUp Animation Timeline
slideUpTl
.set(menuBtn, { pointerEvents: `none` })
.staggerTo(menuSpans, 0.5, { y: '-200%', ease: Power2.easeIn }, 0.1)
.staggerTo(
[shutterAft, shutterBf],
0.75,
{
cssRule: { y: '-120%' },
force3D: true,
rotation: 0.01,
ease: Power2.easeIn
},
0.25,
'-=0.4'
)
.set([menuList, shutter], {
visibility: 'hidden'
})
.set(menuBtn, { pointerEvents: `all` });
}); // end DOMContentLoaded
} // end if window !== undefined
export const slideDown = () => {
slideDownTl.play(0);
};
export const slideUp = () => {
slideUpTl.play(0);
};
I check for window and document !== undefined, because Gatsby requires it on build.
This is Header component which has navAnimation included:
import React from 'react';
import Link from 'gatsby-link';
import './navigation.scss';
import * as navAnimation from '../../static/navAnimation.js';
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {
isOpened: false
};
this.menuToggle = this.menuToggle.bind(this);
this.handleClickOutside = this.handleClickOutside.bind(this);
}
handleClickOutside(e) {
let clickInHeader = false;
if (e.path) {
clickInHeader = e.path.find(node => node.localName === 'header');
}
!clickInHeader && this.menuToggle();
}
menuToggle(e) {
if (this.state.isOpened) {
navAnimation.slideUp();
document.removeEventListener('click', this.handleClickOutside, true);
} else {
navAnimation.slideDown();
document.addEventListener('click', this.handleClickOutside, true);
}
this.setState(prevState => {
return { isOpened: !prevState.isOpened };
});
}
render() {
return (
<header>
<h1>
<div className="logo">
<Link to="/" onClick={this.state.isOpened && this.menuToggle}>
<span>Seba</span>
<span>Hewelt</span>
</Link>
</div>
</h1>
<div id="menu-btn-wrapper">
<button
className={this.state.isOpened ? 'menu-btn open' : 'menu-btn'}
onClick={this.menuToggle}>
<svg className="stick" viewBox="0 0 70 32">
<path d="M 5 5 H70 L 5 21" />
<path d="M 5 15 H70 L 5 31" />
</svg>
</button>
</div>
<div className="shutter" />
<nav className="list-nav">
<ul>
<li>
<div className="menu-link" onClick={this.menuToggle}>
<Link to="/my-work">
<span className="menu-span">my work</span>
</Link>
</div>
</li>
<li>
<div className="menu-link">
<Link to="/blog" onClick={this.menuToggle}>
<span className="menu-span">blog</span>
</Link>
</div>
</li>
<li>
<div className="menu-link">
<Link to="/#contact" onClick={this.menuToggle}>
<span className="menu-span">contact</span>
</Link>
</div>
</li>
</ul>
</nav>
</header>
);
}
}
export default Header;