Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Animated List Selection
import Ember from 'ember';
import move from 'ember-animated/motions/move';
import adjustCSS from 'ember-animated/motions/adjust-css';
import { fadeOut } from 'ember-animated/motions/opacity';
import { easeOut, easeIn } from 'ember-animated/easings/cosine';
const rollUp = function * ({ keptSprites, removedSprites, duration }) {
let [kept] = keptSprites;
for (let sprite of keptSprites) {
let z = removedSprites.length + 1;
sprite.applyStyles({ 'z-index': z });
move(sprite, { duration });
}
// removedSprites.forEach((sprite, index) => {
// let z = removedSprites.length - index;
// sprite.applyStyles({ 'z-index': z });
// console.log(z, index);
// if (sprite.initialBounds.top > kept.initialBounds.top) {
// sprite.endAtSprite(kept);
// } else {
// console.log('kept.initialBounds', kept.initialBounds.height, kept.finalBounds);
// // sprite.endAtSprite(kept);
// sprite.endAtPixel({ y: kept.finalBounds.top - sprite.initialBounds.height/2 });
// }
// console.log(sprite.finalBounds);
// // sprite.endAtSprite(kept);
// // sprite.endAtPixel({ y: -kept.initialBounds.height/2 });
// // let bounds = kept.finalBounds;
// // console.log('...y',bounds.top)
// // sprite.endAtPixel({ y : bounds.top });
// move(sprite, { duration });
// });
removedSprites.forEach((sprite, index) => {
let { initialBounds } = sprite;
let z = removedSprites.length - index;
sprite.applyStyles({ 'z-index': z });
if (initialBounds.top > kept.initialBounds.top) {
sprite.endAtSprite(kept);
} else {
console.log(kept.finalBounds.top, sprite.initialBounds.height, sprite, kept);
sprite.endAtPixel({
y: kept.finalBounds.top - sprite.initialBounds.height,
});
}
move(sprite, { duration });
});
};
const rollDown = function * ({ insertedSprites, keptSprites, duration }) {
let [kept] = keptSprites;
for (let sprite of keptSprites) {
let z = insertedSprites.length + 2;
sprite.applyStyles({ 'z-index': z });
move(sprite, { duration });
}
insertedSprites.forEach((sprite, index) => {
let z = insertedSprites.length - index;
sprite.applyStyles({ 'z-index': z });
sprite.startAtSprite(kept);
move(sprite, { duration });
});
};
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
items: null,
init() {
this._super(...arguments);
this.items = this.makeItems();
this._ogItems = [...this.items];
},
rules({ oldItems, newItems }) {
if (newItems.length === 1) {
return rollUp;
} else {
return rollDown;
}
},
actions: {
select(item) {
if (this.selectedItem === item) {
this.send('reset');
return;
}
this.set('selectedItem', item);
this.set('items', [item]);
},
reset() {
this.set('selectedItem', null);
this.set('items', [...this._ogItems]);
}
},
makeItems() {
let result = [];
for (let i = 0; i < 5; i++) {
result.push(makeRandomItem(i));
}
return (result);
},
});
function makeRandomItem(index) {
var messages = ["Dwight", "Stanley", "Kelly", "Ryan", "Kevin"];
var images = ['https://pbs.twimg.com/profile_images/549268771484229632/WnatiHzT_400x400.jpeg', 'https://pbs.twimg.com/profile_images/1839546020/florida_stanley_400x400.jpg', 'https://pbs.twimg.com/profile_images/71405458/2928282474_24807334d7_400x400.jpg', 'https://pbs.twimg.com/profile_images/740436182107049984/y0N8Sqbi_400x400.jpg', 'https://pbs.twimg.com/profile_images/118888142/Brian_Baumgartner_134198_400x400.jpg'];
return { id: Math.round(Math.random()*1000), message: messages[index], image: images[index] };
}
body {
margin: 12px 16px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
box-sizing: border-box;
}
.item-container {
position: relative;
overflow: hidden;
padding: 1rem;
position: fixed;
bottom: 2rem;
}
.items {
margin: 0;
padding: 0;
width: 200px;
}
.item {
background: white;
list-style: none;
outline: 1px solid #ccc;
margin: 1px 0 0;
padding: 0.5rem;
display: flex;
align-items: center;
}
.item.is-selected {
/* padding-left: 3rem;
padding-right: 3rem; */
}
.avatar {
border-radius: 50%;
margin-right: 1rem;
}
<h1>Welcome to {{appName}}</h1>
{{#animated-container class="item-container"}}
<ul class="items">
{{#animated-each items key="id" rules=rules duration=2000 as |item|}}
<li {{action 'select' item}} class="item {{if (eq selectedItem item) 'is-selected'}}">
<img src={{item.image}} class="avatar" width=40 height=40>
<span class="name">{{item.message}}</span>
</li>
{{/animated-each}}
</ul>
{{/animated-container}}
{{#if selectedItem}}
<button type="button" {{action 'reset'}}>Reset</button>
{{/if}}
<br>
<br>
{{outlet}}
<br>
<br>
{{animated-tools}}
import { run } from '@ember/runloop';
export default function destroyApp(application) {
run(application, 'destroy');
}
import Ember from 'ember';
import Application from '../../app';
import config from '../../config/environment';
const { run } = Ember;
const assign = Ember.assign || Ember.merge;
export default function startApp(attrs) {
let application;
let attributes = assign({rootElement: "#test-root"}, config.APP);
attributes.autoboot = true;
attributes = assign(attributes, attrs); // use defaults, but you can override;
run(() => {
application = Application.create(attributes);
application.setupForTesting();
application.injectTestHelpers();
});
return application;
}
import Application from '../app';
import config from '../config/environment';
import { setApplication } from '@ember/test-helpers';
import { start } from 'ember-qunit';
import { assign } from '@ember/polyfills';
let attributes = assign({ rootElement: '#main' }, config.APP);
setApplication(Application.create(attributes));
start();
{
"version": "0.15.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js",
"ember": "3.4.3",
"ember-template-compiler": "3.4.3",
"ember-testing": "3.4.3"
},
"addons": {
"ember-data": "3.4.2",
"ember-animated": "0.5.4",
"ember-animated-tools": "0.4.1",
"ember-truth-helpers": "2.1.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.