Last active
January 25, 2016 05:47
-
-
Save chrisbolin/541f47e6accadba57c88 to your computer and use it in GitHub Desktop.
Codepen Preview
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html > | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/> | |
<title>chris bolin 2</title> | |
<link rel="stylesheet" href="css/normalize.css"> | |
<link rel="stylesheet" href="css/style.css"> | |
</head> | |
<body> | |
<div id="app"></div> | |
<script src='http://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.min.js'></script> | |
<script src="js/index.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var fx = { | |
limitUnit: function limitUnit(x) { | |
return x < 0 ? 0 : x < 1 ? x : 1; | |
} | |
}; | |
var ColorBar = React.createClass({ | |
displayName: 'ColorBar', | |
render: function render() { | |
var height = fx.limitUnit(this.props.x) * 100; | |
return React.createElement('div', { style: { | |
width: this.props.width, | |
height: height + '%', | |
backgroundColor: this.props.color, | |
left: this.props.left, | |
position: 'absolute', | |
bottom: 0 | |
} }); | |
} | |
}); | |
var CardFront = React.createClass({ | |
displayName: 'CardFront', | |
render: function render() { | |
var x = this.props.x; | |
var zIndex = x < 0.5 ? 1 : 0; | |
var scrollStyle = { | |
opacity: 1 - 10 * x | |
}; | |
return React.createElement( | |
'div', | |
{ className: 'card-face front', style: { zIndex: zIndex } }, | |
React.createElement( | |
'div', | |
{ className: 'title' }, | |
'chris bolin', | |
React.createElement('hr', null) | |
), | |
React.createElement( | |
'div', | |
{ className: 'scroll', style: scrollStyle }, | |
'(scroll)' | |
), | |
React.createElement(ColorBar, { color: '#EDC919', left: '0%', width: '20%', x: x * 5.2 }), | |
React.createElement(ColorBar, { color: '#76919A', left: '20%', width: '20%', x: x * 4.7 }), | |
React.createElement(ColorBar, { color: '#257A97', left: '40%', width: '20%', x: x * 4.4 }), | |
React.createElement(ColorBar, { color: '#7A486E', left: '60%', width: '20%', x: x * 4 }), | |
React.createElement(ColorBar, { color: '#FD556F', left: '80%', width: '20%', x: x * 3.5 }) | |
); | |
} | |
}); | |
var CardBack = React.createClass({ | |
displayName: 'CardBack', | |
render: function render() { | |
var x = this.props.x; | |
var zIndex = x > 0.5 ? 1 : 0; | |
var colorH = 0.06; | |
// if (!zIndex) return null; | |
return React.createElement( | |
'div', | |
{ className: 'card-face back', style: { zIndex: zIndex } }, | |
React.createElement(ColorBar, { color: '#EDC919', width: '10%', left: '0%', x: 2.5 * (1 - x) + colorH }), | |
React.createElement(ColorBar, { color: '#76919A', width: '10%', left: '10%', x: 9 * (1 - x) + colorH }), | |
React.createElement(ColorBar, { color: '#257A97', width: '10%', left: '20%', x: 4 * (1 - x) + colorH }), | |
React.createElement(ColorBar, { color: '#7A486E', width: '10%', left: '30%', x: 6 * (1 - x) + colorH }), | |
React.createElement(ColorBar, { color: '#EDC919', width: '10%', left: '40%', x: 5 * (1 - x) + colorH }), | |
React.createElement(ColorBar, { color: '#76919A', width: '10%', left: '50%', x: 2 * (1 - x) + colorH }), | |
React.createElement(ColorBar, { color: '#257A97', width: '10%', left: '60%', x: 4 * (1 - x) + colorH }), | |
React.createElement(ColorBar, { color: '#7A486E', width: '10%', left: '70%', x: 8 * (1 - x) + colorH }), | |
React.createElement(ColorBar, { color: '#EDC919', width: '10%', left: '80%', x: 7 * (1 - x) + colorH }), | |
React.createElement(ColorBar, { color: '#76919A', width: '10%', left: '90%', x: 3 * (1 - x) + colorH }) | |
); | |
} | |
}); | |
var CardPlane = React.createClass({ | |
displayName: 'CardPlane', | |
getStyle: function getStyle() { | |
var x = this.props.x; | |
var transform = '\n rotateZ(' + 90 * x + 'deg)\n rotateX(' + 180 * x + 'deg)\n translate3d(' + -50 * x + 'px, 0, 0)\n '; | |
return { | |
transform: transform, | |
WebkitTransform: transform | |
}; | |
}, | |
render: function render() { | |
var zFront = this.props.x < 0.5 ? 1 : 0; | |
var zBack = !zFront; | |
return React.createElement( | |
'div', | |
{ style: this.getStyle(), className: 'card-plane' }, | |
React.createElement(CardFront, { x: this.props.x }), | |
React.createElement(CardBack, { x: this.props.x }) | |
); | |
} | |
}); | |
var Typer = React.createClass({ | |
displayName: 'Typer', | |
render: function render() { | |
var x = fx.limitUnit(this.props.x); | |
if (!x) { | |
return null; | |
} | |
var letters = this.props.children.reduce(function (agg, element) { | |
if (element.length) { | |
agg = agg.concat(element.split('')); | |
} else { | |
agg.push(element); | |
} | |
return agg; | |
}, []); | |
letters.push(' '); | |
var cursor = x < 1 ? '|' : ''; | |
var childrenSubset = letters.slice(0, x * letters.length); | |
return React.createElement( | |
'span', | |
null, | |
childrenSubset, | |
' ', | |
cursor, | |
' ' | |
); | |
} | |
}); | |
var Arrow = React.createClass({ | |
displayName: 'Arrow', | |
render: function render() { | |
var x = this.props.x; | |
var grey = Math.floor(255 * (1 - x)); | |
var transform = 'translateY(' + 10 * x + 'px)'; | |
var style = { | |
transform: transform, | |
WebkitTransform: transform, | |
color: 'rgb(' + grey + ',' + grey + ',' + grey + ')', | |
opacity: 10 * (1 - x) | |
}; | |
return React.createElement( | |
'div', | |
{ className: 'arrow', style: style }, | |
'↓' | |
); | |
} | |
}); | |
var BackText = React.createClass({ | |
displayName: 'BackText', | |
render: function render() { | |
return React.createElement( | |
'div', | |
{ className: 'back-text' }, | |
React.createElement( | |
Typer, | |
{ x: this.props.x }, | |
'chris bolin', | |
React.createElement('br', null), | |
'wannabe polymath', | |
React.createElement('br', null), | |
'cambridge, mass, usa', | |
React.createElement('br', null), | |
React.createElement('br', null), | |
'[email protected]' | |
) | |
); | |
} | |
}); | |
var App = React.createClass({ | |
displayName: 'App', | |
getInitialState: function getInitialState() { | |
return { x: 0 }; | |
}, | |
appStyle: { | |
height: window.innerHeight + 200 | |
}, | |
handleScrollChange: function handleScrollChange(e) { | |
var x = fx.limitUnit(window.scrollY / (this.appStyle.height - window.innerHeight)); | |
this.setState({ x: x }); | |
}, | |
componentDidMount: function componentDidMount() { | |
window.addEventListener('scroll', this.handleScrollChange); | |
window.addEventListener('resize', this.handleScrollChange); | |
this.container = document.getElementsByClassName('main'); | |
}, | |
render: function render() { | |
var x = this.state.x; | |
var planeW = 0.9; // plane annimation weight (0-1) | |
var planeX = fx.limitUnit(x / planeW); | |
var typerX = fx.limitUnit(1 / (1 - planeW) * (-planeW + x)); | |
return React.createElement( | |
'div', | |
{ className: 'app', style: this.appStyle }, | |
React.createElement( | |
'div', | |
{ className: 'container' }, | |
React.createElement(CardPlane, { x: planeX }), | |
React.createElement(Arrow, { x: x }), | |
React.createElement(BackText, { x: typerX }) | |
) | |
); | |
} | |
}); | |
React.render(React.createElement(App, null), document.getElementById('app')); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import url(https://fonts.googleapis.com/css?family=Inconsolata); | |
@import url(https://fonts.googleapis.com/css?family=Playfair+Display:400italic); | |
body { | |
background-color: white; | |
margin: 0; | |
} | |
.container { | |
position: fixed; | |
} | |
.card-plane { | |
position: absolute; | |
width: 200px; | |
height: 350px; | |
margin: 50px calc(50vw - 100px); | |
} | |
.card-plane .card-face { | |
width: 100%; | |
height: 100%; | |
position: absolute; | |
} | |
.card-plane .card-face.front { | |
background-color: black; | |
color: white; | |
font-style: italic; | |
font-family: 'Playfair Display', Serif; | |
} | |
.card-plane .card-face.front .title { | |
font-size: 21px; | |
padding: 22px 22px; | |
} | |
.card-plane .card-face.front .title hr { | |
margin: 7px 0; | |
} | |
.card-plane .card-face.front .scroll { | |
position: absolute; | |
text-align: center; | |
width: 100%; | |
color: #7D7D7D; | |
bottom: -30px; | |
font-size: 12px; | |
} | |
.card-plane .card-face.back { | |
color: white; | |
background-color: #FD556F; | |
/* reversed for the back of the card */ | |
width: 350px; | |
height: 200px; | |
-webkit-transform: rotateZ(90deg) rotateX(180deg) translate3d(75px, -75px, 0px); | |
transform: rotateZ(90deg) rotateX(180deg) translate3d(75px, -75px, 0px); | |
} | |
.back-text { | |
position: fixed; | |
left: calc(50vw - 200px + 40px); | |
top: 90px; | |
font-family: Inconsolata, monospace; | |
color: white; | |
font-size: 14px; | |
width: 300px; | |
} | |
.arrow { | |
font-size: 24px; | |
font-family: 'Times New Roman', serif; | |
position: fixed; | |
text-align: center; | |
width: 100%; | |
top: 350px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment