Coder Social home page Coder Social logo

ember-animation / ember-animated Goto Github PK

View Code? Open in Web Editor NEW
243.0 14.0 90.0 30.72 MB

Core animation primitives for Ember.

Home Page: https://ember-animation.github.io/ember-animated/

License: MIT License

JavaScript 49.18% HTML 0.46% TypeScript 45.75% Handlebars 3.53% SCSS 1.00% CSS 0.08%

ember-animated's Introduction

Ember Animated

This library is intended to become a robust foundation for animation in Ember.

Interactive docs are at https://ember-animation.github.io/ember-animated/

Compatibility

  • Ember.js v4.8 or above
  • Embroider or ember-auto-import v2

Installation

ember install ember-animated

Contributing

See the Contributing guide for details.

License

This project is licensed under the MIT License.

ember-animated's People

Contributors

bagby avatar balinterdi avatar chadhietala avatar chrism avatar cibernox avatar dependabot[bot] avatar ef4 avatar esbanarango avatar frederikbosch avatar jamesreggio avatar janwerkhoven avatar jeffhertzler avatar jembezmamy avatar kiwiupover avatar knownasilya avatar machty avatar madnificent avatar mattmarcum avatar mattxyzeth avatar rlivsey avatar rwjblue avatar ryanto avatar samselikoff avatar savvymas avatar sergeastapov avatar stefanpenner avatar tomdale avatar toovy avatar turbo87 avatar wagenet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ember-animated's Issues

Question about building image slider

Hi!

First thanks so much for this awesome library.
I hope here is the right place to ask my question. Please let me know if I should rather do it somewhere else.

I am trying to build an image slider with ember-animated.

  1. I use animated-value like this for the transition. Would you recommend a different approach?
  {{#animated-container tagName="ul"}}
    {{! preload images }}
    {{#each images as |image|}}
      <li>
        <div style="display:none; background-image: url('{{image}}');"></div>
      </li>
    {{/each}}

    {{#animated-value imageIdx rules=rules duration=1000 as |idx|}}
      <li class="current">
        <div class="pic" style="background-image: url('{{object-at idx images}}');"></div>
      </li>
    {{/animated-value}}
  {{/animated-container}}
  1. I am trying to transition the images by scaling and changing the opacity (cross dissolve). Changing the opacity is working great, but scaling it in and out is not working as intended. Basically I am trying to recreate the transition here: http://spacialtheme.herokuapp.com/2.6/index-photography.html

    here is my approach, but I get an error in the console. Guess it is not the right way to use scale.

import { parallel } from 'ember-animated';
import scale from 'ember-animated/motions/scale';
import opacity from 'ember-animated/motions/opacity';

export default function * ({ removedSprites, insertedSprites, keptSprites, duration }) {
  removedSprites.map(s => {
    if (s.revealed) {
      parallel(
        opacity(s, {
          to: 0,
          duration
        }),
        scale(s, {
          from: 1,
          to: 1.2,
          duration
        })
      );
    }
  });

  insertedSprites.concat(keptSprites).map(s =>
    parallel(
      opacity(s, {
        to: 1,
        duration
      }),
      scale(s, {
        from: 0.8,
        to: 1,
        duration
      })
    )
  );
}

Any hint or comment is appreciated.

Interrupted sequence behaving differently first time

I'm running into an issue that might be a bug, or a misunderstanding on my part:

image

The console is a result of me doing the following sequence twice:

  1. From rest, click the button (toggling isShowing)
  2. Click the button again in the middle of the animation, interrupting it

The first two console.tables show this:

  1. Blue box is inserted, Red is removed
  2. Red is inserted, Blue is removed

I would have expected (2) to be, Red is kept and Blue is removed.

The second time the sequence is run, that's exactly what I see.

Any idea what's causing this?

[Octane] animated-container throws "Cannot read property 'unlock' of null"

After upgrading to Octane, I got an Cannot read property 'unlock' of null, thrown by this line:

https://github.com/ember-animation/ember-animated/blob/master/addon/components/animated-container.js#L166

I put a breakpoint there and have found that this.sprite is not set to the correct sprite because this._ownElement returns null:

https://github.com/ember-animation/ember-animated/blob/master/addon/components/animated-container.js#L133-L142

So this.sprite remains its initial value, null.

That, in turn, is because this._ownElement is only set if this._inserted is set to true and that happens in the didInsertElement hook which is called after we get to the line that calls this.sprite.unlock().

The code I have is as follows:

  <AnimatedContainer class="flex flex-row flex-wrap">
    {{#animated-each this.sortedPlayers key="id" use=transition as |player|}}
      {{#link-to
        "player"
        player.id
        class="no-underline text-blue hover:text-blue-darker w-350px"
      }}
        <PlayerCard @player={{player}} />
      {{/link-to}}
    {{/animated-each}}
  </AnimatedContainer>

Not sure how this is related to Octane but this has worked in the non-Octane version, in 0.5.1 of ember-animated.

How does matching work?

I have this template:

{{#animated-if isShowing use=transition}}
  <div class="bg-blue w-32 h-32"></div>
{{else}}
  <div class="bg-blue w-64 h-64 ml-auto"></div>
{{/animated-if}}

The second div is bigger (has more padding) and has margin-left: auto. I'm getting what seems to be some inconsistent results between the Sprites in the various categories. For example, if I interrupt, the same Sprite will show up in two categories.

Is there a better way to hint to EA how to match these things? Something like a key for these two divs? How in general does matching work? (So far its been mostly something I haven't had to worry about.)

How should motions determine their starting and final values?

Just wanted to capture a bit of our conversation from EmberConf before I forgot it.


I was confused why things like this

* transition({ insertedSprites }) {
  insertedSprites.forEach(sprite => {
    sprite.scale(0.8, 0.8);
    scale(sprite);
  });
})

and this

* transition({ insertedSprites }) {
  insertedSprites.forEach(sprite => {
    sprite.applyStyles({
      opacity: 0.5
    });
    fadeIn(sprite);
  });
})

weren't working, when things like this

* transition({ insertedSprites }) {
  insertedSprites.forEach(sprite => {
    sprite.startTranslatedBy(0, -10);
    move(sprite);
  });
}

were.

In our conversation, Ed said things like initialBounds and initialComputedStyle are intended to be thought of immutable, as they come from the expensive measurement operation that takes place before the transition begins animating. Thus, all the logic that happens inside the userland transition function happens after that measurement has happened, and so the idea is that you're not modifying those initial/final properties.

The flaw with

sprite.applyStyles({
  opacity: 0.5
});
fadeIn(sprite);

is that fadeIn isn't looking at the current state of sprite, rather it moves from 0 to 1 (or a from/to option that you pass it):

fadeIn(sprite, { from: 0.5 });

The general idea is that motions should operate on those measured values of the sprites.

However – I'm now a little bit confused, because of this:

insertedSprites.forEach(sprite => {
  console.log(sprite.initialBounds); // null
  sprite.startTranslatedBy(0, -10);
  console.log(sprite.initialBounds); // {top: 0, bottom: 48, left: 36.515625, right: 66.515625, width: 30, …}
});

So it looks like some of the Sprite class methods do update the initial/final properties.

Based on my experience so far, I think the most intuitive thing would be if (1) all of these sprite methods were able to mutate the initial/final properties, and then (2) the convention for motions would be to read from the state of the sprite, unless told otherwise.

z-index issue in hero demo

as you can see, the animating element is behind other 'normal' elements.

image

i think of a way to solve this is adding ember-animated--animating class to animating elements, then set z-index in CSS.

ef4 could you suggest a way to solve this? i can make a PR accordingly.

Help thinking through an animation

Hi! I was hoping to get some guidance/advice on how best to organize an animation I'm working on.

There's a nice animation from the Things OSX app:

kapture 2019-03-05 at 18 20 20

What I'm looking to build is similar to this but actually slightly different.

The animation from Things is actually more straightforward to me, because double-clicking a Todo reflows the contents below it, and there's a lot of stuff in Ember Animated to help there.

What I'm looking to do is render something very similar to the "expanded" state, without "pushing" any of the lower items down. Almost like the expanded state is going to be using position: absolute to grow & show additional data, but there will still be a placeholder "underneath" to keep the space in the list for the existing items.

I'm having trouble thinking about the best way to go about doing this.

My first thought was to make two different versions of the "card", one collapsed and one expanded. Then, when the user selects an item, really I could just add a visibility: hidden class to the collapsed, and show the expanded, and then animate it up. I could start out the expanded sprite at the CSS values for the collapsed version, and use motions to smoothly animate the width and text size up to the expanded version.

This approach feels a little hacky to me though, as I really want to smoothly animate out a card from one state to another. It's the same card, just certain dimensions & contents about it are changing.

So, the other approach I thought was to treat the card as a keptSprite and use something like animated-value, to animate the card between two different states with like item.isExpanded. That would give me one conceptual "card" that exists in two different states.

The problem here is that I'd want a placeholder left behind when isExpanded is true, to hold space in the normal document flow for the items below it. I feel like Sprites are perfect for this since they contain info about their height and width. Is there some way I could use a keptSprite's information, render a placeholder to the DOM, and then animate that keptSprite myself to the expanded state, setting absolute positioning on it?

I wanted to write up some thoughts here if anyone has any ideas, but I'd also love to jump on a screen share to explain more.

Thanks!

Sharing easing

Duration seems to sometimes be shared automatically, e.g. between AnimatedContainer and an animator component that takes @durration arg.

Is it possible to do the same for easing? If I want to use Linear easing on my animator, the Container will now be "out of sync", as it falls back on the default easing of easeInOut.

Need workaround for Ember checkbox's jQuery dependency

This is hopefully an easy one for somebody who wants to contribute.

This PR disables jQuery, but the tests don't pass because Ember's {{input type="checkbox"}} requires jQuery until very recent Ember versions.

Your mission is to change our demos to not use {{input type="checkbox"}} and instead just use <input type="checkbox"> with manual binding of the checked attribute and the necessary event.

An easy way to experiment is to check out the branch from the above-mentioned PR, run the dummy app, visit /demos/here-there, and click the checkbox. It throws an exception.

ember-animated should support to control the progress of the animation

Honestly I'm not sure about how difficult it would be. But if we'd like to have something like iOS's swipe back gesture to go back (or forth), or 3D Touch interactions like peek and pop, we need the ability to control the progress of the animation based on some variable, ideally a percentage. So in the cases above-mentioned, we can calculate a percentage based on touch movement / force, to make our animation look more native and responsive.

Really appreciated if there are any feedbacks and/or discussions about it. Hopefully we could find a way to nail this.

Re-exporting public modules from 'ember-animated'

I wanted to reopen the discussion about exporting EA's modules from the top-level namespace:

// current
import { fadeIn } from 'ember-animated/motions/opacity';
import move from 'ember-animated/motions/move';

// proposed
import { fadeIn, move } from 'ember-animated';

I was chatting with @twokul and @kellyselden and they said Rollup had the ability to tree-shake this style of import. I know you mentioned it is not part of the language-level module specification, but if this feature of Rollup allows us to (eventually) tree-shake packages organized like this when the time comes, what do you think about moving things over today?

Vertical scroll offset of removed Sprite detected as 0

I have a (removed) Sprite which I animate with a custom Motion which behaves kind of like toRight from liquid-fire. If the page is scrolled down before the transition begins scrollY is still detected as 0. I suspect the detection happens "too late".

I have tried to track down why this happens, but have not yet succeeded. Within the findOffsets method in the Sprite class (where scroll detection happens) the scroll position is already 0. It is correctly detecting that the effective offset parent is body.

When manually checking window.scrollY before the transition happens, the scroll size is of course detected correctly.

There are no other scroll containers.

The contents of an animated-if block isn't preserved during animation

I believe this behavior is different for AnimatedValue.

In AnimatedValue's template, we

{{yield item}}

whereas in AnimatedIf, we see just a

{{yield}}

The problem is if a relevant piece of state to the {{#animated-if}} block changes, that block will change during an animation.

<button {{action (mut isShowing) (not isShowing)>
  Toggle
</button>

{{#animated-if isShowing}}
  <p>isShowing is {{isShowing}}</p>
{{/animated-if}}

If I click the button to toggle isShowing to false, the contents will change from isShowing is true to isShowing is false as the animation has begun.

I think we want to preserve the state at the time the value changes to properly animate out the block?

Add a new motion: Freeze

If I do this

<AnimatedContainer>
  {{#animated-if isShowingTools use=transition duration=2000}}
    <TimeControl />
  {{/animated-if}}
</AnimatedContainer>

even with an empty transition, my "animation in" is smooth:

Kapture 2019-03-15 at 23 35 20

That's because <TimeControl> appears immediately, and Container takes care of sliding things in.

When I toggle it to false, though, it immediately disappears.

If I add a simple transition like

removedSprites.forEach(sprite => {
  sprite.endAtPixel({ y: window.innerHeight });
  move(sprite);
});

then the sprite "hangs around" for the duration of the transition.

What I'm looking for is the easiest way to make the Sprite just "stay in place" for that duration. This coupled with Container's behavior, should give it the appearance of sliding down.

I tried a few things to get this working, notably combinations of

sprite.reveal();
sprite.applyStyles({
  opacity: 1
});
yield raf();

which I found by looking at how the built-in motions were implemented – but no luck.

Any ideas on how I can write this sort-of identity/no-op motion, that just says "stay put" for the duration?

`animated-value` with `undefined` value and key throws error

When using ember-elsewhere you might not always want to provide a defined value (e.g. a page where nothing should be rendered in the elsewhere). Currently when passing an undefined value to an animated-value and at the same time providing a key attribute throws a Assertion Failed: Cannot call get with 'text' on an undefined object.

Seems to be originating from https://github.com/ember-animation/ember-animated/blob/master/addon/components/animated-each.js#L88

TaskProperty needs to be updated to be a stage 1 decorator

Heya, so we merged some major refactors upstream to Ember's Descriptor system, we thought we'd found all users of it but missed this library. The gist now is that Descriptors are now stage 1 decorators, and Ember.defineProperty knows how to apply them as such.

You can see how we updated Ember Concurrency here, and using ember-compatibility-helpers it should be possible to do something similar here without breaking changes. I'll try to submit a PR as soon as possible, but if anyone wants to take this on in the meantime let me know, I'm happy to help and provide guidance!

Simplify sprite "garbage collection"

I found the need for a "wait" motion like liquid-fire provides (i.e. for keeping certain elements on screen while another animation finishes).

Sample implementation:

//ember-animated/motions/wait.js
import Motion from 'ember-animated/motion';
import { wait as timeout } from 'ember-animated/concurrency-helpers';

export default function wait(sprite, opts) {
  return new Wait(sprite, opts).run();
}

export class Wait extends Motion {
  constructor(sprite, opts) {
    super(sprite, opts);
  }

  * animate() {
    yield timeout(this.duration);
  }
}

and use:

// some component.js
function * someTransition({ removedSprites }){
    removedSprites.forEach(sprite => {
      wait(sprite);
    });
}

This can of course also be done by yielding the wait/timeout directly in the transition's generator function, but then the duration would need to be provided there.

Let me know your thoughts.

Using Liquid Fire vs. Ember Animated today

I know there is a longer-term plan to reimplement Liquid Fire on top of Ember Animated, but for folks working today, could you provide a 2-3 sentence summary of when they should use Liquid Fire (if they at all) vs. Ember Animated?

Split docs tests and library tests

(cc @cibernox because you said you were working on fixing related issues)

I think it's important that we continue to run the test suite with RAISE_ON_DEPRECATION, so we aren't causing deprecations in consuming apps.

But the tests suite also includes all of ember-cli-addon-docs, which itself pulls in a ton of addons. Quite often some of those trigger deprecation warnings, and it would be better to just accept the warnings until the authors can fix them.

Thus, I want to make it possible to test only our own code using RAISE_ON_DEPRECATION, and test the docs site without RAISE_ON_DEPRECATION.

We should either split things into two dummy apps, or setup a feature flag around all usage of addon docs so we can do a CI run with the docs removed.

applyStyles doesn't affect initialComputedStyle

I think I might be misunderstanding the intended use for applyStyles

let sprite = insertedSprites[0];

console.log(sprite.initialComputedStyle); // null

sprite.applyStyles({
  opacity: '0.5'
});

console.log(sprite.initialComputedStyle); // null

Is there a general way to set/update the initialComputedStyle for a Sprite? I noticed some methods like startAtSprite affect it.

In general I'm having trouble using applyStyles throughout my transition, but I think my mental model for it might be off. I would expect to be able to do something like

sprite.applyStyles({
  opacity: '0.5'
});

adjustCSS('opacity', sprite);

and have it fade in.

Diagnosing the 5px "jump" on the inline text demo

I'm having trouble figuring out why there's a ~5px "jump" on the inline-text demo. I've been looking at the moving-word component from the Living Animation talk as well and can't figure out what's going on.

  • Sometimes animated-orphans is put in a position: absolute or position: fixed div. I've tried different combinations of these but no luck. How does the position of animated-orphans affect the orphans it renders?
  • I've tried "eating" all the white spice with the ~ helper
  • I've experimented with different styles on <AnimatedContainer>, like inline-block and align-top

Any ideas or pointers on what's going on?

Documentation example problemo

It is possible to create unexpected behaviors in the "The power of promises" example on the website. If you click two options back and forth on a steady interval, before the animation completes, the animation gets into a strange state. As you continue to do this, it seems like the velocity of the items slowly increases.

So that's one issue. A related problem is that a coworker of mine was also able to get the cards into a broken state, where cards would stop in a mid-transition state.

Clicking in this way could be written off as nonstandard user behavior, but I frequently require animations where the user can input before the transition completes, so this kind of use case is important to me. To give a concrete example, consider keyboard navigation with a 350ms input throttle paired with a 450ms animation duration.

Perhaps this is just a consequence of the specific way that this example was set up; I'm not sure! But I figured I'd open an issue anyway.

Eating animated-each's whitespace

We're working on using animated-each with an array of lines of text that we're rendering inside of a <pre>. It looks like this:

<AnimatedContainer>
  <pre>
    {{#animated-each exampleTemplateLines key='id' use=codeTransition as |line|~}}
      <div>{{{line.text}}}</div>
    {{~/animated-each}}
  </pre>
</AnimatedContainer>

This almost works, but animated-each generates some whitespace of its own which breaks our formatted code.

If we make this change to animated-each's template, things work:

  {{#each renderedChildren key="id" as |child|}}
    {{#-ea-list-element child=child elementToChild=_elementToChild}}
-     {{yield child.value child.index}}
+     {{~yield child.value child.index~}}
    {{/-ea-list-element}}
  {{/each}}

What do you think about this? Is this something that would break other uses? Is there another way to solve the problem?

[Octane] afterRender hangs app

With the fix for #96 in place, the next thing I bumped into is that when the list that animated-each loops over changes, the app hangs and CPU usage of the tab hovers very close to 100% (the process needs to be shut down). It works fine the first time the list is rendered.

Looking into where it does that I've found that it's the yield afterRender where the code hangs:

Drilling further down it seems like the schedule('afterRender', ...) line is called a few times but then no more (and the hanging ensues). The cancel(ticket) line is never entered though I'm not sure if that should tell us something.

export function afterRender() {
let ticket;
let promise = new Promise(resolve => {
ticket = schedule('afterRender', resolve);
});
promise.__ec_cancel__ = () => {
cancel(ticket);
};
return promise;
}

@ef4 In your commented code to another issue, you wrote that afterRender is supposed to wait for Ember to finish rendering. If you meant route-driven rendering, the app doesn't do that in response to the changed list.

Do you have a hunch of what the reason for this should be?

Here is the relevent js and template code:

export default class IndexController extends Controller {
  sortBy = "standard";

  @tracked model;
  @tracked sortBy;

  get sortedPlayers() {
    return sortBy(this.model.toArray(), [this.sortField]);
  }

  get sortField() {
    return {
      standard: "rankings.standard",
      rapid: "rankings.rapid",
      blitz: "rankings.blitz",
      age: "age"
    }[this.sortBy];
  }

  // eslint-disable-next-line require-yield
  * transition({ /* insertedSprites ,*/ keptSprites/*, removedSprites */ }) {
    keptSprites.forEach(sprite => move(sprite, { duration: 500 }));
  }

  @action
  sortPlayers(value) {
    this.set('sortBy', value);
  }
}
<div class="mx-4">
  <select
    name="sort-selector"
    onchange={{action (mut this.sortBy) value="target.value"}}
    class="mb-4"
    data-ssm="player-sort-selector"
  >
    <option value="standard">Standard</option>
    <option value="rapid">Rapid</option>
    <option value="blitz">Blitz</option>
    <option value="age">Age</option>
  </select>

  <AnimatedContainer class="flex flex-row flex-wrap">
    {{#animated-each this.sortedPlayers key="id" use=transition as |player|}}
      {{#link-to
        "player"
        player.id
        class="no-underline text-blue hover:text-blue-darker w-350px"
        data-test-ssm="player-card-link"
      }}
        <PlayerCard @player={{player}} />
      {{/link-to}}
    {{/animated-each}}
  </AnimatedContainer>
</div>

Sprites animate incorrectly when within a scaled element

I'm not sure if this is a scenario that ember-animated should handle or not. If not, please let me know so that I can consider approaches other than making modifications to ember-animated.

I'm using ember-animated in ember-present. I'm applying a scale to slides based on the available viewport in order to maximise their size of the slide while maintaining a 16:9 aspect ratio. When a scale is applied, the animated sprites seem to move to incorrect positions:

with-scale

When I remove the scale, the sprites animate correctly:

without-scale

Here's a PR which contains a reproduction of the behaviour

scale

Animation Between Routes w/ Loading State

If I missed something in the docs I apologize in advance. What I'm trying to achieve is animating from the loading route to the app once my data is fetched. The structure of my app is:

+ parent/
|
|  + view/
|  + loading/
|  + otherPage/
| template.hbs

I'm just a little lost as what to wrap as a animated-component/if/value so I can animate between the loading component to any route, or better yet how to animate from one route to any other route.

Something like `yield settled` in an animation?

I'm finding myself using this pattern a lot when experimenting with "staggered" behavior in my animations.

Say I have this transiiton:

removedSprites.forEach(fadeOut);
keptSprites.map(sprite => {
  fadeIn(sprite);
  move(sprite);
});

insertedSprites.forEach(fadeIn);

and I want to see what it looks like if I let the removed/kept sprites finish animating before moving onto inserted. I'll do something like this:

  removedSprites.forEach(fadeOut);
  keptSprites.forEach(sprite => {
    fadeIn(sprite);
    move(sprite);
  });

+ yield wait(duration);

  insertedSprites.forEach(fadeIn);

This is easier than using Promise.all or .map or something, and conceptually what I'm really trying to express is something more like yield settled(). What do you think, is that something that can be done or would be good to add?

ember-animated-top-collapse sometimes added to first hero item

When clicking through heroes which are not the first item, the '.ember-animated-top-collapse' class is sometimes added to only the first item, causing it to jump up during the animation. It seems to happen when transitioning in both directions (but not always!).

I'm not entirely familiar with the library yet, so I unfortunately haven't fully tracked it down.

First pointer:

children[i].classList.add('ember-animated-top-collapse');

Introduce sprite.model

I believe this is by design, but I want to make sure my understanding is correct.

If I have a transition function on a component

export default Component.extend({

  foo: 'bar',

  transition: function*({ keptSprites }) {
    console.log(this);
    keptSprites.forEach(sprite => {
    ...

there's no way I can access any component state (such as foo) from within transition - correct? If so, could you explain why?

Interested in TypeScript?

Hi! I learned about this addon at EmberConf, and I'm really wanting to start using it. I’m also participating in this quest issue to add TypeScript support throughout the Ember.js ecosystem. This will benefit to everyone who uses your addon, not just TypeScript users! (See here for an explanation.)

Are you interested in either converting the addon to use TypeScript itself, or in adding type definitions? I’d love to help out, if so! And if not, that’s just fine. Thanks!

Momentum

Momentum seems to be a default property of most/all of the provided Motions, but I'm having trouble tracking down where it "lives".

Is it a part of the motions themselves, the code that is performing calculations on prior tweens?

fade seems like it does not have any sort of momentum. I'm basically trying to recreate this behavior for move – a momentumless move, similar to what you'd have if you added a CSS transition to an element – but I'm having trouble.

I can post some code examples but figured I'd start with this in case I'm missing an obvious place to look.

IE11 / Windows 7 Issue

Testing on IE11 gives me this error in the console.

SCRIPT5009: 'Symbol' is undefined
File: vendor-8336295e6bef0390b14bd99dbe877138.js, Line: 6682, Column: 133

Which looks like it is due to ember-animated code

6679 try{for(var s,u=a(e)[Symbol.iterator]();!(n=(s=u.next()).done);n=!0){var l=s.value
6680 if(l.isEmberAnimatedListElement)r=l.get("child.id")
6681 else if(null!=r){var c=this._ancestorObservers.get(l)
6682 c||this._ancestorObservers.set(l,c=new Map),c.set(t,r),r=null}}}catch(e){i=!0,o=e}finally{try{!n&&u.return&&u.return()}finally{if(i)throw o}}return this},unobserveAncestorAnimations:function(e,t){var r=!0,n=!1,i=void 0
'Symbol' is undefined
6683 try{for(var o,s=a(e)[Symbol.iterator]();!(r=(o=s.next()).done);r=!0){var u=o.value,l=this._ancestorObservers.get(u)

It would make sense because before adding ember-animated the site was working.

Should IE11 be supported? If so, I think this is quite important.

Thanks.

Documentation updates

The documentation is still severely lacking and the library can't really be used without doing lots of code spelunking. I consider this a bug and think the documentation should be prioritized as if the build were broken.

I wanted to do more on the content but have run out of resources to work on this for the time being. I wanted to capture some of my TODOs here for anyone interested in helping.

If anyone wants to take any of these on and wants some guidance, feel free to ping me here!


  • Write a Quickstart. Smooth introduction to the library, introducing only the concepts necessary to move one step at a time. (There are tons of concepts in this library which is one of the biggest barriers to usage atm.)
  • Review existing guides. The existing guides are quite confusing in my opinion and need to be updated. The examples are also not compelling, which I think is important for giving people a reason to learn the library!
  • Lifecycle of an animation. Another guide I thought would be helpful. It'd be great to give a conceptual overview of the lifecycle of an animation, starting with animators and data binding, what happens when an animator's data changes, how first and last states are calculated, how motions happen, and what happens when it's all done. Also how it impact/affects/fits in with Ember's rendering (Are elements clones? What's the state of a variable while it's being animated? etc.)
  • How duration is handled. Duration is sometimes magically shared between animators, sometimes not. Need to document how this works and what to do if the default behavior isn't what you want.
  • How easing is handled. Same as duration. If I have an AnimatedContainer, then do a custom AnimatedIf inside with linear easing, AnimatedContainer will not be in sync. How do I share easings, or change AnimatedContainer's easing?
  • How to write a custom Motion. Tweens might fall under here too, if they are public API.
  • How to write a custom Easing function.
  • Duration/easing/momentum/interruptibility. Many of the included motions/transitions are stateful, or include some sort of momentum. This is basically a black box to the user and I don't know how they work or how to change them. (Looking at some of the code I find things like this.priorTween which I imagine is where the stateful aspects of a motion come in, but it's not clear in the docs.) Often this built-in "momentum" is not what you want, i.e. if you use it on a collapsible panel it is unnatural. Need to document it and how to change/remove it.
    • Reference: #72
    • Reference: #73
  • MotionCurve. Is this public?
  • Examples. I'm thinking a new top-level nav item with CodeSandbox placeholders/embeds might be the best.
  • Add a note somewhere on Liquid Fire vs. Ember Animated. (#79)
  • Testing and test helpers. E.g. #119
  • Other things
    • Document using inline-block to animate inline elements (#76)
    • Mental model around applyStyles (#78)
    • Explain matching (#84)

Tripped up by easing imports

This might be silly, but I was trying to use the linear ease but kept messing up my imports.

I had this

import { easeOut, easeIn } from 'ember-animated/easings/cosine';

and came up and added linear:

import { easeOut, easeIn, linear } from 'ember-animated/easings/cosine';

I plugged that into my move motion but still wasn't seeing it. (Sometimes these are hard to tell just by looking at it). But I was sure it wasn't linear...

I dug into the code and put a breakpoint in the Tween class and saw the default of easeInOut was still being used.

That's when I realized I was trying to import linear from easings/cosine. There is a guard about a Tween's easing needing to be a function, but this was an undefined import I guess...

So I switched it

- import { easeOut, easeIn, linear } from 'ember-animated/easings/cosine';
+ import { easeOut, easeIn } from 'ember-animated/easings/cosine';
+ import { linear } from 'ember-animated/easings/linear';

...same thing.

I then finally realized linear is the default import from easings/linear.

- import { linear } from 'ember-animated/easings/linear';
+ import linear from 'ember-animated/easings/linear';

Maybe we could export an index from ember-animated/easings? So you can

import { easeOut, easeIn, linear } from 'ember-animated/easings';

Also I don't know if this is possible, but if there was some way to warn if users try to pass in an undefined value that would have also been helpful.

Unintentional scale transition occurring during fade

Trying to perform a fade with animated-if, but getting a unwanted bonus height & width animation too!

Cause appears related to content overflow and the appearance of the scrollbars, which changes the dimensions of the animated container as the content is toggled. For some reason even though I am only requesting a fade transition, it is animating a size change and creating the unwanted effect of moving the content on screen.

Link to: Example with slow duration to better see what is going on -- You can see the animated-container width and height being animated in the inspector. The fade transition is used here.

Twiddle example (slow duration) -- Make sure to reduce your window size so that when the menu is shown, it has to scroll.

Thought maybe it was an issue with the transition type. But the animation of animated-container occurs even if I used an empty transition type, eg:

    myTransition: function * ({ insertedSprites, removedSprites }) {

    },

The expected behaviour of applying an opacity/fade transition should be that only opacity/fade be animated.

How to prevent the width and height animation of animated-container?

duration mismatch with fade transition and `<AnimatedContainer>`

I'm using an animated-if with the default fade transition wrapped in a <AnimatedContainer> component. It seems that there is an animation duration mismatch between the two animations though.

Looking at the implementation, it seems that the fade transition uses half of the duration to remove sprites and the other half of the duration to add sprites. It looks like the <AnimatedContainer> is using the full duration though. This causes the elements in the animated-if to already have full opacity when the container is not fully expanded yet.

@ef4 Am I using this incorrectly? Is that intended behavior?

Animation between routes example in documentation

In the documentation there's an example:

{{#animated-value "index-route" initialInsertion=true finalRemoval=true use=transition duration=1000}}
<div class="hero-list">
 <!-- ... -->
</div>
{{/animated-value}}

But what is initialInsertion and finalRemoval? What is the string argument index-route?

Also, what is the function of hero.hbs? I see it invokes {{animated-orphans}}, but I can't find where the component for hero is called.

Thanks for any help

Delaying an animation

Liquid Fire has a delay attribute that can be set to delay the start of an animation. The equivalent functionality appears to be missing in ember-animated. Is that the case, or if not, is it possible to delay an animation?

Allow creation of ephemeral sprites

Context: I've just watched the Emberconf video and am incredibly excited about this library! I've spent considerable time trying to achieve a similar effect using liquid-fire but have struggled to handle synchronisation between different events—exactly as the demonstration explains.

I'm really keen to reimplement using ember-animated but have one reservation.

This is the animation I'm trying to achieve (slowed down and at is most basic).

schedule_animation

It's very similar to tutorial 13 from the living-animation presentation but with a different animation for moving between rows.

Using liquid-fire it was possible because of this.newElement and this.oldElement so could be animated independently. The code necessary looked something like this.

  let oldOffset = this.oldElement.offset();
  let newOffset = this.newElement.offset();

  if (newOffset.top > oldOffset.top) {
    // matches when sliding up a row
    // slides the old element off the screen to the left
    // slide the new element in from off the right

    let oldMotion = {
      translateX: -Math.abs(this.oldElement.width())
    };
    let newMotion = {
      translateX: [0, this.newElement.width()]
    };
    this.newElement.css({ visibility: '' });
    return Promise.all([
      animate(this.oldElement, oldMotion, opts, 'sliding'),
      animate(this.newElement, newMotion, opts, 'sliding')
    ]);
  }

Now with ember-animated and the use of sprites to animate I'm not sure how to achieve a similar effect. I've looked through the codebase but been unable to find a similar example.

In the living-animation presentation I noted the slide that said 'No cloning necessary'.

I think this library is fantastic and am excited to start using it, but would really appreciate some advice on how an animation like this can be achieved.

I'd be very happy to write up an article on how to do this, or help with the documentation if you could point me in the right direction as I'm sure other people would be interested too.

As an example, this is an article I wrote on Migrating from Liquid Fire modals to Ember Elsewhere

Quest: Documentation Site

It's time for docs. Most likely we should use https://ember-learn.github.io/ember-cli-addon-docs/

Sources for learning how things work:

  • My EmberConf demo
  • The development & testing demos within the dummy app in this repo
  • the test suite

The following is a burndown list of things that need to be described:

The Animator Components

  • animated-each
  • animated-value
  • animated-if

The Support Components

  • animated-container
  • animated-orphans
  • animated-beacon

Common options on all animator components

  • key
  • use
  • rules
  • duration
  • group
  • initialInsertion
  • finalRemoval

The Transition Context

  • insertedSprites
  • removedSprites
  • keptSprites
  • receivedSprites
  • sentSprites
  • duration

Sprite API

Many of these already have comments in the code.

  • initialBounds
  • finalBounds
  • absoluteInitialBounds
  • absoluteFinalBounds
  • initialComputedStyle
  • finalComputedStyle
  • getInitialDimension
  • getFinalDimension
  • initialCumulativeTransform
  • finalCumulativeTransform
  • originalInitialBounds
  • originalFinalBounds
  • different
  • element
  • transform
  • revealed
  • hide
  • reveal
  • applyStyles
  • translate
  • scale
  • startAtSprite
  • startAtPixel
  • endAtSprite
  • endAtPixel
  • endRelativeTo

Build In Transitions

  • fade
  • moveOver (toLeft, toRight, toUp, toDown)

Built In Motions

  • adjustColor
  • adjustCSS
  • compensateForScale
  • follow
  • moveSVG
  • move
  • opacity
  • resize
  • scale

How to Author Motions

This you can mostly learn from looking at the nine existing examples. The public API for Motion authors is to implement:

  • constructor (optional)
  • interrupted (optional)
  • animate (mandatory)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.