Howto:Serializing a Canvas to SVG: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
Line 52: Line 52:
=== Group ===
=== Group ===
=== Map ===
=== Map ===
== Challenges ==
Overall this would work pretty well - the main challenges are coming up with a serialization scheme that nicely between canvas/svg space and that is also suitable for streaming SVG to a browser. The most difficult part however is dealing with all the edge cases where Canvas based MFDs currently tend to use all sorts of Nasal workarounds to implement FlightGear specific functionality, such as e.g. using different kinds of event handlers and/or animations driven by listeners and properties.
This is where it is going to be particularly important to come up with dedicated Canvas elements to abstract away and encapsulate these concepts, so that we can do away with huge custom Nasal blobs, and merely introduce dedicated elements for these purposes, which can be more easily mapped to a corresponding SVG element, e.g. by serializing to an <code><animate></code> tag and a corresponding piece of ECMA/JavaScript code.


== Related ==
== Related ==

Revision as of 07:04, 30 October 2016

This article is a stub. You can help the wiki by expanding it.

Background

This was inspired by recurring discussions on the forum to easily reuse existing Canvas based MFDs and show them in a browser or render them remotely using a Python script. The easiest way to do so would be treating a Canvas as a SVG file, simply because most Canvas based MFDs already use SVG files internally. These SVG files are obviously static and parsed by the Nasal svg.nas module to turn them into Canvas properties. However, the opposite would also be possible, all that would require is traversing a canvas node in the tree and iterating over all its child nodes, parsing its properties/attributes to come u p with a corresponding SVG equivalent.

For starters, it makes sense to merely focus on MFDs that are already using SVG files, because instead of actually traversing the full canvas, we can simply let the http server serve the original SVG file itself, which greatly simplifies the whole thing.

However, the next step would actually be traversing an existing Canvas node in the property tree, and then iterating over its child nodes to map certain properties back to their SVG equivalent.

This should work reasonably well, because the module converting svg markup into canvas properties also is implemented in Nasal, and can be easily extended.

Example

We will be working with an example taken from another tutorial, one showing a few raster images (splash screens) using fairly simple SVG markup:

screenshot showing Canvas GUI dialog with SVG image loaded referencing raster images from $FG_ROOT/Textures
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <image x="20" y="20" width="80" height="80" xlink:href="Textures/Splash1.png" />
  <image x="120" y="20" width="80" height="80" xlink:href="Textures/Splash2.png" />
  <image x="220" y="20" width="80" height="80" xlink:href="Textures/Splash3.png" />
  <image x="20" y="120" width="80" height="80" xlink:href="Textures/Splash4.png" />
  <image x="120" y="120" width="80" height="80" xlink:href="Textures/Splash5.png" />
</svg>

This is referencing 5 different splash screen textures found in $FG_ROOT/Textures.

When the patches svg module parses the SVG file, it comes up with a property hierarchy according to this:

Screenshot showing how the patched svg.nas module turns svg/image tags into the corresponding canvas properties, showing two Property browser dialogs illustrating the internal representation, which can be used to help with Howto:Serializing a Canvas to SVG.

The next step is determining how we can traverse each element to arrive back at the original SVG shown above:

Canvas Elements

Basically, we need to the opposite of what svg.nas is doing, so that there is quite a bit of existing code to make this work, the main exception being the Canvas map element that transparently projects child elements using a latitude/longitude, which isn't directly supported by a corresponding SVG tag.

Image

Text

Path

Group

Map

Challenges

Overall this would work pretty well - the main challenges are coming up with a serialization scheme that nicely between canvas/svg space and that is also suitable for streaming SVG to a browser. The most difficult part however is dealing with all the edge cases where Canvas based MFDs currently tend to use all sorts of Nasal workarounds to implement FlightGear specific functionality, such as e.g. using different kinds of event handlers and/or animations driven by listeners and properties.

This is where it is going to be particularly important to come up with dedicated Canvas elements to abstract away and encapsulate these concepts, so that we can do away with huge custom Nasal blobs, and merely introduce dedicated elements for these purposes, which can be more easily mapped to a corresponding SVG element, e.g. by serializing to an <animate> tag and a corresponding piece of ECMA/JavaScript code.

Related

References

References