Aurelia.js: 如何在绑定值更改时为元素设置动画?
Aurelia.js: How do I animate an element when bound value changes?
我正在为我的 UI 使用 Aurelia.js。假设我有以下视图标记:
<tr repeat.for="item in items">
<td>${item.name}</td>
<td>${item.value}</td>
</tr>
绑定到模型 "items"。当模型中的一个值发生变化时,我想为显示更改值的单元格设置动画。我怎样才能做到这一点?
疯狂的 Aurelia 的创造者-CSS-动画师在这:)
为了做你想做的事,你只需要抓住 DOM-Element 然后使用 Aurelia 的 animate 方法。由于我不知道您将如何编辑项目,所以我只是在 VM 中使用超时来模拟它。
attached() {
// demo the item change
setTimeout( () => {
let editedItemIdx = 1;
this.items[editedItemIdx].value = 'Value UPDATED';
console.log(this.element);
var elem = this.element.querySelectorAll('tbody tr')[editedItemIdx];
this.animator.addClass(elem, 'background-animation').then(() => {
this.animator.removeClass(elem, 'background-animation')
});
}, 3000);
}
我创建了一个小插件来演示它是如何工作的。请注意,这是一个旧版本,不包含最新的动画师实例,所以我一起使用 addClass/removeClass 而不是动画。
http://plnkr.co/edit/7pI50hb3cegQJTXp2r4m
也看看官博post,有更多提示
http://blog.durandal.io/2015/07/17/animating-apps-with-aurelia-part-1/
希望对您有所帮助
这可以通过 Aurelia custom attributes 功能来完成。
创建一个新的javascript文件来描述属性(我将属性命名为"animateonchange"):
import {inject, customAttribute} from 'aurelia-framework';
import {CssAnimator} from 'aurelia-animator-css';
@customAttribute('animateonchange')
@inject(Element, CssAnimator)
export class AnimateOnChangeCustomAttribute {
constructor(element, animator) {
this.element = element;
this.animator = animator;
this.initialValueSet = false;
}
valueChanged(newValue){
if (this.initialValueSet) {
this.animator.addClass(this.element, 'background-animation').then(() => {
this.animator.removeClass(this.element, 'background-animation');
});
}
this.initialValueSet = true;
}
}
它在构造函数中接收元素和 CSS 动画师。当值发生变化时,它会使用预定义的 CSS class 名称为元素设置动画。第一个变化被忽略(不需要在初始加载时设置动画)。以下是如何使用此自定义元素:
<template>
<require from="./animateonchange"></require>
<div animateonchange.bind="someProperty">${someProperty}</div>
</template>
查看完整示例in my blog or on plunkr
不幸的是,接受的答案对我不起作用,显示中的值在任何动画完成之前发生变化,看起来很糟糕。
我用一个绑定行为解决了,绑定更新被拦截,之前应用了一个动画,然后更新了值,最后又做了一个动画。
现在一切看起来都很顺利。
import {inject} from 'aurelia-dependency-injection';
import {CssAnimator} from 'aurelia-animator-css';
@inject(CssAnimator)
export class AnimateBindingBehavior {
constructor(_animator){
this.animator = _animator;
}
bind(binding, scope, interceptor) {
let self = this;
let originalUpdateTarget = binding.updateTarget;
binding.updateTarget = (val) => {
self.animator.addClass(binding.target, 'binding-animation').then(() => {
originalUpdateTarget.call(binding, val);
self.animator.removeClass(binding.target, 'binding-animation')
});
}
}
unbind(binding, scope) {
binding.updateTarget = binding.originalUpdateTarget;
binding.originalUpdateTarget = null;
}
}
在样式表中声明动画:
@keyframes fadeInRight {
0% {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
100% {
opacity: 1;
transform: none
}
}
@keyframes fadeOutRight {
0% {
opacity: 1;
transform: none;
}
100% {
opacity: 0;
transform: translate3d(-100%, 0, 0)
}
}
.binding-animation-add{
animation: fadeOutRight 0.6s;
}
.binding-animation-remove{
animation: fadeInRight 0.6s;
}
你在你的视图中使用它就像
<img src.bind="picture & animate">
我正在为我的 UI 使用 Aurelia.js。假设我有以下视图标记:
<tr repeat.for="item in items">
<td>${item.name}</td>
<td>${item.value}</td>
</tr>
绑定到模型 "items"。当模型中的一个值发生变化时,我想为显示更改值的单元格设置动画。我怎样才能做到这一点?
疯狂的 Aurelia 的创造者-CSS-动画师在这:)
为了做你想做的事,你只需要抓住 DOM-Element 然后使用 Aurelia 的 animate 方法。由于我不知道您将如何编辑项目,所以我只是在 VM 中使用超时来模拟它。
attached() {
// demo the item change
setTimeout( () => {
let editedItemIdx = 1;
this.items[editedItemIdx].value = 'Value UPDATED';
console.log(this.element);
var elem = this.element.querySelectorAll('tbody tr')[editedItemIdx];
this.animator.addClass(elem, 'background-animation').then(() => {
this.animator.removeClass(elem, 'background-animation')
});
}, 3000);
}
我创建了一个小插件来演示它是如何工作的。请注意,这是一个旧版本,不包含最新的动画师实例,所以我一起使用 addClass/removeClass 而不是动画。
http://plnkr.co/edit/7pI50hb3cegQJTXp2r4m
也看看官博post,有更多提示 http://blog.durandal.io/2015/07/17/animating-apps-with-aurelia-part-1/
希望对您有所帮助
这可以通过 Aurelia custom attributes 功能来完成。
创建一个新的javascript文件来描述属性(我将属性命名为"animateonchange"):
import {inject, customAttribute} from 'aurelia-framework';
import {CssAnimator} from 'aurelia-animator-css';
@customAttribute('animateonchange')
@inject(Element, CssAnimator)
export class AnimateOnChangeCustomAttribute {
constructor(element, animator) {
this.element = element;
this.animator = animator;
this.initialValueSet = false;
}
valueChanged(newValue){
if (this.initialValueSet) {
this.animator.addClass(this.element, 'background-animation').then(() => {
this.animator.removeClass(this.element, 'background-animation');
});
}
this.initialValueSet = true;
}
}
它在构造函数中接收元素和 CSS 动画师。当值发生变化时,它会使用预定义的 CSS class 名称为元素设置动画。第一个变化被忽略(不需要在初始加载时设置动画)。以下是如何使用此自定义元素:
<template>
<require from="./animateonchange"></require>
<div animateonchange.bind="someProperty">${someProperty}</div>
</template>
查看完整示例in my blog or on plunkr
不幸的是,接受的答案对我不起作用,显示中的值在任何动画完成之前发生变化,看起来很糟糕。
我用一个绑定行为解决了,绑定更新被拦截,之前应用了一个动画,然后更新了值,最后又做了一个动画。 现在一切看起来都很顺利。
import {inject} from 'aurelia-dependency-injection';
import {CssAnimator} from 'aurelia-animator-css';
@inject(CssAnimator)
export class AnimateBindingBehavior {
constructor(_animator){
this.animator = _animator;
}
bind(binding, scope, interceptor) {
let self = this;
let originalUpdateTarget = binding.updateTarget;
binding.updateTarget = (val) => {
self.animator.addClass(binding.target, 'binding-animation').then(() => {
originalUpdateTarget.call(binding, val);
self.animator.removeClass(binding.target, 'binding-animation')
});
}
}
unbind(binding, scope) {
binding.updateTarget = binding.originalUpdateTarget;
binding.originalUpdateTarget = null;
}
}
在样式表中声明动画:
@keyframes fadeInRight {
0% {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
100% {
opacity: 1;
transform: none
}
}
@keyframes fadeOutRight {
0% {
opacity: 1;
transform: none;
}
100% {
opacity: 0;
transform: translate3d(-100%, 0, 0)
}
}
.binding-animation-add{
animation: fadeOutRight 0.6s;
}
.binding-animation-remove{
animation: fadeInRight 0.6s;
}
你在你的视图中使用它就像
<img src.bind="picture & animate">