JSFiddle - React, Tailwind, and code Playground

by thaisgiacomini

HTML

<main class="main">
  <section class="section"></section>
</main>

CSS

body {
  margin: 0;
}

.main {
	width: 100%; /* percentage fixes the X axis white space when zoom out */
	height: 100vh; /* this is still an issue where you see white space when zoom out in the Y axis */
	overflow: scroll; /* needed for safari to show the x axis scrollbar */
}

.main .section {
	width: 200%;
	height: 200vh;
	background-image: url('https://iso.500px.com/wp-content/uploads/2014/07/big-one.jpg');
	transform-origin: 0 0;
}

JavaScript

for (const divMain of document.getElementsByClassName('main')) {
  // drag the section
  for (const divSection of divMain.getElementsByClassName('section')) {
  	// when mouse is pressed store the current mouse x,y
    let previousX, previousY
    divSection.addEventListener('mousedown', (event) => {
      previousX = event.pageX
      previousY = event.pageY
    })
    
    // when mouse is moved, scrollBy() the mouse movement x,y
    divSection.addEventListener('mousemove', (event) => {
    	// only do this when the primary mouse button is pressed (event.buttons = 1)
      if (event.buttons) {
        let dragX = 0
        let dragY = 0
        // skip the drag when the x position was not changed
        if (event.pageX - previousX !== 0) {
          dragX = previousX - event.pageX
          previousX = event.pageX
        }
        // skip the drag when the y position was not changed
        if (event.pageY - previousY !== 0) {
          dragY = previousY - event.pageY
          previousY = event.pageY
        }
        // scrollBy x and y
        if (dragX !== 0 || dragY !== 0) {
          divMain.scrollBy(dragX, dragY)
        }
      }
    })
  }

  // zoom in/out on the section
  let scale = 1
  const factor = 0.05
  const max_scale =4

  divMain.addEventListener('wheel', (e) => {
  	// preventDefault to stop the onselectionstart event logic
    for (const divSection of divMain.getElementsByClassName('section')) {
		e.preventDefault();
		var delta = e.delta || e.wheelDelta;
		if (delta === undefined) {
	      //we are on firefox
	      delta = e.originalEvent.detail;
	    }
	    delta = Math.max(-1,Math.min(1,delta)) // cap the delta to [-1,1] for cross browser consistency
			offset = {x: divMain.scrollLeft, y: divMain.scrollTop};
     image_loc = {
        x: e.pageX + offset.x,
        y: e.pageY + offset.y
     }
     
     zoom_point = {x:image_loc.x/scale, y: image_loc.y/scale}

	    // apply zoom
	    scale += delta*factor * scale
	    scale =...