原生脚本无限翻译动画

Nativescript infinite translate animation

本文关键字:动画 翻译 无限 脚本 原生      更新时间:2023-09-26

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

布局如下所示

登录.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(设置区间法

实用工具.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
        });
}

登录.js

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

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

2( 同时循环方法

登录.js

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

此方法使应用冻结在白屏上。

3(递归方法

在这里,我编辑了动画方法:

实用工具.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

登录.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);
        });
    }
};

这样它就不再是递归的(callstack wise(,但会确保你永远不会超过调用堆栈(因为JS确实有一个相当大的CallStack限制,但如果这个人离开这个运行并走开,使用setTimeout将消除超过调用堆栈。

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

在您的页面中.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;
}

在您的页面中.xml

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

NativeScript 中的 CSS 动画