Shuffle slideshow, only show images in the same orientation as screen.
This commit is contained in:
parent
d0ce89b27c
commit
792471bf00
109
react-slideshow/src/App.js
vendored
109
react-slideshow/src/App.js
vendored
@ -5,9 +5,22 @@ import {
|
||||
Route,
|
||||
useParams
|
||||
} from "react-router-dom";
|
||||
|
||||
import Random from './rand';
|
||||
import './App.css';
|
||||
|
||||
let CONFIG;
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
CONFIG = {
|
||||
sleepTimeSeconds: 5 * 60,
|
||||
showUI: false,
|
||||
}
|
||||
} else {
|
||||
CONFIG = {
|
||||
sleepTimeSeconds: 10,
|
||||
showUI: true,
|
||||
}
|
||||
}
|
||||
|
||||
const IMAGE_CHUNK = 256;
|
||||
const roundup = (v, mod) => {
|
||||
let r = v % mod;
|
||||
@ -18,6 +31,20 @@ const roundup = (v, mod) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Shuffles array in place. ES6 version
|
||||
* From https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array
|
||||
* @param {Array} a items An array containing the items.
|
||||
*/
|
||||
function shuffle(a) {
|
||||
let rng = new Random(new Date().getDay());
|
||||
for (let i = a.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(rng.nextFloat() * (i + 1));
|
||||
[a[i], a[j]] = [a[j], a[i]];
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
class Album extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -25,6 +52,7 @@ class Album extends React.Component {
|
||||
error: null,
|
||||
mediaItems: null,
|
||||
idx: 0,
|
||||
showUI: props.showUI,
|
||||
};
|
||||
}
|
||||
componentDidMount() {
|
||||
@ -52,18 +80,44 @@ class Album extends React.Component {
|
||||
h = roundup(h, IMAGE_CHUNK);
|
||||
w = (h/ratio).toFixed();
|
||||
}
|
||||
console.log(`Window size ${window.innerWidth}x${window.innerHeight} with a devicePixelRatio of ${window.devicePixelRatio} for a total size of ${w}x${h}`);
|
||||
|
||||
//let w = roundup(window.innerWidth*window.devicePixelRatio, IMAGE_CHUNK);
|
||||
//let h = roundup(window.innerHeight*window.devicePixelRatio, IMAGE_CHUNK);
|
||||
let {idx, error, mediaItems} = this.state;
|
||||
let {idx, error, mediaItems, showUI} = this.state;
|
||||
if (error !== null) {
|
||||
return <h2>Error: {JSON.stringify(error)}</h2>;
|
||||
} else if (mediaItems !== null) {
|
||||
let numImages = mediaItems.length;
|
||||
let landscapes = mediaItems.filter((mi) => {
|
||||
let md = mi.mediaMetadata;
|
||||
let ratio = md.width/md.height;
|
||||
return ratio > 1;
|
||||
});
|
||||
|
||||
let portraits = mediaItems.filter((mi) => {
|
||||
let md = mi.mediaMetadata;
|
||||
let ratio = md.width/md.height;
|
||||
return ratio <= 1;
|
||||
});
|
||||
|
||||
console.log(`${landscapes.length} landscape photos`);
|
||||
console.log(`${portraits.length} portraits photos`);
|
||||
let photos;
|
||||
if (ratio > 1) {
|
||||
console.log('display in landscape mode');
|
||||
photos = landscapes;
|
||||
} else {
|
||||
console.log('display in portrait mode');
|
||||
photos = portraits;
|
||||
}
|
||||
photos = shuffle(photos);
|
||||
|
||||
let numImages = photos.length;
|
||||
let nextIdx = (idx+1)%numImages;
|
||||
let prevIdx = (numImages+idx-1)%numImages;
|
||||
let image = mediaItems[idx];
|
||||
let nextImage = mediaItems[nextIdx];
|
||||
let image = photos[idx];
|
||||
let nextImage = photos[nextIdx];
|
||||
let prevImage = photos[prevIdx];
|
||||
let style = {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
@ -74,26 +128,44 @@ class Album extends React.Component {
|
||||
backgroundSize: 'cover',
|
||||
};
|
||||
let prefetchStyle = {
|
||||
// display: 'none'
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
width: '25%',
|
||||
height: '25%',
|
||||
bottom: 0,
|
||||
};
|
||||
console.log(`window.devicePixelRatio ${window.devicePixelRatio}`);
|
||||
return <div style={style} onClick={(e)=>{
|
||||
e.stopPropagation();
|
||||
this.setState({idx: nextIdx})
|
||||
}}>
|
||||
<img
|
||||
style={prefetchStyle}
|
||||
let leftPrefetchStyle = {
|
||||
left: 0,
|
||||
...prefetchStyle
|
||||
};
|
||||
let rightPrefetchStyle = {
|
||||
right: 0,
|
||||
...prefetchStyle
|
||||
};
|
||||
let ui;
|
||||
if (showUI) {
|
||||
ui = <div>
|
||||
<img
|
||||
style={leftPrefetchStyle}
|
||||
onClick={(e)=>{
|
||||
e.stopPropagation();
|
||||
this.setState({idx: prevIdx})
|
||||
}}
|
||||
src={`/api/image/${prevImage.id}?w=${w}&h=${h}`} alt="prefetch prev" />
|
||||
<img
|
||||
style={rightPrefetchStyle}
|
||||
onClick={(e)=>{
|
||||
e.stopPropagation();
|
||||
this.setState({idx: nextIdx})
|
||||
}}
|
||||
src={`/api/image/${nextImage.id}?w=${w}&h=${h}`} alt="prefetch next" />
|
||||
</div>;
|
||||
}
|
||||
return <div style={style} onClick={(e)=>{
|
||||
e.stopPropagation();
|
||||
this.setState({showUI: !showUI})
|
||||
}}>
|
||||
{ ui }
|
||||
</div>;
|
||||
} else {
|
||||
return <h2>Loading...</h2>;
|
||||
}
|
||||
@ -141,14 +213,15 @@ class AlbumIndex extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const AlbumRoute = () => {
|
||||
const AlbumRoute = ({showUI}) => {
|
||||
// We can use the `useParams` hook here to access
|
||||
// the dynamic pieces of the URL.
|
||||
let { albumId } = useParams();
|
||||
return <Album album={albumId} />;
|
||||
return <Album album={albumId} showUI={showUI} />;
|
||||
}
|
||||
|
||||
const App = () => {
|
||||
let {showUI} = CONFIG;
|
||||
return <Router>
|
||||
<Switch>
|
||||
<Route exact path="/">
|
||||
@ -157,7 +230,7 @@ const App = () => {
|
||||
</div>
|
||||
</Route>
|
||||
<Route exact path="/:albumId">
|
||||
<AlbumRoute />
|
||||
<AlbumRoute showUI={showUI} />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
|
||||
30
react-slideshow/src/rand.js
vendored
Normal file
30
react-slideshow/src/rand.js
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// From https://gist.github.com/blixt/f17b47c62508be59987b
|
||||
/**
|
||||
* Creates a pseudo-random value generator. The seed must be an integer.
|
||||
*
|
||||
* Uses an optimized version of the Park-Miller PRNG.
|
||||
* http://www.firstpr.com.au/dsp/rand31/
|
||||
*/
|
||||
function Random(seed) {
|
||||
console.log(`Seeding prng with ${seed}`);
|
||||
this._seed = seed % 2147483647;
|
||||
if (this._seed <= 0) this._seed += 2147483646;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudo-random value between 1 and 2^32 - 2.
|
||||
*/
|
||||
Random.prototype.next = function () {
|
||||
return this._seed = this._seed * 16807 % 2147483647;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a pseudo-random floating point number in range [0, 1).
|
||||
*/
|
||||
Random.prototype.nextFloat = function (opt_minOrMax, opt_max) {
|
||||
// We know that result of next() will be 1 to 2147483646 (inclusive).
|
||||
return (this.next() - 1) / 2147483646;
|
||||
};
|
||||
|
||||
export default Random;
|
||||
Loading…
x
Reference in New Issue
Block a user