<div id="app"></div>
body {
margin: 0;
font-family: 'Open Sans', sans-serif;
}
.app {
position: relative;
height: 100vh;
background-color: #041d3e;
transition: all 0.3s linear;
}
.app--one {
background-color: #0e4a54;
}
.app--two {
background-color: #22695e;
}
.app--three {
background-color: #9e964a;
}
.app--four {
background-color: #9a6631;
}
.app--five {
background-color: #814630;
}
.app__years {
width: 80%;
margin-left: 10%;
text-align: center;
z-index: 2;
position: relative;
}
.app__years__item {
display: inline-block;
margin: 8px;
padding: 5px 8px;
color: white;
border-radius: 15px;
border: 2px solid transparent;
transition: all 0.3s linear;
cursor: pointer;
}
.app__years__item--active {
border: 2px solid white;
}
.child__data {
color: white;
text-align: center;
font-size: 30px;
margin-top: 30px;
line-height: 50px;
z-index: 2;
position: relative;
}
.child__pirates {
width: 100%;
background-repeat: repeat-x;
background-position: center bottom;
background-size: contain;
background-attachment: fixed;
position: fixed;
min-height: 433px;
bottom: 0;
left: 0;
right: 0;
display: block;
z-index: 1;
}
@media screen and (min-width: 960px) {
.child__pirates {
min-height: 600px;
}
}
@media screen and (min-width: 1400px) {
.child__pirates {
min-height: 900px;
}
}
const {Component} = React;
const DATA = {
"1880": { pirates: 20000, temperature: 14.5 },
"1920": { pirates: 15000, temperature: 15.0 },
"1940": { pirates: 5000, temperature: 15.3 },
"1980": { pirates: 400, temperature: 15.7 },
"2000": { pirates: 17, temperature: 16 },
}
// immagini dei pirati
const URLS = {
20000: "https://res.cloudinary.com/dusxjrqiu/image/upload/v1452510351/20000.png",
15000: "https://res.cloudinary.com/dusxjrqiu/image/upload/v1452678308/15000.png",
5000: "https://res.cloudinary.com/dusxjrqiu/image/upload/v1452678308/5000.png",
400: "https://res.cloudinary.com/dusxjrqiu/image/upload/v1452678307/400.png",
17: "https://res.cloudinary.com/dusxjrqiu/image/upload/v1452678129/17.png"
}
class App extends Component {
constructor(props) {
super(props)
this.state = {
selectedYear: null
}
}
handleClick(year, e) {
e.preventDefault()
this.setState({ selectedYear: year})
}
renderYearbuttons(year) {
let appYearsItem = classNames(
"app__years__item",
{ "app__years__item--active": year === this.state.selectedYear }
)
return (
<div
key={year}
className={ appYearsItem }
onClick={ this.handleClick.bind(this, year) }
>
{ year }
</div>
)
}
render() {
let app = classNames(
"app",
this.state.selectedYear ? DATA[this.state.selectedYear].className : ""
)
return (
<div className={ app }>
<div className="app__years">
{ Object.keys(DATA).map(this.renderYearbuttons.bind(this)) }
</div>
{
// Un componente viene chiamato con la stessa sintassi di un tag html.
// Le props e i loro contenuti vengono aggiunti in forma di attributi.
// In questo caso, il contenuto delle props è lo stato del componente padre, App.
}
{
// Se la condizione (in questo caso lo state) è true allora viene renderizzato il contenuto tra tonde
this.state.selectedYear && (
<Child
pirates={ DATA[this.state.selectedYear].pirates }
temperature={ DATA[this.state.selectedYear].temperature }
/>
)
}
</div>
);
}
};
// Child ha soltanto il compito di mostrare un certo tipo di contenuto in funzione
// delle props che riceve da App. Le props vengono chiamate attraverso this.props.nomeProp
class Child extends Component {
render() {
let piratesStyle = {
backgroundImage: 'url(' + URLS[this.props.pirates] + ')'
}
return (
<div className="child">
<div className="child__data">
{
(this.props.temperature) && (
`${this.props.temperature}° C`
)
}
<br />
{
(this.props.pirates) && (
`${this.props.pirates} pirates`
)
}
</div>
{
(this.props.pirates) && (
<div
className="child__pirates"
style={ piratesStyle }
>
</div>
)
}
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('app'));
View Compiled
This Pen doesn't use any external CSS resources.