skip to Main Content

So im using the react-blurhash package to add placeholders for my images. It expects a width and a height parameter in integers, to define the height and width of the placeholder itself. If i dont know the width and height, lets say it is dependent on the parent ( or as a percentage ) How do i use it then?

Sample Code:

<div className='sm:w-[50%] w-full flex items-center justify-center'>
                <div className="relative w-full h-full">
                    {isLoading && <Blurhash
                        hash="L5IW7%8x3@1G2,Dz.{{}BN0g}u1I"
                        width={"100%"}
                        height={"100%"}
                        resolutionX={32}
                        resolutionY={32}
                        punch={1}
                        className='absolute top-0 left-0 w-full h-full transition-opacity duration-500 rounded-lg'
                    />}
                    <img src={Rica} alt="Rica" className='rounded-lg lg:h-[500px] relative z-10 transition-opacity duration-500' onLoad={() => { setIsLoading(false) }} />
                </div>
 </div>

As seen above i have tried using "100%" but that doesnt seem to work. Anyone have any ideas?

2

Answers


  1. The react-blurhash package requires the width and height props to be integers, so passing "100%" as a string won’t work.

    If your image dimensions depend on the parent element’s size (like a percentage), you can calculate the dimenions of the parent and pass them as numbers.

    Use useRef and useEffect for Parent Dimensions.

    const containerRef = useRef(null);
    const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
    
    
    useEffect(() => {
        // Calculate the dimensions of the parent container
        const updateDimensions = () => {
            if (containerRef.current) {
                setDimensions({
                    width: containerRef.current.offsetWidth, // If required use `.scrollWidth` instead.
                    height: containerRef.current.offsetHeight, // and `.scrollHeight`
                });
            }
        };
    
        updateDimensions();
    
        // If you want you can remove this, if window resize won't affect the parent dimensions
        window.addEventListener("resize", updateDimensions);
    
        return () => window.removeEventListener("resize", updateDimensions);
    }, []);
    
    return (
        <div
            ref={containerRef} // Considered it's the parent container
            className='sm:w-[50%] w-full flex items-center justify-center'
        >
            <div className="relative w-full h-full">
                {isLoading && <Blurhash
                    hash="L5IW7%8x3@1G2,Dz.{{}BN0g}u1I"
                    width={dimensions.width}
                    height={dimensions.height}
                    resolutionX={32}
                    resolutionY={32}
                    punch={1}
                    className='absolute top-0 left-0 w-full h-full transition-opacity duration-500 rounded-lg'
                />}
                <img src={Rica} alt="Rica" className='rounded-lg lg:h-[500px] relative z-10 transition-opacity duration-500' onLoad={() => { setIsLoading(false) }} />
            </div>
        </div>
    )
    

    I hope it solves your issue. If you have any queries, feel free to ask. Happy learning!

    Login or Signup to reply.
  2. What if you hide the image when isLoading is true so that it doesn’t take up any space in the DOM, and only the placeholder takes up space in DOM. And when image loads the Placeholder is not rendered and the image is block taking up the width and height. Then u can give the placeholder and image same width and height value.
    So u won’t be using width={"100%"} height={"100%"} with the placeholder.

    Here’s is an example:

    <div className='sm:w-[50%] w-full flex items-center justify-center'>
        <div className="relative w-full h-full">
           {isLoading && <Blurhash
           hash="L5IW7%8x3@1G2,Dz.{{}BN0g}u1I"
           width={"100%"}
           height={"100%"}
           resolutionX={32}
           resolutionY={32}
           punch={1}
           className='absolute top-0 left-0 w-full h-full 
           transition-opacity duration-500 rounded-lg'
         />}
         <img src={Rica} 
          alt="Rica"
          className={`rounded-lg lg:h-[500px] relative z-10 
          transition-opacity duration-500 ${isLoading ? "hidden" : "block" }`}  
          onLoad={() => { setIsLoading(false) }} />
       </div>
     </div>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search