AS3:Tween Lite:补间在完成之前就停止了?

发布于 2024-10-12 00:08:40 字数 5355 浏览 9 评论 0原文

edit2:好吧,我发现出了什么问题。回答了我自己的问题。 *捂脸*抱歉浪费了空间。 (如果您随机遇到这个问题,我的解决方案在底部给出了答案)

编辑:在仔细思考我的代码试图找到解决方案时,我注意到当我的 .swf 在补间时冻结时,舞台上的动画影片剪辑也会在动画中冻结。这让我相信我的问题可能源于代码的加载/创建图像部分。因此,这是我的加载函数来补充以下代码:

function loadImage():void {

    //if it's not already been loaded)
    if ((currentImageNbr+1) > imagesLoaded || images.length == 0) {

        imagesLoaded++;

        tempPic = xmlData.album[albumNum].image[currentImageNbr].attribute("file");
        tempCaption = xmlData.album[albumNum].image[currentImageNbr].attribute("caption");
        trace("Loading: "+galleryPath+tempPic+" ("+tempCaption+")");

        var loader:Loader = new Loader();
        loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, catchIOError);

        loader.load(new URLRequest(galleryPath+tempPic));
        images[currentImageNbr] = loader;
        paths[currentImageNbr] = tempPic;
        captions[currentImageNbr] = tempCaption;
        //loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,onImgProgress); (not incorporated yet.)

        loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onImgComplete);
    }
    else {
        trace("image already loaded.");
        onImgComplete(null);
    }
}

原始帖子: 再次嗨 StackOverflow!

这对我来说解释我的问题可能有点棘手,所以如果我没有多大意义,请幽默我..

我正在尝试制作一个(足够简单..)XML 图像库。 XML 和加载部分(大部分)都非常好。我的问题是使用 greensock 的 TweenLite 让我的照片滑入和滑出舞台。

我想要实现的运动有点像这样:

  1. 从舞台右侧创建我的图像,
  2. 从右侧旋入并停在舞台中央,
  3. 然后当我切换到下一张图片时,我希望当前图像旋风从左侧的舞台中
  4. 删除
  5. 在右侧的舞台外创建一个新幻灯片
  6. ,最后从右侧旋入

当我在 Flash 中使用 Ctrl + Enter 运行它时,我的代码运行得很好,但是当我在浏览器中运行 .swf 时,图像很多时候无法正确滑动。

他们经常在“嗖嗖”的中间停下来,几秒钟内一动不动 然后它们消失,下一个图像突然出现在中心,没有任何补间发生。

我有一种预感(基于我读过的类似问题),我的问题与我错误地为下一个使用相同的补间,并且它在中间被垃圾收集有关。

我对使用仍然很陌生TweenLite 所以我不太了解它的来龙去脉.. 也许我没有正确创建我的补间?

以下是一些我认为可能是问题区域的相关代码片段, 如果您发现我使用了不好的方法或错误,请告诉我,我仍在学习 ActionScript 3:

一些先决条件(这可能很重要?)

import com.greensock.*;
import com.greensock.easing.*;

stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

stage.addEventListener(Event.RESIZE, resizeHandler, false, 0, true);

加载我的图像(这个函数中有更多内容,但我不介意关于这部分)

loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onImgComplete);

加载后:

function onImgComplete(e:Event):void {
    trace("loading done");

    // check if containerSp exists on stage 
    // if it does, tween it, on complete- delete it and make a new one.
    if (containerSp.stage) {
        trace("containerSp already exists. removing, then making a fresh one");

        // need to check if we're going forwards or backwards.
        if (leftRight == "right") {
            //forwards
            trace("tweening out..");
            moving = true;

            TweenLite.to(containerSp, .5, {x:0-(containerSp.width+20), y:containerSp.y, ease:Quint.easeIn, onComplete:removeSprite}); 
        }
        else if (leftRight == "left") {
            //backwards
            trace("tweening out..");
            moving = true;

            TweenLite.to(containerSp, .5, {x:stage.stageWidth+20, y:containerSp.y, ease:Quint.easeIn, onComplete:removeSprite});
        }
    }
    else {
        trace("containerSp doesn't exist. making a fresh one.");
        makeSprite();
    }
}

当补间完成后,删除图像并制作一个新的精灵:

function removeSprite():void {
    moving = false;
    stage.removeChild(containerSp);
    makeSprite();
}

在containerSp内制作我的图像(尚未添加到舞台):

function makeSprite():void {
    containerSp = new Sprite();
    containerSp.graphics.beginFill(0xFF0000);
    containerSp.graphics.drawRect( 0, 0, 0, 0);
    trace("Done.");

    trace("making image");
    var bm:Bitmap = new Bitmap();
    bm = Bitmap(images[currentImageNbr].content);
    bm.smoothing = true;

    containerSp.addChild(bm);

    trace("done");
    tweenIn();
}

设置我们的containerSp的位置,将其添加到舞台并补间:

function tweenIn():void {
    moving = true;
    resizeHandler();

    // need to check if we're going forwards or backwards.
    if (leftRight == "right") {
        //forwards
        containerSp.y = (stage.stageHeight/2)-(containerSp.height/2)-(barHeight/2);
        containerSp.x = stage.stageWidth;
    }
    else if (leftRight == "left") {
        //backwards
        containerSp.y = (stage.stageHeight/2)-(containerSp.height/2)-(barHeight/2);
        containerSp.x = (0 - stage.stageWidth);
    }

    stage.addChild(containerSp);

    trace("tweening in..");

    TweenLite.to(containerSp, .5, {x:(stage.stageWidth/2)-(containerSp.width/2), y:(stage.stageHeight/2)-(containerSp.height/2)-(barHeight/2), ease:Quint.easeOut, onComplete:done}); 
}

function done():void {
    trace("all done");
    moving = false;
    resizeHandler();
}

resizeHandler的使用是在窗口重新打开时重新调整我的图片大小- 大小。 它基本上设置相对于框架大小的 containerSp.width.height.x.y

moving 变量用于 resizeHandler,因此它不会将 XY 设置到舞台中心,除非图片没有动。

所以总结一下我的问题,为什么只有当我在浏览器中加载 .swf 时,补间才会在完成之前停止工作?

如果我忘记提及任何内容,请告诉我,我很乐意填补空白。

预先感谢您的时间和耐心。

edit2: Well I found out what was wrong. answered my own question. * Face-palm* sorry for this waste of space. (if you come across this randomly, my solution is answered at the bottom)

Edit: While mulling over my code trying to find a solution, I noticed that when my .swf freezes as it is tweening out, an animated movie clip that is on the stage also freezes mid-animation. which brings me to believe that my problems may stem from the loading/creating image portion of my code. as a result, here is my loading function to supplement the code below:

function loadImage():void {

    //if it's not already been loaded)
    if ((currentImageNbr+1) > imagesLoaded || images.length == 0) {

        imagesLoaded++;

        tempPic = xmlData.album[albumNum].image[currentImageNbr].attribute("file");
        tempCaption = xmlData.album[albumNum].image[currentImageNbr].attribute("caption");
        trace("Loading: "+galleryPath+tempPic+" ("+tempCaption+")");

        var loader:Loader = new Loader();
        loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, catchIOError);

        loader.load(new URLRequest(galleryPath+tempPic));
        images[currentImageNbr] = loader;
        paths[currentImageNbr] = tempPic;
        captions[currentImageNbr] = tempCaption;
        //loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,onImgProgress); (not incorporated yet.)

        loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onImgComplete);
    }
    else {
        trace("image already loaded.");
        onImgComplete(null);
    }
}

Original Post:
Hi again StackOverflow!

This might be a little tricky for me to explain my problem so please humour me if I don't make much sense..

I'm trying to make a (simple enough..) XML image gallery. the XML and loading part are (for the most part) fine and dandy. my problems are with using greensock's TweenLite to make my pictures slide in and out of the stage.

the motion i am trying to achieve is kinda like this:

  1. create my image from the right of the stage
  2. swoosh in from the right and stop at the center of the stage
  3. then when i switch to the next picture, I want the current image to swoosh out of the stage to the left
  4. be deleted
  5. create a new slide outside of the stage on the right
  6. and finally, swoosh in from the right
  7. etc

My code works perfectly when I run it using Ctrl + Enter in flash, but when I run my .swf in a browser, the images do not slide correctly a lot of the time.

they often stop, mid-"swoosh" and don't move for a few seconds
then they disappear and the next image suddenly appears in the center without any tween occurring.

I have a hunch (based on similar problems I've read) that my problem has something to do with me mistakenly using the same tween for the next one and it getting garbage collected mid-tween..

I'm still very new to using TweenLite so I don't know its ins and outs too well..
Perhaps I'm not creating my tweens correctly?

Here are some relevant snippets of code that I think are probably the problem areas,
if you spot me using a bad method or a bug, please let me know, I'm still learning ActionScript 3:

a few prerequisits (that might be important?)

import com.greensock.*;
import com.greensock.easing.*;

stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

stage.addEventListener(Event.RESIZE, resizeHandler, false, 0, true);

load my image (there's more inside this function but i'm not bothered about this part)

loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onImgComplete);

Once loaded:

function onImgComplete(e:Event):void {
    trace("loading done");

    // check if containerSp exists on stage 
    // if it does, tween it, on complete- delete it and make a new one.
    if (containerSp.stage) {
        trace("containerSp already exists. removing, then making a fresh one");

        // need to check if we're going forwards or backwards.
        if (leftRight == "right") {
            //forwards
            trace("tweening out..");
            moving = true;

            TweenLite.to(containerSp, .5, {x:0-(containerSp.width+20), y:containerSp.y, ease:Quint.easeIn, onComplete:removeSprite}); 
        }
        else if (leftRight == "left") {
            //backwards
            trace("tweening out..");
            moving = true;

            TweenLite.to(containerSp, .5, {x:stage.stageWidth+20, y:containerSp.y, ease:Quint.easeIn, onComplete:removeSprite});
        }
    }
    else {
        trace("containerSp doesn't exist. making a fresh one.");
        makeSprite();
    }
}

When the tween out is done, remove the image and make a fresh sprite:

function removeSprite():void {
    moving = false;
    stage.removeChild(containerSp);
    makeSprite();
}

Make my image inside of containerSp (which hasn't been added to the stage yet):

function makeSprite():void {
    containerSp = new Sprite();
    containerSp.graphics.beginFill(0xFF0000);
    containerSp.graphics.drawRect( 0, 0, 0, 0);
    trace("Done.");

    trace("making image");
    var bm:Bitmap = new Bitmap();
    bm = Bitmap(images[currentImageNbr].content);
    bm.smoothing = true;

    containerSp.addChild(bm);

    trace("done");
    tweenIn();
}

set our containerSp's position, add it to the stage and tween it in:

function tweenIn():void {
    moving = true;
    resizeHandler();

    // need to check if we're going forwards or backwards.
    if (leftRight == "right") {
        //forwards
        containerSp.y = (stage.stageHeight/2)-(containerSp.height/2)-(barHeight/2);
        containerSp.x = stage.stageWidth;
    }
    else if (leftRight == "left") {
        //backwards
        containerSp.y = (stage.stageHeight/2)-(containerSp.height/2)-(barHeight/2);
        containerSp.x = (0 - stage.stageWidth);
    }

    stage.addChild(containerSp);

    trace("tweening in..");

    TweenLite.to(containerSp, .5, {x:(stage.stageWidth/2)-(containerSp.width/2), y:(stage.stageHeight/2)-(containerSp.height/2)-(barHeight/2), ease:Quint.easeOut, onComplete:done}); 
}

function done():void {
    trace("all done");
    moving = false;
    resizeHandler();
}

The use of resizeHandler is to re-size my picture when the window is re-sized.
it basically sets containerSp.width, .height, .x and .y relative to size of frame.

the moving variable is for resizeHandler so it doesn't set the X and Y to the center of stage unless the picture isn't moving.

so to summarize my question, why do the tweens stop working before they're finished only when I load my .swf in the browser?

if I've forgotten to mention anything, please let me know and i'll be happy to fill in the blanks.

thank you in advance for your time and patience.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不乱于心 2024-10-19 00:08:40

您是否尝试过 killTweensOf() 方法?

Have you tried the killTweensOf() method ?

乖乖 2024-10-19 00:08:40

所以这根本不是 TweenLite 的错。事实证明我正在加载的图像大小不适合网络;哪个闪存无法处理(至少在我的笔记本上......)所以即使在我将图像加载到缓存和所有内容之后,当我将MovieClip的庞然大物添加到舞台时,.swf会挂起,同时试图保持在职的。所以补间实际上正确触发。我通过制作一个 40x40 .gif 的较小原型并将其应用到我的项目中发现了这一切。

作为解决方案(除了缩小和优化我的图像),在加载新图像时,我不是在删除前一个图像(即使它已经加载)后将其添加到舞台,而是将影片剪辑添加到舞台作为加载过程的一部分,以便在添加影片剪辑时不会出现难看的补间。

无论如何,感谢所有查看我的代码和/或线程的人。如果再多一些建议就更好了,但我意识到这篇文章相当大而且乏味。

So it wasn't TweenLite's fault at all. turns out the size of images I was loading were not web friendly; which flash couldn't handle (on my lappy at least..) so even after I'd loaded my images into cache and everything, the moment I added that behemoth of a MovieClip to the stage the .swf would hang while trying to keep working. So the tweens were actually triggering correctly. I found all this out by making a smaller prototype with 40x40 .gif's and applying it to my project.

As a solution (besides shrinking and optimizing my images), when loading a new image, instead of adding it to the stage AFTER the previous image was deleted (even though it's already loaded) I've made it add the movie clip to the stage as part of the loading process so that no tweens look ugly when a movie clip is added.

Regardless, thank you to anyone who looked over my code and/or thread. a few more suggestions would have been nice but I realise that this post was rather big and tedious.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文