HTML5 canvas player.


I’m dealing with the raster layers problems to implement in Cairo render. Current status is that the raster layers renders in Cairo as in software renderer by using the same pixel manipulation. Unfortunately due to the nature of many of the layers the calculations still being done in floating point space so the raster Cairo layers are slower than in Synfig.
Synfig is special. It is not pure vector since it mixes many raster effects.
There is not support for wariable width in Cairo so anything in that area has to be done manually. Render the outline as a polygon is reasonably fair because internally Cairo does the same. In fact the render speed is quite similar using beziers in Cairo than polygons when rendering a shape.

Don’t support some kind of effects in html5 is reasonable and it happens in others animation software.



I updated the player several times today.
Outlines are here but without point width. As you can find out by the conversation I had with Genete it’s not reasonable to add the width cause the player is going to be very very slow.

I also added some more conversions and now the original stickman from Morevna project is working.

If you need any conversion to be added just tell me.


hello there,

I have tried to test (in my local computer) lasts versions with fully no success!
– 0.2 b / blank screen / no cpu activity
– master commit 3613366bcf / the stickman appear in the upper left corner with “black bones” … but he do not move / high cpu activity

Tell me what kind of infos you need in case you want to debug.
… my best hommages.



Hi guys,
for the sanity of the sifplayer development, it would be good that the bugs were documented in the github tracker. This way, repetitions of the same problem in other system specifications can be narrowed and replied faster.

Great job haramanai!!


oups…i will try to affine my dev’ reflexes …



Sorry guys I forgotten to update the html in the build dir. I also forgotten to post here that I fixed it. (Yesterday).

But then they will have to be registered users of github… But of curse it’s the best place to point issues.

If you have some basic knowledge of html5 canvas and javascript you will see that the code it’s not so difficult to follow and understand. In fact it’s too simple!

Thanks for testing.

P.S. I also do not have some debug method for this. If there is a problem it will be visible. For example it will not render correctly or an alert will come out with some infos about the problem. The best way to fix a problem is to see the sif file and find out what is wrong.


I believe that sifplayer is in a good shape right now. There is a way to render the layers and to convert values. Conversions are far from completed but we have some of them. Some params do not have conversions at all (in sifPlayer). Like color or gradient. Or the time values. This of curse can change but it needs work ( not something really special but time consuming).
I think that it’s time to start developing side libs for sifPlayer. For example a preRender lib or something like that so we can preRender the animation and use only the imagies. This is going to speed things up but as a side effect it will use too much memory.
Another side lib that I believe is going to push things little bit further. Is a point n click lib. Not a point n click adventure game engine but a way to communicate with the mouse and push inputs.
And my craziest idea… a game engine so we can write games with synfig!? ( that may take years…)
Also side libs that are going to use some other libs like createjs or kineticjs.

Those “libs” are going to be in the namespace of sifPlayer for example sifPlayer.preRender but not in the sifPlayer. What I mean is that if you wand to just render your sif animation you will have to include in your html only the sifPlayer.min.js (right now around 30 kb) but if you wand prerender you will have to also include preRender.min.js ( this is e.q. Not an actual lib right now). Also as side libs will have different place in the github to keep the development separated.

I believe that sifPlayer’s code it’s ease to be modified and expanded or at least a good proof of concept project. What we really need is to attract more people in the synfig world. Javascript developers are easier to be found than c++ so we may have better luck on this.

I am going to create a little game with this and upload it somewhere. So I will postpone the development for now ( I may start the point n click for the game and create a simple shooter ala operation wolf). Of curse If someone is using this and needs a conversion that is not added or have problems with it. I will try to help.



I would love to create a point and click adventure game, like Monkey Island or Machinarium, using Synfig and sifs-player!


I know this is not a thread to contribute to sifplayer … :wink:
but, i have done some little update on my sifplayer test page.
just to share …


Nota : for global village vectorisation, i have used

    • [inkscape] tracebitmap/potrace,
    • [inkscape] some objects/layers work,
    • [inkscape] plugins prepare for synfig export,
    • [inkscape] save as sif and
    • … quickly anim with the best blablablal synfig.


I have error messages from Firefox 17.0 telling: “No param type”
and after that I get this message:

{"blinecalcvertex":{"_type":"vector","_id":"origine figure","_guid":"2A83E3352AF81A5F132442357C6657FE","bline":{"bline":{"_type":"bline_point","_loop":false,"_guid":"AA97932167A50499C5DCE876FF87F6CC","entry":[{"composite":{"_type":"bline_point","point":{"vector":{"x":0.3413333297,"y":-0.3794536889}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":2.6691263024}},"theta":{"angle":{"_value":-202.609192}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":2.6691263024}},"theta":{"angle":{"_value":-202.609192}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-0.3510477841,"y":-0.6666508317}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.4993830621}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.4520883933}},"theta":{"angle":{"_value":-44.42683}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.4520883933}},"theta":{"angle":{"_value":-44.42683}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":0.5333333611,"y":-0.5}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.8139409684}},"theta":{"angle":{"_value":42.510452}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.8139409684}},"theta":{"angle":{"_value":42.510452}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":0.1333333403,"y":0}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.167261753}},"theta":{"angle":{"_value":170.134186}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.167261753}},"theta":{"angle":{"_value":170.134186}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-0.8000000119,"y":-0.0833333358}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.8746427337}},"theta":{"angle":{"_value":-120.96376}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.8746427337}},"theta":{"angle":{"_value":-120.96376}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-0.5833333135,"y":-0.9499999881}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.5976546143}},"theta":{"angle":{"_value":-20.136305}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.5976546143}},"theta":{"angle":{"_value":-20.136305}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":0.9499999881,"y":-0.8000000119}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.1672619553}},"theta":{"angle":{"_value":43.264294}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.1672619553}},"theta":{"angle":{"_value":43.264294}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":0.8000000119,"y":0.6999999881}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.6446884685}},"theta":{"angle":{"_value":160.463333}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.6446884685}},"theta":{"angle":{"_value":160.463333}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-0.4950797558,"y":0.6645931602}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5582777858}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.1619941948}},"theta":{"angle":{"_value":-168.230194}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.1619941948}},"theta":{"angle":{"_value":-168.230194}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-1.3999999762,"y":0.349999994}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.4422205236}},"theta":{"angle":{"_value":-146.309937}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.4422205236}},"theta":{"angle":{"_value":-146.309937}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-1.7374600172,"y":-0.5507590175}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.4865774512}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.2832565044}},"theta":{"angle":{"_value":-94.926727}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.2832565044}},"theta":{"angle":{"_value":-94.926727}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-1.2999999523,"y":-1.4833333492}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.6620770139}},"theta":{"angle":{"_value":-21.161264}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.6620770139}},"theta":{"angle":{"_value":-21.161264}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":0.0422389954,"y":-1.6800552607}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.4479345679}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.6971046509}},"theta":{"angle":{"_value":-2.79451}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.6971046509}},"theta":{"angle":{"_value":-2.79451}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":1.6666666269,"y":-1.4666666985}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.5556350535}},"theta":{"angle":{"_value":45.000008}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.5556350535}},"theta":{"angle":{"_value":45.000008}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":2.0010242462,"y":-0.2197706401}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.4951247573}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.5888241382}},"theta":{"angle":{"_value":86.033028}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.5888241382}},"theta":{"angle":{"_value":86.033028}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":1.8500000238,"y":0.9833333492}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.1672619428}},"theta":{"angle":{"_value":136.735718}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.1672619428}},"theta":{"angle":{"_value":136.735718}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-0.0009363329,"y":1.4194107056}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5372735858}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":2.1703997945}},"theta":{"angle":{"_value":173.395859}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":2.1703997945}},"theta":{"angle":{"_value":173.395859}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-1.6166666746,"y":1.3500000238}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.6710774967}},"theta":{"angle":{"_value":-141.072464}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.6710774967}},"theta":{"angle":{"_value":-141.072464}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-2.1013333797,"y":0.4222090244}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.3459199965}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.5912195443}},"theta":{"angle":{"_value":-102.503639}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.5912195443}},"theta":{"angle":{"_value":-102.503639}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-2.3253333569,"y":-0.7214964628}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5840492845}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.2903672457}},"theta":{"angle":{"_value":-96.327148}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.2903672457}},"theta":{"angle":{"_value":-96.327148}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-2.1666667461,"y":-1.7833333015}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.5}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.557241121}},"theta":{"angle":{"_value":-47.602566}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":1.557241121}},"theta":{"angle":{"_value":-47.602566}}}}}},{"composite":{"_type":"bline_point","point":{"vector":{"x":-1.1733332872,"y":-2.1217339039}},"width":{"real":{"_value":1}},"origin":{"real":{"_value":0.3161510527}},"split":{"bool":{"_value":false}},"t1":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.4172340602}},"theta":{"angle":{"_value":-4.407812}}}},"t2":{"radial_composite":{"_type":"vector","radius":{"real":{"_value":0.41

The pillar of something is the one that fails.
Awesome work! Thanks for put it all together d.j.a.y!


dises esto porque ya un poquito de castilano in la pagina … pues :wink:
ya lo sabia :stuck_out_tongue:

Yep, thank’s for the report; i also think that all this animated squares are cute.
Mess a cat (who say a dog?) to be more buzzzable



Thanks d.j.a.y. for putting all this online. I will look to the issues I just have to find some free time.

About the no Param Type : SifPlayer is not completed so when you come in a param type that is not implemented you will get a pop up alert dialog box that will print the data. For example {"blinecalcvertex":{"_type":"vector","_id":"origine figure ...
blinecalcvertex is the param i haven’t implemented and throws the error. This way it’s easier for me to observe a param that I wand to implement and of curse it can be used from the users as warnings that what he is going to use it is not implemented.

Another problem is my inexperience as synfig user. For example I have no idea how blinecalcvertex is created or how is used but I will find out now as d.j.a.y. uploaded a file with it.

I wanted to answer to your post all this time. Do you think we can start a community project and see if we can come up with something.


Sorry. Double post.


Just to update the progress.
From now on you will be able to find the latest version in the dev branch.
Time loop is supported but without animated params for the time being.
Some more conversions where added. Like vector angle.

I also made and a tools dir in the src directory. From now on I will create tools that are not part of the real sifplayer development in there.
See the img_example.html for an example of how you can render all the frames in a array of canvases.

As rylleman mentioned it’s a good idea to use the canvas meta data to make the external communication. My only problem right now is the luck of the ability to rename the meta data. This drives me crazy cause my main idea was to name the key of the meta data with name of the layer and then in the data to point what to do.
For example a region layer that will run a function;
Key : NewDrawing018 Region
Data : Dragable(0,0,10,10)

Or for an exported value that will be a value.

Key : Canon_Target_x
Data : MouseX

Or Something like that… I have yet to start working on it.
What do you think? Any suggestions? Or a better way t communicate?

One last thing that I wand to add is that I implemented the timeloop layer but the over all performance of the player got worser. If I implement the Depth order the player will be even slower. Also I haven’t touched the raster side of Synfig cause my knowledge is very limited in the field and it will destroy the real time drawing.
Also I don’t know how to draw for example a Spiral Gradient in the HTML5 Canvas so I cannot create the layer for it. I believe that anyone with some knowledge of javascript and html5 canvas can create a missing layer for the sifPlayer. Just check the code for the Cricle layer in the src/Layers/circle.js to see how simple a layer can look.

That’s all. Now I am going back to add some more conversions…


TODOList : update my sif player test page


There will be no changes in the test page cause there is no implementetion of TBC tween of globalvillage.sif, spiral gradient, blinecalcvertex and paste layer in the pilar.sif and many other layers in the logotml.sif.

The first sifPlayer.html example now is resized to the window size.

Quick note.
sifPlayer is scalable by all means. When it’s drawing it transforms the canvas’s context to mach the given width and height of the def param in the SifObject creation method.

Also can we move this topic somewhere else? Like work in progress or somewhere else?


, yep, but will try to show ‘sifz’ the progress you have done ( vector angle convertion / unanimated Time loop / …) : if you already have a file i can upload to the test page will be faster :wink:

“work in progress” is more artwork things ;;; maybe “feature discussions” , some subproject (svg2sif or like) where there…

Moving the topic or not, in any case, i think that can be useful to create an entry in the synfig wiki/doc to give more visibility to the tool you are making.



I will finish the timeloop implementation and I will include and a file to demonstrate it. I wanted to mention it cause it changes how the timing is done in sifPlayer. I also realized how useful the timeloop layer is to control the animations of characters.

I agree with the wiki but I will need some help if I have to create the entry cause I do not know how to do it.



And … ? you have talked too much or too less :wink:
What’s the differences, how it was before how it is now?

you will need a login ( , and “to add an additional page (also translated pages) just call the page by editing the address in your browser”

If you need more infos about the synfig wiki :



It was open to be able to change the tweening lib (tweenjs). Now a change will be harder.

But I guess it is not so important after all.