Prefetch images for next slide.

This commit is contained in:
Bill Thiede 2020-03-08 11:56:07 -07:00
parent 9e4fdf7644
commit 89037b6b24

View File

@ -5,6 +5,8 @@ import {
Route, Route,
useParams useParams
} from "react-router-dom"; } from "react-router-dom";
import 'animate.css';
import Random from './rand'; import Random from './rand';
import './App.css'; import './App.css';
@ -60,7 +62,11 @@ class Slide {
constructor(items: Array<MediaItem>) { constructor(items: Array<MediaItem>) {
this.items = items; this.items = items;
} }
render() { prefetchImages() {
console.log(`prefetchImages, I have ${this.imageUrls.length} images`);
this.imageUrls.map(url => new Image().src = url);
}
get imageUrls(): Array<string> {
let w = window.innerWidth * window.devicePixelRatio; let w = window.innerWidth * window.devicePixelRatio;
let h = window.innerHeight * window.devicePixelRatio; let h = window.innerHeight * window.devicePixelRatio;
let ratio = w/h; let ratio = w/h;
@ -73,18 +79,27 @@ class Slide {
h = roundup(h, IMAGE_CHUNK); h = roundup(h, IMAGE_CHUNK);
w = Math.round(h/ratio); w = Math.round(h/ratio);
} }
console.log(`Window size ${window.innerWidth}x${window.innerHeight} with a devicePixelRatio of ${window.devicePixelRatio} for a total size of ${w}x${h}`); //console.log(`Window size ${window.innerWidth}x${window.innerHeight} with a devicePixelRatio of ${window.devicePixelRatio} for a total size of ${w}x${h}`);
return this.items.map(img => `/api/image/${img.id}?w=${w}&h=${h}`);
}
render() {
const imgs = this.imageUrls.map(url => {
let style: React.CSSProperties = { let style: React.CSSProperties = {
height: '100%', height: '100%',
width: '100%', width: '100%',
backgroundColor: 'black', backgroundColor: 'black',
// TODO(wathiede): make this handle multiple items. backgroundImage: `url(${url})`,
backgroundImage: `url(/api/image/${this.items[0].id}?w=${w}&h=${h})`,
backgroundRepeat: 'no-repeat', backgroundRepeat: 'no-repeat',
backgroundPosition: 'center center', backgroundPosition: 'center center',
backgroundSize: 'cover', backgroundSize: 'cover',
}; };
return <div style={style}></div> return <div key={url} style={style}></div>;
});
// TODO(wathiede): make sure the style handles multiple items.
return <div style={{
height: '100%',
width: '100%',
}}>{imgs}</div>;
} }
}; };
@ -183,7 +198,7 @@ class Album extends React.Component<AlbumProps, AlbumState> {
render() { render() {
// TODO(wathiede): fade transition. // TODO(wathiede): fade transition.
// TODO(wathiede): pair-up portrait orientation images. // TODO(wathiede): pair-up portrait orientation images.
let {curSlide, error, mediaItems, showUI} = this.state; let {curSlide, error, showUI} = this.state;
if (error !== null) { if (error !== null) {
return <h2>Error: {JSON.stringify(error)}</h2>; return <h2>Error: {JSON.stringify(error)}</h2>;
} else if (curSlide) { } else if (curSlide) {
@ -224,6 +239,7 @@ class Album extends React.Component<AlbumProps, AlbumState> {
}}>{ nextSlide?.render() }</div> }}>{ nextSlide?.render() }</div>
</div>; </div>;
} }
nextSlide?.prefetchImages();
return <div id="slide" onClick={(e)=>{ return <div id="slide" onClick={(e)=>{
e.stopPropagation(); e.stopPropagation();
this.setState({showUI: !showUI}) this.setState({showUI: !showUI})