Skip to content

Commit

Permalink
Merge pull request #24 from BKWLD/fix-sanity-crop-handling
Browse files Browse the repository at this point in the history
Fix Sanity crop handling
  • Loading branch information
weotch committed Aug 21, 2023
2 parents cb7b55b + e34521a commit 3970024
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 18 deletions.
11 changes: 11 additions & 0 deletions packages/sanity-next/cypress/component/SanityNextVisual.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import dereferencedVisual from '../fixtures/dereferencedVisual.json'
import referentialImage from '../fixtures/referentialImage.json'
import referentialVideo from '../fixtures/referentialVideo.json'
import referentialVisual from '../fixtures/referentialVisual.json'
import resizedImage from '../fixtures/resizedImage.json'

// Viewport sizes
const VW = Cypress.config('viewportWidth'),
Expand Down Expand Up @@ -54,6 +55,16 @@ describe('de-referenced source', () => {
cy.get('video').should('have.attr', 'aria-label', 'Placeholder test visual')
})

it('passes through Sanity cropping instructions', () => {
cy.mount(<SanityNextVisual
image={ resizedImage }
data-cy='next-visual' />)
cy.get('[data-cy=next-visual]').should('exist')
cy.get('img')
.invoke('attr', 'src')
.should('contain', 'rect=150,0,150,150')
})

})

describe('referential source', () => {
Expand Down
99 changes: 99 additions & 0 deletions packages/sanity-next/cypress/fixtures/resizedImage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{
"alt": "Placeholder test image",
"asset": {
"uploadId": "BQg2QlOwtC9viIp8Qc6mYaNsbfYeO4cc",
"_type": "sanity.imageAsset",
"_id": "image-5e598e68ba3ee4438ac113a8df445afe21b5a164-300x150-png",
"_createdAt": "2023-08-10T21:35:18Z",
"_updatedAt": "2023-08-10T21:35:18Z",
"originalFilename": "300x150.png",
"extension": "png",
"metadata": {
"hasAlpha": true,
"lqip": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAuklEQVQokbWSaw6DIBCEvf+5CEJ8xMhLQc6yzWxKQ9Rq06Y/JsDO8jkbaXLOtG0blfUb5YrR1MWiTwD73vzcM/AOcvehfJYQSinRsizkvX9pXVeuQzFG9kMI7GGfUjomLELDOI6klKK2bUlrTdM0kbWWnHNkjGG/6zr2hmFg+CUQTVJKEkIwFIB5nhmGte97hsEDOFwBMRJGwWUIyXABY5dxkRT1kjrG+OefUh/e6ey57P3TkX992AA+AD0OxVcQwnW2AAAAAElFTkSuQmCC",
"dimensions": {
"width": 300,
"aspectRatio": 2,
"height": 150,
"_type": "sanity.imageDimensions"
},
"isOpaque": true,
"blurHash": "M5PGjX%M-;-;-;_3j[j[j[j[~qj[IUWBIU",
"_type": "sanity.imageMetadata",
"palette": {
"_type": "sanity.imagePalette",
"darkMuted": {
"population": 0,
"background": "#4c4c4c",
"_type": "sanity.imagePaletteSwatch",
"foreground": "#fff",
"title": "#fff"
},
"muted": {
"background": "#9b9b9b",
"_type": "sanity.imagePaletteSwatch",
"foreground": "#000",
"title": "#fff",
"population": 3.58
},
"lightVibrant": {
"title": "#fff",
"population": 0,
"background": "#bcbcbc",
"_type": "sanity.imagePaletteSwatch",
"foreground": "#000"
},
"darkVibrant": {
"background": "#424242",
"_type": "sanity.imagePaletteSwatch",
"foreground": "#fff",
"title": "#fff",
"population": 0
},
"lightMuted": {
"background": "#bcbcbc",
"_type": "sanity.imagePaletteSwatch",
"foreground": "#000",
"title": "#fff",
"population": 0.47
},
"vibrant": {
"foreground": "#fff",
"title": "#fff",
"population": 0,
"background": "#7f7f7f",
"_type": "sanity.imagePaletteSwatch"
},
"dominant": {
"title": "#fff",
"population": 3.58,
"background": "#9b9b9b",
"_type": "sanity.imagePaletteSwatch",
"foreground": "#000"
}
}
},
"url": "https://cdn.sanity.io/images/3dmwp8fs/development/5e598e68ba3ee4438ac113a8df445afe21b5a164-300x150.png",
"size": 3427,
"_rev": "76ewoxhAm9hNbPwR5Egg7s",
"mimeType": "image/png",
"sha1hash": "5e598e68ba3ee4438ac113a8df445afe21b5a164",
"path": "images/3dmwp8fs/development/5e598e68ba3ee4438ac113a8df445afe21b5a164-300x150.png",
"assetId": "5e598e68ba3ee4438ac113a8df445afe21b5a164"
},
"crop": {
"top": 0,
"left": 0.5,
"bottom": 0,
"_type": "sanity.imageCrop",
"right": 0
},
"hotspot": {
"width": 0.5,
"x": 0,
"y": 0.5,
"height": 1,
"_type": "sanity.imageHotspot"
},
"_type": "image"
}
4 changes: 2 additions & 2 deletions packages/sanity-next/src/SanityNextVisual.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ReactElement } from 'react'
import NextVisual from '@react-visual/next'
import { makeImageUrl, makeFileUrl, imageLoader } from './lib/urlBuilding'
import { makeImageUrl, makeFileUrl, makeImageLoader } from './lib/urlBuilding'
import {
aspectRatioFromSource,
altTextFromSource,
Expand Down Expand Up @@ -42,7 +42,7 @@ export default function SanityNextVisual(

// Props that are calculated from Sanity data (mostly images)
image={ makeImageUrl(image) }
imageLoader={ imageLoader }
imageLoader={ makeImageLoader(image) }
video={ makeFileUrl(video) }
aspect={ aspect || aspectRatioFromSource(image) }
position={ position || objectPositionFromSource(image) }
Expand Down
31 changes: 15 additions & 16 deletions packages/sanity-next/src/lib/urlBuilding.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import createImageUrlBuilder from '@sanity/image-url'
import {
getFileAsset,
getImage,
type SanityFileSource
} from '@sanity/asset-utils'
import { getFileAsset, type SanityFileSource } from '@sanity/asset-utils'
import type { ImageUrlBuilder } from '@sanity/image-url/lib/types/builder'
import type { ImageLoaderProps } from 'next/image'
import type { ImageLoader, ImageLoaderProps } from 'next/image'
import type { SanityImageSource } from '@sanity/image-url/lib/types/types'
import { ObjectFit } from '@react-visual/next'

Expand Down Expand Up @@ -38,28 +34,31 @@ export function makeImageBuilder(source: SanityImageSource, {
}: imageUrlBuildingOptions = {}): ImageUrlBuilder {

// Open up builder
const builder = imageBuilder?.image(source).auto('format')
let builder = imageBuilder?.image(source).auto('format')

// Map the ObjectFit values to Sanity image CDN equivalents. The default
// is 'max'.
// https://www.sanity.io/docs/image-urls#fit-45b29dc6f09f
builder.fit(fit == ObjectFit.Cover ? 'min' : 'max')
builder = builder.fit(fit == ObjectFit.Cover ? 'min' : 'max')

// Conditionally add dimensions
if (width) builder.width(width)
if (height) builder.height(height)
if (width) builder = builder.width(width)
if (height) builder = builder.height(height)

// Return builder
return builder
}

// Make a next/image url loader
export function imageLoader(
{ src, width, quality }: ImageLoaderProps
): string {
const builder = makeImageBuilder(getImage(src)).width(width)
if (quality) builder.quality(quality)
return builder.url()
export function makeImageLoader(
source?: SanityImageSource
): ImageLoader | undefined {
if (!source) return undefined
return ({ width, quality }: ImageLoaderProps): string => {
let builder = makeImageBuilder(source, { width })
if (quality) builder = builder.quality(quality)
return builder.url()
}
}

// Return the URL of an asset
Expand Down

0 comments on commit 3970024

Please sign in to comment.