Skip to content

Instantly share code, notes, and snippets.

@dmfrancisco
Last active August 27, 2017 11:17
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save dmfrancisco/97869b042bd2b1002c0fa2ed8fecbec5 to your computer and use it in GitHub Desktop.
Create React Video: Demo Project
import React from "react";
import ReactDOM from "react-dom";
import Gideo, { Audio, Video, animatable } from "@robo54/gideo";
import "typeface-montserrat";
import locationIcon from "./location.svg";
const colors = {
primary: "#7c4dff",
black: "#1a1f21",
white: "#fff"
};
const Border = props => {
const style = {
border: `15px solid ${colors.primary}`,
height: "100%",
pointerEvents: "none",
position: "absolute",
width: "100%",
zIndex: 100
};
return (
<div style={style}>
{props.children}
</div>
);
};
const PaddedText = props => {
const { spacing, style, ...otherProps } = props;
if (spacing && style.background) {
style.paddingTop = spacing * 0.6;
style.paddingBottom = spacing * 0.6;
style.boxShadow = `${spacing}px 0 0 ${style.background},
-${spacing}px 0 0 ${style.background}`;
}
return (
<span style={Object.assign(style, props.style)} {...otherProps}>
{props.children}
</span>
);
};
const OpeningText = animatable(props => {
const style = {
container: {
alignItems: "center",
bottom: 0,
display: "flex",
justifyContent: "center",
left: `${props.animate(100, 0, {
duration: 2,
easing: "easeOutQuart"
})}%`,
overflow: "hidden",
position: "absolute",
right: 0,
top: 0
},
content: {
position: "absolute",
width: props.width
},
text: {
background: colors.white,
fontSize: 46,
lineHeight: 1.25
}
};
return (
<div style={style.container}>
<div style={style.content}>
<PaddedText spacing={10} style={style.text}>
{props.children}
</PaddedText>
</div>
</div>
);
});
const StepText = animatable(props => {
const counterSize = 55;
const style = {
main: {
alignItems: "center",
display: "flex",
height: props.height,
margin: "0 auto",
width: props.width + counterSize + 15
},
wrapper: {
width: "100%"
},
counter: {
background: colors.primary,
color: colors.white,
float: "left",
fontFamily: "Montserrat",
fontSize: 42,
fontWeight: 600,
height: counterSize,
lineHeight: `${counterSize}px`,
paddingBottom: 2,
textAlign: "center",
transformOrigin: "top right",
transform: `scale(${props.animate(0, 1, {
duration: 0.5,
easing: "easeOutSine"
})})`,
width: counterSize
},
container: {
marginLeft: counterSize,
overflow: "hidden"
},
content: {
marginLeft: `${props.animate(-props.width, 0, {
duration: 1,
easing: "easeOutSine"
})}px`,
paddingLeft: 10,
width: props.width
},
text: {
background: colors.white,
color: colors.black,
fontSize: 25,
lineHeight: 1.4
},
name: {
background: colors.black,
color: colors.white,
fontSize: 27,
lineHeight: 1.7,
marginRight: 20
},
location: {
color: colors.white,
fontSize: 22,
lineHeight: 1.4,
opacity: 0.7,
textShadow: "0 1px 2px rgba(0,0,0,.5)"
},
locationIcon: {
marginRight: 4,
width: "1rem"
}
};
return (
<div style={style.main}>
<div style={style.wrapper}>
<div style={style.counter}>
{props.counter}
</div>
<div style={style.container}>
<div style={style.content}>
<PaddedText spacing={10} style={style.name}>
{props.name}
</PaddedText>
<PaddedText spacing={10} style={style.location}>
<img src={locationIcon} style={style.locationIcon} />
{props.location}
</PaddedText>
<br />
<PaddedText spacing={10} style={style.text}>
{props.text}
</PaddedText>
</div>
</div>
</div>
</div>
);
});
const SourceText = props => {
const style = {
container: {
bottom: 30,
left: 40,
position: "absolute",
zIndex: 100
},
text: {
background: colors.black,
color: colors.white,
fontSize: 23,
lineHeight: 1.5
}
};
return (
<div style={style.container}>
<PaddedText spacing={10} style={style.text}>
{props.children}
</PaddedText>
</div>
);
};
const Project = () => {
const styles = {
base: {
color: colors.black,
fontFamily: "BlinkMacSystemFont",
fontWeight: 700
},
video: {
centered: {
position: "absolute",
height: "100%",
left: "50%",
transform: "translate(-50%, 0)"
}
}
};
return (
<Gideo width={600} height={600} duration={30} style={styles.base}>
<Border begin={0} duration={30} />
<Video
begin={0}
duration={6}
src="/man-working-during-dawn.mp4"
style={styles.video.centered}
/>
<OpeningText startWith={-1} endWith={-1} width={390}>
These
<span style={{ color: colors.primary }}> 4 food tech startups </span>
are worth sharing
</OpeningText>
<Video
startAfter={-1}
duration={6}
src="/people-at-the-market.mp4"
style={styles.video.centered}
/>
<StepText
startWith={-1}
endWith={-1}
counter={1}
width={400}
height="80%"
name="Agruppa"
location="Bogota, Colombia"
text="Connects vendors with small farmers to establish direct supply chains and reduce costs"
/>
<Video
startAfter={-1}
duration={6}
src="/cows-in-the-field.mp4"
style={styles.video.centered}
/>
<StepText
startWith={-1}
endWith={-1}
counter={2}
width={390}
height="50%"
name="Cowlar"
location="Islamabad, Pakistan"
text="Produces a smart collar to help farmers improve daily herd health and boost milk yields"
/>
<Video
startAfter={-1}
duration={6}
src="/tractor-in-field.mp4"
style={styles.video.centered}
/>
<StepText
startWith={-1}
endWith={-1}
counter={3}
width={420}
height="140%"
name="GenZ Technology"
location="Seattle, USA"
text="Develops spray equipment that provides superior crop coverage while reducing air and soil pollution"
/>
<Video
startAfter={-1}
duration={6}
src="/greenhouse.mp4"
startAt={7}
playbackRate={0.6}
style={styles.video.centered}
/>
<StepText
startWith={-1}
endWith={-1}
counter={4}
width={465}
height="90%"
name="Illuminum Greenhouses"
location="Kenya"
text="Constructs affordable greenhouses and drip irrigation kits for small-scale farmers using solar panels and sensors"
/>
<SourceText startWith={-1} endWidth={-1}>
Song: &nbsp;Deep Breath,<br />Mattia Vlad Morleo
</SourceText>
<Audio begin={0} end={30} src="/deep-breath.mp3" />
</Gideo>
);
};
ReactDOM.render(<Project />, document.getElementById("root"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment