Forum Academy Marketplace Showcase Pricing Features

Hammer.js and ID Attribute (pinch zoom)

Hi,

Bit of a “not-so-bubble” type of question this is, but I was just wondering, has anyone used Hammer.js and have it working with Pinch zoom on any type of element in Bubble if it’s given an ID attribute?

Does that make sense?

So, if I had an image for example, or even used the slideshow, gave it an ID attribute, would it be possible to something like this…

https://codepen.io/josephmaynard/pen/OjWvNP

(Good for mobile when zooming)
I’ve been trying since day dot to get a nice pinch zoom working on a specific element ID and not have the whole screen zoom in and out. Ended up revisiting it again today, not managed to get any further though!

1 Like

I don’t know a lot about hammer.js, but I think it still should work. Try applying the script to the .parentElement of the image or whatever you’re trying.

It seems Bubble always places a div element, and I’ve had to target that instead for some things.

Thanks for the reply Tim, I’ll try that and have a play with it.

1 Like

I actually managed to get pinch zoom working with Bubble’s own slideshow on mobile devices! Feels great!

Anyone else wanting this functionality, do it like this…

Give the Slideshow an ID Attribute:
image

Create a small HTML element with the following code inside it

<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script>
<script>
function hammerIt(elm) {
    hammertime = new Hammer(elm, {});
    hammertime.get('pinch').set({
        enable: true
    });
    var posX = 0,
        posY = 0,
        scale = 1,
        last_scale = 1,
        last_posX = 0,
        last_posY = 0,
        max_pos_x = 0,
        max_pos_y = 0,
        transform = "",
        el = elm;

    hammertime.on('doubletap pan pinch panend pinchend', function(ev) {
        if (ev.type == "doubletap") {
            transform =
                "translate3d(0, 0, 0) " +
                "scale3d(2, 2, 1) ";
            scale = 2;
            last_scale = 2;
            try {
                if (window.getComputedStyle(el, null).getPropertyValue('-webkit-transform').toString() != "matrix(1, 0, 0, 1, 0, 0)") {
                    transform =
                        "translate3d(0, 0, 0) " +
                        "scale3d(1, 1, 1) ";
                    scale = 1;
                    last_scale = 1;
                }
            } catch (err) {}
            el.style.webkitTransform = transform;
            transform = "";
        }

        //pan    
        if (scale != 1) {
            posX = last_posX + ev.deltaX;
            posY = last_posY + ev.deltaY;
            max_pos_x = Math.ceil((scale - 1) * el.clientWidth / 2);
            max_pos_y = Math.ceil((scale - 1) * el.clientHeight / 2);
            if (posX > max_pos_x) {
                posX = max_pos_x;
            }
            if (posX < -max_pos_x) {
                posX = -max_pos_x;
            }
            if (posY > max_pos_y) {
                posY = max_pos_y;
            }
            if (posY < -max_pos_y) {
                posY = -max_pos_y;
            }
        }


        //pinch
        if (ev.type == "pinch") {
            scale = Math.max(.999, Math.min(last_scale * (ev.scale), 4));
        }
        if(ev.type == "pinchend"){last_scale = scale;}

        //panend
        if(ev.type == "panend"){
            last_posX = posX < max_pos_x ? posX : max_pos_x;
            last_posY = posY < max_pos_y ? posY : max_pos_y;
        }

        if (scale != 1) {
            transform =
                "translate3d(" + posX + "px," + posY + "px, 0) " +
                "scale3d(" + scale + ", " + scale + ", 1)";
        }

        if (transform) {
            el.style.webkitTransform = transform;
        }
    });
}
</script>
</head>
</html>

Now create a workflow action that runs JavaScript when the slideshow is visible

hammerIt(document.getElementById("slideshow_a"));

7 Likes

Thanks for passing along this tip.

No probs!

Hello again @pork1977gm,

I just implemented this. It works great. Thanks for sharing!

George

Glad to hear it, no probs

Thank you so much @pork1977gm , thanks to this post i could understand how to trigger a javascript function from a bubble button!!!

<3

Hello @pork1977gm

This works great. I’m wondering if there’s a way to disable the ability to zoom after an element has been zoomed to the desired level, and have the element remain at the current zoom.

Use case: A user zooms a canvas element then adds an object to it. When trying to move the added object on the canvas this also causes the zoomed canvas element to move around.

I’d like to be able to disable and re-enable the zoom as needed without resetting the zoom level. Is this possible!

Thanks for any help you can provide.

I was able to accomplish what I needed by removing the pan and panend from your script below. The element can still be panned using two fingers when pinching, but since the panning is now disabled the element won’t move around while moving other elements/objects with a single finger.