'A-Frame. Zoom on wheel scroll

I've come through the official docs but wasn't able to locate information about how possibility of zooming in/out panorama images, is it supported in the A-Frame or maybe there is a workaround to read about implementing some of three.js on top of it?



Solution 1:[1]

You could either:

  1. Scale an <a-sphere> up or down when detecting the mouse wheel event
  2. zoom in or out the camera, like documented here

This article might be helpful, as it covers using the mousewheel event on multiple browsers.

I think scaling may screw up Your setup, or be a resource waste, so I'd go with 2.

Solution 2:[2]

This might be a cleaner way in 2018. I limited the zoom of the Aframe camera 1-5 so it doesn't get too messy.I just tested this and its working greatly.Hope it helps others.

window.addEventListener("mousewheel", event => {
    const delta = Math.sign(event.wheelDelta);
    //getting the mouse wheel change (120 or -120 and normalizing it to 1 or -1)
    var mycam=document.getElementById('cam').getAttribute('camera');
    var finalZoom=document.getElementById('cam').getAttribute('camera').zoom+delta;
    //limiting the zoom so it doesnt zoom too much in or out
    if(finalZoom<1)
      finalZoom=1;
    if(finalZoom>5)
      finalZoom=5;  

    mycam.zoom=finalZoom;
    //setting the camera element
    document.getElementById('cam').setAttribute('camera',mycam);
  });

Solution 3:[3]

This is what I put together to do it. Check the initial vrZoom variable.

For me, what I struggled the most, was to understand the way you set a parameter that's inside a component. You have to call it like this: element.setAttribute('componentName', 'parameterName', 'value') and in my case cam.setAttribute('camera', 'zoom', vrZoom)

Here's my script all together. It would be possible to create a component with this, such as look-controls.

var mousewheelevt=(/Firefox/i.test(navigator.userAgent))? "DOMMouseScroll" : "mousewheel";

if (document.attachEvent)
  document.attachEvent("on"+mousewheelevt, function(e){scroller(e)});
else if (document.addEventListener)
  document.addEventListener(mousewheelevt, function(e){scroller(e)},false);

var vrZoom = 4; // My initial zoom after animation
var cam = document.querySelector('#mainCam');

function scroller(evt)
{
  //Guess the delta.
  var delta = 0;
  if (!evt) evt = window.event;
  if (evt.wheelDelta) {
    delta = evt.wheelDelta/120;
  } else if (evt.detail) {
    delta = -evt.detail/3;
  }
  if (evt.preventDefault) evt.preventDefault();
  evt.returnValue = false;

  //Actual Zooming.
  vrZoom += delta * 0.1
  vrZoom = Math.min(Math.max(vrZoom, 1), 8); // clamp between 1 and 8
  cam.setAttribute('camera', 'zoom', vrZoom)
}

Solution 4:[4]

Sandy's answer helped me. I want to contribute an answer which shows the full code and enables smoother zooming (increments of 0.1):

<script>
  window.addEventListener("wheel", (event) => {
    // small increments for smoother zooming
    const delta = event.wheelDelta / 120 / 10;
    var mycam = document.getElementById("cam").getAttribute("camera");
    var finalZoom =
      document.getElementById("cam").getAttribute("camera").zoom + delta;

    // limiting the zoom
    if (finalZoom < 0.5) finalZoom = 0.5;
    if (finalZoom > 2) finalZoom = 2;
    mycam.zoom = finalZoom;

    document.getElementById("cam").setAttribute("camera", mycam);
  });
</script>
<a-scene>
  <a-entity
    id="cam"
    camera="zoom: 1"
    look-controls="reverseMouseDrag: true"
  ></a-entity>
  <!-- my pano image stuff -->
  <a-assets>
    <img id="skyTexture" crossorigin="anonymous" />
  </a-assets>
  <a-sky src="#skyTexture"></a-sky>
</a-scene>

Solution 5:[5]

I struggled quite a bit with getting this to work for an embedded a-frame, especially because the scene would become skewed upon dynamically adjusting the camera's zoom setting. This is a bug with a-frame. Here are the two ways I found to reset the scene upon setting the zoom level.

AFRAME.scenes[0].resize();

Or ...

let scene = document.querySelector('a-scene');
scene.camera.aspect = scene.clientWidth / scene.clientHeight;
scene.camera.updateProjectionMatrix();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 H. Pauwelyn
Solution 2 nnyby
Solution 3 Gonzalo Moiguer
Solution 4 alpharoz
Solution 5 capcom-r