This commit is contained in:
2018-12-28 15:18:48 -07:00
parent b3820ca43b
commit 53fa2be4fa
6 changed files with 219 additions and 196 deletions

View File

@@ -13,32 +13,38 @@ export class BigPicture extends React.PureComponent<Props, {}> {
render() { render() {
const src = `img/1600/${this.props.image.src}`; const src = `img/1600/${this.props.image.src}`;
return <div className="BigPicture"> return (
<div className="BigPicture">
<div <div
className="BigPicture-image" className="BigPicture-image"
style={{ style={{
backgroundImage: `url(${src})` backgroundImage: `url(${src})`
}}> }}
</div> />
<div className="BigPicture-footer"> <div className="BigPicture-footer">
<a className="BigPicture-footerLink" <a
className="BigPicture-footerLink"
href={`img/${this.props.image.src}`} href={`img/${this.props.image.src}`}
target="_blank"> target="_blank"
>
Download Download
</a> </a>
<span className="BigPicture-footerLink" <span
className="BigPicture-footerLink"
onClick={this.props.onClose} onClick={this.props.onClose}
onKeyPress={this._keyPress} onKeyPress={this._keyPress}
tabIndex={0} > tabIndex={0}
>
Close Close
</span> </span>
</div> </div>
</div>; </div>
);
} }
private _keyPress = (e: React.KeyboardEvent) => { private _keyPress = (e: React.KeyboardEvent) => {
if (e.key === "Enter") { if (e.key === "Enter") {
this.props.onClose(); this.props.onClose();
} }
} };
} }

View File

@@ -26,7 +26,7 @@ export class Grid extends React.PureComponent<Props, {}> {
let rowWidth = 0; let rowWidth = 0;
this.props.images.forEach(image => { this.props.images.forEach(image => {
const newWidth = rowWidth + (image.width/image.height); const newWidth = rowWidth + image.width / image.height;
const height = this.props.width / newWidth; const height = this.props.width / newWidth;
if (height < this._rowHeight()) { if (height < this._rowHeight()) {
@@ -36,7 +36,7 @@ export class Grid extends React.PureComponent<Props, {}> {
}); });
row = []; row = [];
rowWidth = (image.width/image.height); rowWidth = image.width / image.height;
} else { } else {
rowWidth = newWidth; rowWidth = newWidth;
} }
@@ -51,19 +51,24 @@ export class Grid extends React.PureComponent<Props, {}> {
const height = this.props.width / row.width; const height = this.props.width / row.width;
const pics = row.images.map(image => { const pics = row.images.map(image => {
return <Picture return (
<Picture
image={image} image={image}
onClick={() => this.props.onImageSelected(image)} onClick={() => this.props.onImageSelected(image)}
key={image.src} key={image.src}
width={image.width/image.height * height} width={(image.width / image.height) * height}
/> />
);
}); });
return <div return (
<div
className="Grid-row" className="Grid-row"
style={{ height: height + "px" }} style={{ height: height + "px" }}
key={row.images.map(image => image.src).join(",")}> key={row.images.map(image => image.src).join(",")}
>
{pics} {pics}
</div>; </div>
);
}); });
return <div className="Grid">{images}</div>; return <div className="Grid">{images}</div>;

View File

@@ -13,12 +13,17 @@ export class ImageSet extends React.PureComponent<Props, {}> {
static displayName = "ImageSet"; static displayName = "ImageSet";
render() { render() {
return <div className="ImageSet"> return (
<h2>{ this.props.imageSet.location } · { this.props.imageSet.description }</h2> <div className="ImageSet">
<h2>
{this.props.imageSet.location} · {this.props.imageSet.description}
</h2>
<Grid <Grid
images={this.props.imageSet.images} images={this.props.imageSet.images}
onImageSelected={this.props.onImageSelected} onImageSelected={this.props.onImageSelected}
width={ this.props.width } /> width={this.props.width}
</div>; />
</div>
);
} }
} }

View File

@@ -13,21 +13,24 @@ export class Picture extends React.PureComponent<Props, {}> {
render() { render() {
const src = `img/600/${this.props.image.src}`; const src = `img/600/${this.props.image.src}`;
return <img return (
<img
onClick={this.props.onClick} onClick={this.props.onClick}
srcSet={this._srcset()} srcSet={this._srcset()}
src={src} src={src}
width={this.props.width + "px"} width={this.props.width + "px"}
/>; />
);
} }
private _srcset = (): string => { private _srcset = (): string => {
const srcs: string[] = []; const srcs: string[] = [];
Model.SIZES.forEach(size => { Model.SIZES.forEach(size => {
const width = this.props.image.width > this.props.image.height const width =
this.props.image.width > this.props.image.height
? size ? size
: this.props.image.width / this.props.image.height * size; : (this.props.image.width / this.props.image.height) * size;
const scale = width / this.props.width; const scale = width / this.props.width;
@@ -37,5 +40,5 @@ export class Picture extends React.PureComponent<Props, {}> {
}); });
return srcs.join(","); return srcs.join(",");
} };
} }

View File

@@ -17,10 +17,11 @@ export class Root extends React.PureComponent<Props, State> {
state: State = { state: State = {
width: window.innerWidth width: window.innerWidth
} };
componentDidMount() { componentDidMount() {
window.fetch(Model.URL) window
.fetch(Model.URL)
.then(data => data.json()) .then(data => data.json())
.then(json => this.setState({ data: json })) .then(json => this.setState({ data: json }))
.then(this._loadHash) .then(this._loadHash)
@@ -28,37 +29,40 @@ 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; window.onpopstate = this._loadHash;
} }
render() { render() {
const imageSets = this.state.data const imageSets = this.state.data
? this.state.data.sets.map(set => ? this.state.data.sets.map(set => (
<ImageSet <ImageSet
key={set.location + set.description} key={set.location + set.description}
imageSet={set} imageSet={set}
onImageSelected={this._onImageSelected} onImageSelected={this._onImageSelected}
width={this.state.width} /> width={this.state.width}
) />
))
: null; : null;
return <div className="Root"> return (
<div className="Root">
{this._bigPicture()} {this._bigPicture()}
<h1>Ski</h1> <h1>Ski</h1>
{imageSets} {imageSets}
</div>; </div>
);
} }
private _bigPicture = () => private _bigPicture = () =>
this.state.selectedImage this.state.selectedImage ? (
? <BigPicture <BigPicture
image={this.state.selectedImage} image={this.state.selectedImage}
onClose={this._showGrid} onClose={this._showGrid}
width={this.state.width} /> width={this.state.width}
: null />
) : null;
private _loadHash = () => { private _loadHash = () => {
if (window.location.hash.length > 0 && this.state.data) { if (window.location.hash.length > 0 && this.state.data) {
@@ -76,15 +80,15 @@ export class Root extends React.PureComponent<Props, State> {
} else { } else {
this.setState({ selectedImage: null }); this.setState({ selectedImage: null });
} }
} };
private _onImageSelected = (img: Model.Image) => { private _onImageSelected = (img: Model.Image) => {
this.setState({ selectedImage: img }); this.setState({ selectedImage: img });
window.history.pushState(null, "", `#${img.src}`); window.history.pushState(null, "", `#${img.src}`);
} };
private _showGrid = () => { private _showGrid = () => {
this.setState({ selectedImage: null }); this.setState({ selectedImage: null });
window.history.pushState(null, "", "#"); window.history.pushState(null, "", "#");
} };
} }

View File

@@ -2,13 +2,13 @@ export const SIZES = [1600, 1200, 800, 600, 400, 200];
export const URL = "img/data.json"; export const URL = "img/data.json";
export interface Data { export interface Data {
sets: ImageSet[] sets: ImageSet[];
} }
export interface ImageSet { export interface ImageSet {
location: string; location: string;
description: string; description: string;
images: Image[] images: Image[];
} }
export interface Image { export interface Image {