View Source Scenic.Primitives (Scenic v0.11.2)
A set of helper functions to make it easy to add to, or modify, a graph.
In general, each helper function is of the form
def name_of_primitive( graph, data, opts \\ [] )
or
def name_of_primitive_spec( data, opts \\ [] )
The first form builds the primitive immediately and adds it to the graph that is passed in. The second form creates a specification for the primitive (basically, a data structure describing how to draw it). You then add this to a graph at some later time.
Let's start by looking at the immediate versions.
immediate-primitive-helpers
Immediate Primitive Helpers
When adding primitives to a graph, each helper function accepts a graph as the first parameter and returns the transformed graph. This makes it very easy to build a complex graph by piping helper functions together.
@graph Graph.build()
|> text( "Hello World" )
|> rectangle( {100, 200} )
|> line( {{10,20}, {100, 20}})
When modifying a graph, you can again use the helpers by passing in the primitive to be modified. The transformed primitive will be returned.
Graph.modify(graph, :rect, fn(p) ->
rectangle(p, {200, 300})
end)
# or, more compactly...
Graph.modify(graph, :rect, &rectangle(&1, {200, 300}) )
In each case, the second parameter is a data term that is specific to the primitive being acted on. See the documentation below. If you pass in invalid data for the second parameter, an error will be thrown, along with some explanation of what it expected.
The third parameter is a keyword list of options that are to be applied to the primitive. This includes setting the id, styles, transforms and such.
@graph Graph.build()
|> text( "Hello World", id: :hello, font_size: 24, rotate: 0.4 )
|> rectangle( {100, 200}, translate: {10, 30}, fill: :yellow)
|> line( {{10,20}, {100, 20}}, id: :a_line, stroke: {4, :green})
deferred-primitive-helpers
Deferred Primitive Helpers
Each immediate primitive helper has a corresponding deferred helper. The deferred variant does not add the primitive to a graph. Instead, the deferred helper returns a function. You can then call that function, passing it a graph, and the primitive will be added to that graph.
text = text_spec( "Hello World" )
rect = rectangle_spec( {100, 200} )
line = line_spec( {{10,20}, {100, 20}})
g = Graph.build()
g = text.(g)
g = rect.(g)
g = line.(g)
Written like this, the deferred helpers aren't compelling. But we could also write
items = [
text_spec( "Hello World" ),
rectangle_spec( {100, 200} ),
line_spec( {{10,20}, {100, 20}}),
]
g = items
|> Enum.reduce(Graph.build(), fn item, g -> item.(g) end)
Deferred helpers let us express primitives as data. This
makes it easier to define display graphs at compile time, particularly
when we use the group_spec/2
helper to express the grouping of
components:
@line {{0, 0}, {60, 60}}
@lines [
line_spec(@line, stroke: {4, :red}),
line_spec(@line, stroke: {20, :green}, cap: :butt, t: {60, 0}),
line_spec(@line, stroke: {20, :yellow}, cap: :round, t: {120, 0}),
]
@text [
text_spec("Hello", translate: {0, 40}),
text_spec("World", translate: {90, 40}, fill: :yellow),
]
@drawing Graph.build() |> add_specs_to_graph([ @lines, @text ])
If you wanted to put the lines into one group and the text into
another, simply interpose the group_spec/2
helper:
@drawing Graph.build()
|> add_specs_to_graph([
group_spec(@lines, t: [100, 50]),
group_spec(@text, t: [150, 50])
])
If you have a smaller graph or just like to see everything in one
place, you might prefer using group_spec_r/2
:
@line {{0, 0}, {60, 60}}
@drawing Graph.build()
|> add_specs_to_graph([
group_spec_r([t: {100, 50}], [
line_spec(@line, stroke: {4, :red}),
line_spec(@line, stroke: {20, :green}, cap: :butt, t: {60, 0}),
line_spec(@line, stroke: {20, :yellow}, cap: :round, t: {120, 0})
]),
group_spec_r([t: {150, 50}], [
text_spec("Hello", translate: {0, 40}),
text_spec("World", translate: {90, 40}, fill: :yellow),
])
])
These examples use add_specs_to_graph/2
, a simple helper that
converts specs into primitives and adds them to a graph.
style-options
Style options
Style options affect the way primitives are drawn. They include options such
as :fill
, :stroke
, :font
and many more. See the Scenic.Primitive.Style
documentation
for the full list. Style options are inherited down the graph. In other words,
if you set a style on the root of the graph like this:
Graph.build(font_size: 24)
, then all text items in all groups will be
rendered with a point size of 24 unless they set a different size.
Not every primitive accepts every style. For example, it doesn't make much sense to apply a font to a rectangle. If you try, the rectangle will ignore that value. See the documentation for each primitive for a list of what styles they pay attention to.
Transforms that are applied to a Group are inherited by all primitives in that group's branch of the tree. Note that style inheritance does not cross SceneRef boundaries.
transform-options
Transform options
Transform options affect the size, position and rotation of elements in the graph. Any transform you can express as a 4x4 matrix of floats, you can apply to any primitive in the graph, including groups and SceneRefs.
Transform options are applied on the element they are specified on. If you specify a transform on a group, then it is applied to everything rendered in that branch of the graph tree.
This is done mathematically as a "stack" of transforms. As the renderer traverses up and down the graph, transforms are pushed and popped from the matrix stack as appropriate. Transform inheritance does cross SceneRef boundaries.
draw-order
Draw Order
Primitives will be drawn in the order you add them to the graph. For example, the graph below draws text on top of a filled rectangle. If the order of the text and rectangle were reversed, they would both still be rendered, but the text would not be visible because the rectangle would cover it up.
@graph Graph.build( font: {:roboto, 20} )
|> rect( {100, 200}, color: :blue )
|> text( "Hello World", id: :hello, translate: {10, 10} )
Link to this section Summary
Functions
Given a graph and a list of deferred primitive specifications, run the specs in order, adding the primitives to the graph.
Add an arc to a graph
Create the specification that adds an arc to a graph.
Add a Circle to a graph.
Create the specification that adds a circle to a graph.
Add an Ellipse to a graph.
Create the specification that adds an ellipse to a graph.
Create a new branch in a Graph.
Bundle a list of specifications together, and return a function that, when called, will add those specs as a group to a graph.
Bundle a list of specifications together, and return a function that, when called, will add those specs as a group to a graph.
Add a line to a graph.
Create the specification that adds a line to a graph.
Add custom, complex shape to a graph.
Create the specification that adds a path to a graph.
Add a Quadrilateral (quad) to a graph.
Create the specification that adds a quad to a graph.
Shortcut to the rectangle/3
function.
Create the specification that adds a rectangle to a graph.
Add a rectangle to a graph.
Create the specification that adds a rectangle to a graph.
Add a rounded rectangle to a graph.
Create the specification that adds a rounded rectangle to a graph.
Shortcut to the rounded_rectangle/3
function.
Create the specification that adds a rounded rectangle to a graph.
Add a named script to a graph.
Create the specification that adds a script to a graph.
Add a sector to a graph
Create the specification that adds a sector ref to a graph.
Add a sprites list a graph.
Create the specification that adds a sprites list to a graph.
Adds text to a graph.
Create the specification that adds text to a graph.
Add a Triangle to a graph.
Create the specification that adds a triangle to a graph.
Update the options of a primitive without changing its data.
Link to this section Functions
@spec add_specs_to_graph(Scenic.Graph.t(), [Scenic.Graph.deferred(), ...]) :: Scenic.Graph.t()
Given a graph and a list of deferred primitive specifications, run the specs in order, adding the primitives to the graph.
Example:
items = [
text_spec("hello "),
text_spec("world")
]
graph = graph |> add_specs_to_graph(items)
If given a third parameter, the specs are wrapped in a group, and that parameter is used as the group's options.
graph = graph |> add_specs_to_graph(items, t: {100,100})
@spec add_specs_to_graph(Scenic.Graph.t(), [Scenic.Graph.deferred(), ...], keyword()) :: Scenic.Graph.t()
@spec arc( source :: Scenic.Graph.t() | Scenic.Primitive.t(), arc :: {radius :: number(), angle :: number()}, options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add an arc to a graph
An arc is the outer edge of a part of a circle or ellipse. It is the sort of thing you would use a compass to draw on a piece of paper. It has a radius, and angle that defines how much of the arc to sweep through. The angle is specified in radians.
Data:
{radius, angle}
If you want something that looks like a piece of pie (maybe for a pie chart??), then you want a Sector, not an Arc.
To create an arc of an ellipse, create a normal arc, and apply
a :scale
transform with unequal x and y sizing.
The following example will draw a simple arc with a radius of 100, starting straight out to the right, then going down 0.4 radians.
graph
|> arc( {100, 0.6} )
note
Note
The format for Arc has changed since v0.10. It used to be {radius, start_angle, end_angle}. You can achieve the same effect in the new, simpler format by using the same radius and the new angle is the difference between the old end_angle and start_angle. Then you can apply a rotation transform to get it in the right position.
styles
Styles
Arcs honor the following styles
:hidden
- Iftrue
, the outline is rendered. Iffalse
, it is skipped. Default:false
.:fill
- Fills in the interior with the specified paint. If not set, the default is to not draw anything in the interior. This is similar to specifyingfill: :clear
, but optimized.:stroke
- Draws the outline with the specified width and paint. The default if not set is{1, :white}
.
Example:
graph
|> arc( {100, 0.4}, stroke: {4, :blue} )
@spec arc_spec( arc :: {radius :: number(), angle :: number()}, options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds an arc to a graph.
See the documentation for arc/3
for details.
Example:
arc = arc_spec( {100, 0, 0.4}, stroke: {4, :blue} )
graph = arc.(graph)
note
Note
The format for Arc has changed since v0.10. It used to be {radius, start_angle, end_angle}. You can achieve the same effect in the new, simpler format by using the same radius and the new angle is the difference between the old end_angle and start_angle. Then you can apply a rotation transform to get it in the right position.
@spec circle( source :: Scenic.Graph.t() | Scenic.Primitive.t(), radius :: number(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add a Circle to a graph.
Circles are defined by a radius.
The following example will draw circle with radius 100.
graph
|> circle( 100 )
styles
Styles
Circles honor the following styles
:hidden
- Iftrue
, the outline is rendered. Iffalse
, it is skipped. Default:false
.:fill
- Fills in the interior with the specified paint. If not set, the default is to not draw anything in the interior. This is similar to specifyingfill: :clear
, but more optimized.:stroke
- The width and paint to draw the outline with. If the stroke is not specified, the default stroke is{1, :white}
.
Example:
graph
|> circle( 40, fill: :red, stroke: {3, :blue}, translate: {100, 200} )
While you could apply a :rotate
transform to a circle, it wouldn't do
anything visible unless you also add a uneven :scale
transform to make it
into an ellipse.
@spec circle_spec( radius :: number(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a circle to a graph.
See the documentation for circle/3
for details.
Example:
circle = circle_spec( 40, stroke: {4, :blue} )
graph = circle.(graph)
@spec ellipse( source :: Scenic.Graph.t() | Scenic.Primitive.t(), radii :: Scenic.Math.vector_2(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add an Ellipse to a graph.
Ellipses are defined by two radii.
The following example will draw an ellipse.
graph
|> ellipse( {100, 140} )
If you want the ellipse to be on an angle, apply a :rotate
transform.
styles
Styles
Ellipses honor the following styles
:hidden
- Iftrue
, the outline is rendered. Iffalse
, it is skipped. Default:false
.:fill
- Fills in the interior with the specified paint. If not set, the default is to not draw anything in the interior. This is similar to specifyingfill: :clear
, but optimized.:stroke
- The width and paint to draw the outline with. If the stroke is not specified, the default stroke is{1, :white}
Example:
graph
|> ellipse( {40, 60}, fill: :red, stroke: {3, :blue}, rotate: 0.4 )
@spec ellipse_spec( radii :: Scenic.Math.vector_2(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds an ellipse to a graph.
See the documentation for ellipse/3
for details.
Example:
ellipse = ellipse_spec( { 40, 60 }, stroke: {4, :blue} )
graph = ellipse.(graph)
@spec group( source :: Scenic.Graph.t(), builder :: function(), options :: list() ) :: Scenic.Graph.t()
Create a new branch in a Graph.
The Group primitive creates a new branch in the Graph's tree. The data field you pass in is a function callback, which allows you to add more primitives inside the new group.
The single parameter to your anonymous callback is a transformed graph that knows to add new primitives to the right branch in the tree.
@graph Graph.build( )
|> text( "Hello World" )
|> group(fn(g) ->
g
|> text( "I'm in the Group" )
end, translate: {40,200})
NOTE: Unlike other primitives, group/3
currently only takes a graph and not
an existing group primitive.
styles
Styles
Groups will accept all styles. They don't use the styles directly, but any styles you set on a group become the new defaults for all primitives you add to that group's branch in the graph.
The :hidden
style is particularly effective when applied to a group as it
causes that entire branch to be drawn, or not.
transforms
Transforms
Any transforms you apply to a group are added into the render matrix stack and are applied to all items in that branch, including crossing SceneRefs.
@spec group_spec( items :: Scenic.Graph.deferred() | [Scenic.Graph.deferred(), ...], options :: list() ) :: Scenic.Graph.deferred()
Bundle a list of specifications together, and return a function that, when called, will add those specs as a group to a graph.
The options are the same as for group/3
Example:
line = {{0, 0}, {60, 60}}
lines = [
line_spec(@line, stroke: {4, :red}),
line_spec(@line, stroke: {20, :green}, cap: :butt, t: {60, 0}),
line_spec(@line, stroke: {20, :yellow}, cap: :round, t: {120, 0}),
]
line_group = group_spec(lines, t: [ 100, 100 ])
graph = line_group.(graph)
You can also pass in a single primitive spec:
line = line_spec({{0, 0}, {60, 60}}, stroke: {4, :red}),
line_group = group_spec(line, t: [ 100, 100 ])
graph = line_group.(graph)
@spec group_spec_r( options :: list(), items :: Scenic.Graph.deferred() | [Scenic.Graph.deferred(), ...] ) :: Scenic.Graph.deferred()
Bundle a list of specifications together, and return a function that, when called, will add those specs as a group to a graph.
The options are the same as for group_spec/2
, but reversed, making
it suitable to use when declaring graph specs as big literals due to
the increased readability.
Example:
line = {{0, 0}, {60, 60}}
line_group = group_spec_r([t: {100, 100}], [
line_spec(@line, stroke: {4, :red}),
line_spec(@line, stroke: {20, :green}, cap: :butt, t: {60, 0}),
line_spec(@line, stroke: {20, :yellow}, cap: :round, t: {120, 0}),
])
graph = line_group.(graph)
You can also pass in a single primitive spec:
line = line_spec({{0, 0}, {60, 60}}, stroke: {4, :red}),
line_group = group_spec_r([t: {100, 100}], line)
graph = line_group.(graph)
@spec line( source :: Scenic.Graph.t() | Scenic.Primitive.t(), line :: Scenic.Math.line(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add a line to a graph.
Lines are pretty simple. They start at one point and go to another.
Data:
{ {from_x, from_y}, {to_x,to_y} }
The following example will draw a diagonal line from the upper left
corner {0,0}
to the point {100,200}
, which is down and to the right.
graph
|> line( {{0,0}, {100,200}} )
styles
Styles
Lines honor the following styles
:hidden
- Iftrue
, the line is skipped. Iffalse
, the line is rendered. Default:false
.:stroke
- The width and paint to draw the line with. If the stroke is not specified, the default stroke is{1, :white}
.:cap
- Specifies the shape of the ends of the line. Can be one of:round
,:butt
, or:square
. If cap is not specified, then the default is:butt
.
Example:
graph
|> line( {{0,0}, {100,200}}, stroke: {4, :blue}, cap: :round )
@spec line_spec( line :: Scenic.Math.line(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a line to a graph.
See the documentation for line/3
for details.
Example:
line = line_spec( {{0,0}, {100,200}, stroke: {4, :blue} )
graph = line.(graph)
@spec path( source :: Scenic.Graph.t() | Scenic.Primitive.t(), elements :: list(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add custom, complex shape to a graph.
A custom path is defined by a list of actions that the renderer can follow. This is about as close as Scenic gets to immediate mode rendering.
See Scenic.Primitive.Path
for details.
graph
|> path( [
:begin,
{:move_to, 10, 20},
{:line_to, 30, 40},
{:bezier_to, 10, 11, 20, 21, 30, 40},
{:quadratic_to, 10, 11, 50, 60},
{:arc_to, 70, 80, 90, 100, 20},
:close_path,
],
stroke: {4, :blue}, cap: :round
)
@spec path_spec( elements :: list(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a path to a graph.
See the documentation for path/3
for details.
Example:
path = path_spec( [
:begin,
{:move_to, 10, 20},
{:line_to, 30, 40},
{:bezier_to, 10, 11, 20, 21, 30, 40},
{:quadratic_to, 10, 11, 50, 60},
{:arc_to, 70, 80, 90, 100, 20},
:close_path,
],
stroke: {4, :blue}, cap: :round
)
graph = path.(graph)
@spec quad( source :: Scenic.Graph.t() | Scenic.Primitive.t(), quad :: Scenic.Math.quad(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add a Quadrilateral (quad) to a graph.
Quads are defined by four points on the screen.
Data:
{ {x0,y0}, {x1,y1}, {x2,y2}, {x3,y3} }
The following example will draw a quad.
graph
|> quad( {{10,20}, {100,20}, {90, 120}, {15, 70}} )
styles
Styles
Quads honor the following styles
:hidden
- Iftrue
, the outline is rendered. Iffalse
, it is skipped. Default:false
.:fill
- Fills in the interior with the specified paint. If not set, the default is to not draw anything in the interior. This is similar to specifying fill: :clear, except optimized out to do nothing.:stroke
- The width and paint to draw the outline with. If the stroke is not specified then the default stroke is{1, :white}
:join
- Specifies how the lines are joined together where they meet. Can be one of:miter
,:round
, or:bevel
. If join is not specified, then the default is:miter
:miter_limit
- Apply an optional miter limit to the joints. If the angle is very shallow, the pointy bit might extend out far beyond the joint. Specifying:miter_limit
puts a limit on the joint and bevels it if it goes out too far.
Example:
graph
|> quad( {{10,20}, {100,20}, {90, 120}, {15, 70}},
fill: :red, stroke: {3, :blue}, join: :round )
@spec quad_spec( corners :: Scenic.Math.quad(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a quad to a graph.
See the documentation for quad/3
for details.
Example:
quad = quad_spec(
{{10,20}, {100,20}, {90, 120}, {15, 70}},
fill: :red, stroke: {3, :blue}, join: :round
)
graph = quad.(graph)
@spec rect( source :: Scenic.Graph.t() | Scenic.Primitive.t(), rect :: width_and_height(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Shortcut to the rectangle/3
function.
rect/3
is the same as calling rectangle/3
@spec rect_spec( dims :: width_and_height(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a rectangle to a graph.
See the documentation for rectangle/3
for details.
Example:
rect = rect_spec(
{{10,20}, {100,20}},
fill: :red, stroke: {3, :blue}, join: :round
)
graph = rect.(graph)
@spec rectangle( source :: Scenic.Graph.t() | Scenic.Primitive.t(), rectangle :: {width :: number(), height :: number()}, options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add a rectangle to a graph.
Rectangles are defined by a width and height.
Data:
{ width, height }
The following example will draw a rectangle.
graph
|> rectangle( {100, 200} )
styles
Styles
Rectangles honor the following styles
:hidden
- Iftrue
, the outline is rendered. Iffalse
, it is skipped. Default:false
.:fill
- Fills in the interior with the specified paint. If not set, the default is to not draw anything in the interior. This is similar to specifying fill: :clear, except optimized out to do nothing.:stroke
- The width and paint to draw the outline with. If the stroke is not specified then the default stroke is{1, :white}
:join
- Specifies how the lines are joined together where they meet. Can be one of:miter
,:round
, or:bevel
. If join is not specified, then the default is:miter
:miter_limit
- Apply an optional miter limit to the joints. If the angle is very shallow, the pointy bit might extend out far beyond the joint. Specifying:miter_limit
puts a limit on the joint and bevels it if it goes out too far.
Example:
graph
|> rectangle( {100, 200},
fill: :red, stroke: {3, :blue}, join: :round )
@spec rectangle_spec( dims :: width_and_height(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a rectangle to a graph.
See the documentation for rectangle/3
for details.
Example:
rect = rectangle_spec(
{{10,20}, {100,20}},
fill: :red, stroke: {3, :blue}, join: :round
)
graph = rect.(graph)
rounded_rectangle(graph_or_primitive, rounded_rectangle, opts \\ [])
View Source@spec rounded_rectangle( source :: Scenic.Graph.t() | Scenic.Primitive.t(), rounded_rectangle :: {width :: number(), height :: number(), radius :: number()}, options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add a rounded rectangle to a graph.
Rounded rectangles are defined by a width, height, and radius.
Data:
{ width, height, radius }
The following example will draw a rounded rectangle.
graph
|> rounded_rectangle( {100, 200, 8} )
styles
Styles
Rounded rectangles honor the following styles
:hidden
- Iftrue
, the outline is rendered. Iffalse
, it is skipped. Default:false
.:fill
- Fills in the interior with the specified paint. If not set, the default is to not draw anything in the interior. This is similar to specifying fill: :clear, except optimized out to do nothing.:stroke
- The width and paint to draw the outline with. If the stroke is not specified then the default stroke is{1, :white}
Example:
graph
|> rounded_rectangle( {100, 200, 8},
fill: :red, stroke: {3, :blue} )
@spec rounded_rectangle_spec( dims :: width_height_and_radius(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a rounded rectangle to a graph.
See the documentation for rounded_rectangle/3
for details.
Example:
rect = rounded_rectangle_spec(
{{10,20}, {100,20}},
fill: :red, stroke: {3, :blue}, join: :round
)
graph = rect.(graph)
@spec rrect( source :: Scenic.Graph.t() | Scenic.Primitive.t(), rrect :: width_height_and_radius(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Shortcut to the rounded_rectangle/3
function.
rrect/3
is the same as calling rounded_rectangle/3
@spec rrect_spec( dims :: width_height_and_radius(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a rounded rectangle to a graph.
See the documentation for rounded_rectangle/3
for details.
Example:
rect = rrect_spec(
{{10,20}, {100,20}},
fill: :red, stroke: {3, :blue}, join: :round
)
graph = rect.(graph)
@spec script( source :: Scenic.Graph.t() | Scenic.Primitive.t(), name :: atom() | String.t() | pid() | reference(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add a named script to a graph.
Scripts are defined by a name, which can be an atom, string, pid or reference.
NOTE: this doesn't add the script itself. Only places a reference to it in
the graph. You still need to add the script to the ViewPort via
Scenic.ViewPort.put_script/4
.
Data:
name
styles
Styles
Setting styles on a script is similar to setting styles on a group
Example:
graph
|> script( :my_script )
@spec script_spec( name :: any(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a script to a graph.
See the documentation for script/3
for details.
Example:
script = script_spec("script_name", translate: {20,30} )
@spec sector( source :: Scenic.Graph.t() | Scenic.Primitive.t(), sector :: sector(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add a sector to a graph
A sector looks like a piece of pie. It is wedge shaped with a pointy bit on one side and a rounded bit on the other. It has a radius, and angle that defines how much of the arc to sweep through. The angle is specified in radians.
Data:
{radius, angle}
To create a sector of an ellipse, create a normal sector, and apply
a :scale
transform with unequal x and y sizing.
The following example will draw a sector with a radius of 100, starting straight out to the right, then going down 0.4 radians.
|> sector( {100, 0.4} )
note
Note
The format for Sector has changed since v0.10. It used to be {radius, start_angle, end_angle}. You can achieve the same effect in the new, simpler format by using the same radius and the new angle is the difference between the old end_angle and start_angle. Then you can apply a rotation transform to get it in the right position.
styles
Styles
Sectors honor the following styles
:hidden
- Iftrue
, the outline is rendered. Iffalse
, it is skipped. Default:false
.:fill
- Fills in the interior with the specified paint. If not set, the default is to not draw anything in the interior. This is similar to specifying fill: :clear, except optimized out to do nothing.:stroke
- Draws the outline with the specified width and paint. The default if not set is{1, :white}
When you apply a stroke to a sector, it goes around the whole piece of pie. If you only want to stroke the curvy part, which is common in pie charts, overlay an Arc on top of the sector and stroke that.
If you also put both the sector and the arc together in a Group, you can then apply transforms to the group to position both the primitives as a single unit.
Example:
graph
|> group(fn(g) ->
g
|> sector( {100, 0, 0.4}, fill: :red )
|> arc( {100, 0, 0.4}, stroke: {4, :blue} )
end, translate: {30, 40})
@spec sector_spec( params :: sector(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a sector ref to a graph.
See the documentation for sector/3
for details.
Example:
sector = sector_spec( {100, 0.4}, fill: :red )
graph = sector.(graph)
note
Note
The format for Sector has changed since v0.10. It used to be {radius, start_angle, end_angle}. You can achieve the same effect in the new, simpler format by using the same radius and the new angle is the difference between the old end_angle and start_angle. Then you can apply a rotation transform to get it in the right position.
@spec sprites( source :: Scenic.Graph.t() | Scenic.Primitive.t(), Scenic.Primitive.Sprites.t(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add a sprites list a graph.
@spec sprites_spec( sprites :: Scenic.Primitive.Sprites.t(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a sprites list to a graph.
See the documentation for sprites/3
for details.
Example:
sprites = sprites_spec({:static, "source_texure"}, translate: {20,30} )
@spec text( source :: Scenic.Graph.t() | Scenic.Primitive.t(), text :: String.t(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Adds text to a graph.
Text is pretty simple. Specify the string you would like drawn.
The following example will draw some text on the screen.
graph
|> text( "Hello World", translate: {20, 20} )
styles
Styles
Text honors the following styles
:hidden
- Iftrue
, the outline is rendered. Iffalse
, it is skipped. Default:false
.:fill
- The paint to color the text with. If not specified, the default is :white. Note: Text can only be filled with solid colors at this time.:font
- Specifies font family to draw the text with. The built-in system fonts are:roboto
and:roboto_mono
. If not specified, the default is:roboto
. You can also load your own font into theScenic.Cache
, then specify its key for the font.:font_blur
- Draw the text with a blur effect. If you draw text with blur, then draw it again without blur, slightly offset, you get a nice drop shadow effect. The default is to draw with no blur.:text_align
- Specify the alignment of the text you are drawing. You will usually specify one of::left
,:center
, or:right
. SeeScenic.Primitive.Style.TextAlign
for details.:text_height
- Specify the vertical spacing between rows of text.
Example:
graph
|> text( "Hello World", fill: :yellow, font: :roboto_mono
font_blur: 2.0, text_align: :center )
@spec text_spec( string :: String.t(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds text to a graph.
See the documentation for text/3
for details.
Example:
text = text_spec( "a wombat is a marsupial", fill: :red )
graph = text.(graph)
@spec triangle( source :: Scenic.Graph.t() | Scenic.Primitive.t(), triangle :: Scenic.Math.triangle(), options :: list() ) :: Scenic.Graph.t() | Scenic.Primitive.t()
Add a Triangle to a graph.
Triangles are defined by three points on the screen.
Data:
{ {x0,y0}, {x1,y1}, {x2,y2} }
The following example will draw a triangle.
graph
|> triangle( {{10,20}, {100,20}, {50, 120}} )
styles
Styles
Triangles honor the following styles
:hidden
- Iftrue
, the outline is rendered. Iffalse
, it is skipped. Default:false
.:fill
- Fills in the interior with the specified paint. If not set, the default is to not draw anything in the interior. This is similar to specifyingfill: :clear
, but optimized.:stroke
- The width and paint to draw the outline with. If the stroke is not specified, the default stroke is{1, :white}
.:join
- Specifies how the lines are joined together where they meet. Can be one of:miter
,:round
, or:bevel
. If join is not specified, then the default is:miter
.:miter_limit
- Apply an optional miter limit to the joints. If the angle is very shallow, the pointy bit might extend out far beyond the joint. Specifying:miter_limit
puts a limit on the joint and bevels it if it goes out too far.
Example:
graph
|> triangle( {{10,20}, {100,20}, {50, 120}}, fill: :red,
stroke: {3, :blue}, join: :round )
@spec triangle_spec( corners :: Scenic.Math.triangle(), options :: list() ) :: Scenic.Graph.deferred()
Create the specification that adds a triangle to a graph.
See the documentation for triangle/3
for details.
Example:
triangle = triangle_spec({{10,20}, {100,20}, {50, 120}}, fill: :red )
graph = triangle.(graph)
@spec update_opts( Scenic.Primitive.t(), options :: list() ) :: Scenic.Primitive.t()
Update the options of a primitive without changing its data.
This is not used during graph creation - only when modifying it later.
All the primitive-specific helpers require you to specify the data for the primitive. If you only want to modify a transform or add a style, then use this function.
Example:
Graph.modify(graph, :rect, fn(p) ->
update_opts(p, rotate: 0.5)
end)
# or, more compactly...
Graph.modify(graph, :rect, &update_opts(&1, rotate: 0.5) )