0
votes

This is my first attempt at building an a-frame experience, and I'm doing so by cobbling together multiple community components.

I'm currently attempting to implement a spritesheet animation using aframe-spritesheet-component ( https://github.com/EkoLabs/aframe-spritesheet-component ) and having an issue getting it to play well with others.

My build here: https://afantasy.github.io/spritetest/

So far, I've managed to get the spritesheet animation to loop through once, after which it causes a total freeze of the entire environment.

I am not sure whether it's a bad interaction with the other components I've installed, or with the aframe framework itself.

From what I gather from the console, something is up with the update / tick functions.

I've managed to isolate the direct cause to this bit of code I grabbed directly from the aframe-spritesheet-component example on github ( https://ekolabs.github.io/aframe-spritesheet-component/examples/rowscols/ )

<!-- SPRITE ANIMATION LOOP -->
<script type="text/javascript">
  var animation = { progress: 0 };

  var tween = new TWEEN.Tween(animation)
      .to({ progress: 1 }, 1000)
      .onUpdate(function(){
          document.querySelector('a-image').setAttribute('sprite-sheet', 'progress', animation.progress);
      });

  tween.onComplete(function() { animation.progress = 0; });
  tween.chain(tween);
  tween.start();
</script>

Super stumped and sure how to proceed from here, any hints would be appreciated.

3

3 Answers

1
votes

Here is the code for an alternative spritesheet animation component that might work for you, without requiring the external TWEEN.js dependency:


AFRAME.registerComponent('spritesheet-animation', {

    schema: 
    {
        rows: {type: 'number', default: 1},
        columns: {type: 'number', default: 1},

        // set these values to play a (consecutive) subset of frames from spritesheet
        firstFrameIndex: {type: 'number', default: 0},
        lastFrameIndex: {type: 'number', default: -1}, // index is inclusive

        // goes from top-left to bottom-right.
        frameDuration: {type: 'number', default: 1}, // seconds to display each frame
        loop: {type: 'boolean', default: true},
    },

    init: function()
    {
        this.repeatX = 1 / this.data.columns;
        this.repeatY = 1 / this.data.rows;

        if (this.data.lastFrameIndex == -1) // indicates value not set; default to full sheet
            this.data.lastFrameIndex = this.data.columns * this.data.rows - 1;

        this.mesh = this.el.getObject3D("mesh");

        this.frameTimer = 0;
        this.currentFrameIndex = this.data.firstFrameIndex;
        this.animationFinished = false;
    },

    tick: function (time, timeDelta) 
    {
        // return if animation finished.
        if (this.animationFinished)
            return;

        this.frameTimer += timeDelta / 1000;

        while (this.frameTimer > this.data.frameDuration)
        {
            this.currentFrameIndex += 1;
            this.frameTimer -= this.data.frameDuration;

            if (this.currentFrameIndex > this.data.lastFrameIndex)
            {
                if (this.data.loop)
                {
                    this.currentFrameIndex = this.data.firstFrameIndex;
                }
                else
                {
                    this.animationFinished = true;
                    return;
                }
            }
        }

        let rowNumber = Math.floor(this.currentFrameIndex / this.data.columns);
        let columnNumber = this.currentFrameIndex % this.data.columns;

        let offsetY = (this.data.rows - rowNumber - 1) / this.data.rows;
        let offsetX = columnNumber / this.data.columns;

        if ( this.mesh.material.map )
        {
            this.mesh.material.map.repeat.set(this.repeatX, this.repeatY);
            this.mesh.material.map.offset.set(offsetX, offsetY);
        }
    }
});

A complete example of the component in code: https://github.com/stemkoski/A-Frame-Examples/blob/master/spritesheet.html

Live preview of example: https://stemkoski.github.io/A-Frame-Examples/spritesheet.html

0
votes

Your app.js is minified, so it's hard to trace the issue. However, I replaced the Tween library in your version with the exact Tween library used on their version and it seemed to work:

https://stackoverflow-51620935.glitch.me

My guess is that either you may be forgetting to configure Tween (I have never used this library before) or are using an unsupported version (the console also shows several warnings about deprecated methods).

I copy/pasted your code into that glitch above, and changed line 96 to include the overwrite:

<!-- SPRITE ANIMATION LOOP -->
<script src="tween-rewrite.js"></script>
<script type="text/javascript">
  var animation = { progress: 0 };

  var tween = new TWEEN.Tween(animation)
      .to({ progress: 1 }, 1000)
      .onUpdate(function(){
          document.querySelector('a-image').setAttribute('sprite-sheet', 'progress', animation.progress);
      });

  tween.onComplete(function() { animation.progress = 0; });
  tween.chain(tween);
  tween.start();
</script>
0
votes

Ran into the same problem. Looping the animation like this works for me:

    <script>
        function smokeLoop(){
            var animation = { progress: 0 };
            var tween = new TWEEN.Tween(animation)
                .to({ progress: 1 }, 4000)
                .onUpdate(function(){
                    document.querySelector('a-image').setAttribute('sprite-sheet', 'progress', animation.progress);
                });
            tween.onComplete(function() { animation.progress = 0; smokeLoop();});
            tween.start();
        }
        smokeLoop();
    </script>