Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Seb-AS

Draggable + zoom out

Recommended Posts

Hi,

 

It's my first time using gsap with react(used a lot in as3), and  I've a lot of questions if someone can show me an example o guide me in the right direction.

 

I need to make a map like "google maps",  the map it's a div with a background-image and inside svg with point.

The issue I'm having it's if I drag the map the +/- buttons scale the map but in the wrong position,  my idea it's if I scale up the the map then drag then scale down it should come back and animate to the starting position.

 

Now I'm forcing to move to the starting position if the scale it's equal to 1

window.TweenLite.set(this.map, {force3D: true, ease: ease, scale: minScale, transformOrigin: "center center", x: 0, y: 0, z: .001});

 

Hope it's something easy to fix.

 

Thanks

 

Link to comment
Share on other sites

Welcome to the forums, @Seb-AS. Another AS3 guy, huh? Nice!

 

In my opinion, the most intuitive behavior would involve altering the transformOrigin of your element so that it's lined up in the center of the area/screen every time you do a scale. One idea would be to create a wrapper <div> around your element and scale THAT instead. So the draggable x/y coordinate stuff is still on your original <div>, but the scaling only happens on the container. That way, the center of the container isn't shifting around all the time with the dragging. 

 

If you need to do all the scaling on the original element, that's totally doable but it's not a simple thing to do seamlessly. You just need to do some math and juggle coordinates. If you want to pursue that, I'd recommend providing a reduced test case in codepen that'd serve as a good jumping-off point. I don't have time to build something from scratch for you right now. 


But again, I suspect the wrapper <div> would simplify all this for you anyway. At least in my head that seems like the easiest solution - I haven't battle-tested the idea. Let us know how it goes. 

 

Happy tweening/dragging!

  • Like 1
Link to comment
Share on other sites

Thanks Jack,

 

It's what's I'm doing.

 

I created a codepen, has buttons and mouse wheel I still need to add to zoom from the mouse position, thanks

See the Pen GGqjLO by Bayo (@Bayo) on CodePen

 

Link to comment
Share on other sites

2 hours ago, Seb-AS said:

It's what's I'm doing.

 

Hm, it doesn't look like that's what you're doing. According to your code, you're having your scale tweens and your x/y tweens and your Draggable all applied to the exact same element (this.map). I was saying that you should wrap this.map in a container <div> that you'd apply [only] the scaling to. See what I mean? You'd set it up so that the container <div> is always centered on the area/screen. That way, the transform origin would always be centered. 

Link to comment
Share on other sites

I guess I must be misunderstanding what you want, then. The wrapper thing seemed to work perfectly - whatever is in the middle of that area gets zoomed in on. But it almost sounds like you want it to work differently than Google Maps in that zooming out also shifts what's in the middle of the area/screen, eventually forcing you back to where you started (even though you dragged to focus elsewhere). Is that true? 

 

In other words, if I'm looking at a map of Illinois but I drag it so that California is in the middle instead, and then I zoom in further and further on San Francisco...then I zoom out again to state-level, I'd end up in Illinois again? So zooming out would shift the center further and further away from what I was focusing on (San Fransisco)? Seems very counter-intuitive to me. 

 

But perhaps what you really want is to apply some kind of bounds so that when zooming out, the edges don't show. Thus once you're back at 100%, it'd appear centered only because it re-oriented itself during the zoom-out to avoid edges showing. Is that what you want? That'd make sense to me as a user. If that's what you're after, then I'd just apply some logic on each tick of the zooming animation so that if edges are showing, it shifts the position accordingly. See what I mean? 

Link to comment
Share on other sites

I hope I can explain better with another gif.

 

The idea it's to always go back to the starting position (yellow square) after dragging and scaling(when scale it's equal to minScale),.

 

Something like Tweenlite.to(obj, 0.5{scale: scale, x: 0, y:0}); when it's zooming out.

 

 

 

zoom+draggable.gif

Link to comment
Share on other sites

Okay, then maybe just alter the x/y according to the scale ratio, like:

var t = this.map._gsTransform; //this is where all the transform data is stored, assuming this.map is the element.
var ratio = (newScale - 1) / (currentScale - 1);
TweenMax.to(this.map, 1, {x:t.x * ratio, y:t.y * ratio, scale:newScale});

 

That way, when newScale gets to 1, x and y will always be 0. 

 

Does that help?

  • Like 1
Link to comment
Share on other sites

now the animation works better(I can animate the zoom out on the same position) but after dragging and zooming out it's not scaling down and moving the object to the starting point(0, 0), I think might me related to the translate3d it remains in the point it was dragged the object.

Link to comment
Share on other sites

17 minutes ago, Seb-AS said:

now the animation works better(I can animate the zoom out on the same position) but after dragging and zooming out it's not scaling down and moving the object to the starting point(0, 0), I think might me related to the translate3d it remains in the point it was dragged the object.

 

Tough to troubleshoot blind - got a codepen? The simpler the better. 

Link to comment
Share on other sites

The yellow square it's a placeholder to show the where I want to move the grey square on zoom out.
 
The idea it's drag and zoom the grey square then on zoom out it should move and scale down to the starting position(yellow square).
 

See the Pen GGqjLO by Bayo (@Bayo) on CodePen

 

Link to comment
Share on other sites

That codepen doesn't show that you've implemented any of my suggestions (except the container), yet you changed several other things (like the size of the DIVs and now you're making the initial zoom level 0.6 which throws things off). I thought you wanted it to start from a scale of 1. Did I misunderstand?

 

It's tough for me to hit a moving target. I'm willing to invest some time here as long as you'll also put in the effort too. Did you understand the suggestion I made with the "ratio" stuff? Any particular reason you didn't try implementing that? And what scale is the "normal" state that you need? Please provide an updated codepen. 

  • Like 2
Link to comment
Share on other sites

sorry updated the codepen with your code.

 

The idea it's the same, scale then drag then when you scale down it supposed to go to the starting x & y(0,0)

 

See the Pen GGqjLO by Bayo (@Bayo) on CodePen

 

Link to comment
Share on other sites

Here's a simplified version: 

See the Pen b2751668999438a6e70b28cb6e790bf4 by GreenSock (@GreenSock) on CodePen

 

The important piece is:

var t = this.map._gsTransform; //this is where all the transform data is stored, assuming this.map is the element.
var ratio = (oldScale === minScale) ? 1 + newScale / minScale : (newScale - minScale) / (oldScale - minScale);
TweenMax.to(this.map, dur, {x:t.x * ratio, y:t.y * ratio, scale:newScale});

 

Is that what you're looking for? It basically boils down to math :)

  • Like 4
Link to comment
Share on other sites

Amazing, thank you so much!!! works perfectly.

 

 

  • Like 1
Link to comment
Share on other sites

Glad I was able to help, @Seb-AS. Good luck with the project!

Link to comment
Share on other sites

@GreenSock Hey Jack,

 

Another question, can you guide me  to add mouse wheel to zoom to the mouse position?, I'm being trying since yesterday but I get the map to flick like crazy.

 

Thanks

 

Link to comment
Share on other sites

I really wish we had the time and resources to offer free general consulting here but unfortunately we've got to try to keep these forums focused on GSAP-specific questions. I love challenges like this and wouldn't end up getting much work done on GSAP or answering GSAP-specific questions if I dove into every challenge I was asked to solve for people. That genuinely bums me out. 

 

You may need to consider hiring someone for that task. Or, of course, of someone else here wants to do it for you for free, that's up to them. But I've already burned a lot of time coding that custom zoom functionality for you and I've gotta tap out. Feel free to PM me if you're looking for paid consulting services. 

 

Happy tweening!

  • Like 1
Link to comment
Share on other sites

sorry, I didn't mean you do it for me, I was asking if you knew a post in the forum.

 

Thanks again for your help.

Link to comment
Share on other sites

Blake has a nice pan and zoom demo which may help.

 

See the Pen pedmMW by osublake (@osublake) on CodePen

 

  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×