storyblok-toolkit icon indicating copy to clipboard operation
storyblok-toolkit copied to clipboard

[Image] Allow adjustment of aspect ratio

Open Dangoo opened this issue 3 years ago • 1 comments

Is your feature request related to a problem? Please describe. Currently the Image component parses the originalWidth and originalHeight from the Storyblok image URL within getImageProps and returns them for imageProps as width and height: https://github.com/storyofams/storyblok-toolkit/blob/3bae06ab0c6c5d1c4b74e82c7395077994ffa476/src/image/getImageProps.ts#L47-L48

These are then used for the dummy element spanning the container for the aspect ratio, which makes it impossible to adjust the aspect ratio from the outside: https://github.com/storyofams/storyblok-toolkit/blob/3bae06ab0c6c5d1c4b74e82c7395077994ffa476/src/image/Image.tsx#L131

Describe the solution you'd like Do you see a way to provide a desired aspect ratio through props or inferring them from fluid or fixed props when they contain width && height? Maybe even the handling of the aspect ratio itself could be improved by using CSS aspect-ratio:

const supportsAspectRatio = CSS?.supports('aspect-ratio: 1/1') || false

const pictureStyles: CSSProperties = {
  /* ... */
  ...supportsAspectRatio && {aspectRatio: `${aspectRatio[0]} / ${aspectRatio[1]}`}
}

return (
  <Wrapper style={{ height, width }}>
    {!supportsAspectRatio && (
      <div
        aria-hidden
        style={{
          paddingTop: `${(imageProps.height / imageProps.width) * 100}%`,
        }}
      />
    )}
    <Picture
      {...pictureProps}
      style={{
        ...pictureStyles,
        /* ... */
      }}
    />
    ...
  </Wrapper>
)

Describe alternatives you've considered For now we had to patch it from the outside using a custom wrapper:

export const PatchedImage: React.FC<ImageProps & {aspectRatio: [number, number]}> = ({
  aspectRatio,
  height,
  width,
  ...restProps
}) => {
  return (
    <div style={{ aspectRatio: `${aspectRatio[0]} / ${aspectRatio[1]}` }}>
      <Image {...restProps} fluid={[width, height]} width="100%" height="100%" />
    </div>
  )
}

Let me know what you think, happy to discuss the details or helping with the implementation :)

/cc @martinjuhasz

Dangoo avatar Jul 22 '21 10:07 Dangoo

I am running into this issue as well. I am trying to use a "fixed" image that I supply a width and height. The width and height are correctly put into the image url and load an image with those exact dimensions however the div with padding-top that achieves the image ratio is based off of the original images dimensions.

cronin4392 avatar Oct 28 '21 18:10 cronin4392