Canvas draw library: Difference between revisions
m (→CanvasDrawDev add-on: add links to the original docs) |
No edit summary |
||
(3 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{Note|Canvas draw is currently work in progress. You can test and improve it by downloading the [[Addons|CanvasDrawDev add-on]]. The canvas.draw library will hopefully be ready to use in FG version 2019.1}} | |||
{{Canvas Navigation}} | {{Canvas Navigation}} | ||
= CanvasDrawDev add-on = | = CanvasDrawDev add-on = | ||
Line 51: | Line 51: | ||
=== arc() === | === arc() === | ||
[[File:Canvas-draw-scales03.png|thumb|circular marks]] | |||
arc(cgroup, radius, center, from_deg = nil, to_deg = nil) | arc(cgroup, radius, center, from_deg = nil, to_deg = nil) | ||
Draw an arc (part of a circle) with given radius around center. In the example image a red, green and blue arc are shown, nasal code below. | |||
'''center''' center point of circle as vector [x,y] | '''center''' center point of circle as vector [x,y] | ||
'''from_deg''', '''to_deg''' start and end of arc in degree of compass rose (0 = North, 90 = East, ...); defaults to 0, 360 (full circle) | '''from_deg''', '''to_deg''' start and end of arc in degree of compass rose (0 = North, 90 = East, ...); defaults to 0, 360 (full circle) | ||
<syntaxhighlight lang="nasal"> | |||
# [CX, CY] center point | |||
var start = -40; | |||
canvas.draw.arc(myGroup, radius, [CX, CY], start, start+190).setColor(COLORS["red"]); | |||
start += 90; | |||
canvas.draw.arc(myGroup, radius, [CX, CY], start, start+270).setColor(COLORS["green"]); | |||
start += 90; | |||
canvas.draw.arc(myGroup, radius, [CX, CY], start, start+190).setColor(COLORS["blue"]); | |||
</syntaxhighlight> | |||
=== rectange() === | === rectange() === | ||
Line 74: | Line 85: | ||
=== deltoid() === | === deltoid() === | ||
[[File:Canvas-draw-shapes01.png|thumbnail|right]] | |||
deltoid (cgroup, dx, dy1, dy2, x = 0, y = 0) | deltoid (cgroup, dx, dy1, dy2, x = 0, y = 0) | ||
Line 85: | Line 97: | ||
'''x''', '''y''' position of tip | '''x''', '''y''' position of tip | ||
<syntaxhighlight lang="nasal"> | |||
var dx = 40; | |||
#rhombus draws around a center point while deltoid uses x,y for tip point | |||
shapes["rhombus1"] = canvas.draw.rhombus(group, dx, 2*dx, 5 + dx/2, CY) | |||
.setColor(COLORS["cyan"]); | |||
# width = 40, height = 25 + 50; | |||
shapes["deltoid1"] = canvas.draw.deltoid(group, dx, 25, 50, 2*dx, CY) | |||
.setColor(COLORS["magenta"]); | |||
# y2 < 0 results in arrow head | |||
canvas.draw.deltoid(group, dx, 2*dx, -dx, 4*dx, CY) | |||
.setColor(COLORS["yellow"]); | |||
# y2 = 0 results in triangle | |||
canvas.draw.deltoid(group, dx, 2*dx, 0, 6*dx, CY) | |||
.setColor(COLORS["green"]); | |||
# y2 < 0 and |y2| > y1 results in arrowhead with tip above baseline | |||
canvas.draw.deltoid(group, dx, 1.5*dx, -2.5*dx, 8*dx, CY) | |||
.setColor(COLORS["red"]); | |||
</syntaxhighlight> | |||
=== rhombus() / diamond() === | === rhombus() / diamond() === | ||
rhombus: func(cgroup, dx, dy, center_x = 0, center_y = 0) | rhombus: func(cgroup, dx, dy, center_x = 0, center_y = 0) | ||
draws a diamond | draws a diamond around ['''center_x''', '''center_y'''] | ||
(first element from left in sample image above) | |||
'''dx''' width | '''dx''' width | ||
'''dy''' height | '''dy''' height | ||
=== grid() === | === grid() === | ||
[[File:Canvas-draw-grids01.png|thumbnail|right]] | |||
Draw horizontal and verical lines. Two signatures are available | Draw horizontal and verical lines. Two signatures are available | ||
Line 109: | Line 148: | ||
'''border''' optional boolean, draw lines at sizeX and sizeY, true by default. | '''border''' optional boolean, draw lines at sizeX and sizeY, true by default. | ||
<syntaxhighlight lang="nasal"> | |||
var group = myRoot.createChild("group", "grid_scales"); | |||
#-- grid test -- | |||
canvas.draw.grid(group, [62, 55], 10, 10, 0).setTranslation(10, 100); | |||
canvas.draw.grid(group, [62, 55], 10, 10, 1).setTranslation(100, 100); | |||
canvas.draw.grid(group, 4, 4, 20, 10, 0).setTranslation(10, 200); | |||
canvas.draw.grid(group, 4, 4, 20, 10, 1).setTranslation(100, 200); | |||
</syntaxhighlight> | |||
== Marks == | == Marks == | ||
Line 114: | Line 162: | ||
=== marksLinear() === | === marksLinear() === | ||
[[File:Canvas-draw-scales01.png|thumb|linear marks (horizontal)|right]] | |||
[[File:Canvas-draw-scales02.png|thumb|linear marks (vertical)|right]] | |||
marksLinear(cgroup, orientation, num_marks, interval, style) | marksLinear(cgroup, orientation, num_marks, interval, style) | ||
Draw marks for a linear scale on a canvas group, e.g. speed tape. Mark lines are draws perpendicular to baseline. | Draw marks for a linear scale on a canvas group, e.g. speed tape. Mark lines are draws perpendicular to baseline. | ||
'''orientation''' of baseline, | '''orientation''' of baseline, "up", "down" (="vertical"), "left", "right" (="horizontal"), only first character is evaluated (u,d,v,l,r,h). | ||
'''num_marks''' number of marks to draw | '''num_marks''' number of marks to draw | ||
Line 125: | Line 175: | ||
'''style''' marksStyle hash with more parameters | '''style''' marksStyle hash with more parameters | ||
<syntaxhighlight lang="nasal"> | |||
#-- marks for linear scales -- | |||
var group = myRoot.createChild("group", "marks"); | |||
var style = canvas.draw.marksStyle.new() | |||
.setBaseline(1) | |||
.setMarkLength(0.8) # 0.8 * interval | |||
.setSubdivisions(2); | |||
canvas.draw.marksLinear(group, "right", 5, 30, style).setTranslation(CX, 150) | |||
.setColor(COLORS["green"]); | |||
style.setSubdivisions(1); | |||
style.setMarkOffset(style.MARK_LEFT); # left/up | |||
canvas.draw.marksLinear(group, "v", 5, 20, style).setTranslation(50, CY) | |||
.setColor(COLORS["red"]); | |||
canvas.draw.marksLinear(group, "h", 4, 20, style).setTranslation(CX, 30) | |||
.setColor(COLORS["red"]); | |||
style.setMarkOffset(style.MARK_CENTER); #center | |||
canvas.draw.marksLinear(group, "down", 5, 20, style).setTranslation(100, CY) | |||
.setColor(COLORS["green"]); | |||
canvas.draw.marksLinear(group, "left", 4, 20, style).setTranslation(CX, 70) | |||
.setColor(COLORS["green"]); | |||
style.setMarkOffset(style.MARK_RIGHT); #right / down | |||
canvas.draw.marksLinear(group, "up", 5, 20, style).setTranslation(150, CY) | |||
.setColor(COLORS["blue"]); | |||
canvas.draw.marksLinear(group, "r", 4, 20, style).setTranslation(CX, 110) | |||
.setColor(COLORS["blue"]); | |||
</syntaxhighlight> | |||
=== marksCircular() === | === marksCircular() === | ||
[[File:Canvas-draw-scales03.png|thumb|circular marks|right]] | |||
marksCircular(cgroup, radius, interval, phi_start = 0, phi_stop = 360, style = nil) | marksCircular(cgroup, radius, interval, phi_start = 0, phi_stop = 360, style = nil) | ||
Line 138: | Line 218: | ||
'''phi_stop''' position of last mark in degree (default 360) | '''phi_stop''' position of last mark in degree (default 360) | ||
<syntaxhighlight lang="nasal"> | |||
#-- marks on arc / circle -- | |||
style.setMarkLength(0.1); | |||
style.setMarkOffset(style.MARK_IN); # pointing to center | |||
style.setSubdivisions(2); | |||
style.setBaseline(1); | |||
var radius = 150; | |||
var interval = 30; | |||
canvas.draw.marksCircular(group, radius, interval, 30, 120, style) | |||
.setTranslation(CX,CY); | |||
style.setMarkOffset(style.MARK_OUT); # pointing outside | |||
style.setSubdivisions(1); | |||
radius = 90; | |||
interval = 10; | |||
canvas.draw.marksCircular(group, radius, interval, 0, 360, style) | |||
.setTranslation(CX,CY) | |||
.setColor(COLORS["cyan"]); | |||
</syntaxhighlight> | |||
== draw.style == | == draw.style == | ||
Line 180: | Line 280: | ||
=== setSubdivisionLength() === | === setSubdivisionLength() === | ||
Set length of subdivision marker in %marker_length | Set length of subdivision marker in %marker_length | ||
== Modules == | |||
[[CompassRose]] |
Revision as of 20:23, 23 December 2018
Note Canvas draw is currently work in progress. You can test and improve it by downloading the CanvasDrawDev add-on. The canvas.draw library will hopefully be ready to use in FG version 2019.1 |
The FlightGear forum has a subforum related to: Canvas |
CanvasDrawDev add-on
Note As of 12/2018, the add-on is largely based on GPL'ed plot2D code written originally by Rodolfo (rleibner on the forums) as part of the Spoken GCA, PAR instrument and Oscilloscope add-ons. |
The purpose of this add-on is to develop and grow a nasal library of canvas drawing functions. This lib should eventually be moved to FGDATA/Nasal once it has reached a sufficient quality.
Motivation
There are basically two ways to populate a canvas, loading an SVG file which has been created with some tool like inkscape, or by writing a nasal program that calls drawing functions of the canvas API.
Both ways are valid and have their pros and cons.
The canvas API is quite limited (at the time of writing), only a few basic commands are available. There should be more drawing commands to allow rapid development of canvas instruments for other aircraft.
Goals
- Make the code flexible and powerful so people will like to use it
- Provide complex drawing commands needed for e.g. compass rose or speed tapes
- Provide easy to use styles
- Support API versioning to allow later extensions of the library
canvas.draw API
Note This API is subject to change without notice until it has been released with FG in FGDATA |
draw module
All draw methods expect a canvas group element 'cgroup' as first parameter to draw on.
draw.colors
A hash with some standard colors like white, black, red, green, blue, cyan, magenta, yellow, orange. Just in case you need them ;)
circle()
circle(cgroup, radius, center_x = nil, center_y = nil)
radius in pixel
center_x, center_y optional center of circle
ellipse()
ellipse(cgroup, radius, center_x = nil, center_y = nil)
radius_x, radius_y in pixel
center_x, center_y optional center of ellipse
arc()
arc(cgroup, radius, center, from_deg = nil, to_deg = nil)
Draw an arc (part of a circle) with given radius around center. In the example image a red, green and blue arc are shown, nasal code below.
center center point of circle as vector [x,y]
from_deg, to_deg start and end of arc in degree of compass rose (0 = North, 90 = East, ...); defaults to 0, 360 (full circle)
# [CX, CY] center point
var start = -40;
canvas.draw.arc(myGroup, radius, [CX, CY], start, start+190).setColor(COLORS["red"]);
start += 90;
canvas.draw.arc(myGroup, radius, [CX, CY], start, start+270).setColor(COLORS["green"]);
start += 90;
canvas.draw.arc(myGroup, radius, [CX, CY], start, start+190).setColor(COLORS["blue"]);
rectange()
rectangle(cgroup, width, height, x = 0, y = 0, rounded = nil)
width, height dimensions in pixels
x, y top-left corner of rectangle
rounded optional radius of corners in pixel
square()
square(cgroup, length, center_x = 0, center_y = 0, cfg = nil)
shorthand for rectangle with width = height = length
deltoid()
deltoid (cgroup, dx, dy1, dy2, x = 0, y = 0)
Deltoid draws a kite (dy1 > 0 and dy2 > 0) or a arrow head (dy2 < 0).
dx width
dy1 height of "upper" triangle
dy2 height of "lower" triangle, < 0 draws an arrow head
x, y position of tip
var dx = 40;
#rhombus draws around a center point while deltoid uses x,y for tip point
shapes["rhombus1"] = canvas.draw.rhombus(group, dx, 2*dx, 5 + dx/2, CY)
.setColor(COLORS["cyan"]);
# width = 40, height = 25 + 50;
shapes["deltoid1"] = canvas.draw.deltoid(group, dx, 25, 50, 2*dx, CY)
.setColor(COLORS["magenta"]);
# y2 < 0 results in arrow head
canvas.draw.deltoid(group, dx, 2*dx, -dx, 4*dx, CY)
.setColor(COLORS["yellow"]);
# y2 = 0 results in triangle
canvas.draw.deltoid(group, dx, 2*dx, 0, 6*dx, CY)
.setColor(COLORS["green"]);
# y2 < 0 and |y2| > y1 results in arrowhead with tip above baseline
canvas.draw.deltoid(group, dx, 1.5*dx, -2.5*dx, 8*dx, CY)
.setColor(COLORS["red"]);
rhombus() / diamond()
rhombus: func(cgroup, dx, dy, center_x = 0, center_y = 0)
draws a diamond around [center_x, center_y] (first element from left in sample image above)
dx width
dy height
grid()
Draw horizontal and verical lines. Two signatures are available
1) (cgroup, [sizeX, sizeY], dx, dy, border = 1)
2) (cgroup, nx, ny, dx, dy, border = 1)
size [width, height] of grid in pixels.
nx, ny number of lines in x/y direction
dx, dy distance between lines in pixels.
border optional boolean, draw lines at sizeX and sizeY, true by default.
var group = myRoot.createChild("group", "grid_scales");
#-- grid test --
canvas.draw.grid(group, [62, 55], 10, 10, 0).setTranslation(10, 100);
canvas.draw.grid(group, [62, 55], 10, 10, 1).setTranslation(100, 100);
canvas.draw.grid(group, 4, 4, 20, 10, 0).setTranslation(10, 200);
canvas.draw.grid(group, 4, 4, 20, 10, 1).setTranslation(100, 200);
Marks
Marks can be used to create scales / gauges.
marksLinear()
marksLinear(cgroup, orientation, num_marks, interval, style)
Draw marks for a linear scale on a canvas group, e.g. speed tape. Mark lines are draws perpendicular to baseline.
orientation of baseline, "up", "down" (="vertical"), "left", "right" (="horizontal"), only first character is evaluated (u,d,v,l,r,h).
num_marks number of marks to draw
interval distance between marks (pixel)
style marksStyle hash with more parameters
#-- marks for linear scales --
var group = myRoot.createChild("group", "marks");
var style = canvas.draw.marksStyle.new()
.setBaseline(1)
.setMarkLength(0.8) # 0.8 * interval
.setSubdivisions(2);
canvas.draw.marksLinear(group, "right", 5, 30, style).setTranslation(CX, 150)
.setColor(COLORS["green"]);
style.setSubdivisions(1);
style.setMarkOffset(style.MARK_LEFT); # left/up
canvas.draw.marksLinear(group, "v", 5, 20, style).setTranslation(50, CY)
.setColor(COLORS["red"]);
canvas.draw.marksLinear(group, "h", 4, 20, style).setTranslation(CX, 30)
.setColor(COLORS["red"]);
style.setMarkOffset(style.MARK_CENTER); #center
canvas.draw.marksLinear(group, "down", 5, 20, style).setTranslation(100, CY)
.setColor(COLORS["green"]);
canvas.draw.marksLinear(group, "left", 4, 20, style).setTranslation(CX, 70)
.setColor(COLORS["green"]);
style.setMarkOffset(style.MARK_RIGHT); #right / down
canvas.draw.marksLinear(group, "up", 5, 20, style).setTranslation(150, CY)
.setColor(COLORS["blue"]);
canvas.draw.marksLinear(group, "r", 4, 20, style).setTranslation(CX, 110)
.setColor(COLORS["blue"]);
marksCircular()
marksCircular(cgroup, radius, interval, phi_start = 0, phi_stop = 360, style = nil)
draw marks along an arc or circle of given radius
radius of baseline (circle)
interval distance of marks in degree
phi_start position of first mark in degree (default 0 = north)
phi_stop position of last mark in degree (default 360)
#-- marks on arc / circle --
style.setMarkLength(0.1);
style.setMarkOffset(style.MARK_IN); # pointing to center
style.setSubdivisions(2);
style.setBaseline(1);
var radius = 150;
var interval = 30;
canvas.draw.marksCircular(group, radius, interval, 30, 120, style)
.setTranslation(CX,CY);
style.setMarkOffset(style.MARK_OUT); # pointing outside
style.setSubdivisions(1);
radius = 90;
interval = 10;
canvas.draw.marksCircular(group, radius, interval, 0, 360, style)
.setTranslation(CX,CY)
.setColor(COLORS["cyan"]);
draw.style
Base class for styles.
draw.marksStyle
Parameter hash for drawing marks (see above).
new()
Create a new style instance.
var myMarkStyle = canvas.draw.marksStyle.new()
setMarkLength()
Set length of marker in %interval or %radius
setMarkOffset()
Set alignment of markers.
You can use marksStyle.MARK_LEFT marks left of vertical baseline
MARK_UP marks above horizontal baseline
MARK_CENTER marks centered on baseline
MARK_RIGHT marks right of vertical baseline
MARK_DOWN marks below horizontal baseline
var myMarkStyle = canvas.draw.marksStyle.new()
myMarkStyle.setMarkOffset(myMarkStyle.MARK_LEFT);
setMarkWidth()
Set line width in pixel.
setSubdivisions()
Set number of subdivisions (default = 0).
setSubdivisionLength()
Set length of subdivision marker in %marker_length