Skip to content

Instantly share code, notes, and snippets.

@alexeyraspopov
Last active December 23, 2021 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexeyraspopov/5527fc528c4b834be0a443679d7b772e to your computer and use it in GitHub Desktop.
Save alexeyraspopov/5527fc528c4b834be0a443679d7b772e to your computer and use it in GitHub Desktop.
/** ISC License (c) 2021 Alexey Raspopov */
import { useLayoutEffect, useRef, useState } from "react";
import cns from "./ResponsiveFrame.module.css"
export function ResponsiveFrame({ className, style, children }) {
let sceneRef = useRef();
let [width, height] = useElementSize(sceneRef);
return (
<div className={className} style={style} ref={sceneRef}>
<svg className={cns.svgFrame} width={width} height={height}>
{size != null ? children : null}
</svg>
</div>
);
}
function useElementSize(ref) {
let [size, setSize] = useState(null);
useLayoutEffect(() => {
let element = ref.current;
if (element != null) {
let rect = element.getBoundingClientRect();
setSize([rect.width, rect.height]);
let observer = new ResizeObserver((entries) => {
if (entries.length > 0) {
let rect = entries[0].contentRect;
setSize([rect.width, rect.height]);
}
});
observer.observe(element);
return () => observer.disconnect();
}
}, []);
return size;
}
.svgFrame {
display: block;
position: relative;
width: 100%;
height: 100%;
overflow: visible;
box-sizing: border-box;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment