Skip to content

Commit

Permalink
Fix image blur cover when fill and blurDataURL (#44317)
Browse files Browse the repository at this point in the history
- Fixes #42765 
- Fixes #40644
  • Loading branch information
styfle committed Feb 2, 2023
1 parent b294073 commit bf7fea5
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/next/src/client/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,7 @@ const Image = forwardRef<HTMLImageElement | null, ImageProps>(
blurWidth,
blurHeight,
blurDataURL,
objectFit: imgStyle.objectFit,
}
)}")`,
}
Expand Down
10 changes: 9 additions & 1 deletion packages/next/src/shared/lib/image-blur-svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ export function getImageBlurSvg({
blurWidth,
blurHeight,
blurDataURL,
objectFit,
}: {
widthInt?: number
heightInt?: number
blurWidth?: number
blurHeight?: number
blurDataURL: string
objectFit?: string
}): string {
const std = blurWidth && blurHeight ? '1' : '20'
const svgWidth = blurWidth || widthInt
Expand All @@ -23,5 +25,11 @@ export function getImageBlurSvg({
if (svgWidth && svgHeight) {
return `%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 ${svgWidth} ${svgHeight}'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='${std}'/%3E${feComponentTransfer}%3C/filter%3E%3Cimage preserveAspectRatio='none' filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='${blurDataURL}'/%3E%3C/svg%3E`
}
return `%3Csvg xmlns='http%3A//www.w3.org/2000/svg'%3E%3Cimage style='filter:blur(20px)' x='0' y='0' height='100%25' width='100%25' href='${blurDataURL}'/%3E%3C/svg%3E`
const preserveAspectRatio =
objectFit === 'contain'
? 'xMidYMid'
: objectFit === 'cover'
? 'xMidYMid slice'
: 'none'
return `%3Csvg xmlns='http%3A//www.w3.org/2000/svg'%3E%3Cimage style='filter:blur(20px)' preserveAspectRatio='${preserveAspectRatio}' x='0' y='0' height='100%25' width='100%25' href='${blurDataURL}'/%3E%3C/svg%3E`
}
49 changes: 49 additions & 0 deletions test/integration/next-image-new/default/pages/fill-blur.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react'
import Image from 'next/image'

// We don't use a static import intentionally
const blurDataURL =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAAAAABd+vKJAAAANklEQVR42mNg4GRwdWBgZ2BgUGI4dYhBmYFBgiHy308PBlEGKYbr//9fYJBlYDBYv3nzGkUGANGMDBq2MCnBAAAAAElFTkSuQmCC'

export default function Page() {
return (
<>
<p>Image with fill with blurDataURL</p>
<div style={{ position: 'relative', display: 'flex', minHeight: '30vh' }}>
<Image
fill
alt="alt"
src="/wide.png"
placeholder="blur"
blurDataURL={blurDataURL}
id="fit-cover"
style={{ objectFit: 'cover' }}
/>
</div>

<div style={{ position: 'relative', display: 'flex', minHeight: '30vh' }}>
<Image
fill
alt="alt"
src="/wide.png"
placeholder="blur"
blurDataURL={blurDataURL}
id="fit-contain"
style={{ objectFit: 'contain' }}
/>
</div>

<div style={{ position: 'relative', display: 'flex', minHeight: '30vh' }}>
<Image
fill
alt="alt"
src="/wide.png"
placeholder="blur"
blurDataURL={blurDataURL}
id="fit-fill"
style={{ objectFit: 'fill' }}
/>
</div>
</>
)
}
17 changes: 17 additions & 0 deletions test/integration/next-image-new/default/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,23 @@ function runTests(mode) {
)
})

it('should render correct objectFit when blurDataURL and fill', async () => {
const html = await renderViaHTTP(appPort, '/fill-blur')
const $ = cheerio.load(html)

expect($('#fit-cover')[0].attribs.style).toBe(
`position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;object-fit:cover;color:transparent;background-size:cover;background-position:50% 50%;background-repeat:no-repeat;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg'%3E%3Cimage style='filter:blur(20px)' preserveAspectRatio='xMidYMid slice' x='0' y='0' height='100%25' width='100%25' href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAAAAABd+vKJAAAANklEQVR42mNg4GRwdWBgZ2BgUGI4dYhBmYFBgiHy308PBlEGKYbr//9fYJBlYDBYv3nzGkUGANGMDBq2MCnBAAAAAElFTkSuQmCC'/%3E%3C/svg%3E")`
)

expect($('#fit-contain')[0].attribs.style).toBe(
`position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;object-fit:contain;color:transparent;background-size:contain;background-position:50% 50%;background-repeat:no-repeat;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg'%3E%3Cimage style='filter:blur(20px)' preserveAspectRatio='xMidYMid' x='0' y='0' height='100%25' width='100%25' href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAAAAABd+vKJAAAANklEQVR42mNg4GRwdWBgZ2BgUGI4dYhBmYFBgiHy308PBlEGKYbr//9fYJBlYDBYv3nzGkUGANGMDBq2MCnBAAAAAElFTkSuQmCC'/%3E%3C/svg%3E")`
)

expect($('#fit-fill')[0].attribs.style).toBe(
`position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;object-fit:fill;color:transparent;background-size:fill;background-position:50% 50%;background-repeat:no-repeat;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg'%3E%3Cimage style='filter:blur(20px)' preserveAspectRatio='none' x='0' y='0' height='100%25' width='100%25' href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAAAAABd+vKJAAAANklEQVR42mNg4GRwdWBgZ2BgUGI4dYhBmYFBgiHy308PBlEGKYbr//9fYJBlYDBYv3nzGkUGANGMDBq2MCnBAAAAAElFTkSuQmCC'/%3E%3C/svg%3E")`
)
})

it('should be valid HTML', async () => {
let browser
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ const runTests = (isDev) => {
it('should add placeholder with blurDataURL and fill', async () => {
const style = $('#blurdataurl-fill').attr('style')
expect(style).toBe(
`position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent;background-size:cover;background-position:50% 50%;background-repeat:no-repeat;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg'%3E%3Cimage style='filter:blur(20px)' x='0' y='0' height='100%25' width='100%25' href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNM/s/wBwAFjwJgf8HDLgAAAABJRU5ErkJggg=='/%3E%3C/svg%3E")`
`position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent;background-size:cover;background-position:50% 50%;background-repeat:no-repeat;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg'%3E%3Cimage style='filter:blur(20px)' preserveAspectRatio='none' x='0' y='0' height='100%25' width='100%25' href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNM/s/wBwAFjwJgf8HDLgAAAABJRU5ErkJggg=='/%3E%3C/svg%3E")`
)
})

Expand Down

0 comments on commit bf7fea5

Please sign in to comment.