简体   繁体   中英

Dynamic font-size calculate based on container size

I have a container size of 400wx300h. Inside the container is a single paragraph tag bind to a Textarea field. The max character that can be entered is 255. The max font size of the paragraph tag is 96px and the minimum is 28px. Now, I want to calculate the in-between font size of the paragraph based on the height of the container such that it will always stay inside the container without overflowing.

Here a simple a implementation that I came up with:

    import { useEffect, useRef, useState } from "react";

export default function App() {
  const [text, setText] = useState("");
  const [fontSize, setFontSize] = useState(96);
  const paragraph = useRef();

  useEffect(() => {
    let ph = paragraph.current.offsetHeight;
    let noOflines = ph / fontSize;
    let minFontsize = 28;
    let fs = 300 / noOflines;


    if (ph > 225) {
      console.log("fs and nolines and text length and ph", fs, noOflines, ph);
      if (fs < minFontsize) {
        setFontSize(minFontsize);
      } else {
        setFontSize(fs);
      }
    }
    if (fs > 96 && ph < 225 && noOflines <= 3) {
      console.log("fs and nolines and text length and ph", fs, noOflines, ph);
      setFontSize(96);
    }
  }, [text]);
  return (
    <div className="App" style={{ textAlign: "center" }}>
      <h1>Hello CodeSandbox</h1>
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          background: "red",
          width: "400px",
          margin: "auto",
          height: "300px"
        }}
      >
        <p
          id="par"
          style={{
            wordBreak: "break-word",
            lineHeight: 1,
            textAlign: "center",
            fontSize: fontSize
          }}
          ref={paragraph}
        >
          {text}
        </p>
      </div>
      <br />
      <br />
      <br />
      <textarea
        type="text"
        value={text}
        onChange={(e) => {
          if (e.target.value.length > 255) {
            return;
          }

          setText(e.target.value);
        }}
      />
    </div>
  );
}

https://codesandbox.io/s/clever-meadow-zooyo?file=/src/App.js:0-1644

It works but there is logical issue somewhere which I am unable to figure out. At certain scenario the paragraph overflows. 溢出段落

Try change your useEffect in this way:

useEffect(() => {
  let ph = paragraph.current.offsetHeight;

  if (ph > 300) {

    let noOflines = ph / fontSize;
    let minFontsize = 28;
    let fs = 300 / noOflines;

    setFontSize(fs < minFontsize ? minFontsize : fs);

  } else if (300 - fontSize > ph) {

    let noOflines = ph / fontSize;
    let fs = fontSize + fontSize / noOflines;

    setFontSize(fs > 96 ? 96 : fs);
  }
}, [text, fontSize]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM