I had an issue before with using clip-path
, and so I switched to using values of the transformOrigin
and backgroundPosition
,
My issue was as follows:
assume I have two boxes, and 1 box is larger than the other, and the other will always be smaller than the bigger box, and the smaller box will overlap the big box, when that happens I need to have an Event that when it happens I zoom into the area, and highlight the smaller box cutout,
AS EASY AS IT SOUNDS, I ended up with the following:
styles:
export const styles ={
outerWrapper: {
width: "100dvw",
height: "100dvh",
position: "relative",
top: 0,
left: 0,
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
},
backGround: {
display: "flex",
flexDirection: "column",
backgroundAttachment: "fixed",
position: "fixed",
top: 0,
left: 0,
width: "100%",
height: "100%",
backgroundPosition: "center center ",
backgroundRepeat: "no-repeat",
// backgroundSize: "cover",
backgroundImage:
"url(https://buffer.com/cdn-cgi/image/w=1000,fit=contain,q=90,f=auto/library/content/images/size/w1200/2023/10/free-images.jpg)",
zIndex: "0",
transition: "clip-path 0.5s ease",
clipPath: "clip",
},
scaleTransition: {
// transformOrigin: "center",
transition: "transform 0.5s ease",
transform: "scale(1)",
},
}
React element, following is somepieces of code:
<div style={styles.outerWrapper}>
<div
style={{
...styles.backGround,
...styles.scaleTransition,
// clipPath:clip,
backgroundSize: "contain",
objectFit: "fill",
overscrollBehaviorBlock: "contain",
transform: inViewPort ? "scale(2.5)" : "scale(1)",
transformOrigin: inViewPort ? position : "center center",
backgroundPosition: inViewPort ? position : "center center",
backgroundBlendMode: "multiply",
transformBox: "fill-box",
}}
ref={bg}
></div>
{!inViewPort && (
<Rnd
ref={selectionBox}
style={{ ...style, scale: inViewPort ? "scale(3)" : "scale(1)" }}
default={{
x: 0,
y: 0,
width: 200,
height: 200,
}}
onDrag={(e) => zoomHelper()}
onDragStop={() => zoomHelper()}
onMouseUp={() => zoomHelper()}
onMouseDown={() => zoomHelper()}
>
Choose an area to highlight
</Rnd>
)}
</div>
functions:
function zoomHelper() {
const outerBoundary = bg.current?.getBoundingClientRect();
const rndElement = document.querySelector(".react-draggable-dragged");
if (outerBoundary && rndElement) {
const outerRect = outerBoundary;
const rndRect = rndElement.getBoundingClientRect();
// Check if the Rnd element overlaps with the background
if (
outerRect.right > rndRect.left &&
outerRect.left < rndRect.right &&
outerRect.bottom > rndRect.top &&
outerRect.top < rndRect.bottom
) {
// Calculate the overlapping area
const x1 = Math.max(outerRect.left, rndRect.left);
const y1 = Math.max(outerRect.top, rndRect.top);
const x2 = Math.min(outerRect.right, rndRect.right);
const y2 = Math.min(outerRect.bottom, rndRect.bottom);
const width = x2 - x1;
const height = y2 - y1;
const xCenter = x1 + width / 2;
const yCenter = y1 + height / 2;
const topCenter = { x: xCenter, y: y1 };
const leftCenter = { x: x1, y: yCenter };
const rightCenter = { x: x2, y: yCenter };
const bottomCenter = { x: xCenter, y: y2 };
const centerCenterPosition = { x: xCenter, y: yCenter };
let detectedArea = null;
// all of the top area
if (
y1 <= outerRect.top &&
y2 >= yCenter &&
xCenter >= outerRect.left &&
xCenter <= outerRect.right
) {
// console.log("top center ");
setPosition("top center");
}
if (
y1 <= yCenter &&
y2 >= outerRect.bottom &&
xCenter >= outerRect.left &&
xCenter <= outerRect.right
) {
// console.log("bottom center");
setPosition("bottom center");
}
if (
x1 <= xCenter &&
x2 >= outerRect.right &&
yCenter >= outerRect.top &&
yCenter <= outerRect.bottom
) {
// console.log("right center");
setPosition("right center");
}
if (
x1 <= outerRect.left &&
x2 >= xCenter &&
yCenter >= outerRect.top &&
yCenter <= outerRect.bottom
) {
setPosition("left center");
}
}
}
}
function isInViewPort() {
const el = point.current?.children[0].getBoundingClientRect();
return !(el.top > innerHeight || el.bottom < 0);
}
what I was trying to achieve, is specify where the position of the overlapped box is, and move the origin and background position into that position and zoom into it using scale()
, so I would like to know wether there is a simpler way to do this? since I'm clearly doing something wrong.
Thank you