Skip to content

Commit

Permalink
use currentSrc for imgs in <picture> tags - #174
Browse files Browse the repository at this point in the history
  • Loading branch information
fennifith committed Nov 15, 2022
1 parent 8a7777d commit a490d0b
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 2 deletions.
24 changes: 24 additions & 0 deletions src/__tests__/__snapshots__/medium-zoom.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,30 @@ exports[`open() open() twice does not zoom twice 1`] = `
</body>
`;

exports[`open() open() with \`<picture>\` renders correctly 1`] = `
<body
class="medium-zoom--opened"
>
<picture>
<source
srcset="image-300x200.jpg 300w"
/>
<img
class="medium-zoom-image medium-zoom-image--hidden"
/>
</picture>
<div
class="medium-zoom-overlay"
style="background: rgb(255, 255, 255);"
/>
<img
class="medium-zoom-image medium-zoom-image--opened"
src="http://localhost/mock-src.png"
style="position: absolute; top: 0px; left: 0px; width: 0px; height: 0px;"
/>
</body>
`;
exports[`open() open() with \`data-zoom-src\` renders correctly 1`] = `
<body
class="medium-zoom--opened"
Expand Down
35 changes: 35 additions & 0 deletions src/__tests__/medium-zoom.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,41 @@ describe('open()', () => {
expect(root).toMatchSnapshot()
})

test('open() with `<picture>` renders correctly', async () => {
expect.assertions(6)

// <picture>
const picture = document.createElement('picture')
// | <source ... ></source>
const source = document.createElement('source')
source.srcset = `image-300x200.jpg 300w`
picture.appendChild(source)
// | <img>
const img = document.createElement('img')
jest
.spyOn(img, 'currentSrc', 'get')
.mockReturnValue('http://localhost/mock-src.png')
picture.appendChild(img)
// </picture>
root.appendChild(picture)

const zoom = mediumZoom('img')
await zoom.open()
jest.runAllTimers()

expect([...img.classList]).toEqual([
'medium-zoom-image',
'medium-zoom-image--hidden',
])
expect(document.querySelector('.medium-zoom-image--opened')).toBeTruthy()
expect(document.querySelector('.medium-zoom-image--opened').src).toEqual(
img.currentSrc
)
expect(document.querySelector('.medium-zoom-overlay')).toBeTruthy()
expect(document.querySelector('.medium-zoom--opened')).toBeTruthy()
expect(root).toMatchSnapshot()
})

test('mediumZoom({ background }).open() renders correctly', async () => {
expect.assertions(1)

Expand Down
17 changes: 15 additions & 2 deletions src/medium-zoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,10 @@ const mediumZoom = (selector, options = {}) => {
: zoomTarget.naturalHeight || viewportHeight
const { top, left, width, height } = zoomTarget.getBoundingClientRect()

const scaleX = Math.min(Math.max(width, naturalWidth), viewportWidth) / width
const scaleY = Math.min(Math.max(height, naturalHeight), viewportHeight) / height
const scaleX =
Math.min(Math.max(width, naturalWidth), viewportWidth) / width
const scaleY =
Math.min(Math.max(height, naturalHeight), viewportHeight) / height
const scale = Math.min(scaleX, scaleY)
const translateX =
(-left +
Expand Down Expand Up @@ -328,6 +330,17 @@ const mediumZoom = (selector, options = {}) => {
document.body.appendChild(active.template)
}

// If the selected <img> tag is inside a <picture> tag, set the
// currently-applied source as the cloned `src=` attribute.
// (as these might differ, or src= might be unset in some cases)
if (
active.original.parentElement &&
active.original.parentElement.tagName === 'PICTURE' &&
active.original.currentSrc
) {
active.zoomed.src = active.original.currentSrc
}

document.body.appendChild(active.zoomed)

window.requestAnimationFrame(() => {
Expand Down
38 changes: 38 additions & 0 deletions stories/attributes.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,41 @@ Zoom on an image having \`srcset\` attributes.
`,
}
)
.add(
'<picture> tag',
() => `
<picture>
<source type="image/jpeg" srcset="image-1x300.jpg 300w, image-1x600.jpg 600w"></source>
<img>
</picture>
<script>
const zoom = mediumZoom('img');
</script>
`,
{
notes: `
Zoom on an image inside a &lt;picture&gt; tag.
The cloned image mirrors the picture structure and resizes the same as a usual image tag.
`,
}
)
.add(
'<picture> tag and data-zoom-src',
() => `
<picture>
<source type="image/jpeg" srcset="image-1x300.jpg 300w, image-1x600.jpg 600w"></source>
<img data-zoom-src="image-1.jpg">
</picture>
<script>
const zoom = mediumZoom('img');
</script>
`,
{
notes: `
Zoom on an image inside a &lt;picture&gt; tag.
The cloned image mirrors the picture structure and resizes the same as a usual image tag, which then uses the data-zoom-src value once loaded.
`,
}
)

0 comments on commit a490d0b

Please sign in to comment.