Nativescript 无限翻译动画

Nativescript infinite translate animation

您好,我正在尝试在 NativeScript 视图上实现移动背景图像。

布局看起来像这样

login.xml

<Page loaded="loaded" android:actionBarHidden="true">
<GridLayout>
<Image src="~/img/haloose_bg.png" id="bg"/>

<StackLayout orientation="vertical" verticalAlignment="center" id="sl_login">
...
</StackLayout>
</GridLayout>
</Page>

我想让Image在背景上随机移动

我尝试了以下方法:

1)设置间隔方法

utils.js

utils.animateBG = function(container,id,duration){
        var newx = newy = Math.random() + 1.2;
        container.getViewById(id).animate({
            translate : {x: newx - 10 , y : newy + 70 },
            duration : duration
        });
}

login.js

exports.loaded = function(args){
page = args.object;
setInterval(utils.animateBG(page,"bg",3000),3000);
} 

然后我会清除用户点击按钮或离开视图时的间隔。这种方法会使应用程序在 4 秒后崩溃。

2) While循环方法

login.js

while(!user.hasClickedSomething){
    utils.animateBG(page,"bg",3000);
}

这种方法会使应用程序在白屏上冻结。

3)递归方法

这里我编辑了动画方法:

utils.js

utils.animateBG = function(container,id,duration,continueAnimation){
    if(continueAnimation){
        var newx = newy = Math.random() + 1.2;
        container.getViewById(id).animate({
            scale : { x: newx, y: newy},
            translate : {x: newx - 10 , y : newy + 70 },
            duration : duration
        }).then(function(){
            utils.animateBG(container,id,duration,continueAnimation);
        });
    }
}

然后我调用它并传递 user.continueAnimation 作为停止循环的条件。 user 是绑定到页面的可观察视图模型,默认情况下 continueAnimation 字段设置为 true

login.js

exports.pageloaded = function(args){
page=args.object; 
page.bindingContext = user;
utils.animateBG(page,"bg",3000,user.continueAnimation); 
}

然后,当我单击其他按钮时,我尝试将 user.continueAnimation 设置为 false,但不知何故它在方法中始终保持正确。这导致动画永远不会停止,如果我转到另一个视图并返回,应用程序会冻结或崩溃。

有没有人实现了我正在尝试做的事情?有更好的方法吗? 谢谢

您的#3 实际上几乎是正确的;这是固定代码:

var continueAnimation = true;
utils.animateBG = function(container,id,duration){
    if(continueAnimation){
        var newx = newy = Math.random() + 1.2;
        container.getViewById(id).animate({
            scale : { x: newx, y: newy},
            translate : {x: newx - 10 , y : newy + 70 },
            duration : duration } );
        }).then(function(){
            utils.animateBG(container,id,duration);
        });
    }
};

continueAnimation 变量必须是对函数外部变量的引用,否则它永远不会被设置为 false,并且总是将 "true" 传递给它的递归兄弟。现在我实际上可能会将代码更改为:

var continueAnimation = true;
utils.animateBG = function(container,id,duration){
    if(continueAnimation){
        var newx = newy = Math.random() + 1.2;
        container.getViewById(id).animate({
            scale : { x: newx, y: newy},
            translate : {x: newx - 10 , y : newy + 70 },
            duration : duration } );
        }).then(function(){
            setTimeout(function() {
               utils.animateBG(container,id,duration);
            },0);
        });
    }
};

所以它不再是递归的(调用堆栈明智),但会确保你永远不会超过调用堆栈(因为 JS 确实有一个相当大的 CallStack 限制,但如果这个人离开这个 运行 然后走开,使用 setTimeout 将消除超出调用堆栈的情况。

无限动画还有另一种不同的方法 - 使用 CSS-动画。 例如:

在你的 page.css

@keyframes example {
    0%   { transform: translate(0, 0); }
    25%  { transform: translate(200, 0); }
    50%  { transform: translate(200, 200); }
    75%  { transform: translate(0, 200); }
    100% { transform: translate(0, 0); }
}


.img-logo {
   animation-name: example;
   animation-duration: 2s;
   animation-iteration-count: infinite;
}

在你的 page.xml

<StackLayout>
    <Image src="res://logo" class="img-logo"/>
</StackLayout>

CSS-animations in NativeScript