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.

Create the specification that adds an arc to a graph.

Create the specification that adds a circle 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.

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.

Create the specification that adds a rectangle to a graph.

Create the specification that adds a rectangle to a graph.

Create the specification that adds a rounded rectangle to a graph.

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.

Create the specification that adds a sector ref to a graph.

Create the specification that adds a sprites list to a graph.

Create the specification that adds text 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

Link to this function

add_specs_to_graph(g, list)

View Source
@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})
Link to this function

add_specs_to_graph(g, list, options)

View Source
@spec add_specs_to_graph(Scenic.Graph.t(), [Scenic.Graph.deferred(), ...], keyword()) ::
  Scenic.Graph.t()
Link to this function

arc(graph_or_primitive, arc, opts \\ [])

View Source
@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 - If true, the outline is rendered. If false, 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, 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} )
Link to this function

arc_spec(arc_params, opts \\ [])

View Source
@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.

Link to this function

circle(graph_or_primitive, radius, opts \\ [])

View Source
@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 - If true, the outline is rendered. If false, 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, 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.

Link to this function

circle_spec(radius, opts \\ [])

View Source
@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)
Link to this function

ellipse(graph_or_primitive, radii, opts \\ [])

View Source
@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 - If true, the outline is rendered. If false, 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, 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 )
Link to this function

ellipse_spec(radii, opts \\ [])

View Source
@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)
Link to this function

group(graph, builder, opts \\ [])

View Source
@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)
Link to this function

group_spec_r(opts, list)

View Source
@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)
Link to this function

line(graph_or_primitive, line, opts \\ [])

View Source
@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 - If true, the line is skipped. If false, 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 )
Link to this function

line_spec(line_params, opts \\ [])

View Source
@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)
Link to this function

path(graph_or_primitive, elements, opts \\ [])

View Source
@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
)
Link to this function

path_spec(elements, opts \\ [])

View Source
@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)
Link to this function

quad(graph_or_primitive, quad, opts \\ [])

View Source
@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 - If true, the outline is rendered. If false, 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 )
Link to this function

quad_spec(corners, opts \\ [])

View Source
@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)
Link to this function

rect(graph_or_primitive, rect, opts \\ [])

View Source
@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

Link to this function

rect_spec(dims, opts \\ [])

View Source
@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)
Link to this function

rectangle(graph_or_primitive, rectangle, opts \\ [])

View Source
@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 - If true, the outline is rendered. If false, 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 )
Link to this function

rectangle_spec(dims, opts \\ [])

View Source
@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)
Link to this function

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 - If true, the outline is rendered. If false, 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} )
Link to this function

rounded_rectangle_spec(dims, opts \\ [])

View Source
@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)
Link to this function

rrect(graph_or_primitive, rrect, opts \\ [])

View Source
@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

Link to this function

rrect_spec(dims, opts \\ [])

View Source
@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)
Link to this function

script(graph_or_primitive, name, opts \\ [])

View Source
@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 )
Link to this function

script_spec(name, opts \\ [])

View Source
@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} )
Link to this function

sector(graph_or_primitive, sector, opts \\ [])

View Source
@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 - If true, the outline is rendered. If false, 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})
Link to this function

sector_spec(params, opts \\ [])

View Source
@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.

Link to this function

sprites(graph_or_primitive, sprites, opts \\ [])

View Source
@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.

Link to this function

sprites_spec(sprites, opts \\ [])

View Source
@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} )
Link to this function

text(graph_or_primitive, text, opts \\ [])

View Source
@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 - If true, the outline is rendered. If false, 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 the Scenic.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. See Scenic.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 )
Link to this function

text_spec(string, opts \\ [])

View Source
@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)
Link to this function

triangle(graph_or_primitive, triangle, opts \\ [])

View Source
@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 - If true, the outline is rendered. If false, 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, 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 )
Link to this function

triangle_spec(corners, opts \\ [])

View Source
@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) )