skip to Main Content

I have an image and I want to create a new div (on click) with a larger version of the same image.

I’ve tried four approaches:

  1. Render div on Click
function zoom_img (event) {
    console.log(event.target);
    console.log(event.target['data-loaded-src'])
    const src = event.target['data-loaded-src']
    
    return (
      <div className='w-screen h-screen fixed flex justify-center items-center'>
        <div className='w-9/12 h-5/6 bg-slate-200 opacity-50'>
          <Image src={src} fill={true} />
        </div>
      </div>
    )
  }

...

<Image src={'/gafas.png'} width={150} height={150} alt='Gafas 1' onClick={zoom_img}/>
  1. Custom component
function Glasses ({src, height, width, alt}) {
    function enlrg() {
      console.log(src);
      return (
        <div className='w-screen h-screen fixed flex justify-center items-center'>
          <div className='w-9/12 h-5/6 bg-slate-200 opacity-50'>
            <Image src={src} fill={true} />
          </div>
        </div>
      )
    }
    return (
      <Image src={src} width={width} height={height} alt={alt} onClick={enlrg} />
    )
  }


...

<Glasses src={'/gafas.png'} width={150} height={150} alt='Gafas 1' />
  1. Existing div onClick remove hidden class
function Glasses2 ({src, height, width, alt}) {
    function enlrg() {
      console.log(src);
      let x = document.getElementById('temp');
      x.classList.remove('hidden');
      x.classList.add('flex');
    }
    return (
      <Image src={src} width={width} height={height} alt={alt} onClick={enlrg} />
    )
  }


...

<Glasses2 src={'/gafas.png'} width={150} height={150} alt='Gafas 1' />
<div id='temp' className='w-screen h-screen fixed hidden justify-center items-center'>
  <div className='w-9/12 h-5/6 bg-slate-200 opacity-50'>
    <Image src={'/gafas.png'} fill={true} />
  </div>
</div>
  1. This one DID work but I’m loosing nextjs image optimization
function zoom_img (event) {
    console.log(event.target);
    console.log(event.target['data-loaded-src'])
    const src = event.target['data-loaded-src']
    const new_cont = document.createElement('div');
    const new_div = document.createElement('div');
    const main = document.getElementById('main');
    new_cont.classList.add('w-screen', 'h-screen', 'fixed', 'flex', 'justify-center', 'items-center');
    new_div.classList.add('w-9/12', 'h-5/6', 'bg-slate-200', 'opacity-50');
    // add img tag here
    new_cont.appendChild(new_div);
    main.appendChild(new_cont);
  }


...

<Image src={'/gafas.png'} width={150} height={150} alt='Gafas 1' onClick={zoom_img} />

In every approach I DO get to see the log in the console but only in approach 4 I see the new div.

Is approach 4 the only correct way? I would prefer to use the Image component if possible. What do you guys think?

2

Answers


  1. Chosen as BEST ANSWER

    Thank you very much @Atena Dadkhah. Your answer worked perfectly.

    In the project a have not one but a bunch of images so the final code looked like this:

    function enlarge(e) {
        setLrg(true);
        let img = document.getElementById('largerImage'),
            src = e.target['data-loaded-src'];
        img['src'] = src;
      }
    

    Then a bunch of images like this:

    <Image src={'/gafas.png'} width={150} height={150} alt='Gafas 1' onClick={enlarge} className='cursor-zoom-in' />
    

    Then the hidden div:

    <div className={`${lrg ? 'flex' : 'hidden'} w-screen h-screen fixed justify-center items-center`}>
      <div className='w-9/12 h-5/6 bg-slate-200 flex justify-center items-center relative'>
        <Image id='largerImage' fill={true} />
      </div>
    </div>
    

    It's still missing the behaviour for closing the div but that should be easy to add.

    Once again. Thank you :)


  2. You can try something like this:

    Set the hook:

    [zoomImage, setZoomImage] = useState(false)
    
    <Image src={'/gafas.png'} width={150} height={150} alt='Gafas 1' onClick={() => setZoomImage(true)}/>
    
    // zoomed image
    <div className={`${zoomImage ? 'block' : 'hidden'} w-screen h-screen fixed flex justify-center items-center`}>
    <div className='w-9/12 h-5/6 bg-slate-200 opacity-50'>
       <Image src={src} fill={true} />
    </div>
    </div>
    

    In this code you are actually telling Next.JS that whenever user clicks that image, change variable zoomImage to true and as a result that bigger image that is hidden by default, will have display block. (I supposed you’re using tailwindcss)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search