Search code examples
javascriptvue.jskonvajs

How to use Sprite objects/animations in Vue Konva?


I'm trying to create a spritesheet animation in Vue with konva.js (utilizing vue-konva).

In pure konva.js, the Sprite object is created this way - in short, the Image object is created at first, and then the Sprite object is created in the onload callback of Image object.

var imageObj = new Image();
imageObj.onload = function() {
  var blob = new Konva.Sprite({
    x: 50,
    y: 50,
    image: imageObj,
    animation: 'idle',
    animations: animations, // object defined earlier
    frameRate: 7,
    frameIndex: 0
  });

  // add the shape to the layer
  layer.add(blob);

  // add the layer to the stage
  stage.add(layer);

  // start sprite animation
  blob.start();
};
imageObj.src = '/assets/blob-sprite.png';

On the other hand, in vue-konva it is possible to create Konva objects as components directly in the <template> section of the .vue file, like this:

<template>
  <v-stage :config="configKonva">
    <v-layer>
      <v-circle :config="configCircle"></v-circle>
    </v-layer>
  </v-stage>
</template>

My questions are:

  1. is it possible to create <v-sprite :config="configSprite"></v-sprite> component? There are no mentions of this in the documentation.
  2. If so, how should one correctly provide the necessary image attribute for the configSprite object?
  3. How can one control the animations of v-sprite (starting/stopping)?
  4. If all of this is not possible by using a v-sprite component, is it possible to somehow create the Sprite object manually and add it to the necessary v-layer?

Thank you!


Solution

  • The sprite component is very similar to v-image component. You can take a look into images demos: https://konvajs.github.io/docs/vue/Images.html

    To start/pause sprite you have to access native Konva object and control animation manually. You can do this using references:

    <template>
      <v-stage ref="stage" :config="stageSize">
        <v-layer ref="layer">
          <v-sprite
            @click="handleClick"
            ref="sprite"
            :config="{
              image: image,
              animation: 'idle',
              animations: animations,
              frameRate: 7,
              frameIndex: 0,
              animations: {
                idle: [
                  2,
                  2,
                  70,
                  119,
                  71,
                  2,
                  74,
                  119,
                  146,
                  2,
                  81,
                  119,
                  226,
                  2,
                  76,
                  119
                ],
                punch: [2, 138, 74, 122, 76, 138, 84, 122, 346, 138, 120, 122]
              }
            }"
          />
        </v-layer>
      </v-stage>
    </template>
    
    <script>
    const width = window.innerWidth;
    const height = window.innerHeight;
    
    export default {
      data() {
        return {
          stageSize: {
            width: width,
            height: height
          },
          image: null
        };
      },
      created() {
        const image = new window.Image();
        image.src = "https://konvajs.github.io/assets/blob-sprite.png";
        image.onload = () => {
          // set image only when it is loaded
          this.image = image;
        };
      },
      methods: {
        handleClick() {
          const node = this.$refs.sprite.getNode();
          if (node.isRunning()) {
            node.stop();
          } else {
            node.start();
          }
        }
      }
    };
    </script>
    

    Online demo: https://codesandbox.io/s/lxlqzok2m9