Minimal Photo Gallery (ReactJS)

Minimal Image Gallery using @reactjs.  I'm very happy to be sharing on @codepen again! 🙌

  • You can apply CSS to your Pen from any stylesheet on the web.
  • Just put a URL to it here and we’ll apply it, in the order you have them, before the CSS in the Pen itself.
  • If the stylesheet you link to has the file extension of a preprocessor, we’ll attempt to process it before applying.
  • You can also link to another Pen here, and we’ll pull the CSS from that Pen and include it.
  • If it’s using a matching preprocessor, we’ll combine the code before preprocessing, so you can use the linked Pen as a true dependency.

Had this idea bubbling around in my head for a while for a simple photo gallery with animations. Decided to get some more React practice in and make it…

@nathantokyo: Minimal Image Gallery using @reactjs. I’m very happy to be sharing on @codepen again! 🙌

HTML preprocessors can make writing HTML more powerful or convenient. For instance, Markdown is designed to be easier to write and read for text documents and you could write a loop in Pug.

CSS preprocessors help make authoring CSS easier. All of them offer things like variables and mixins to provide convenient abstractions.

It’s a common practice to apply CSS to a page that styles elements such that they are consistent across all browsers. We offer two of the most popular choices: normalize.css and a reset. Or, choose Neither and nothing will be applied.

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing “font” or “ribbon” below.

You can apply CSS to your Pen from any stylesheet on the web. Just put a URL to it here and we’ll apply it, in the order you have them, before the CSS in the Pen itself.

If the stylesheet you link to has the file extension of a preprocessor, we’ll attempt to process it before applying.

You can also link to another Pen here, and we’ll pull the CSS from that Pen and include it. If it’s using a matching preprocessor, we’ll combine the code before preprocessing, so you can use the linked Pen as a true dependency.

JavaScript preprocessors can help make authoring JavaScript easier and more convenient. For instance, CoffeeScript can help prevent easy-to-make mistakes and offer a cleaner syntax and Babel can bring ECMAScript 6 features to browsers that only support ECMAScript 5.

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

You can apply a script from anywhere on the web to your Pen. Just put a URL to it here and we’ll add it, in the order you have them, before the JavaScript in the Pen itself.

If the script you link to has the file extension of a preprocessor, we’ll attempt to process it before applying.

You can also link to another Pen here, and we’ll pull the JavaScript from that Pen and include it. If it’s using a matching preprocessor, we’ll combine the code before preprocessing, so you can use the linked Pen as a true dependency.

$base: 1vh; $color: white; $dark: darken(adjust-hue($color, 20%),40%); $ease-in: cubic-bezier(0.600, 0.040, 0.980, 0.335); $ease-out: cubic-bezier(0.075, 0.820, 0.165, 1.000); $ease-in-out: cubic-bezier(0.785, 0.135, 0.150, 0.860); $short: 300ms; $long: 2500ms; html{ font-size: $base; @media (orientation: portrait){ font-size: 1vw; } } .Selected{ position: absolute; width: 100%; height: 100%; overflow: hidden; &__image{ position: absolute; top: 50%; left: 50%; height: 125%; width: 125%; background-size: cover; background-position: center; transform: translate3d(-50%, -50%, 0) scale(0.85); transition: transform $long $ease-out; transform-origin: 50% 50%; } &:before, &:after{ content: ”; background: $color; position: absolute; top: -2%; height: 104%; width: 102%; } &:before{ right: 101%; z-index: 2; } &:after{ left: 101%; } &–entering{ &:before, &:after{ transition: transform $short $ease-in-out; } &.Selected–moving{ &-left{ transition: transform $short $ease-in; &:after{transform: translateX(-100%);} .Selected__image{ transform: translate3d(-42.5%, -50%, 0) scale(0.85) skew(-5deg); transition: transform 1ms linear $short; } } &-right{ transition: transform $short $ease-in; &:before{transform: translateX(100%);} .Selected__image{ transform: translate3d(-57.5%, -50%, 0) scale(0.85) skew(5deg); transition: transform 1ms linear $short; } } } } &–exiting{ &:before, &:after{ transition: transform $short $ease-in-out; } &.Selected–moving{ &-left:after{ transform: translateX(-200%); } &-right:before{ transform: translateX(200%); } } } } .Thumb{ position: absolute; bottom: 0; left: 50%; width: 16%; height: 80%; display: inline-block; cursor: pointer; transform: translateX(-100vw); opacity: 0; overflow: hidden; &__inner{ position: absolute; width: 125%; height: 80%; top: 50%; left: 50%; background-size: cover; background-position: center; transform: scale(0.8) translate3d(-50%,-50%,0); transform-origin: left top; transition: transform $long $ease-out; } &:hover{ .Thumb__inner{ transition: transform $long $ease-out; transform: scale(1.2) translate3d(-50%,-50%,0); } } &–offset{ &-4, &-3, &-2, &-1, &0, &1, &2, &3, &4{ opacity: 1; transition: transform $long $ease-out, opacity $short $ease-out; } } &–offset-5, &–offset-6, &–offset-7{transform: translateX(-700%); } &–offset-4{transform: translateX(-550%); transition-delay: $short*4/8;} &–offset-3{transform: translateX(-425%); transition-delay: $short*3/8;} &–offset-2{transform: translateX(-300%); transition-delay: $short*2/8;} &–offset-1{transform: translateX(-175%); transition-delay: $short*1/8;} &–offset0{ transform: translateX(-50%); transition-delay: $short*0/8; .Thumb__inner{ transform: scale(0.8) translate3d(-50%,-50%,0) !important;} } &–offset1{transform: translateX(75%); transition-delay: $short*1/8;} &–offset2{transform: translateX(200%); transition-delay: $short*2/8;} &–offset3{transform: translateX(325%); transition-delay: $short*3/8;} &–offset4{transform: translateX(450%); transition-delay: $short*4/8;} &–offset5, &–offset6, &–offset7{transform: translateX(600%);} } .Thumbs{ text-align: center; position: relative; position: absolute; width: 100%; height: 100%; overflow: hidden; transform-origin: 50% 50%; transition: transform $long $ease-out; &–entering{ transition: transform 1ms linear; &.Thumbs–moving{ &-left{ transform: skewX(3deg)} &-right{ transform: skewX(-3deg)} } } } .Gallery{ height: 60rem; width: 100rem; &__selected{ position: absolute; top: 0; left: 0; width: 100%; height: 75%; } &__thumbs{ position: absolute; bottom: 0; left: 0; width: 100%; height: 20%; } } .Center{ position: relative; height: 100vh; width: 100vw; &__content{ position: absolute; top: 50%; left: 50%; transform: translate3d(-50%,-50%,0); } }

console.clear(); const { Component } = React; const Selected = (props) => { return (

) } const Thumb = (props) => { return (

{ props.select(props.index, props.offset) } } >

); } const positions = [-2, -1, 0, 1, 2]; const Thumbs = (props) => { return (

{props.images.map( (src, index) => { const count = props.images.length; let offset = index – props.active if (offset > count/2) offset -= count else if (offset < -count/2) offset += count return })}

); } class Gallery extends Component { constructor(props){ super(props); let loopedImages = images; while(loopedImages.length < 13) loopedImages = loopedImages.concat(props.images) this.state = { active: 0, showing: 0, phase: null, direction: 'left', loopedImages } } componentDidMount(){ setTimeout(()=>{ this.selectImage(1,1); },1000) } selectImage(index, offset){ if (!this.state.phase && offset !== 0){ this.setState({ active: index, phase: ‘entering’, direction: offset >= 0 ? ‘left’ : ‘right’ }) setTimeout(()=>{ this.setState({ changing: false, showing: index, phase: ‘exiting’ }) setTimeout(()=>{ this.setState({phase: null}) }, 300) }, 400) } } render(){ return (

) } } const Center = (props) => { return (

{props.children}

) } const images = [ ‘https://unsplash.it/1000/600?image=1069’, ‘https://unsplash.it/1000/600?image=1068’, ‘https://unsplash.it/1000/600?image=1081’, ‘https://unsplash.it/1000/600?image=855’, ‘https://unsplash.it/1000/600?image=824’, ‘https://unsplash.it/1000/600?image=655’, ‘https://unsplash.it/1000/600?image=881’, ‘https://unsplash.it/1000/600?image=314’, ‘https://unsplash.it/1000/600?image=503’, ‘https://unsplash.it/1000/600?image=447’, ] class App extends Component { render(){ return (

); } } ReactDOM.render(, document.querySelector(“.container”));

Minimal Photo Gallery (ReactJS)