Canvas Nasal API
The FlightGear forum has a subforum related to: Canvas |
Canvas consist of a class with various nestable classes (elements).
See inside the current (Git) API here and here.
For the Canvas GUI API see Canvas GUI API
Canvas
For constructor see: Initialize a Canvas
addPlacement
Note It is possible to place a canvas on models in the scene. Tom has not tested if it also works for MP/AI aircraft but it should. The placement in scenery objects needs a different placement type to select also the model it should be placed on. For scenery objects a special placement exists:
var placement = { "module-id": _module_id, type: "scenery-object", <normal placement parameters like eg. node> } '_module_id' is a special variable which is only set in scenery object <load> handlers.[1] |
See: Place a Canvas
setColorBackground
Parameters: (r, g, b, a)
Fills the background of the entire canvas with the supplied color.
createGroup
Parameters: ()
Parameters: (name)
Returns: Group
Create a new group under this Canvas. Supplying name is optional.
getPath
Parameters: ()
?
del
Parameters: ()
Deletes this Canvas.
wrapCanvas
Parameters: ()
?
get
Parameters: (name)
Returns: Canvas
Returns the canvas with the specified name.
Possible settings
- character-size - font size
- character-aspect-ratio - font aspect ratio
- ... please contribute and expand this list!
set
Parameters: (setting, value)
Not sure all the below settings can be used after initialization.
Settings can be:
"name" string
"size" vector of size 2 with ints
"view" vector of size 2 with ints
"mipmapping" bool
"additive-blend" bool
"coverage-samples" int
"color-samples" int
"freeze" bool
"render-always" bool
"update" bool
parsesvg
Parameters: (group, file)
Parameters: (group, file, font-mapper)
See: SVG inside a Canvas
Element
Note that in each element there are 2 transformation matrices. The first will be applied first, then the second.
set
Parameters: (key, value)
Key = "z-index":
Default value = 0
Minimum value = 0
Integer value indicates the explicit Z sort order, highest on top. If this is not set, elements that are added later gets drawn on top. Notice that if you have for example two paths inside their own groups, and you want to order those paths in relation to each other, its on their groups you should call this method, not on the paths themselves.
FG 2.10.0.3: Elements added after z-index has been set will overrule it. (fix is in GIT)
Key = "blend-source":
Key = "blend-destination":
Key = "blend-source-rgb":
Key = "blend-destination-rgb":
Key = "blend-source-alpha":
Key = "blend-destination-alpha":
These are blending operations, they determine how a texel is drawn based on what your current element want to draw (source) and what is already drawn at this texel (destination).
For example for the 2 first listed keys, the formula is output_color = (blend_source * src_color) + (blend_destination * dst_color).
The value for the keys can be one of: (string)
zero, one, dst-color, src-color, one-minus-dst-color, one-minus-src-color, src-alpha, dst-alpha, one-minus-dst-alpha, one-minus-src-alpha, src-alpha-saturate
You can see the formulas [here]
With a little creativity these can be used for many things, like creating custom clipping geometry and other stuff.
NOTICE: Blending does NOT work for paths. They are confirmed to work with text and images though.
update
Parameters: ()
Normally an element gets updated in the next frame. Calling this will make it update in the current frame. Note that visibility methods do get updated in the current frame.
getVisible
Parameters: ()
Returns: visible
Returns 0 if not visible, 1 if visible.
setVisible
Parameters: ()
Parameters: (visible)
Sets if this element should be visible. 0 sets it not visible, 1 visible. No parameters sets it visible.
show
Parameters: ()
Sets the element visible.
hide
Parameters: ()
Sets the element not visible.
toggleVisibility
Parameters: ()
Toggles if element should be visible.
setGeoPosition
Parameters: (lat, lon)
Sets the geographic coordinates for a map element. Parent element must be of type "map".
Example: setGeoPosition(37.615223, -122.389978)
Places element at San Francisco International Airport.
createTransform
createTransform creates a new matrix on top of the existing matrix stack. A while ago I've added an example for a HUD built using the Canvas to the wiki: Canvas HUD It doesn't use SVG but manually creates everything instead. As loading an SVG should basically do the same than handcrafting icons there shouldn't be much of a difference.
Parameters: ()
Parameters: ([a, b, c, d, e, f])
Return: The new (second) transform
Creates a new (second) transformation matrix for this element. No parameters will create a default identity matrix transform. Otherwise supply a 6 element vector for the matrix:
a | b | c |
d | e | f |
0 | 0 | 1 |
You should probably change the order of creating the transforms for pitch and roll as normally one would rotate first and then move according to roll and then move according to pitch up and down. Keep in mind that rotations always happens around the origin of the local coordinate frame of the object being rotated. For a rotation around another point you would need to move the object first until the center coincides with the local origin then rotate and afterwards move back. Instead of applying three transformations there exists a shortcut to pass the center of rotation as second argument to setRotation.
To further shorten the code an especially to allow rotating objects imported from SVG there exists setRotation also for canvas Elements (not only Transformation) and additionally setCenter which instead of passing the center as an argument sets the center which is being used while calling setRotation on this element. setCenter only affects setRotation of this not object but not for any matrix added with createTransform. If you set the center of rotation in Inkscape (switch to rotate mode and drag the cross to the center of rotation) it is automatically loaded with setCenter so you just need to call setRotation and automatically get a rotation around the correct center.
You don't need to care about tf[0] being reserved as it only reserves the index 0 and doesn't affect anything if not used. createTransform creates a new matrix with the next unused index starting at 1 (0 is reserved). If you later call setRotation directly on an element a new Transform will be created but this time using tf[0] to ensure it is applied before all other matrices and therefore rotating the object around its own center before being moved around.
For the HUD I'd set the rotation center correctly inside Inkscape and later on just call ladder.setRotation to rotate for changes in the roll angle. Afterwards create a Transform and use setTranslate for changes in pitch angle.
setTranslation
Parameters: (x, y)
Translates the element. The translation is set on the second transform.
setRotation
Parameters: (x, y)
Rotates the element around the center. The rotation is set on the first transform.
setRotation really just combines a rotation with two translations -> translate(-center[0], -center[1]) * rotate * translate(center[0], center[1])
You can also have a look in the property browser and check the bounding box (/canvas/by-index/texture[i]/[group[j]+]/path[j]/bounding-box) and use its coordinates to determine the correct center of rotation.
setScale
Parameters: (x, y)
Scales the element. The scale is set on the second transform.
getScale
Parameters: ()
Return: 2 element vector [x,y]
Returns the scale of this element.
setColorFill
Parameters: (r, g, b)
Parameters: (r, g, b, a)
Sets the color/alpha to be used as fill value. If you do not want the element to be filled, do not call this method.
getBoundingBox
Parameters: ()
Returns: [minX, minY, maxX, maxY]
Returns the bounds of the element.
updateCenter
Parameters: ()
Sets the center to be the center of the boundingbox in relation to the elements position in its parent.
setCenter
Parameters: (x, y)
Sets the center of the element that is used for rotation.
getCenter
Parameters: ()
Gets the center of the element.
del
Parameters: ()
Deletes this element.
Group
Inherits from Element.
set
Parameters: (key, value)
key = "clip"
Makes a clipping bounds for the group, only what is inside the clipping bounds will be shown.
It uses same coordinate format as Clipping
Example: my_grp.set("clip", "rect(62px, 587px, 262px, 437px)"); # top,right,bottom,left
key = "clip-frame"
Sets the coordinate system to be used for clip coordinates.
Can be canvas.Element.GLOBAL (the default value), canvas.Element.PARENT or canvas.Element.LOCAL
Notice that if set to local or parent and there is a rotation is play, the clipping wont rotate properly, it will move around and scale instead.
key = "font"
Sets the default font.
Example: my_group.set("font", "LiberationFonts/LiberationMono-Regular.ttf");
key = "stroke"
?
key = "fill"
?
setDouble
Parameters: (key, value)
key = "character-aspect-ration"
?
key = "character-size"
?
createChild
Parameters: (type)
Parameters: (type, name)
Returns: Element
Creates a child element under this Group. Name can be supplied. Type can be "text", "group", "path", "image", "map". Return an Element of the particular type specified.
createChildren
Parameters: (type, count)
Returns: [Element]
Creates a number of child elements under this Group. Return a vector of Elements of the particular type specified.
getChildren
Parameters: ()
Returns: [Element]
Returns all the child elements of this group.
getElementById
Parameters: (name)
Returns: Element
Returns the first found child element with the specified name.
removeAllChildren
Parameters: ()
Removes all the child elements from this group.
Text
Inherits from Element.
enableUpdate
Enables the updateText() method for a text element.
setText
Parameters: (text)
Sets the text to be displayed.
updateText
Parameters: (text)
The setText method internally writes the text string into a property node. If the method is run inside an update loop (as usually done for displays), setText writes the property regardless of whether the text has actually changed in the last update cycle. For complicated displays, this may cause a lot of unnecessary property I/O slowing down the simulation.
To improve this, updateText() keeps a Nasal variable record of the last text that has been written and writes the property only if the text has changed. Since this record needs to be allocated, the method requires to call enableUpdate() once before using it.
Note also that updateText() and setText() should not be both used on the same text element (updateText() will not register any changes made to the property string by any other means).
setAlignment
Parameters: (alignment)
Sets how the text should be aligned with its position.
Full list:
- left-top
- left-center
- left-bottom
- center-top
- center-center
- center-bottom
- right-top
- right-center
- right-bottom
- left-baseline
- center-baseline
- right-baseline
- left-bottom-baseline
- center-bottom-baseline
- right-bottom-baseline
setFontSize
Parameters: (size, aspectRatio)
Sets the size and aspectRatio of the font. AspectRatio is the Ratio between character height and width. Default aspectRatio is 1.
setFont
Parameters: (fontName)
Sets the font to be used. See $FG_ROOT/Fonts for list of fonts.
setDrawMode
Parameters: (mode)
Sets the drawing mode. You can use the values below and add those you need.
Text.TEXT: Draws the text
Text.BOUNDINGBOX: Draws the boundingbox
Text.FILLEDBOUNDINGBOX: Draws the filled boundingbox
Text.ALIGNMENT: Draws a cross where the element position is
Example: my_text.setDrawMode(Text.TEXT + Text.BOUNDINGBOX);
setPadding
Sets bounding box padding
setMaxWidth
?
setColor
Parameters: (r, g, b)
Parameters: (r, g, b, a)
Sets the color the text should be drawn in.
setColorFill
Parameters: (r, g, b)
Parameters: (r, g, b, a)
Sets the color the text background should be drawn in.
Path
Inherits from Element.
A path is similar to drawing with a pen on paper. The move and moveTo methods represent lifting the pen from the paper and moving to a new position. The drawing methods like lineTo would then be seen as starting from the current position of the pen. Therefore offcouse the order the methods is called in, is important.
pop_front
Parameters: ()
Remove first segment
pop_back
Parameters: ()
Remove last segment
getNumSegments
Parameters: ()
Get the number of segments
reset
Parameters: ()
Remove all existing path data
moveTo
Parameters: (x, y)
Moves the position to an new absolute position.
move
Parameters: (x, y)
Moves the position to a new relative position from the current.
lineTo
Parameters: (x, y)
Draws a line to specified position.
line
Parameters: (x, y)
Draws a line to specified relative position.
horizTo
Parameters: (x)
Draws a horizontal line to specified position.
horiz
Parameters: (x)
Draws a horizontal line to specified relative position.
vertTo
Parameters: (y)
Draws a vertical line to specified position.
vert
Parameters: (y)
Draws a vertical line to specified relative position.
quadTo
Parameters: (x0, y0, x1, y1)
Draws quadratic Bézier curve.
quad
Parameters: (x0, y0, x1, y1)
Draws quadratic Bézier curve. Relative coordinates.
squadTo
Parameters: (x, y)
Draws smooth quadratic Bézier curve.
squad
Parameters: (x, y)
Draws smooth quadratic Bézier curve. Relative coordinates.
cubicTo
Parameters: (x0, y0, x1, y1, x2, y2)
Draws cubic Bézier curve.
cubic
Parameters: (x0, y0, x1, y1, x2, y2)
Draws cubic Bézier curve. Relative coordinates.
scubicTo
Parameters: (x, y, x2, y2)
Add a smooth cubic Bézier curve
scubic
Parameters: (x, y)
Add a smooth cubic Bézier curve. Relative coordinates.
rect
Parameters: (x, y, w, h, cfg = nil)
cfg: Optional settings (eg. {"border-top-radius": 5}, {"border-bottom-radius": 5}, {"border-radius": 5}, {"border-bottom-right-radius": 5} or {"border-left-radius": 5})
Add a (rounded) rectangle to the path
square
available on next, expected release 2019.1
Parameters: (x, y, length, cfg = nil)
alias for rect(x, y, length, length, cfg)
Add a (rounded) square to the path
arcSmallCCWTo
arcSmallCCW
arcSmallCWTo
arcSmallCW
Parameters: (xRadius, yRadius,0,xEnd,yEnd)
Draws an arc with the specified radii, up to the specified end point. The end point is relative to the starting point.
To draw half a circle with radius 20 around the origin:
.moveTo(-20,0) .arcSmallCW(20,20,0,40,0);
To draw a circle with radius 20 around the origin:
.moveTo(-20,0) .arcSmallCW(20,20,0,40,0) .arcSmallCW(20,20,0,-40,0);
arcLargeCCWTo
arcLargeCCW
arcLargeCWTo
arcLargeCW
Drawing arcs examples :
var fpv = group.createChild("group", "FPV");
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,255,1)")
.moveTo(100, 100).arcSmallCCW(50, 50, 0, 50, 50);
fpv.createChild("path").setStrokeLineWidth(4) .set("stroke", "rgba(255,0,255,1)")
.moveTo(300, 100).arcSmallCCW(50, 50, 0, 100, 0);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,255,1)")
.moveTo(500, 100).arcSmallCCW(50, 50, 0, 50, -50);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(55,0,255,1)")
.moveTo(100, 300).arcSmallCW(50, 50, 0, 50, 50);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(55,0,255,1)")
.moveTo(300, 300).arcSmallCW(50, 50, 0, 100, 0);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(55,0,255,1)")
.moveTo(500, 300).arcSmallCW(50, 50, 0, 50, -50);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,55,1)")
.moveTo(100, 500).arcLargeCCW(50, 50, 0, 50, 50);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,55,1)")
.moveTo(300, 500).arcLargeCCW(50, 50, 0, 100, 0);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,55,1)")
.moveTo(500, 500).arcLargeCCW(50, 50, 0, 50, -50);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,55,1)")
.moveTo(100, 500).arcLargeCCW(50, 50, 0, 50, 50);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,55,1)")
.moveTo(300, 500).arcLargeCCW(50, 50, 0, 100, 0);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,55,1)")
.moveTo(500, 500).arcLargeCCW(50, 50, 0, 50, -50);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,55,1)")
.moveTo(100, 700).arcLargeCW(50, 50, 0, 50, 50);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,55,1)")
.moveTo(300, 700).arcLargeCW(50, 50, 0, 100, 0);
fpv.createChild("path").setStrokeLineWidth(4).set("stroke", "rgba(255,0,5
ellipse
available on next, expected release 2019.1
Parameters: (rx, ry, cx = nil, cy = nil)
rx, ry are the radii of the ellipse cx, cy is optional for the center coordinates
Add an ellipse to the path
circle
available on next, expected release 2019.1
Parameters: (r, cx, cy)
alias for ellipse(r, r, cx, cy), cx, cy optional for center coordinates
Add a circle to the path.
close
Parameters: ()
Close the path (implicit lineTo to first point of path)
setColor
Parameters: (r, g, b)
Parameters: (r, g, b, a)
Sets the color of the drawn path
setColorFill
Parameters: (r, g, b)
Parameters: (r, g, b, a)
Calling this will make the path get filled in the specified color. For example if you draw a 'V' and fill it, the fill area will be a triangle inside the 'V'.
setStrokeLineWidth
Parameters: (width)
The width of the path.
setStrokeLineJoin
Parameters: (type)
Set stroke linejoin. Type can be "miter", "round" or "bevel".
setStrokeLineCap
Parameters: (type)
Caps the path. Type can be "butt", "round" or "square".
setStrokeDashArray
Parameters: (pattern)
Make dashed path. Pattern is a vector of alternating dash and gap lengths. Lines drawn will follow this pattern.
Example: my_path.setStrokeDashArray([10, 20, 10, 20, 10]);
setData
Parameters: (cmds, points)
Re-sets the data structure for a plot. cmds is an array containing the draw commands (integers, but they can be referenced via canvas.Path.VG_LINE_TO or canvas.Path.VG_MOVE_TO etc.) and points an array containing the associated points to which the curve is to be drawn in the form [x1, y1, x2, y2,...].
Example: my_path.setData([2, 4], [10, 20, 10, 40]);
See addSegment for list of commands.
setDataGeo
Parameters: (cmds, points)
Same as setData(), just for GPS coords. See addSegmentGeo() for details.
Parent element must be of type "map".
addSegment
Parameters: (cmd, coords)
Add a path segment.
Cmd can for example be canvas.Path.VG_MOVE_TO
Coords is a vector with the numbers/coordinates that the command needs.
See this list of all commands and how many coords they require.
VG_CLOSE_PATH: 0, VG_MOVE_TO: 2, VG_MOVE_TO_ABS: 2, VG_MOVE_TO_REL: 2, VG_LINE_TO: 2, VG_LINE_TO_ABS: 2, VG_LINE_TO_REL: 2, VG_HLINE_TO: 1, VG_HLINE_TO_ABS: 1, VG_HLINE_TO_REL: 1, VG_VLINE_TO: 1, VG_VLINE_TO_ABS: 1, VG_VLINE_TO_REL: 1, VG_QUAD_TO: 4, VG_QUAD_TO_ABS: 4, VG_QUAD_TO_REL: 4, VG_CUBIC_TO: 6, VG_CUBIC_TO_ABS: 6, VG_CUBIC_TO_REL: 6, VG_SQUAD_TO: 2, VG_SQUAD_TO_ABS: 2, VG_SQUAD_TO_REL: 2, VG_SCUBIC_TO: 4, VG_SCUBIC_TO_ABS: 4, VG_SCUBIC_TO_REL: 4, VG_SCCWARC_TO: 5, VG_SCCWARC_TO_ABS: 5, VG_SCCWARC_TO_REL: 5, VG_SCWARC_TO: 5, VG_SCWARC_TO_ABS: 5, VG_SCWARC_TO_REL: 5, VG_LCCWARC_TO: 5, VG_LCCWARC_TO_ABS: 5, VG_LCCWARC_TO_REL: 5, VG_LCWARC_TO: 5, VG_LCWARC_TO_ABS: 5, VG_LCWARC_TO_REL: 5,
addSegmentGeo
Parameters: (cmd, coords)
Add a path segment.
Cmd can for example be canvas.Path.VG_MOVE_TO
Coords is a vector with the numbers/coordinates that the command needs in GPS format.
The coords can for example be "E32.45" for latitude and "N45.34" for longitude. If an 'S' or 'W' is seen instead of E or N, the sign is flipped.
See addSegment for list of commands.
Parent element must be of type "map".
Map
Inherits from Element.
Class for a group element on a canvas with possibly geographic positions which automatically get projected according to the specified projection. Each map consists of an arbitrary number of layers (canvas groups)
del
Parameters: ()
Deletes the Map instance.
setController
Parameters: (controller)
A controller needs to inherit from Map.Controller
addLayer
Parameters: (factory, type_arg=nil, priority=nil, style=nil, opts=nil, visible=1)
Each layer is some kind of data to be rendered - there’s all the built in layers but WXR, TERRain or anything else specific to the acft would be another layer.
getLayer
Parameters: (type_arg)
Returns the layer corresponding to the argument type.
setRange
Parameters: (range)
This sets the display range of the map in NM.
getRange
Parameters: ()
Get current range setting
setPos
Parameters: (lat, lon, hdg=nil, range=nil, alt=nil)
This is the center of the map (very often the aircraft position, except in something special such as PLAN mode). Hdg sets the up direction (could be north, track, heading and true vs magnetic depending on the aircraft)
getPos
Parameters: ()
Returns vector with lat, lon, heading, range and altitude
getLat
Parameters: ()
Returns position latitude.
getLon
Parameters: ()
Returns position longitude.
getHdg
Parameters: ()
Return current 'up' heading.
getAlt
Parameters: ()
Returns current altitude setting in feet.
getRange
Parameters: ()
Returns current range setting.
getLatLon
Parameters: ()
Returns the center position of the map as a vector with lat and lon
getPosCoord
Parameters: ()
Returns the center position of the map as a geo.Coord
N.B.: This always returns the same geo.Coord object, so its values can and will change at any time (call update() on the coord to ensure it is up-to-date, which basically calls this method again).
update
Parameters: (predicate=nil)
Update each layer on this Map. Predicate is a function that takes a layer as argument and returns true if that layer should be updated. If predicate is not supplied, all layers will be updated.
See also
Canvas Maps and Canvas Map API
Image
Inherits from Element.
See: Canvas Image
- ↑ Thomas Geymayer (May 17th, 2016). Re: [Flightgear-devel] Canvas in dynamically loaded scene models .