Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] scale bounding client rect #48

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

GavinJoyce
Copy link
Contributor

@GavinJoyce GavinJoyce commented Jul 30, 2018

A WIP PR to address #46

TODO:

  • Write tests for scaled containers
  • Either figure out what's happening with the container or open a separate issue
  • Fix failing tests
    • Acceptance | hero 1️⃣
    • Unit | sprite 2️⃣
  • Refactor _getScaledBoundingClientRect?
  • Add scale option to ember-animated-tools: [wip] add scale control ember-animated-tools#2

This seems seems to fix movement of sprites when in a scaled container:

better

There still seems to be some issues to solve with containers:

issues

Although these seem to be present on master too:

master

@GavinJoyce
Copy link
Contributor Author

@ef4 before I bring this further, perhaps you could sanity check my approach?

@ef4
Copy link
Contributor

ef4 commented Jul 30, 2018

Thanks for working on this.

The key question here is what initialBounds is supposed to mean, as an API design decision. If we can automatically account for all situations by building scale into the sprite bounds, that's great. If we can't, it becomes something that Motions are required to understand.

Right now, some motions do account for scaling, and that is probably what is messing up your containers. Their default motion (Resize) is already accounting for scale, so you would need to take that out: see

sprite.initialBounds.width / sprite.initialCumulativeTransform.a,
sprite.finalBounds.width / sprite.finalCumulativeTransform.a, duration
.

The smallest change that would fix the bug here is making Move understand the cumulative transforms, the same way Resize does. Probably here:

{
let initial = sprite.initialBounds;
let final = sprite.finalBounds;
dx = final.left - initial.left;
dy = final.top - initial.top;
}

But in general, I agree with the goal of making it so that motions don't need to individually understand the surrounding cumulative transform. In the most general case, you may be animating inside an Element that is also animating its own scale. The way to make that kind of situation tenable is to keep motions thinking in relative terms. That's why initialBounds is relative to your offset parent -- it means you don't need to know about the fact that you may be inside a context that is itself moving. Probably this means initialBounds should be in coordinates local to the inside of the surrounding cumulative transform, so I think you're on the right track.

@@ -435,7 +435,7 @@ export default class Sprite {
}
this._inInitialPosition = true;
if (this._offsetSprite) {
this._initialBounds = relativeBounds(this.element.getBoundingClientRect(), this._offsetSprite.initialBounds);
this._initialBounds = relativeBounds(this._getScaledBoundingClientRect(), this._offsetSprite.initialBounds);
} else {
this._initialBounds = this.element.getBoundingClientRect();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this branch of the if needs to follow the same coordinate system as the other, so your change would need to go here too.

@@ -461,6 +461,38 @@ export default class Sprite {
this._finalCumulativeTransform = cumulativeTransform(this.element);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now causing us to calculate the cumulative transform twice. I think this line can just become this._finalCumulativeTransform = this.cumulativeTransform, and then it will share the cache.

@GavinJoyce
Copy link
Contributor Author

GavinJoyce commented Jul 30, 2018

Thanks for the feedback @ef4. I've made those changes and almost everything seems to work:

working

There is an issue in the hero demo, possibly because it animates scale. I don't fully understand the issue yet, please let me know if it's obvious to you:

not-working

There are three failing tests, one is related the the hero issue above. The other two seem like they might just need to be updated to test correct values.

@GavinJoyce
Copy link
Contributor Author

GavinJoyce commented Aug 25, 2018

With a margin, hero animates incorrectly:

.hero-detail {
    margin-left: 6rem;
    margin-top: 6rem;
}

scaled-heros-margin

When I remove the .hero-detail margin, it works as expected:

scaled-heros

@GavinJoyce GavinJoyce force-pushed the gj/scale-bounding-client-rect branch from 470f9f9 to e315228 Compare August 25, 2018 14:31
@GavinJoyce GavinJoyce force-pushed the gj/scale-bounding-client-rect branch from e315228 to d7a3be3 Compare August 25, 2018 14:31
@GavinJoyce
Copy link
Contributor Author

I rebased and the hero animation seems to be working correctly now:

scaled-heros-working

@GavinJoyce
Copy link
Contributor Author

@ef4 I'm having a little trouble determining if the three failing tests are due to a bug with scaling or if the tests need to be changes now that we handle scaled containers. Perhaps you could let me know if it's obvious to you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants