• Runtimes
  • Animation work in player web, but not work in canvas

Related Discussions
...

I create my animation model, but this not show in spine-canvas
Standart model (spineboy) work in canvas, but my model not work in canvas (nothing is visible, all textures are loaded), but my model work in player.

Maybe specifed export for canvas (already export json) or specifed options in code?

Hello, could you share your code?

Luke wrote

Hello, could you share your code?

In runtimes i used example.
Maybe in animation i used mesh. Canvas supports mesh or no?

Player .skel not play
Error: Could not load skeleton binary.

But json in player ok

What version of the Spine editor did you export from? What version of the Spine Runtime are you using?

Nate wrote

What version of the Spine editor did you export from? What version of the Spine Runtime are you using?

Spine editor - 4.0.47, spine runtime 4.0.28
export json from spine 4.0 select

Nate wrote

Thanks.

doublesh wrote

Canvas supports mesh or no?

No, it doesn't. See here:
https://github.com/EsotericSoftware/spine-runtimes/blob/4.0/spine-ts/README.md#spine-version
You can enable experimental support for meshes in spine-canvas, but it's not great. It would be better to use spine-webgl.

I already used webGL. but skin not center (standart skin already too)
How i centered my animation?
Code standart test-simple.html. but i add resize and calculateSetupPoseBounds

<script>

   var ANIMATION = "walk";
   var mvp = new spine.Matrix4();

   var canvas, context, gl, renderer, input, assetManager;
   var timeKeeper;
   var skeleton;
   var animationState;

   function init() {
      canvas = document.getElementById("canvas");
      canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight;
      context = new spine.ManagedWebGLRenderingContext(canvas, { alpha: false });
      gl = context.gl;

  renderer = new spine.SceneRenderer(canvas, context);
  assetManager = new spine.AssetManager(context, "../example/assets/");
  input = new spine.Input(canvas);

  assetManager.loadTextureAtlas("winskin.atlas");
  assetManager.loadText("winskin.json");

  timeKeeper = new spine.TimeKeeper();
  requestAnimationFrame(load);
   }

   var run = true;

   function load() {
      timeKeeper.update();
      if (assetManager.isLoadingComplete()) {
         var atlas = assetManager.get("winskin.atlas");
         var atlasLoader = new spine.AtlasAttachmentLoader(atlas);

     let skeletonJson = new spine.SkeletonJson(atlasLoader);
     let skeletonData = skeletonJson.readSkeletonData(assetManager.require("winskin.json"));

     var time = new spine.TimeKeeper()

     skeleton = new spine.Skeleton(skeletonData);
     this.bounds = calculateSetupPoseBounds(skeleton);
     var stateData = new spine.AnimationStateData(skeleton.data);
     animationState = new spine.AnimationState(stateData);
     stateData.defaultMix = 0;
     animationState.setAnimation(0, ANIMATION, true);

     requestAnimationFrame(render);
  } else {
     requestAnimationFrame(load);
  }
   }

   function render() {
      var start = Date.now()
      timeKeeper.update();
      var delta = timeKeeper.delta;
      resize();
      animationState.update(delta);
      animationState.apply(skeleton);
      skeleton.updateWorldTransform();

  gl.clearColor(0.2, 0.2, 0.2, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  renderer.resize(spine.ResizeMode.Expand);
  renderer.begin();
  renderer.drawSkeleton(skeleton, true);
  renderer.end();

  requestAnimationFrame(render)
   }
   
function resize() { var w = canvas.clientWidth; var h = canvas.clientHeight; if (canvas.width != w || canvas.height != h) { canvas.width = w; canvas.height = h; } // Calculations to center the skeleton in the canvas. var bounds = this.bounds; var centerX = bounds.offset.x + bounds.size.x / 2; var centerY = bounds.offset.y + bounds.size.y / 2; var scaleX = bounds.size.x / canvas.width; var scaleY = bounds.size.y / canvas.height; var scale = Math.max(scaleX, scaleY) * 2; if (scale < 1) scale = 1; var width = canvas.width * scale; var height = canvas.height * scale; mvp.ortho2d(centerX - width / 2, centerY - height / 2, width, height); gl.viewport(0, 0, canvas.width, canvas.height); } function calculateSetupPoseBounds(skeleton) { skeleton.setToSetupPose(); skeleton.updateWorldTransform(); var offset = new spine.Vector2(); var size = new spine.Vector2(); skeleton.getBounds(offset, size, []); return { offset: offset, size: size }; } init(); </script>

To center the rendering you'd have to adjust the camera, or figure out why it isn't centered. It could your skeleton is very large and this line prevents it from being scaled down below 100%:

if (scale < 1) scale = 1;

If you just need to display your skeleton centered, it would be easiest to use the Spine web player:
Spine Web Player
You can turn off all the controls so it doesn't look like a player. We used the player for the skeletons on this page:
Blog: Spine 4.0 is here
The code is very simple, it looks like this:
http://n4te.com/x/5108-PkDi.txt
You can customize the player rendering and input. You can access the AnimationState to queue up animations, play animations on multiple tracks, etc.

If you want to write a whole game, you probably want to use a game toolkit like Pixi.js or Phaser.

Nate wrote

To center the rendering you'd have to adjust the camera, or figure out why it isn't centered. It could your skeleton is very large and this line prevents it from being scaled down below 100%:

if (scale < 1) scale = 1;

If you just need to display your skeleton centered, it would be easiest to use the Spine web player:
Spine Web Player
You can turn off all the controls so it doesn't look like a player. We used the player for the skeletons on this page:
Blog: Spine 4.0 is here
The code is very simple, it looks like this:
http://n4te.com/x/5108-PkDi.txt
You can customize the player rendering and input. You can access the AnimationState to queue up animations, play animations on multiple tracks, etc.

If you want to write a whole game, you probably want to use a game toolkit like Pixi.js or Phaser.

I don't resize from webgl? i need used this animation on the website, how do i make my character small?

the player is not exactly what I need


If i used renderer.resize(spine.ResizeMode.Fit); and move the console
https://gyazo.com/73a20e0643f1274d9cc5d06a35ed895c
my skin resized. how i resize manual and fix this resize

doublesh wrote

I don't resize from webgl? i need used this animation on the website, how do i make my character small?

Positioning the camera determines the size of your skeleton on screen. That is what this line does:

mvp.ortho2d(centerX - width / 2, centerY - height / 2, width, height);

The first 2 parameters are the position of the camera. The last 2 parameters are the size of the rendering. Calculating the values is somewhat tricky. In your code it's done based on the canvas size and the bounds calculated by calculateSetupPoseBounds.

I suggest using our newer code for rendering, it is simpler:
https://github.com/EsotericSoftware/spine-runtimes/blob/4.0/spine-ts/spine-webgl/example/barebones.html

doublesh wrote

the player is not exactly what I need

Why? What do you need?

Nate wrote
doublesh wrote

I don't resize from webgl? i need used this animation on the website, how do i make my character small?

Positioning the camera determines the size of your skeleton on screen. That is what this line does:

mvp.ortho2d(centerX - width / 2, centerY - height / 2, width, height);

The first 2 parameters are the position of the camera. The last 2 parameters are the size of the rendering. Calculating the values is somewhat tricky. In your code it's done based on the canvas size and the bounds calculated by calculateSetupPoseBounds.

I suggest using our newer code for rendering, it is simpler:
https://github.com/EsotericSoftware/spine-runtimes/blob/4.0/spine-ts/spine-webgl/example/barebones.html

doublesh wrote

the player is not exactly what I need

Why? What do you need?

Thanks. i found solution for me

let camera = renderer.camera;
  camera.zoom = 10;
  camera.update();

work in html ok, but i imported in my vue project new error with downloader

methods: {
  init() {
    this.canvas = document.getElementById("canvas");
    this.canvas.width = this.canvas.clientWidth;
    this.canvas.height = this.canvas.clientHeight;
    this.context = new spine.ManagedWebGLRenderingContext(this.canvas, { alpha: true });
    this.gl = this.context.gl;

this.renderer = new spine.SceneRenderer(this.canvas, this.context);
this.assetManager = new spine.AssetManager(this.context, "../../../assets/");

this.assetManager.loadText("pers.json");
this.assetManager.loadTextureAtlas("pers.atlas");

this.timeKeeper = new spine.TimeKeeper();
requestAnimationFrame(this.load);
  }
},
mounted() {
  this.init();
},

in spine-canvas all worked


OMG i install spine-webgl v 4.1.19 and it's work. but my export and spine for 4.0

4.0.28 bug libs spine-webgl

Not sure what's going on in 4.0, but we've moved on to 4.1 so I'm glad to hear that is working! 🙂