reactjs 如何使用CSS transform:scale();在react中将子div与父div相对应?

siv3szwd  于 2023-08-04  发布在  React
关注(0)|答案(5)|浏览(175)

我真的卡住了。我的div包含固定大小的div,文本和图像,有很多基于像素的定位。我如何将它们 Package 在另一个div中,并使它们缩放以适应 Package 器?
这可能非常相似:https://css-tricks.com/scaled-proportional-blocks-with-css-and-javascript/

iq0todco

iq0todco1#

假设一些元素有一个类.scaled-wrapper,并且这些元素有一个名为.scaled-content的子元素。然后我们有一个函数applyScaling,它接受一个.scaled-wrapper元素,并相应地缩放它的子元素:

let scaledWrapper = document.getElementsByClassName('scaled-wrapper')[0];

let applyScaling = scaledWrapper => {
  
  // Get the scaled content, and reset its scaling for an instant
  let scaledContent = scaledWrapper.getElementsByClassName('scaled-content')[0];
  scaledContent.style.transform = 'scale(1, 1)';
  
  let { width: cw, height: ch } = scaledContent.getBoundingClientRect();
  let { width: ww, height: wh } = scaledWrapper.getBoundingClientRect();
  
  let scaleAmtX = ww / cw;
  let scaleAmtY = wh / ch;
  
  scaledContent.style.transform = `scale(${scaleAmtX}, ${scaleAmtY})`;
        
};

applyScaling(scaledWrapper);

// ---- The rest of the code is just for the demonstration ui ----
let change = () => {
  let w = parseInt(wInp.value);
  let h = parseInt(hInp.value);
  if (!isNaN(w)) scaledWrapper.style.width = `${w}px`;
  if (!isNaN(h)) scaledWrapper.style.height = `${h}px`;
  scaledWrapper.getElementsByClassName('scaled-content')[0].innerHTML = textInp.value;
  applyScaling(scaledWrapper);
};

let wInp = document.createElement('input');
wInp.setAttribute('placeholder', 'input parent width in px');
wInp.addEventListener('input', change);
wInp.value = '200';
document.body.appendChild(wInp);

let hInp = document.createElement('input');
hInp.setAttribute('placeholder', 'input parent height in px');
hInp.addEventListener('input', change);
hInp.value = '200';
document.body.appendChild(hInp);

let textInp = document.createElement('input');
textInp.setAttribute('placeholder', 'input text content');
textInp.addEventListener('input', change);
textInp.value = 'abc';
document.body.appendChild(textInp);
.scaled-wrapper {
  position: absolute;
  left: 10px; top: 30px;
  width: 200px; height: 200px;
  outline: 1px solid red;
  z-index: 1;
}
.scaled-content {
  box-sizing: border-box;
  display: inline-block;
  transform-origin: 0 0;
  background-color: #ffd0d0;
  z-index: -1;
}
<div class="scaled-wrapper"><div class="scaled-content">abc</div></div>

主要思想是取父/子之间的大小比率,并使用该比率相应地缩放子。请注意,子对象的transform-origin位于左上角是很重要的(具有transform-origin: 50% 50%会导致子对象以父对象的左上角为中心)。
还要注意,如果父级的大小发生变化(例如,如果父级是窗口的百分比大小,并且窗口调整大小),则需要调用applyScaling

ttisahbt

ttisahbt2#

使用@Gershom的片段,但保持纵横比

let scaledWrapper = document.getElementsByClassName('scaled-wrapper')[0];

let applyScaling = scaledWrapper => {
  
  // Get the scaled content, and reset its scaling for an instant
  let scaledContent = scaledWrapper.getElementsByClassName('scaled-content')[0];
  scaledContent.style.transform = 'scale(1, 1)';
  
  let { width: cw, height: ch } = scaledContent.getBoundingClientRect();
  let { width: ww, height: wh } = scaledWrapper.getBoundingClientRect();
  
//  let scaleAmtX = ww / cw;
//  let scaleAmtY = wh / ch;
  let scaleAmtX = Math.min(ww / cw, wh / ch);
  let scaleAmtY = scaleAmtX;
  
  
  scaledContent.style.transform = `scale(${scaleAmtX}, ${scaleAmtY})`;
        
};

applyScaling(scaledWrapper);

// ---- The rest of the code is just for the demonstration ui ----
let change = () => {
  let w = parseInt(wInp.value);
  let h = parseInt(hInp.value);
  if (!isNaN(w)) scaledWrapper.style.width = `${w}px`;
  if (!isNaN(h)) scaledWrapper.style.height = `${h}px`;
  scaledWrapper.getElementsByClassName('scaled-content')[0].innerHTML = textInp.value;
  applyScaling(scaledWrapper);
};

let wInp = document.createElement('input');
wInp.setAttribute('placeholder', 'input parent width in px');
wInp.addEventListener('input', change);
wInp.value = '100';
document.body.appendChild(wInp);

let hInp = document.createElement('input');
hInp.setAttribute('placeholder', 'input parent height in px');
hInp.addEventListener('input', change);
hInp.value = '100';
document.body.appendChild(hInp);

let textInp = document.createElement('input');
textInp.setAttribute('placeholder', 'input text content');
textInp.addEventListener('input', change);
textInp.value = 'abc';
document.body.appendChild(textInp);
.wrapper-wrapper {
  box-sizing: border-box;
  border: solid 2px blue;
  position: relative;
}
.scaled-wrapper {
  position: relative;
  width: 100px; height: 100px;
  outline: 1px solid red;
  z-index: 1;
}
.scaled-content {
  box-sizing: border-box;
  display: inline-block;
  transform-origin: 0 0;
  background-color: #ffd0d0;
  z-index: -1;
}
<div class="wrapper-wrapper">
  <div class="scaled-wrapper">
    <div class="scaled-content">abc</div>
  </div>
</div>

x1c 0d1x的数据

ar7v8xwq

ar7v8xwq3#

对于React,你可以这样做:

const applyScaling = (scaledWrapper, scaledContent) => {
  scaledContent.style.transform = 'scale(1, 1)';

  let { width: cw, height: ch } = scaledContent.getBoundingClientRect();
  let { width: ww, height: wh } = scaledWrapper.getBoundingClientRect();
  let scaleAmtX = Math.min(ww / cw, wh / ch);
  let scaleAmtY = scaleAmtX;
  scaledContent.style.transform = `scale(${scaleAmtX}, ${scaleAmtY})`;
};

const App = ()=>{
       const scaledWrapper=useRef();
       const scaledContent=useRef();
       useEffect(()=>{
             if (scaledWrapper.current && scaledContent.current) {
              applyScaling(scaledWrapper.current, scaledContent.current);
             }
       },[scaledWrapper.current,scaledContent.current]);

        return(
           <div ref={scaledWrapper}>
              <div ref={scaledContent}></div>
           </div>
        );
    }

字符串

ibps3vxo

ibps3vxo4#

scale()是相对于当前容器的大小。高度和宽度是相对于父容器的大小的。在本例中,我将简单地将height和width都设置为100%以填充父DOM元素。如果你必须使用比例-尝试100%。设置高度和宽度后。

jhiyze9q

jhiyze9q5#

它可以更容易地做,只是通过css。

.parent {
  width: 400px;
  height: 300px
}

.children {
  scale: 0.25;
  width: 400%;
  height: 400%;
  transform-origin: 0 0;
}

字符串

相关问题