Jump to content
GreenSock

Molt

Positioning relative to center.

Go to solution Solved by Jonathan,

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Wtih Greensock it's easy enough to move something to the centre of the container by using...

 

.to(".target", 1,
      {
        left:'50%', top:'50%',
        xPercent:'-50', yPercent:'-50'
      }
  )

Once it is positioned it can then be moved relative (in px, %, em, or whatever) by using..

.to(".target", 1, {left:'+=20px'})

But is there any way to combine these two positional transforms in one go and basically say 'Smoothly move this object to a point 20px right of the centre of screen'?  I've tried a few attempts but nothing seems to  be working.

 

Do I need to fudge things by moving the object to the centre, applying the relative offset, getting the resultant transform, resetting the position to the original, and then tweening to the result or am I missing something?

What I'd imagine would be the 'dream solution' would be something like:

.to(".target", 1,
      {
        left:'50%+20px', top:'50%',
        xPercent:'-50', yPercent:'-50'
      }
  )

See the Pen mVMOxb by Molt (@Molt) on CodePen

Link to comment
Share on other sites

Hi Molt :)

 

you can use x/y property :

.to(".target",1,{left:'50%',top:'50%', x:20 ,xPercent:'-50',yPercent:'-50'})
  • Like 1
Link to comment
Share on other sites

Thanks for the quick response, it's much appreciated.  Unfortunately while this works in a lot of use cases it loses the ability to specify units in the relative offset, and I do need that.

 

What I'm writing is an authoring system for video overlays, and for this I do need to allow things to be positioned in mixed units.  For the initial position of things I can get around this and say 'Position this item at the center of the screen, now move it down by 2em and right by 40px' as two separate tweens (as in the original Codepen), but I can't use this for 'I want this item to move to a position 2em down and 40px from the center of the screen'.

 

I think I can work round this by:

  • Store the initial position of an item
  • Tween the item immediately to the target position
  • Find the pixel position of the object
  • Convert to percentage to allow the video to be fullscreened/resized while tweening
  • Move the item immediately back to it's origin
  • Add a timed tween to move the item to the computed position

This does feel like a serious hack though and likely to come back and bite me (I'm also not sure the measurements will be right until the renderer actually moves the item, which would cause a nasty flicker), so I was just checking I wasn't missing a cleaner way using Greensock magic.  I know it's asking a lot but so far I've been pleasantly surprised by what Greensock is capable of so thought I'd check.

Link to comment
Share on other sites

Thanks for the quick response, it's much appreciated.  Unfortunately while this works in a lot of use cases it loses the ability to specify units in the relative offset, and I do need that.

 

What I'm writing is an authoring system for video overlays, and for this I do need to allow things to be positioned in mixed units.

 

Do you need mixed units or just percentages? Can you put a codepen together illustrating clearly what you're looking for? I would think for video overlays (which I assume could scale in size responsively), percentage values that update onResize would be suitable; but hard to say without the full picture.

  • Like 3
Link to comment
Share on other sites

  • Solution

If it was me i wouldn't be animating using position offsets like top, right, bottom, and left. Your better off just animating CSS transforms x and y or xPercent and yPercent, so you make sure you animate using hardware acceleration and sub-pixel rendering. Otherwise your animations will have jank and will trigger layout when rendering which is bad.

 

So you should never animate using top, right, bottom, and left CSS properties, otherwise your tweens will not be smooth, have jank, and will not render consistently cross browser. I would leave your initial position with those position offsets in your CSS file, and only animate using transforms.. x and y .. and leave the usage of top, right, bottom, and left in your style-sheet and out of your tweens.

 

https://css-tricks.com/myth-busting-css-animations-vs-javascript/

 

:)

  • Like 2
Link to comment
Share on other sites

Thanks for the feedback folks, I'll look into what I can do with the x,y parameters.

 

As Shaun hinted towards a lot of the problems I'm having are due to responsive, or in this case semi-responsive, layout systems.

 

There are times when elements need to be handled as percentages (A lot of standard layouts such as team listings for sports, or when you want to attach a label to something on the graphic), but there are also times when the font-size is the important factor such as when dealing with accessible subtitles.

Link to comment
Share on other sites

This seems more of an issue with CSS length units and how there being calculated based on your parent container. Looks like you are using ems, which are calculated by the immediate parent of your element. You could try and use rems instead which is calculated based on the root element of the DOM, the <html> element. ems can give you mixed results, especially with nested elements.

 

But this looks more like a CSS related question and how your html markup is setup and the CSS unit of length your using. And not a GSAP specific question. But a limited codepen with what your seeing. I noticed that your codepen above is using ems. But you have no baseline font-size declared on your body tag so they can be inherited. When you don't specifically declare a font-size in your CSS it will calculate your ems based on the browser defined style sheet.

 

So i think that is why your having inconsistent results. If you really wanted to use CSS length units for responsive, then you should go with CSS vw (viewport width) and vh (viewport height) units. ems are not that great for responsive unless your specifying specific breakpoints using media queries and checking the max-width and min-width based on ems. And declaring a baseline unit for each of your ems parents.

 

So i think once you equalize your CSS unit lengths inside your stylesheet, and explicitly set your base font-size or widths you will be able to achieve the responsiveness your looking for. Never trust CSS length units inherited from the browser defined stylesheet. Always declare your baseline length units. But to be honest you should decide the CSS length units you want to use and stay away from using mixed units, otherwise you will have the issues your currently experiencing cross browser. So in your stylesheet i would either use ems (define baseline unit), rems, percentages or the viewport units vw and vh.

  • Like 1
Link to comment
Share on other sites

The reason I was using 'em' rather than 'rem' was twofold- I didn't control the base HTML (Only the div overlaying the video), and I needed to support variant font sizes based on factors such as the screen size, viewer distance, and any eyesight issues.  It was never perfect to be honest, and was a hangover from an earlier (non-Greensock) version of my project.

 

I have been playing round with the X,Y based approach today though and it seems to work nicely.  I'm basically still allowing percentage (based on the video size), pixel, and what I'm now calling 'Accessibility scale' to be combined- but now just working on converting them to px and feeding them into the X,Y rather than left, right, top and bottom.

 

I now have a label happily tracking an item on the video, scale changing as the 'Accessibility scale' slider is moved. Subtitles are correctly positioned and working, and it all works on different devices and fullscreening.  Meanwhile a logo sits there, not rescaling since that'd be silly.

Thanks folks, problem solved.

  • Like 1
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.
×