I'm trying to create a map of button elements that overlay a full-screen image, positioned over all the 'buttons' depicted on the image. When the image resizes, the button elements should resize as well.
I initially used an SVG image map for this, but it had a positioning bug (the link below) that didn't allow for the video player inside the foreignObject to show.
SVG foreignObject and absolute positioning
I figured using absolute positioning, and JS to measure the width of the background image was the best way to go. However, I'm having trouble making it work.
Below is the project, with the white box needing to be positioned over the background image (the entire box, with chocolates, and the screen).
The image is within a div as a background, like so:
export const BackgroundLightsOn = styled.div`
position: absolute;
background: url(${BgLightsOn});
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
height: 100%;
width: 100%;
border: 1px solid red;
`
Unfortunately, getting the dimensions of this DOM element gets the dimensions of the div, not the image (which is sometimes larger than the viewport). Below is the 'resizing' code, but this connects to backgroundRef (which is the div element the image is the background, not the image itself).
import React, { useEffect, useRef } from 'react';
import {
TruffleTinContainer,
TruffleTinOutside,
} from '../truffle-tin/styledTruffleTin';
export default function TruffleTin({ backgroundRef }) {
const truffleTinRef = useRef();
const initialPos = { x: 150, y: 150 };
const padding = 25;
let truffleBoxWidth = 0;
let truffleBoxHeight = 0;
useEffect(() => {
truffleBoxWidth = truffleTinRef.current.offsetWidth;
truffleBoxHeight = truffleTinRef.current.offsetHeight;
resize();
}, []);
function resize() {
let backgroundDivRect = backgroundRef.current.getBoundingClientRect();
truffleTinRef.current.style.left =
(initialPos.x / truffleBoxWidth) * backgroundDivRect.width -
padding +
'px';
truffleTinRef.current.style.top =
(initialPos.y / truffleBoxHeight) * backgroundDivRect.height -
padding +
'px';
}
useEffect(() => {
window.addEventListener('resize', resize);
return () => window.removeEventListener('resize', resize);
});
return (
<TruffleTinContainer ref={truffleTinRef}>
I'm the truffle tin
</TruffleTinContainer>
);
}
See the GIF below for the issue:
What's the best way to get this div to proportionally match the width of the background image?
(Edit: I changed the 'div with image background' to an img tag, but even then, the getBoundingClientRect shows not the width of the image, but the width of the viewport:
(in other words, even though the image is much wider than the viewport, I'm still getting the viewports dimensions, when what I want is the image's dimensions))


