0

How would I go about making a scroll-and-pan effect with the mouse wheel for the entire page? Basically like any 2D editor with the scroll to zoom, click and drag to pan but for the entire body.

I haven't been able to find anything online about it.

Mayday
  • 1
  • Are you asking us to suggest you random libraries from the internet, or will you code the solution yourself? this is not Reddit or WhatsApp. Asking for 3rd-party libraries suggestions is not allowed... – vsync Jan 24 '23 at 15:32
  • The mousewheel event is reserved for scrolling. if you will highjack it for zooming, you won't be able to scroll. Is that desirable? – vsync Jan 24 '23 at 15:34
  • yes i don't want to scroll. – Mayday Jan 24 '23 at 15:53
  • I will code the solution myself i just don't know where to start. – Mayday Jan 24 '23 at 15:54

2 Answers2

0

If you don't know where to start, you will very soon hit another wall, because knowing where to start is the easy part. Here is a rough guide:

  1. Add event listener to the wheel event (learn how](https://stackoverflow.com/a/51276012/104380))
  2. Start with an initial (current) zoom value and calculate the delta from the wheel event and update your zoom value.
  3. Use the zoom value to manipulate the scale of the page in some form. You can use CSS transform: scale() for that, on the body element.
  4. Add event listener for the mousemove event (learn how](https://developer.mozilla.org/en-US/docs/Web/API/Element/mousemove_event))
  5. Act upon the detected mouse move, and calculate how much you need to pan the zoomed body element in order to reach any of the 4 edges, and not beyond. panning may be done via CSS transform: translate(x,y)
vsync
  • 118,978
  • 58
  • 307
  • 400
0

Implementation I made based off of vsyncs answer:

window.onload = init;

let root;
let content;
let zoom = 1.0;
let translateY = 0;
let translateX = 0;
let middleMouseDown = false;

function init(){
    content = document.getElementById("content");
    root = document.getElementById("root");

    root.addEventListener("wheel", (event)=>{
        zoom += event.wheelDelta / 1000;
        if(zoom > 2.0){zoom = 2.0}
        else if (zoom < 0.5) {zoom = 0.5}
        console.log(zoom);

        transform();
    })
    
    root.addEventListener("mousedown", (event)=>{
        event.preventDefault();
        middleMouseDown = (event.button == 1);
    })

    root.addEventListener("mouseup", (event)=>{
        if(event.button == 1){
            middleMouseDown = false;
        }
    })

    root.addEventListener("mousemove", (event)=>{
        // console.log(event);
        if(middleMouseDown){
            translateY += event.movementY;
            translateX += event.movementX;
            transform();
        }
    })
}

function transform(){
    content.style.transform = `scale(${zoom}, ${zoom}) translate(${translateX}px, ${translateY}px)`;
}
body{
    margin: 0px;
}

#root{
    width: 400px;
    height: 400px;
    border: 1px solid red;
    overflow: scroll;
}

#content{
    width: 200px;
    height: 200px;
    border: 1px solid black;
}
<html lang="en">
    <head>
        <link rel="stylesheet" href="index.css">
        <script src="main.js"></script>
    </head>
    <body>
        <div id="root">
            <div id="content">
            </div>
        </div>
    </body>

</html>