Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SanityImage component doesn't apply hotspot / crop #714

Open
philefstat opened this issue Mar 17, 2023 · 4 comments
Open

SanityImage component doesn't apply hotspot / crop #714

philefstat opened this issue Mar 17, 2023 · 4 comments
Labels
bug Something isn't working

Comments

@philefstat
Copy link

Heya, my understanding is that SanityImage should apply hotspot / crop automatically but it doesn't appear to be working.

I'm using version 1.6.0 of the module and 3.1.1 of nuxt

@philefstat philefstat added the bug Something isn't working label Mar 17, 2023
@philefstat
Copy link
Author

managed to solve it with "@sanity/image-url" but will leave open for discussion

@davidstackio
Copy link

I'm in the same boat. I'm using @sanity/image-url for images instead of this module's image functionality - mainly because of the hotspot issue.

@rylanharper
Copy link

@philefstat @davidstackio The SanityImage component hasn't been working with the hotspot for a while unfortunately..

I've been using Nuxt3 with @nuxt/image-edge which is working quite well. Here is my snippet:

My picture.js in my Sanity schema:

import { ImageSquare } from 'phosphor-react'

const aspectRatios = [
 {
   title: 'Original',
   value: 'aspect-0'
 },
 {
   title: '1/1 (Square)',
   value: 'aspect-1/1'
 },
 {
   title: '2/1',
   value: 'aspect-2/1'
 },
 {
   title: '3/2',
   value: 'aspect-3/2'
 },
 {
   title: '4/6',
   value: 'aspect-4/6'
 },
 {
   title: '16/9',
   value: 'aspect-16/9'
 }
]

export default {
 title: 'Image',
 name: 'picture',
 type: 'image',
 icon: ImageSquare,
 options: {
   hotspot: true,
   metadata: ['lqip']
 },
 fields: [
   {
     title: 'Alternative text',
     name: 'alt',
     type: 'string',
     description: 'A short description of the image. Important for SEO and accessiblity.',
     validation: (Rule) => Rule.required()
   },
   {
     title: 'Display Size (Aspect Ratio)',
     name: 'customRatio',
     type: 'string',
     description: 'Select how the image is displayed. This affects the aspect ratio of the image within its container.',
     options: {
       list: aspectRatios
     },
     initialValue: 'aspect-0'
   }
 ],
 preview: {
   select: {
     alt: 'alt',
     filename: 'asset.originalFilename',
     dimensions: 'asset.metadata.dimensions',
     image: 'asset'
   },
   prepare({ alt, dimensions, filename, image }) {
     return {
       title: alt ?? filename,
       subtitle: dimensions ? `${dimensions.width}px × ${dimensions.height}px` : '…',
       media: image ?? ImageSquare
     }
   }
 }
}

You want to install @nuxt/image-edge for Nuxt3 and add the following code to your nuxt.config.js file:

image: {
   sanity: {
     projectId: process.env.SANITY_PROJECT_ID,
     dataset: process.env.SANITY_DATASET
   },
   screens: {
     xs: 320,
     sm: 640,
     md: 768,
     lg: 1024,
     xl: 1280,
     xxl: 1536,
     '2xl': 1920,
     '3xl': 2400
   },
 }

And my custom sanity-image.vue component:

<script setup>
const props = defineProps({
  image: {
    type: Object,
    default: undefined
  }
})

const styles = computed(() => {
  if (!props.image.customRatio) {
    return {}
  }
  return {
    'aspect-0': props.image.customRatio === 'aspect-0',
    'aspect-1/1': props.image.customRatio === 'aspect-1/1',
    'aspect-2/1': props.image.customRatio === 'aspect-2/1',
    'aspect-3/2': props.image.customRatio === 'aspect-3/2',
    'aspect-4/6': props.image.customRatio === 'aspect-4/6',
    'aspect-16/9': props.image.customRatio === 'aspect-16/9'
  }
})

const computedSizes = computed(() => {
  const sizeVars = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', '2xl', '3xl']
  return sizeVars.map(size => `${size}:100vw`).join(' ')
})
</script>

<template>
  <figure class="relative w-full overflow-hidden" :class="styles">
    <nuxt-img
      :src="props.image.asset._ref"
      :alt="props.image.alt"
      provider="sanity"
      fit="cover"
      :sizes="computedSizes"
      :modifiers="{
        crop: props.image.crop,
        hotspot: props.image.hotspot,
      }"
      loading="lazy"
      class="relative w-full h-full"
    />
  </figure>
</template>

This example allows for a fully responsive image across almost all screen-sizes with a predefined srcset. It also allows the user to easily select how the aspect ratio of the image is displayed within its own container. Additionally, crops and hotspots are also supported. *Note that I am using tailwind/unocss with this example

@danielroe Maybe we can add this example above to the docs since Nuxt-Image has an official Sanity provider?

@davidstackio
Copy link

@rylanharper Thanks for sharing! I'm using Nuxt 3 as well, but will wait for @nuxt/image to hit v1. Already bookmarked your comment for future reference :)

@danielroe danielroe removed their assignment Sep 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants