Animating in 2D

Continuing the discussion from Using Canvas for texture:

I don’t think Animate CC can export animations in a format that we support (for example FBX).

You have two main options:

  1. Export animations into FBX format. You can create animations in a tool like 3DS Max, Maya, Blender or Cinema 4D. These can be imported directly into PlayCanvas.

  2. Use a separate animation tool like Spine, Creature or another to create 2D animations then you will need to support playback in PlayCanvas. For Spine we have a plugin which works on the 2.X version of Spine (waiting on them to update their JS runtime to 3.0). Creature can export to FBX which supports some of their features, but for all features you’d need to implement a runtime.

Well, it directly exports as a HTML5 canvas and as WEBGL. In the WebGL version gives me some JS libraries and a HTML document, so that’s why I thought it could be possible.

I suspect it exports a complete WebGL application which performs all the rendering itself this isn’t really compatible with PlayCanvas (which also performs the rendering task).

It is possible that you could load the export files .fla, textures and other data. But you would need to understand the format and implement something which was able to playback the animation in PlayCanvas. I don’t think that Adobe have this idea in mind with Animate files. Is the format documented anywhere?

Yes, in fact it exports a whole application.

About the format, not sure what you’re asking (sorry…), the WebGL exports has two JSON files, a JS library (documented here) and an HTML file:

(WEBGL Version)

 >    <html>
> 	<head>
> 		<meta charset="UTF-8">
> 		<title>boton_prueba_webgl</title>
> 		<script src="libs/flwebgl-0.2.min.js"></script>
> 		<script>
> 			var player, result = flwebgl.Player.S_OK;
> 			var atlasList = [], content = undefined;

> 			function loadContent() {
> 				getAsset("assets/boton_prueba_webgl.json", function (response) {content = JSON.parse(response); assetLoaded(); });
> 				getAsset("assets/boton_prueba_webgl_atlas.json", function (response) { atlasList.push({json:JSON.parse(response), image:"assets/boton_prueba_webgl_atlas.png"}); assetLoaded(); });
> 			}

> 			function assetLoaded() {
> 				if (atlasList.length == 1 && content) {
> 					var canvas = document.getElementById("canvas");
> 					player = new flwebgl.Player();

> 					//Create textureatlas object for all the textures which you have
> 					var textureAtlasList = [];
> 					for (var i = 0; i < atlasList.length; i++) {
> 						textureAtlasList.push(new flwebgl.TextureAtlas(atlasList[i].json, atlasList[i].image));
> 					}

> 					result = player.init(canvas, content, textureAtlasList, handleComplete);

> 					if(result === flwebgl.Player.E_CONTEXT_CREATION_FAILED) {
> 						document.getElementById("err_nowebglsupport").style.display="block";
> 						return;
> 					} else if(result === flwebgl.Player.E_REQUIRED_EXTENSION_NOT_PRESENT) {
> 						document.getElementById("err_extensionnotpresent").style.display="block";
> 						return;
> 					}

> 					//Resize the canvas and reset the viewport
> 					var w = player.getStageWidth();
> 					var h = player.getStageHeight();
> 					canvas.width = w;
> 					canvas.height = h;
> 					player.setViewport(new flwebgl.geom.Rect(0, 0, w, h));
> 				}
> 			}

> 			function getAsset(url, callbk) {
> 				if (!window.XMLHttpRequest) {
> 					document.getElementById("err_nowebglsupport").style.display="block";
> 					return;
> 				}

> 				var req = new XMLHttpRequest();
> 				req.onreadystatechange = function() {
> 					if (req.readyState == 4 && req.status == 200)
> 						callbk(req.responseText);
> 				};
> 				req.open("GET", url, true);
> 				req.send();
> 			}

> 			function handleComplete() {
> 				if(result === flwebgl.Player.S_OK) {
> 					player.play();

> 					// ==> This is a good place to add code <==
> 				}
> 			}
> 		</script>
> 	</head>
> 	<body onload="loadContent();">
> 		<canvas id="canvas" style="border: none;"></canvas>
> 		<div class="error" id="err_nowebglsupport" style="display:none;"><span>Su navegador no admite WebGL.</span>&nbsp;<span><a href="http://get.webgl.org">Consulte la compatibilidad de WebGL.</a></span></div>
> 		<div class="error" id="err_extensionnotpresent" style="display:none;">Su navegador no admite una extensión requerida por WebGL.</div>
> 	</body>
> </html>

So… i think this is dead end for this workflow. We have to switch to Spine / creature, right?

I’ve been playing around with the spine example project and I think this is the best way to do what I need. Animate is a great tool, but I think we’ll use it for UI and so.

Thank you very much for your time! As always, it couldn’t be better! You rock.

1 Like

What I mean is that Animate exports a bunch of files which define the images and the animations and other information. They also some a bunch of code which plays back this information. Basically you have there an Editor (Animate) and an engine (flwebgl.Player I guess). You may notice that this is similar to PlayCanvas (Editor & Engine). So that is why it’s hard to combine them. We’re both doing very similar things.

With something like Spine or Creature they export the data and they provide an integration (runtime) with other engines. This makes it easier to integrate into PlayCanvas as they aren’t trying to do any of the rendering.

1 Like

Yeah, It’s better to use spine, I’ve been “playing” a bit with your spine “heroes” project and definitely, we’re switching. Much easier and results are beautiful. Thanks @dave , we’ll use Animate only ir HUDs and so on. (Overlaping canvases…)

By the way, how can I manipulate speed/frames/playback direction (reverse, forward) with your plugin? is the same way as with FBX animations?

Most of the controls for spine objects are done directly via the Spine Component where you can access the Spine API.

e.g.


// set playback speed
this.entity.spine.speed = 0.5;

// other API 
var animationState = this.entity.spine.state;
var skeleton = this.entity.spine.skeleton;

//.. do stuff

Worth noting that Spine have just released v3.0 of their editor, but they haven’t updated the javascript runtime yet. So our plugin only supports exports from v2.X.

When they update their runtime, I can update the plugin.

I see. Ok, I’ll keep that in mind! :smile:

As usual, you guys rock. Thank you so much. @dave @max