arnaldo
arnaldo

Reputation: 894

Change reveal.js zoom shortcut

Currently the shortcut for zomm inside a slide is Alt + click

// Custom reveal.js integration
(function(){
var isEnabled = true;

document.querySelector( '.reveal .slides' ).addEventListener( 'mousedown', function( event ) {
    var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : 'alt' ) + 'Key';

    var zoomPadding = 20;
    var revealScale = Reveal.getScale();

    if( event[ modifier ] && isEnabled ) {
        event.preventDefault();

        var bounds = event.target.getBoundingClientRect();

        zoom.to({
            x: ( bounds.left * revealScale ) - zoomPadding,
            y: ( bounds.top * revealScale ) - zoomPadding,
            width: ( bounds.width * revealScale ) + ( zoomPadding * 2 ),
            height: ( bounds.height * revealScale ) + ( zoomPadding * 2 ),
            pan: false
        });
    }
} );

How should I change this Alt + mouse click to just press the "z" key? The main file is: https://github.com/hakimel/reveal.js/blob/master/plugin/zoom-js/zoom.js

Cheers, Arnaldo.

Upvotes: 1

Views: 1262

Answers (1)

Oliver W.
Oliver W.

Reputation: 13459

You could achieve this by checking mousemove events to the slides. This will serve to keep track of where the mouse was last when "z" was pressed. You'll then also need to update the defined key bindings, such that whenever you press "z" (a keyDown event will trigger the calling of the onDocumentKeyDown function in reveal.js) the webpage zooms in on the element.

While I've tested the below and found it working, I should add that I'm not a frequent javascript coder. I'm using a global variable and it's a general consensus in many scripting and programming languages that that's a bad thing.

In zoom.js add:

var bbox_elm_below_mouse; // keeps track of the mouselocation

(function(){
document.querySelector( '.reveal .slides' ).addEventListener('mousemove', function(event){
    bbox_elm_below_mouse = event.target;
    })
})();  // Update the global var any time the mouse moves.

function initiateZoom(){
    // based on the function on the function at the top in reveal.js's modification to zoom.js
    var isEnabled = true;
    var zoomPadding = 20;
    var revealScale = Reveal.getScale();

    if( isEnabled ) {
        var bounds = bbox_elm_below_mouse.getBoundingClientRect();
        zoom.to({
            x: ( bounds.left * revealScale ) - zoomPadding,
            y: ( bounds.top * revealScale ) - zoomPadding,
            width: ( bounds.width * revealScale ) + ( zoomPadding * 2 ),
            height: ( bounds.height * revealScale ) + ( zoomPadding * 2 ),
            pan: false
        });
    }

    Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } );
    Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } );
};

The reason you need to keep track of the mouse events and the keyboard event is that when a keyboard event triggers, the event has no way of knowing where the mouse was (as discussed in this forum).

Finally, add to reveal.js's onDocumentKeyDown function, in the section that reads // 2. System defined key bindings the following lines:

// letter "z"
case 90: initiateZoom(); break;

The switch statement will then look like this:

        switch( event.keyCode ) {
            // p, page up
            case 80: case 33: navigatePrev(); break;
            // n, page down
            case 78: case 34: navigateNext(); break;
            // h, left
            case 72: case 37: navigateLeft(); break;
            // l, right
            case 76: case 39: navigateRight(); break;
            // k, up
            case 75: case 38: navigateUp(); break;
            // j, down
            case 74: case 40: navigateDown(); break;
            // home
            case 36: slide( 0 ); break;
            // end
            case 35: slide( Number.MAX_VALUE ); break;
            // space
            case 32: isOverview() ? deactivateOverview() : event.shiftKey ? navigatePrev() : navigateNext(); break;
            // return
            case 13: isOverview() ? deactivateOverview() : triggered = false; break;
            // two-spot, semicolon, b, period, Logitech presenter tools "black screen" button
            case 58: case 59: case 66: case 190: case 191: togglePause(); break;
            // f
            case 70: enterFullscreen(); break;
            // a
            case 65: if ( config.autoSlideStoppable ) toggleAutoSlide( autoSlideWasPaused ); break;
            // letter "z"
            case 90: initiateZoom(); break;
            default:
                triggered = false;
        }

Now reload your presentation and press "z" when the mouse is over the element you want to zoom in on.

I'd probably change the call to zoom.to to make the browser zoom in on exactly the point where the cursor is at. As it is now (even in the default configuration of Reveal.js), you'll zoom in on a position related to the element under the cursor, which could be a bit away from where you actually want it, especially if that element takes some screen-space.

Be aware that this method doesn't lend itself well to Reveal.js's API of changing the keyboard bindings, because of the asynchronous call to its zoom.js dependency (the function initiateZoom must be defined before you call Reveal.configure()). However, you might be able to get around it by using Reveal.isReady(). That's only necessary though if you want to use the API to reconfigure the hotkey bindings, rather than editing the source like I did in the example above.

Upvotes: 1

Related Questions