big picture

This commit is contained in:
2018-12-27 16:55:40 -08:00
parent 9c052aebd2
commit c4704a920b
5 changed files with 114 additions and 13 deletions

View File

@@ -30,3 +30,42 @@ h1 {
.Grid img { .Grid img {
cursor: pointer; cursor: pointer;
} }
.BigPicture {
background-color: rgba(0, 0, 0, 0.6);
bottom: 0;
display: flex;
flex-direction: column;
left: 0;
padding: 30px;
position: fixed;
right: 0;
top: 0;
}
.BigPicture-image {
background-position: center;
background-repeat: no-repeat;
background-size: contain;
flex: 1 1 auto;
}
.BigPicture-footer {
align-self: center;
display: flex;
flex: 0 0 auto;
justify-content: space-between;
margin-top: 30px;
max-width: 200px;
width: 100%;
}
.BigPicture-footerLink {
color: #69c;
cursor: pointer;
text-decoration: none;
}
.BigPicture-footerLink:hover {
text-decoration: underline;
}

View File

@@ -0,0 +1,38 @@
import * as Model from "../model";
import * as React from "react";
export interface Props {
src: string;
image: Model.Image;
onClose: () => void;
width: number;
}
export class BigPicture extends React.PureComponent<Props, {}> {
static displayName = "BigPicture";
render() {
const src = `img/1600/${this.props.src}`;
return <div className="BigPicture">
<div
className="BigPicture-image"
style={{
backgroundImage: `url(${src})`
}}>
</div>
<div className="BigPicture-footer">
<a className="BigPicture-footerLink"
href={`img/${this.props.src}`}
target="_blank">
Download
</a>
<span className="BigPicture-footerLink"
onClick={this.props.onClose}
tabIndex={1} >
Close
</span>
</div>
</div>;
}
}

View File

@@ -6,7 +6,6 @@ import * as React from "react";
export interface Props { export interface Props {
images: Model.Images; images: Model.Images;
onImageSelected: (key: string) => void; onImageSelected: (key: string) => void;
selectedImage: string | null;
width: number; width: number;
} }
@@ -52,7 +51,6 @@ export class Grid extends React.PureComponent<Props, {}> {
return <Picture return <Picture
image={image} image={image}
onClick={() => this.props.onImageSelected(key)} onClick={() => this.props.onImageSelected(key)}
selected={this.props.selectedImage === key}
src={key} src={key}
key={key} key={key}
width={image.width/image.height * scale} width={image.width/image.height * scale}

View File

@@ -6,7 +6,6 @@ export interface Props {
src: string; src: string;
image: Model.Image; image: Model.Image;
onClick: () => void; onClick: () => void;
selected?: boolean;
width: number; width: number;
} }
@@ -16,11 +15,10 @@ export class Picture extends React.PureComponent<Props, {}> {
render() { render() {
const src = `img/600/${this.props.src}`; const src = `img/600/${this.props.src}`;
return <img return <img
className={ this.props.selected ? "Picture-selected" : ""}
onClick={this.props.onClick} onClick={this.props.onClick}
srcSet={this._srcset()} srcSet={this._srcset()}
src={src} src={src}
width={ this.props.selected ? "100%" : this.props.width + "px" } width={ this.props.width + "px" }
/>; />;
} }

View File

@@ -1,3 +1,4 @@
import { BigPicture } from "./big_picture";
import { Grid } from "./grid"; import { Grid } from "./grid";
import * as Model from "../model"; import * as Model from "../model";
@@ -7,16 +8,15 @@ export interface Props {}
export interface State { export interface State {
images: Model.Images; images: Model.Images;
selectedIamge?: string | null; selectedImage?: string | null;
width: number; width: number;
} }
export class Root extends React.PureComponent<Props, State> { export class Root extends React.PureComponent<Props, State> {
static displayName = "Root"; static displayName = "Root";
state = { state: State = {
images: {}, images: {},
selectedImage: null,
width: window.innerWidth width: window.innerWidth
} }
@@ -29,24 +29,52 @@ export class Root extends React.PureComponent<Props, State> {
window.onresize = () => { window.onresize = () => {
this.setState({ width: window.innerWidth }); this.setState({ width: window.innerWidth });
} }
window.onpopstate = this._loadHash;
this._loadHash();
} }
render() { render() {
return <div className="Root"> return <div className="Root">
<h1>Ski</h1> <h1>Ski</h1>
<hr /> <hr />
{ this._bigPicture() }
<Grid <Grid
images={ this.state.images } images={ this.state.images }
onImageSelected={ this._onImageSelected } onImageSelected={ this._onImageSelected }
selectedImage={ this.state.selectedImage }
width={ this.state.width } /> width={ this.state.width } />
</div>; </div>;
} }
private _bigPicture = () => {
if (this.state.selectedImage && this.state.images[this.state.selectedImage]) {
return <BigPicture
image={this.state.images[this.state.selectedImage]}
src={this.state.selectedImage}
onClose={this._showGrid}
width={this.state.width}
/>
} else {
return null;
}
}
private _loadHash = () => {
if (window.location.hash.length > 0) {
this.setState({ selectedImage: window.location.hash.slice(1) });
} else {
this.setState({ selectedImage: null });
}
}
private _onImageSelected = (key: string) => { private _onImageSelected = (key: string) => {
this.setState(state => ({ this.setState({ selectedImage: key });
...state, window.history.pushState(null, "", `#${key}`);
selectedImage: key }
}));
private _showGrid = () => {
this.setState({ selectedImage: null });
window.history.pushState(null, "", "#");
} }
} }