new hero animation using bodymovin and lottie
|
Before Width: | Height: | Size: 809 KiB |
|
Before Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 571 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 307 KiB |
|
Before Width: | Height: | Size: 535 KiB |
|
Before Width: | Height: | Size: 409 KiB |
|
Before Width: | Height: | Size: 983 KiB |
@@ -23,6 +23,8 @@
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-loadable": "^5.5.0",
|
||||
"react-lottie": "^1.2.3",
|
||||
"react-tabs": "^2.3.0",
|
||||
"styled-components": "^4.0.2",
|
||||
"styled-normalize": "^8.0.1"
|
||||
@@ -35,6 +37,8 @@
|
||||
"@types/react": "^16.4.2",
|
||||
"@types/react-dom": "^16.0.7",
|
||||
"@types/react-helmet": "^5.0.6",
|
||||
"@types/react-loadable": "^5.4.1",
|
||||
"@types/react-lottie": "^1.2.0",
|
||||
"@types/react-router-dom": "^4.0.4",
|
||||
"@types/react-tabs": "^2.3.0",
|
||||
"@types/react-tap-event-plugin": "0.0.30",
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import Animation from '../index';
|
||||
import * as animationData from './data.json';
|
||||
|
||||
function AnimationCompiler() {
|
||||
return <Animation animationData={animationData} width={2150} height={700} />;
|
||||
}
|
||||
|
||||
export default AnimationCompiler;
|
||||
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import Animation from '../index';
|
||||
import * as animationData from './data.json';
|
||||
|
||||
function AnimationCov() {
|
||||
return <Animation animationData={animationData} width={1981} height={660} />;
|
||||
}
|
||||
|
||||
export default AnimationCov;
|
||||
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import Animation from '../index';
|
||||
import * as animationData from './data.json';
|
||||
|
||||
function AnimationProfiler() {
|
||||
return <Animation animationData={animationData} width={1985} height={657} />;
|
||||
}
|
||||
|
||||
export default AnimationProfiler;
|
||||
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import Animation from '../index';
|
||||
import * as animationData from './data.json';
|
||||
|
||||
function AnimationTrace() {
|
||||
return <Animation animationData={animationData} width={2241} height={610} />;
|
||||
}
|
||||
|
||||
export default AnimationTrace;
|
||||
105
packages/dev-tools-pages/ts/components/Animations/index.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
import * as React from 'react';
|
||||
import Lottie from 'react-lottie';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { media } from 'ts/variables';
|
||||
|
||||
interface AnimationProps {
|
||||
animationData: object;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
interface AnimationState {
|
||||
width?: number;
|
||||
height?: number;
|
||||
}
|
||||
|
||||
class Animation extends React.PureComponent<AnimationProps, AnimationState> {
|
||||
timeout = null as any;
|
||||
constructor(props: AnimationProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
height: undefined,
|
||||
width: undefined,
|
||||
};
|
||||
|
||||
this.handleResize = this.handleResize.bind(this);
|
||||
this.updateAnimationSize = this.updateAnimationSize.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.updateAnimationSize();
|
||||
window.addEventListener('resize', this.handleResize);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
}
|
||||
|
||||
handleResize() {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(this.updateAnimationSize, 200);
|
||||
}
|
||||
|
||||
updateAnimationSize() {
|
||||
const windowWidth = window.innerWidth;
|
||||
let width = undefined;
|
||||
let height = undefined;
|
||||
if (windowWidth < 1200) {
|
||||
const maxWidth = windowWidth + 250;
|
||||
const ratio = maxWidth / this.props.width;
|
||||
|
||||
height = Math.round(this.props.height * ratio);
|
||||
width = Math.round(this.props.width * ratio);
|
||||
}
|
||||
|
||||
this.setState({ width, height });
|
||||
}
|
||||
|
||||
render() {
|
||||
let { animationData } = this.props;
|
||||
const height = this.state.height || this.props.height;
|
||||
const width = this.state.width || this.props.width;
|
||||
|
||||
return (
|
||||
<Container height={height}>
|
||||
<InnerContainer>
|
||||
<Lottie
|
||||
width={width}
|
||||
height={height}
|
||||
options={{
|
||||
loop: true,
|
||||
autoplay: true,
|
||||
animationData: animationData,
|
||||
}}
|
||||
/>
|
||||
</InnerContainer>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const Container = styled.div`
|
||||
width: 100%;
|
||||
height: ${(props: { height: number }) => props.height}px;
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
overflow: hidden;
|
||||
${media.medium`
|
||||
top: auto;
|
||||
bottom: -3rem;
|
||||
`};
|
||||
`;
|
||||
|
||||
const InnerContainer = styled.div`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
`;
|
||||
|
||||
export default Animation;
|
||||
@@ -3,7 +3,6 @@ import * as React from 'react';
|
||||
import ThemeContext from 'ts/context';
|
||||
import GlobalStyles from 'ts/globalStyles';
|
||||
import Header from 'ts/components/Header';
|
||||
import Hero from 'ts/components/Hero';
|
||||
import Footer from 'ts/components/Footer';
|
||||
|
||||
interface BaseProps {
|
||||
@@ -16,7 +15,6 @@ function Base(props: BaseProps) {
|
||||
<ThemeContext.Provider value={props.context}>
|
||||
<GlobalStyles />
|
||||
<Header />
|
||||
<Hero />
|
||||
{props.children}
|
||||
<Footer />
|
||||
</ThemeContext.Provider>
|
||||
|
||||
@@ -6,8 +6,12 @@ import { withContext, Props } from './withContext';
|
||||
import Button from './Button';
|
||||
import { Beta } from './Typography';
|
||||
|
||||
function Hero(props: Props) {
|
||||
const { subtitle, tagline, title } = props;
|
||||
interface HeroProps extends Props {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function Hero(props: HeroProps) {
|
||||
const { subtitle, tagline } = props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -19,13 +23,7 @@ function Hero(props: Props) {
|
||||
Read the Docs
|
||||
</Button>
|
||||
</HeroContainer>
|
||||
|
||||
<ImageContainer>
|
||||
<Image
|
||||
src={`/images/${title}@1x.gif`}
|
||||
srcSet={`/images/${title}@1x.gif, /images/${title}@2x.gif 2x`}
|
||||
/>
|
||||
</ImageContainer>
|
||||
{navigator.userAgent !== 'ReactSnap' ? props.children : null}
|
||||
</StyledHero>
|
||||
</React.Fragment>
|
||||
);
|
||||
@@ -67,39 +65,4 @@ const Tagline = styled(Beta)`
|
||||
`};
|
||||
`;
|
||||
|
||||
const ImageContainer = styled.div`
|
||||
width: 100%;
|
||||
height: 800px;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
transform: translateY(-50%);
|
||||
z-index: -1;
|
||||
${media.xlarge`
|
||||
height: 533.333333334px;
|
||||
transform: translateY(-60%);
|
||||
`};
|
||||
${media.small`
|
||||
height: 400px;
|
||||
transform: translateY(-70%);
|
||||
`};
|
||||
`;
|
||||
|
||||
const Image = styled.img`
|
||||
width: min-content;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
object-fit: contain;
|
||||
${media.small`
|
||||
height: 100%;
|
||||
width: auto;
|
||||
left: 0;
|
||||
transform: translateX(-15%);
|
||||
`};
|
||||
`;
|
||||
|
||||
export default withContext(Hero);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { render, hydrate } from 'react-dom';
|
||||
import * as Loadable from 'react-loadable';
|
||||
|
||||
import { Lead } from 'ts/components/Typography';
|
||||
import context from 'ts/context/compiler';
|
||||
@@ -10,10 +11,20 @@ import Code from 'ts/components/Code';
|
||||
import InlineCode from 'ts/components/InlineCode';
|
||||
import CompilerComponent from 'ts/components/Compiler';
|
||||
import Breakout from 'ts/components/Breakout';
|
||||
import Hero from 'ts/components/Hero';
|
||||
|
||||
const Animation = Loadable({
|
||||
loader: () => System.import(/* webpackChunkName: 'compiler-animation' */ 'ts/components/Animations/Compiler'),
|
||||
loading: () => <div />,
|
||||
delay: 1000,
|
||||
});
|
||||
|
||||
function Compiler() {
|
||||
return (
|
||||
<Base context={context}>
|
||||
<Hero>
|
||||
<Animation />
|
||||
</Hero>
|
||||
<CompilerComponent />
|
||||
<Content>
|
||||
<ContentBlock main title="Get started" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { render, hydrate } from 'react-dom';
|
||||
import * as Loadable from 'react-loadable';
|
||||
|
||||
import context from 'ts/context/cov';
|
||||
import Base from 'ts/components/Base';
|
||||
@@ -11,10 +12,20 @@ import InlineCode from 'ts/components/InlineCode';
|
||||
import { List, ListItem } from 'ts/components/List';
|
||||
import Breakout from 'ts/components/Breakout';
|
||||
import { Intro, IntroLead, IntroAside } from 'ts/components/Intro';
|
||||
import Hero from 'ts/components/Hero';
|
||||
|
||||
const Animation = Loadable({
|
||||
loader: () => System.import(/* webpackChunkName: 'cov-animation' */ 'ts/components/Animations/Cov'),
|
||||
loading: () => <div />,
|
||||
delay: 1000,
|
||||
});
|
||||
|
||||
function Cov() {
|
||||
return (
|
||||
<Base context={context}>
|
||||
<Hero>
|
||||
<Animation />
|
||||
</Hero>
|
||||
<Intro>
|
||||
<IntroLead title="Measure your tests">
|
||||
<p>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { render, hydrate } from 'react-dom';
|
||||
import * as Loadable from 'react-loadable';
|
||||
|
||||
import context from 'ts/context/profiler';
|
||||
import Base from 'ts/components/Base';
|
||||
@@ -11,10 +12,20 @@ import Code from 'ts/components/Code';
|
||||
import InlineCode from 'ts/components/InlineCode';
|
||||
import { List, ListItem } from 'ts/components/List';
|
||||
import { Intro, IntroLead, IntroAside } from 'ts/components/Intro';
|
||||
import Hero from 'ts/components/Hero';
|
||||
|
||||
const Animation = Loadable({
|
||||
loader: () => System.import(/* webpackChunkName: 'profiler-animation' */ 'ts/components/Animations/Profiler'),
|
||||
loading: () => <div />,
|
||||
delay: 1000,
|
||||
});
|
||||
|
||||
function Profiler() {
|
||||
return (
|
||||
<Base context={context}>
|
||||
<Hero>
|
||||
<Animation />
|
||||
</Hero>
|
||||
<Intro>
|
||||
<IntroLead title="Outline gas usage">
|
||||
<p>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { render, hydrate } from 'react-dom';
|
||||
import * as Loadable from 'react-loadable';
|
||||
|
||||
import context from 'ts/context/trace';
|
||||
import Base from 'ts/components/Base';
|
||||
@@ -11,10 +12,20 @@ import InlineCode from 'ts/components/InlineCode';
|
||||
import { List, ListItem } from 'ts/components/List';
|
||||
import TraceComponent from 'ts/components/Trace';
|
||||
import Breakout from 'ts/components/Breakout';
|
||||
import Hero from 'ts/components/Hero';
|
||||
|
||||
const Animation = Loadable({
|
||||
loader: () => System.import(/* webpackChunkName: 'trace-animation' */ 'ts/components/Animations/Trace'),
|
||||
loading: () => <div />,
|
||||
delay: 1000,
|
||||
});
|
||||
|
||||
function Trace() {
|
||||
return (
|
||||
<Base context={context}>
|
||||
<Hero>
|
||||
<Animation />
|
||||
</Hero>
|
||||
<TraceComponent />
|
||||
<Content>
|
||||
<ContentBlock main title="Get started" />
|
||||
|
||||
57
yarn.lock
@@ -1379,6 +1379,21 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-loadable@^5.4.1":
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-loadable/-/react-loadable-5.4.1.tgz#bc76978c6d9039e5808797b5ee35f6ae18b7329f"
|
||||
integrity sha512-nBvsWjPfBHepN5LoK/wgaunZSK9LmkKsPYum+/QrEKzUAb1yoe1/dwqTH6ZrinHDjru9LgjvXOqek9hvbq4Skw==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
"@types/webpack" "*"
|
||||
|
||||
"@types/react-lottie@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-lottie/-/react-lottie-1.2.0.tgz#87eccca2580a18c95a3fbb9f421c85debafb95e4"
|
||||
integrity sha512-3ZE0QxbHEpGeuKTTvnCchfgVt4xW7VMxzMd2PgVNOXwkO8qLrNggkXudsk3RJ92IQLFnYRfbACPD1/X7zIjDdQ==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-redux@^4.4.37":
|
||||
version "4.4.47"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-4.4.47.tgz#12af1677116e08d413fe2620d0a85560c8a0536e"
|
||||
@@ -1518,11 +1533,23 @@
|
||||
"@types/node" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/tapable@*":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370"
|
||||
integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ==
|
||||
|
||||
"@types/tmp@^0.0.33":
|
||||
version "0.0.33"
|
||||
resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.0.33.tgz#1073c4bc824754ae3d10cfab88ab0237ba964e4d"
|
||||
integrity sha1-EHPEvIJHVK49EM+riKsCN7qWTk0=
|
||||
|
||||
"@types/uglify-js@*":
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082"
|
||||
integrity sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ==
|
||||
dependencies:
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@types/uuid@^3.4.2", "@types/uuid@^3.4.3":
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.3.tgz#121ace265f5569ce40f4f6d0ff78a338c732a754"
|
||||
@@ -1542,6 +1569,16 @@
|
||||
dependencies:
|
||||
"@types/ethereum-protocol" "*"
|
||||
|
||||
"@types/webpack@*":
|
||||
version "4.4.17"
|
||||
resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.4.17.tgz#3da3e0823a051311ba510bdc32354888921fc8b4"
|
||||
integrity sha512-f8fHYEhlrSQJ5BHaonyatL11MYwqQ7I6QDVCT41LqIyxR7j9B2uY4cQKxDoWFC9l2NbFGsIhiJBKZ6Y6LMBFLA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
"@types/tapable" "*"
|
||||
"@types/uglify-js" "*"
|
||||
source-map "^0.6.0"
|
||||
|
||||
"@types/websocket@^0.0.39":
|
||||
version "0.0.39"
|
||||
resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-0.0.39.tgz#aa971e24f9c1455fe2a57ee3e69c7d395016b12a"
|
||||
@@ -11180,6 +11217,11 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3
|
||||
dependencies:
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
lottie-web@^5.1.3:
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/lottie-web/-/lottie-web-5.4.1.tgz#98465741d4907293656cab31e395d79d0546ef26"
|
||||
integrity sha512-pn5nCxobPVY9dcl+gh5s4q5k5MX6GeayUh4l7AhelDSTWkvyvGGK9dOMu6+FS0pseXjUyuZwzxtx2Tf796B0IQ==
|
||||
|
||||
loud-rejection@^1.0.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
|
||||
@@ -14431,6 +14473,21 @@ react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4:
|
||||
resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react-loadable@^5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/react-loadable/-/react-loadable-5.5.0.tgz#582251679d3da86c32aae2c8e689c59f1196d8c4"
|
||||
integrity sha512-C8Aui0ZpMd4KokxRdVAm2bQtI03k2RMRNzOB+IipV3yxFTSVICv7WoUr5L9ALB5BmKO1iHgZtWM8EvYG83otdg==
|
||||
dependencies:
|
||||
prop-types "^15.5.0"
|
||||
|
||||
react-lottie@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/react-lottie/-/react-lottie-1.2.3.tgz#8544b96939e088658072eea5e12d912cdaa3acc1"
|
||||
integrity sha512-qLCERxUr8M+4mm1LU0Ruxw5Y5Fn/OmYkGfnA+JDM/dZb3oKwVAJCjwnjkj9TMHtzR2U6sMEUD3ZZ1RaHagM7kA==
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
lottie-web "^5.1.3"
|
||||
|
||||
react-markdown@^3.2.2:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.3.0.tgz#a87cdd822aa9302d6add9687961dd1a82a45d02e"
|
||||
|
||||