Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
LanceH

Draggable + scaled mini view

Recommended Posts

Hello,

 

I have a div with a large background image that I'm using draggable and ThrowPos on for users to drag around a map.

 

I now need to have a small scaled down version of the map so people can see where they are currently in the context of the entire map.

 

It's common to see but I can't put a name to it making it difficult to get a start.

 

The map to date is here: https://map.polycode.co.nz/map 

 

What I think I need is:

  1. A scaled view of the map as the background for the small version. The width and height presumably a percentage of the original map.
  2. A div over that representing the current window size and position. With some scaling factor.
  3. Some code in the Draggable drag event(?) to move 2 above around inside 1 above

 

I'd appreciate any thoughts on 1-3 and any tips to get me started.

 

The simplified version of the Draggable code is:

 

Map = new Draggable($draggable, {
            type: "x, y",
            throwProps: true,
            trigger: "#viewport",
            bounds:{
                top: 0,
                left: -(mapWidth-viewportWidth),
                width: mapWidth,
                height: viewportHeight
            }
        });

 

 

 

Share this post


Link to post
Share on other sites

The best way to get help is to at least set a demo up. 

 

 

 

That said, you can use onDrag/onThrowUpdate callbacks to map your draggable's x/y position onto your mini-map.

 

See how this demo maps the movement of top box onto the bottom box. A map function similar to that is going to be included in the next version of GSAP.

 

See the Pen 5d439258a9fb08c03c121d41e79cc3ac by osublake (@osublake) on CodePen

 

 

  • Like 3

Share this post


Link to post
Share on other sites

@OSUblake 

 

Thank you for replying.

I figured it out with the help of your example. Especially the map function.

In action: https://map.polycode.co.nz/map

 

Here's the code I used. I removed some parts to simplify it. If there's a more efficient/better way I could improve it let me know.

 

var viewportWidth;
var viewportHeight;

var mapWidth;
var mapHeight;

var miniMapWidth;
var miniMapHeight;

var mapMarkerWidth;
var mapMarkerHeight;

var $viewport;

var $map;
var $draggable;

var $miniMap;
var $mapMarker;

var pos;

$(function()
{
    $viewport   = $('#viewport');
    $map        = $('#map');
    $draggable  = $('#draggable');
    $miniMap    = $('#miniMap');
    $mapMarker  = $('#mapMarker');
    
    function loadMap()
    {
		// Code removed
        setMapDimensions();
    }

    // Loader in front of this
    loadMap();

    function setMapDimensions()
    {
        mapWidth  = $map.outerWidth();
        mapHeight = $map.outerHeight();

        initDraggable();
    }

    function setMiniMapDimensions()
    {
        miniMapWidth  = $miniMap.outerWidth();
        miniMapHeight = $miniMap.outerHeight();

        $mapMarker.css({
            width: ((viewportWidth / mapWidth) * 100)+'%',
            height: ((viewportHeight / mapHeight) * 100)+'%',
        });

        mapMarkerWidth  = $mapMarker.outerWidth();
        mapMarkerHeight = $mapMarker.outerHeight();
    }

    function initDraggable()
    {
        setDraggable();

        var start_x = -(mapWidth - viewportWidth) / 2;
        var start_y = -(mapHeight - viewportHeight) / 2;

        pos = $draggable[0]._gsTransform;

        TweenLite.set($draggable, {
            x: start_x, 
            y: start_y, 
            force3D: true, 
            transformOrigin: "left top"
        });

        TweenLite.set($mapMarker, {
            x: (miniMapWidth - mapMarkerWidth) / 2,
            y: (miniMapHeight - mapMarkerHeight) / 2,
            force3D: true, 
            transformOrigin: "left top"
        });
    }

    function setDraggable()
    {
        viewportWidth  = $viewport.outerWidth();
        viewportHeight = $viewport.outerHeight();

        Map = new Draggable($draggable, {
            type: "x, y",
            throwProps: true,
            trigger: "#viewport",
            bounds:{
                top: 0,
                left: -(mapWidth-viewportWidth),
                width: mapWidth,
                height: viewportHeight
            },
            onDrag: update,
            onThrowUpdate: update
        });

        setMiniMapDimensions();
    }
    
    function update()
    {
        TweenLite.set($mapMarker, { 
            x: clamp(pos.x, 0, -mapWidth, 0, miniMapWidth),
            y: clamp(pos.y, 0, -mapHeight, 0, miniMapHeight),
            force3D: true, 
            transformOrigin: "left top"
        });
    }

    $(window).resize(function(){
        setDraggable();
    }); 
});

function clamp(x, a, b, c, d) {
    return c + (d - c) * ((x - a) / (b - a)) || 0;
}

 

  • Like 3

Share this post


Link to post
Share on other sites
21 minutes ago, LanceH said:

If there's a more efficient/better way I could improve it let me know.

 

What you have looks fine to me. And thanks for the posting the code. I'm sure it will help someone else out in the future.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×