Skip to content

Instantly share code, notes, and snippets.

@vtenfys
Created August 22, 2019 18:21
Show Gist options
  • Save vtenfys/d63cd57985bca6c367c5380d04dd2487 to your computer and use it in GitHub Desktop.
Save vtenfys/d63cd57985bca6c367c5380d04dd2487 to your computer and use it in GitHub Desktop.
Storyblok Responsive Image
import React from 'react'
import PropTypes from 'prop-types'
function transformImage(image, options) {
const imageService = 'https://img2.storyblok.com/'
const path = image.replace('https://a.storyblok.com', '')
return imageService + options.join('/') + path
}
function getSrcSet({ src, width, height, format, quality, scales }) {
const srcSet = []
scales.forEach(scale => {
const size = `${scale * width}x${scale * height}`
const filters = `filters:quality(${quality}):format(${format})`
const resultSrc = transformImage(src, [size, filters])
if (scale === 1) {
srcSet.push(resultSrc)
} else {
srcSet.push(`${resultSrc} ${scale}x`)
}
})
return srcSet.join(', ')
}
function ResponsiveImg({
src,
alt,
width,
height,
quality = 90,
formats = ['webp', 'jpeg'],
defaultFormat = 'jpeg',
scales = [1, 2, 3]
}) {
return (
<picture>
{formats.map(format => (
<source
key={format}
srcSet={getSrcSet({ src, width, height, format, quality, scales })}
type={`image/${format}`}
/>
))}
<img
src={getSrcSet({
src,
width,
height,
format: defaultFormat,
quality,
scales: [1]
})}
alt={alt}
width={width}
height={height}
/>
</picture>
)
}
ResponsiveImg.propTypes = {
src: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
quality: PropTypes.number,
formats: PropTypes.arrayOf(PropTypes.string.isRequired),
defaultFormat: PropTypes.string,
scales: PropTypes.arrayOf(PropTypes.number.isRequired)
}
export default ResponsiveImg
@vtenfys
Copy link
Author

vtenfys commented Aug 22, 2019

usage example:

<ResponsiveImg
  src='https://a.storyblok.com/f/51376/6016x4016/328eff2b8c/nathan-anderson-fhijwobodrs-unsplash.jpg'
  alt='Two men laughing at each other by Nathan Anderson'
  width={200}
  height={200}
/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment