Public functions
Javis.Action
— TypeAction <: AbstractAction
An Action can be used in the keyword arguments of an Object
to define small sub objects on the object function, such as appear
.
An Action should not be created by hand but instead by using one of the constructors.
Fields
frames::Frames
: the frames relative to the parentObject
anim::Animation
: defines the interpolation function for the transitionfunc::Function
: the function that gets called in each of those frames. Takes the following arguments:video, object, action, rel_frame
transition::Union{Nothing, AbstractTransition}
keep::Bool
defines whether this Action is called even after the last frame it was defined ondefs::Dict{Symbol, Any}
any kind of definitions that are relevant for the action.
Javis.Action
— MethodAction([frames], [Animation], func::Function; keep=true)
An Action
gives an Object
or a Layer
the opportunity to move, change color or much more. It can be defined in many different ways.
Arguments
- frames can be a
Symbol
, aUnitRange
or aGFrames
to define them in a global way.- Default: If not defined it will be the same as the previous
Action
or if it's the first action then it will be applied for the whole length of the object. - It defines for which frames the action acts on the object.
- These are defined in a relative fashion so
1:10
means the first ten frames of the object and not the first ten frames of theVideo
- Default: If not defined it will be the same as the previous
- animation can be an easing function or animation which can be defined by Animations.jl
- Default: The default is
linear()
- Possible simple easing functions is
sineio()
for more check Animations.jl
- Default: The default is
- func is the function that describes the actual action
- It can be a general function which takes in the following four arguments
- video, object, action, rel_frame
- If you don't need them you can write
(args...)->your_function(arg1, arg2)
- You often don't need an own function and instead can use predefined functions like
- It can be a general function which takes in the following four arguments
Keywords
keep::Bool
defaults totrue
defines whether theAction
is called even for frames after it's last defined. In more simple terms: If one hasAction(1:10, anim, translate())
It will get translated to the last position on frame11:END_OF_OBJECT
. One can set; keep = false
to turn off this behavior.
Example
function ground(args...)
background("black")
sethue("white")
end
video = Video(500, 500)
Background(1:100, ground)
obj = Object((args...)->circle(O, 50, :fill))
act!(obj, Action(1:20, appear(:fade)))
act!(obj, Action(21:50, Translation(50, 50)))
act!(obj, Action(51:80, Translation(-50, -50)))
act!(obj, Action(81:100, disappear(:fade)))
render(video; pathname="test.gif")
Actions can be applied to a layer using a similar syntax
l1 = @JLayer 20:60 100 100 Point(0, 0) begin
obj = Object((args...)->circle(O, 50, :fill))
act!(obj, Action(1:20, appear(:fade)))
end
act!(l2, anim_translate(Point(100, 100)))
Javis.GFrames
— TypeGFrames
Ability to define frames in a global fashion inside Action
.
Example
red_circ = Object(1:90, (args...)->circ("red"))
blue_circ = Object(21:90, (args...)->circ("blue"))
act!([red_circ, blue_circ], Action(GFrames(85:90), disappear(:fade)))
is the same as
red_circ = Object(1:90, (args...)->circ("red"))
blue_circ = Object(21:90, (args...)->circ("blue"))
act!(red_circ, Action(85:90, disappear(:fade)))
act!(blue_circ, Action(65:70, disappear(:fade)))
Fields
- frames::UnitRange defines the frames in a global fashion.
Javis.Line
— TypeLine
A type to define a line by two points. Can be used i.e. in projection
We mean the mathematic definition of a continuous line and not a segment of a line.
Fields
p1::Point
: start pointp2::Point
: second point to define the line
Javis.MorphFunction
— Typestruct MorphFunction
func::Function
args::Array
jpaths::Vector{JPath}
Fields
- func::Function : a function with luxor calls to draw something that objects will be morphed into
- args : args to the function . Object will be morphed into what is drawn by calling
func(args...)
- jpaths : The jpaths returned by what is drawn.
JPath[]
by default, this is populated the first instance it encounters a morph/partial draw at render time.
TODO: find a better place(file) to put these functions and structs.
Javis.Object
— TypeObject
Defines what is drawn in a defined frame range.
Fields
frames::Frames
: A range of frames for which theObject
is calledfunc::Function
: The drawing function which draws something on the canvas. It gets called with the argumentsvideo, object, frame
start_pos::Union{Object, Point}
defines the origin of the object. It gets translated to this pointactions::Vector{AbstractAction}
a list of actions applied to this objectcurrent_setting
:: The current state of the object seeObjectSetting
opts::Any
can hold any options defined by the userchange_keywords::Dict{Symbol,Any}
the modified keywords changed bychange
result::Vector
the result of the object (if something gets returned)
Javis.Object
— MethodObject([frames], func::Function, [start_pos]; kwargs...)
Arguments
- frames can be a
Symbol
, aUnitRange
or a relative way to define frames seeRFrames
- Default: If not defined it will be the same as the previous
Object
. - Important: The first
Object
needs the frames specified as aUnitRange
. - It defines for which frames the object is active
- Default: If not defined it will be the same as the previous
- func is a
Function
and the only required argument- This defines the actual object that gets drawn.
- The function takes the following three arguments:
- video, object, frame
- If you don't need them you can write
(args...)->your_function(arg1, arg2)
Example
function ground(args...)
background("black")
sethue("white")
end
video = Video(500, 500)
Background(1:100, ground)
Object((args...)->circle(O, 50, :fill))
render(video; pathname="test.gif")
Here the Background
uses the named way of defining the function whereas the circle object is defined in the anonymous function (args...)->circle(O, 50, :fill)
. It basically depends whether you want to have a simple Luxor object or something more complex.
Javis.RFrames
— TypeRFrames
Ability to define frames in a relative fashion.
Example
Background(1:100, ground)
Object(1:90, (args...)->circ("red"))
Object(RFrames(10), (args...)->circ("blue"))
Object((args...)->circ("red"))
is the same as
Background(1:100, ground)
Object(1:90, (args...)->circ("red"))
Object(91:100, (args...)->circ("blue"))
Object(91:100, (args...)->circ("red"))
Fields
- frames::UnitRange defines the frames in a relative fashion.
Javis.RFrames
— MethodRFrames(i::Int)
Shorthand for RFrames(1:i)
Javis.Transformation
— TypeTransformation
Defines a transformation which can be returned by an object to be accessible later. This is further explained in the Javis tutorials.
Fields
point::Point
: the translation part of the transformationangle::Float64
: the angle component of the transformation (in radians)scale::Tuple{Float64, Float64}
: the scaling component of the transformation
Javis.Video
— TypeVideo
Defines the video canvas for an animation.
Fields
width::Int
the width in pixelheight::Int
the height in pixelobjects::Vector{AbstractObject}
the objects defined in this videolayers::Vector{AbstractObject}
the layers defined in this videobackground_frames::Vector{Int}
saves for which frames a background is defineddefs::Dict{Symbol, Any}
Some definitions which should be accessible throughout the video.
Javis.Video
— MethodVideo(width, height)
Create a video with a certain width
and height
in pixel. This also sets CURRENT_VIDEO
.
Base.:*
— MethodBase.:*(m::Array{Float64,2}, transformation::Transformation)
Convert the transformation to a matrix and multiplies m*trans_matrix. Return a new Transformation
Javis.Background
— MethodBackground(frames, func)
The Background
is internally just an Object
and can be defined the same way. In contrast to an object this a Background
will change the global canvas and not just a layer. Normally it's used to define defaults and the background
color. See Luxor.background
Example
function ground(args...)
background("black")
sethue("white")
end
video = Video(500, 500)
Background(1:100, ground)
Object((args...)->circle(O, 50, :fill))
render(video; pathname="test.gif")
This draws a white circle on a black background as sethue
is defined for the global frame.
Javis.JBox
— MethodJBox(points::Array; color="black", action=:stroke, vertices=false)
Create a box/rectangle using the first two points of an array of Points to defined opposite corners. Returns the top left corner point of the box.
Javis.JBox
— MethodJBox(x::Int64, y::Int64, width::Real, height::Real; color="black", action=:stroke)
Create a box/rectangle centered at point x/y with width and height.
Javis.JBox
— MethodJBox(cornerpoint1::Point, cornerpoint2::Point; color="black", action=:stroke, vertices=false)
Create a box (rectangle) between two points and do an action. Returns the top left corner point of the box.
Javis.JBox
— MethodJBox(pt::Point, width::Real, height::Real, cornerradius::Float64; color="black", action=:stroke)
Draw a box/rectangle centered at point pt with width and height and round each corner by cornerradius.
Javis.JBox
— MethodJBox(pt::Point, width::Real, height::Real; color="black", action=:stroke, vertices=false)
Create a box/rectangle centered at point pt with width and height. Use vertices=true to return an array of the four corner points rather than draw the box.
Javis.JCircle
— Method1. JCircle(center::Point, radius::Real; kwargs...)
2. JCircle(center_x::Real, center_y::Real, radius::Real; kwargs...)
3. JCircle(p1::Point, p2::Point; kwargs...)
- A circle that touches `p1` and `p2`
4. JCircle(radius::Real)
- A circle at the origin
Draw a circle at center
with the given radius
Keywords for all
color
= "black"linewidth
= 2action::Symbol
:stroke by default can be:fill
or other actions explained in the Luxor documentation.
Returns the center of the circle
Javis.JEllipse
— MethodJEllipse(focus1::Point, focus2::Point, pt::Point; color="black", linewidth=2, action=:stroke, stepvalue=pi/100, reversepath=false)
Build a polygon approximation to an ellipse, given two points and a point somewhere on the ellipse.
Javis.JEllipse
— MethodJEllipse(focus1::Point, focus2::Point, k::Real; color="black", linewidth=2, action=:stroke, stepvalue=pi/100, vertices=false, reversepath=false)
Build a polygon approximation to an ellipse, given two points and a distance, k, which is the sum of the distances to the focii of any points on the ellipse (or the shortest length of string required to go from one focus to the perimeter and on to the other focus).
Javis.JEllipse
— Method1. JEllipse(cpt::Point, w::Real, h::Real; kwargs...)
2. JEllipse(xcenter::Int, ycenter::Int, w::Real, h::Real; kwargs...)
Make an ellipse, centered at point c, with width w, and height h. Returns the center of the ellipse.
Keywords for all
color
= "black"linewidth
= 2action::Symbol
:stroke by default can be:fill
or other actions explained in the Luxor documentation.
Javis.JLine
— Method1. JLine(pt1::Point, pt2::Point; kwargs...)
2. JLine(pt2::Point; kwargs...)
- `pt1` is set as the origin `O`
Keywords for all
color
= "black"linewidth
= 2
Draw a line between the points pt1 and pt2. Returns the final point of the line
Javis.JPoly
— MethodJPoly(pointlist::Vector{Point}; color="black", linewidth=2, action = :stroke, close=true, reversepath=false)
Draw a polygon around points in the pointlist.
Keywords
color
specifies the color of the outline or the fill of it (depends on action)linewidth
linewidth of the outlineaction
can be:stroke
,:fill
or other symbols (check the Luxor documentation for details) (default: :stroke)close
whether the polygon should be closed or not (default: closed)reversepath
can be set totrue
to reverse the path and create a polygon hole
Javis.JRect
— Method1. JRect(cornerpoint::Point, w::Real, h::Real; kwargs...)
2. JRect(xmin::Int64, ymin::Int64, w::Real, h::Real; kwargs...)
- same as 1. with `cornerpoint = Point(xmin, ymin)`
Create a rectangle with one corner at cornerpoint with width w and height h and do an action. You can specify the linewidth
and the color
of the rectangle.
Keywords for all
color
= "black"linewidth
= 2action
Defines whether the rectangle should be outlined (:stroke
) or filled (:fill
)
Javis.JStar
— Method1. JStar(center::Point, radius; kwargs...)
2. JStar(xcenter, ycenter, radius; kwargs...)
- same as 1. with `center = Point(xcenter, ycenter)`
Draw a star centered at a position. Return the center of the star.
Keywords for all
color
color of the outline or fill of the star (default: "black")linewidth
linewidth of the outline (default: 2)action
defines whether the rectangle should be outlined (:stroke
) or filled (:fill
)npoints
number of points the star has (default: 5)ratio
height of the smaller radius relative to the larger radius (default: 0.5)orientation
orientation of the star given by an angle (default: 0)reversepath
if true it reverses the path and therefore creates a hole (default: true)
Javis.act!
— Methodact!
Adds an [Action
] or a list of actions to an Object
/ Layer
or a list of objects/layers. One key different to note is that an action is applied to a layer as a whole and not on the objects inside it.
Example
Background(1:100, ground)
obj = Object((args...) -> rect(O, 50, 50, :fill), Point(100, 0))
act!(obj, Action(1:50, anim_scale(1.5)))
Here the scaling is applied to the rectangle for the first fifty frames.
Options
A single object/layer and action:
act!(object::AbstractObject, action::AbstractAction)
object::AbstractObject
- the object the action is applied toaction::AbstractAction
- the action applied to the object
A single object/layer and a list of actions:
act!(object::AbstractObject, action)
object::AbstractObject
- the object actions are applied toactions
- the actions applied to an object Attention: Will fail ifactions
is not iterable
A list of objects/layers and a list of actions:
act!(object::Vector{<:AbstractObject}, action::Vector{<:AbstractAction})
object::Vector{<:AbstractObject}
- the objects actions are applied toaction::Vector{<:AbstractAction}
- the actions applied to the objects
Actions can be applied to a layer using a similar syntax
l1 = Javis.@Javis.Layer 20:60 100 100 Point(0, 0) begin
obj = Object((args...)->circle(O, 50, :fill))
act!(obj, Action(1:20, appear(:fade)))
end
act!(l1, anim_translate(Point(100, 100)))
Javis.ang
— Methodang(x)
ang
is just a short-hand for get_angle
Javis.anim_rotate
— Methodanim_rotate
Animate the rotation of the attached object (see act!
). Similiar function: anim_rotate_around
to rotate around a point
Example
Background(1:100, ground)
obj = Object((args...) -> rect(O, 50, 50, :fill), Point(100, 0))
act!(obj, Action(1:50, anim_rotate(2π)))
Options
anim_rotate(ta::Real)
define the end angle of the rotationanim_rotate(fa::Real, ta::Real)
define the from and end angle
Javis.anim_rotate_around
— Methodanim_rotate_around
Animate the rotation of the attached object (see act!
) around a point. Similiar function: anim_rotate
to rotate or spin an object
Example
Background(1:100, ground)
obj = Object((args...) -> rect(O, 50, 50, :fill), Point(100, 0))
act!(obj, Action(1:50, anim_rotate_around(2π, O)))
Options
anim_rotate_around(ta::Real, p)
define the end angle of the rotation + the rotation center.anim_rotate_around(fa::Real, ta::Real, p)
define the from and end angle + the rotation center.
Javis.anim_scale
— Methodanim_scale
Animate the scaling of the attached object (see act!
). Attention: Scaling is always done from the current origin.
Example
Background(1:100, ground)
obj = Object((args...) -> rect(O, 50, 50, :fill), Point(100, 0))
act!(obj, Action(1:50, anim_scale(1.5)))
Options
anim_scale(ts)
scales from the current scale tots
.anim_scale(fs, ts)
scales fromfs
tots
.
The scales itself should be either a Float64 or a tuple of Float64 or a reference to an object if the object itself returns a value like that.
Javis.anim_translate
— Methodanim_translate
Animate the translation of the attached object (see act!
).
Example
Background(1:100, ground)
obj = Object((args...) -> circle(O, 50, :fill), Point(100, 0))
act!(obj, Action(1:50, anim_translate(10, 10)))
Options
anim_translate(x::Real, y::Real)
define by how much the object should be translated. The end point will be current_pos + Point(x,y)anim_translate(tp::Point)
define direction and length of the translation vector by usingPoint
anim_translate(fp::Union{Object,Point}, tp::Union{Object,Point})
define the from and to point of a translation. It will be translated bytp - fp
.Object
can be used to move to the position of another object
Javis.appear
— Methodappear(s::Symbol)
Appear can be used inside an Action
to make an Object
or an entire Object
(including it's objects) to appear.
Example
house = Object(101:200, (args...)->house_of_nicholas())
act!(house, Action(1:20, appear(:fade)))
act!(house, Action(81:100, disappear(:fade)))
In this case the house_of_nicholas
will fade in during the first 20 frames of the Object
so 101-120
.
Arguments
s::Symbol
: the symbol defines the animation of appearance The only symbols that are currently supported are::fade_line_width
which increases the line width up to the default value or the value specified bysetline
:fade
which increases the opcacity up to the default value or the value specified bysetopacity
:scale
which increases the scale up to the default value1
or the value specified byscale
:draw_text
which only works fortext
and lets it appear from left to right.
For a layer only appear(:fade)
is supported
Javis.background
— Methodbackground(str)
Has bacially the same functionality as Luxor.background() but overrides that method to allow for transparent layers.
Checks if a layer should be present, and if a background has been defined or not for the current layer.
Arguments
background_color
background color
Javis.cancel_stream
— Methodcancel_stream()
Sends a SIGKILL
signal to the livestreaming process. Though used internally, it can be used stop streaming. However this method is not guaranted to end the stream on the client side.
Javis.change
— Methodchange(s::Symbol, [val(s)])
Changes the keyword s
of the parent Object
from vals[1]
to vals[2]
in an animated way if vals is given as a Pair
otherwise it sets the keyword s
to val
.
Arguments
s::Symbol
Change the keyword with the names
vals::Pair
If vals is given i.e0 => 25
it will be animated from 0 to 25.- The default is to use
0 => 1
or use the value given by the animation
Action
- The default is to use
Example
Background(1:100, ground)
obj = Object((args...; radius = 25, color="red") -> object(O, radius, color), Point(100, 0))
act!(obj, Action(1:50, change(:radius, 25 => 0)))
act!(Action(51:100, change(:radius, 0 => 25)))
act!(Action(51:100, change(:color, "blue")))
Javis.disappear
— Methoddisappear(s::Symbol)
Disappear can be used inside an Action
to make an Object
or an entire Layer
(including it's objects) to disappear.
Example
house = Object(101:200, (args...)->house_of_nicholas())
act!(house, Action(1:20, appear(:fade)))
act!(house, Action(81:100, disappear(:fade)))
In this case the house_of_nicholas
will fade out during the last 20 frames of the Object
so 181-200
.
Arguments
s::Symbol
: the symbol defines the animation of disappearance The only symbols that are currently supported are::fade_line_width
which decreases the line width down to0
:fade
which decreases the opacity down to0
:scale
which decreases the scale down to0
:draw_text
which only works for text and let the text disappear from right to left.
For a layer only disappear(:fade)
is supported
Javis.draw_grid
— Methoddraw_grid(video::Video, object::AbstractObject, frame::Int; direction::AbstractString = "TR", line_gap = 25)
Draws an oriented grid on the given frame of a Video.
Arguments
direction::AbstractString
: Where grid animation finishes. Default:"TR"
Available Orientations:"TR"
- Animation finishes in the Top Right corner of the frame."TL"
- Animation finishes in the Top Left corner of the frame."BR"
- Animation finishes in the Bottom Right corner of the frame."BL"
- Animation finishes in the Bottom Left corner of the frame.
line_gap
: How many pixels between each line. Default:25
Example
Example call of this function within an Object
.
Object(1:100, :line, draw_grid(direction = "TL", line_gap = 25))
Javis.drawpartial
— Method drawpartial(fraction::Real)
Returns a function to be used with Action , draws the object upto a fraction
of itself.
Javis.follow_path
— Methodfollow_path(points::Vector{Point}; closed=true)
Can be applied inside an action such that the parent object follows a path. It takes a vector of points which can be created as an example by calling circle(O, 50)
. Notice that the object is set to :none
, the default.
Example
Action(1:150, follow_path(star(O, 300)))
Arguments
points::Vector{Point}
- the vector of points the object should follow
Keywords
closed::Bool
default: true, sets whether the path is a closed path as for example when using a circle, ellipse or any polygon. For a bezier path it should be set to false.
Javis.fontsize
— Methodfontsize(fsize)
Same as Luxor.fontsize
: Sets the current font size.
Example
fontsize(12)
text("Hello World!")
Arguments:
fsize
: the new font size
Javis.get_angle
— Methodget_angle(obj::AbstractObject)
Get access to the angle that got saved in a previous object.
Returns
Float64
: the angle stored by a previous object i.e viareturn Transformation(p, angle)
Javis.get_fontsize
— Methodget_fontsize(fsize)
Same as Luxor.get_fontsize
but works with every version of Luxor that is supported by Javis.
Example
fontsize(12)
fsize = get_fontsize()
text("Hello World! $fsize")
Returns
Float64
: the current font size
Javis.get_position
— Methodget_position(l::Layer)
Get access to the position of a layer.
Returns
Point
: the point stored by the layer.
Throws
- If the function of Layer didn't return a Point or Transformation
Javis.get_position
— Methodget_position(obj::Object)
Get access to the position that got saved in a previous object.
Returns
Point
: the point stored by a previous object.
Throws
- If the function of Object didn't return a Point or Transformation
Javis.get_scale
— Methodget_scale(obj::AbstractObject)
Get access to the scaling that got saved in a previous object.
Returns
Scaling
: the scale stored by a previous object.
Javis.get_value
— Methodget_value(obj::AbstractObject)
Returns the value saved by obj
Javis.latex
— Methodlatex(text::LaTeXString, pos::Point, object::Symbol; valign = :top, halign = :left)
Add the latex string text
to the top left corner of the LaTeX path. Can be added to Luxor.jl
graphics via Video
.
NOTES:
This only works if
tex2svg
is installed. It can be installed using the following command (you may have to prefix this command withsudo
depending on your installation):npm install -g mathjax-node-cli
The
latex
method must be called from within anObject
.
Arguments
text::LaTeXString
: a LaTeX string to render.pos::Point
: position of the upper left corner of the latex text. Default:O
- can be written as
x, y
instead ofPoint(x, y)
- can be written as
object::Symbol
: graphics objects defined byLuxor.jl
. Default:stroke
.
Available objects:
:stroke
- Draws the latex string on the canvas. For more info checkLuxor.strokepath
:path
- Creates the path of the latex string but does not render it to the canvas.
Keywords:
valign::Symbol=:top
: vertical alignment with respect to the specifiedpos
parameter.- Options available are
:top
,:middle
,:bottom
- Options available are
halign::Symbol=:left
: horizontal alignment with respect to the specifiedpos
parameter.- Options available are
:left
,:center/:centre
,:right
- Options available are
Throws
IOError
: mathjax-node-cli is not installed
Warning
Shows a warning if either of the alignment options are unrecognised.
Example
using Javis
using LaTeXStrings
function ground(args...)
background("white")
sethue("black")
end
function draw_latex(video, object, frame)
fontsize(50)
x = 100
y = 120
latex(L"\sqrt{5}", x, y)
end
demo = Video(500, 500)
Background(1:2, ground)
Object(draw_latex)
render(demo; pathname = "latex.gif")
Javis.morph
— Functionmorph(samples = 100)
morph() to be used with Action, when an animation from Animations.jl is provided with Animation{MorphFunction}
. Default samples for every polygon is 100, increase this if needed. Animation must be of type Animation{MorphFunction} or Animation{Object} when passing morph()
to Action
.
Animation{MorphFunction} can be made using the following syntax. (constructors for the following signatures are written to return the apropriate Animation{MorphFunction})
anim = Animation([0,a1,a2,...,an,1] , MorphFunction[ (func0,args0), (func1,args1) , (func2,args2) ... (funcn,argsn), (func_fin,args_fin) ])
0< a1 < a2 < a3... < an < 1.0
if your functions dont take any arguments then you may also use...
Animation([0,a1...,a_n,1] , [ f0 , f1 , f2 ...,f_n, f_fin] )
The first element is a function. Arguments to be passed to the function can either be wrapped in an Array or as subsequent elements in the Tuple for example the following two lines have the same effect.
MorphFunction[(func1,[arg11,arg12,arg13]), (func2,[arg21,arg22]) ]
MorphFunction[(func1,arg1,arg2,arg3), (func2,arg21,arg22)]
Animation can also be of type Animation{Object}
anim = Animation([0,a1 ... , a_n , 1 ] , [obj, obj1, obj2 , ... objn , obj_fin] )
Example
using Javis
using Animations
video = Video(500,500)
nframes = 160
function circdraw(colo)
sethue(colo)
setopacity(0.5)
circle(O,50,:fillpreserve)
setopacity(1.0)
sethue("white")
strokepath()
end
function boxdraw(colo)
sethue(colo)
box(O,100,100,:fillpreserve)
setopacity(1.0)
sethue("white")
strokepath()
end
function stardraw()
sethue("white")
star(O,100,5,0.5,0.0,:stroke)
end
Background(1:nframes+10,(args...)->background("black"))
boxobj = Object(1:nframes+10 , (args...) -> boxdraw("green") )
anim = Animation([0, 0.7, 1],[(boxdraw, ["green"]), stardraw, (circdraw, "red")])
action = Action(1:nframes,anim,morph())
act!(boxobj,action)
render(video,pathname="box_to_star_to_circ.gif")
Above snippet morphs a Box to a Star then to a Circle
Javis.morph_to
— Methodmorph_to(to_func::Function; samples=100)
A closure for the _morph_to
function. To be used with Action. morph_to
will morph an object into whatever is drawn by the to_func
passed to it.
Arguments
to_func::Function
: Function that defines what the object should be morphed into
Keywords
samples
: Number of points to resample every polygon to for the morphing
Limitations
- cant handle clips inside
to_func
or theobject
- sethue animation doesnt work with this , since the color's to be morphed into are derived from the
object
andto_func
. to change hue while morphing , change it in theto_func
Example
This creates a star that morphs into a circle and back.
astar() = star(O, 50, 5, 0.5, 0)
acirc() = circle(O, 50)
video = Video(500, 500)
back = Background(1:20, ground)
star_obj = Object(1:10,(args...)-> astar())
act!(star_obj, Action(linear(), morph_to(acirc)))
act!(star_obj, Action(11:20, morph_to(astar)))
morph_to(to_obj::Object; samples=100)
Morphs one object into another object.
# Arguments
- `to_obj::Object`: Object that defines what the object should be morphed into
# Keywords
- `samples` : Number of points to resample every polygon to for the morphing
# Limitations
- cant handle clips inside `to_func` or the `object`
- sethue animation doesnt work with this , since the color's to be morphed into are derived from the `object` and `to_func`. to change hue while morphing , change it in the `to_func`
# Example
This creates a star that morphs into a circle.
julia astar() = star(O, 50, 5, 0.5, 0) acirc() = circle(O, 50)
video = Video(500, 500) back = Background(1:20, ground) starobj = Object(1:10,(args...)-> astar()) circobj = Object(1:10,(args...)-> acirc()) act!(starobj, Action(linear(), morphto(acirc))) ```
Javis.pos
— Methodpos(x)
pos
is just a short-hand for get_position
Javis.prev_end
— Methodprev_end()
The end frame of the previous object or for an action the end frame of the parental object. Can be used to provide frame ranges like:
@Frames(prev_end()-10, 10)
Javis.prev_start
— Methodprev_start()
The start frame of the previous object or for an action the start frame of the parental object. Can be used to provide frame ranges like:
@Frames(prev_start(), 10)
Javis.projection
— Methodprojection(p::Point, l::Line)
Return the projection of a point to a line.
Javis.render
— Methodrender(
video::Video;
framerate=30,
pathname="javis_GIBBERISH.gif",
liveview=false,
streamconfig::Union{StreamConfig, Nothing} = nothing,
tempdirectory="",
ffmpeg_loglevel="panic",
rescale_factor=1.0,
postprocess_frame=identity,
postprocess_frames_flow=default_postprocess
)
Renders all previously defined Object
drawings to the user-defined Video
as a gif or mp4.
Arguments
video::Video
: The video which defines the dimensions of the output
Keywords
framerate::Int
: The frame rate of the videopathname::String
: The path for the rendered gif or mp4 (i.eoutput.gif
oroutput.mp4
)- Default: The animation is rendered as a gif with the
javis_
prefix and some gibberish afterwards
- Default: The animation is rendered as a gif with the
liveview::Bool
: Causes a live image viewer to appear to assist with animation developmentstreamconfig::Union{StreamConfig, Nothing}
: Contains livestream specific instructions, passed on tosetup_stream
.
Streaming to Twitch or other platforms are not yet supported.
tempdirectory::String
: The folder where each frame is stored Defaults to a temporary directory when not setffmpeg_loglevel::String
:- Can be used if there are errors with ffmpeg. Defaults to panic:
rescale_factor::Float64
factor to which the frames should be rescaled for faster renderingpostprocess_frame::Function
function that is applied to the imagematrix of each frame after they have been computed
takes as argument frame_image, frame, frames
, useful to apply a postprocessing e.g. blur to all or some of the images. By default it is the identity and nothing happens.
postprocess_frames_flow::Function
function that is applied to the vector of the frames indices should return a new vector
where elements are a subset of the number of frames. Useful to reorder the frames, e.g. reverse the video with postprocess_frames_flow=reverse
. By default it is the identity and nothing happens.
Javis.rev
— Methodrev(e::Easing)
Reverse an easing function such that easing_to_animation
maps it to [1.0, 0.0]
instead of [0.0, 1.0]
. An example can be seen in rotate
Javis.rotate_around
— Methodrotate_around(p)
Rotate an Object
or a Layer
using an Action
and an Animation defined with Animations.jl around a point p
. For rotate
it rotates around the current origin.
An example can be seen in rotate
.
Arguments
p
: the point to rotate around
Javis.scale
— Methodscale(scl_x, scl_y)
Same as scale
but the x scale and y scale can be changed independently.
Arguments:
scl_x
: scale in x directionscl_y
: scale in y direction
Javis.scale
— Methodscale(scl)
Set the scale and multiply it with the current multiplier which is i.e. set by appear
and disappear
.
Normal behavior without any animation is the same as Luxor.scale
.
Example
scale(0.5)
circle(O, 20, :fill) # the radius would be 10 because of the scaling
Arguments:
scl
: the new default scale
Javis.scale
— Methodscale()
Scale a function defined inside an Action
using an Animation defined with Animations.jl.
An example can be seen in rotate
.
Javis.scale_linear
— Methodscale_linear(fmin, fmax, tmin, tmax; clamp=true)
Creating a mapping which takes values from fmin
to fmax
and outputs values ranging from tmin
to tmax
. If the input is outside the range it will be by default clamped to the fmin
- fmax
. This can be prevented by setting clamp=false
.
Example
scale = scale_linear(0, 10, 0, 100)
scale(5) # returns 50
scale_point = scale_linear(O, Point(10, 10), O, Point(100, 100))
scale_point(Point(7,8)) # returns Point(70, 80)
Javis.scaleto
— Methodscaleto(x, y)
Scale to a specific scaling instead of multiplying it with the current scale. For scaling on top of the current scale have a look at scale
.
Javis.scl
— Methodscl(x)
scl
is just a short-hand for get_scale
Javis.setline
— Methodsetline(linewidth)
Set the line width and multiply it with the current multiplier which is i.e. set by appear
and disappear
.
Normal behavior without any animation is the same as Luxor.setline
.
Example
setline(10)
line(O, Point(10, 10))
Arguments:
linewidth
: the line width in pixel
Javis.setopacity
— Methodsetopacity(opacity)
Set the opacity and multiply it with the current multiplier which is i.e. set by appear
and disappear
.
Normal behavior without any animation is the same as Luxor.setopacity
.
Example
setopacity(0.5)
circle(O, 20, :fill)
Arguments:
opacity
: the opacity between 0.0 and 1.0
Javis.setopacity
— Methodsetopacity()
Set the color of an Object
or a Layer
using an Action
and an Animation defined with Animations.jl.
Example
A possible animation would look like this:
opacity_anim = Animation(
[0, 0.5, 1], # must go from 0 to 1
[
0.0,
0.3,
0.7,
],
[sineio(), sineio()],
)
An example on how to integrate this into an Action
can be seen in rotate
. Where this would be a valid Action: Action(1:150, opacity_anim, setopacity())
.
Javis.setup_stream
— Functionsetup_stream(livestreamto=:local; protocol="udp", address="0.0.0.0", port=14015, twitch_key="")
Sets up the livestream configuration. NOTE: Twitch not fully implemented, do not use.
Javis.showcreation
— Method showcreation()
Returns a function to be used with Action. Shows the creation of the object incrementally.
Ex.
Background(1:nframes+60,(args...)->ground())
boxobj = Object(1:nframes+60 , (args...) -> boxdraw("green") )
action_create = Action(1:nframes÷2,sineio(),showcreation())
act!(boxobj,action_create)
Javis.showdestruction
— Methodshowdestruction()
Similar to showcreation
but un-draws the object.
Javis.text
— Functiontext(str, pos = O; valign = :baseline, halign = :left, angle = 0.0)
Has bacially the same functionality as Luxor.text but overrides that method to allow to animate text with appear
.
Example
text_obj = Object(1:100, (args...) -> text("Hello Stream!"; halign = :center))
act!(text_obj, Action(1:15, sineio(), appear(:draw_text)))
act!(text_obj, Action(76:100, sineio(), disappear(:draw_text)))
draws the text from left to right in the first 15 frames and in the last 15 frames it disappears.
Arguments
str::AbstractString
the string that should be shownpos::Point
defaults to the origin and can be written asx,y
as well asPoint(x,y)
.
Keywords
valign::Symbol
defaults to:baseline
and takes(:top, :middle, :bottom, :baseline)
halign::Symbol
defaults to:left
and takes(:left, :center, :centre, :right)
angle::Float64
defaults to0.0
and specifies the angle of the text
Javis.val
— Methodval(x)
val
is just a short-hand for get_value
Javis.zero_lines
— Methodzero_lines(video::Video, object::AbstractObject, frame::Int; direction::AbstractString = "TR", line_thickness = 10)
Draws zero lines on the given frame of a Video.
Arguments
direction::AbstractString
: Direction for how vertical and horizontal axes are drawn.
Default: "TR"
Available Orientations:
"TR"
- Vertical axis drawn towards the Top and horizontal axis drawn to the Right of the frame."TL"
- Vertical axis drawn towards the Top and horizontal axis drawn to the Left of the frame."BR"
- Vertical axis drawn towards the Bottom and horizontal axis drawn to the Right of the frame."BL"
- Vertical axis drawn towards the Bottom and horizontal axis drawn to the Left of the frame.line_thickness
: Defines the thickness of the zero lines. Default:10
Example
This example will produce an animation with the vertical axis being drawn towards the top and the horizontal axis being drawn towards the left. One will need to define their own path for tempdirectory
and pathname
.
Object(1:100, :line, zero_lines(direction = "TL", line_thickness = 10)),
Luxor.pathtopoly
— Methodpathtopoly(::Val{:costate})
Method similar to Luxors pathtopoly()
. Converts the current path to an array of polygons and returns them. This function also returns an array of Bool (co_states::Array{Bool}
) of exactly the same length as number of polygons that are being returned . co_states[i]
is true/false
means polygonlist[i]
is a closed/open polygon respectively.
Another minor change from luxors pathtopoly()
is when a CAIROPATHMOVE_TO is encountered , a new poly is started.
Returns Tuple(Array{Point},Array{Bool})
Luxor.rotate
— Methodrotate()
Rotate an Object
or a Layer
using an Action
and an Animation defined with Animations.jl.
If you're used to working with Animations.jl this should feel quite natural. Instead of defining each movement in its own action it's possible to define it in one by using an Animation.
Example
using Javis, Animations
# define ground function here
video = Video(500, 500)
translate_anim = Animation(
[0, 1], # must go from 0 to 1
[O, Point(150, 0)],
[sineio()],
)
translate_back_anim = Animation(
[0, 1], # must go from 0 to 1
[O, Point(-150, 0)],
[sineio()],
)
rotate_anim = Animation(
[0, 1], # must go from 0 to 1
[0, 2π],
[linear()],
)
Background(1:150, ground)
ball = Object((args...) -> circle(O, 25, :fill))
act!(ball, Action(1:10, sineio(), scale()))
act!(ball, Action(11:50, translate_anim, translate()))
act!(ball, Action(51:100, rotate_anim, rotate_around(Point(-150, 0))))
act!(ball, Action(101:140, translate_back_anim, translate()))
act!(ball, Action(141:150, rev(sineio()), scale()))
render(video)
which uses the Action
syntax five times with both easing functions directly and animation objects. The rev(sineio())
creates an Animation
which goes from 1.0
to 0.0
.
Luxor.sethue
— Methodsethue()
Set the color of an Object
using an Action
and an Animation defined with Animations.jl.
Example
A possible animation would look like this:
color_anim = Animation(
[0, 0.5, 1], # must go from 0 to 1
[
Lab(colorant"red"),
Lab(colorant"cyan"),
Lab(colorant"black"),
],
[sineio(), sineio()],
)
An example on how to integrate this into an Action
can be seen in rotate
. Where this would be a valid Action: Action(1:150, color_anim, sethue())
.
Luxor.translate
— Methodtranslate()
Translate an Object
or a Layer
using an Action
and an Animation defined with Animations.jl.
If you're used to working with Animations.jl this should feel quite natural. Instead of defining each movement in its own action it's possible to define it in one by using an Animation.
Example
using Javis, Animations
function ground(args...)
background("black")
sethue("white")
end
video = Video(500, 500)
circle_anim = Animation(
[0.0, 0.3, 0.6, 1.0], # must go from 0 to 1
# the circle will move from the origin to `Point(150, 0)` then `Point(150, 150)`
# and back to the origin `O`.
[O, Point(150, 0), Point(150, 150), O],
[sineio(), polyin(5), expin(8)],
)
Background(1:150, ground)
obj = Object((args...)->circle(O, 25, :fill))
act!(obj, Action(1:150, circle_anim, translate()))
render(video)
Here circle_anim
defines the movement of the circle. The most important part is that the time in animations has to be from 0.0
to 1.0
.
This notation uses the Animations.jl library very explicitly. It's also possible to do the same with:
obj = Object((args...)->circle(O, 25, :fill))
act!(obj, Action(1:50, sineio(), anim_translate(150, 0)))
act!(obj, Action(51:100, polyin(2), anim_translate(0, 150)))
act!(obj, Action(101:150, expin(8), anim_translate(-150, -150)))
which uses the Action
syntax three times and only uses easing functions instead of specifying the Animation
directly. Have a look at anim_translate
for details.
Javis.@Frames
— Macro@Frames(start, len)
@Frames(start, stop=)
Can be used to define frames using functions like prev_start
or prev_end
Example
red_circ = Object(1:90, (args...)->circ("red"))
blue_circ = Object(@Frames(prev_start()+20, 70), (args...)->circ("blue"))
blue_circ = Object(@Frames(prev_start()+20, stop=90), (args...)->circ("blue"))
is the same as
red_circ = Object(1:90, (args...)->circ("red"))
blue_circ = Object(21:90, (args...)->circ("blue"))
blue_circ = Object(41:90, (args...)->circ("blue"))
Javis.@JLayer
— Macro@JLayer(frames, width, height, position, body)
Calls the to_layer_m
method to create a Layer
out of the arguments given.
Arguments
frames
:aUnitRange
that defines for which frames the layer is activewidth
: defines the width of the layerheight
: defines the height of the layerposition
: location of the center of the layer on the main canvastransparent
: Whether the layer should have a transparent background(:transparent or :opaque)body
- It contains all the objects(and thier respective actions) definitions for a layer
- A layer can have it's own separate background
- Anything defined within the
begin...end
block stays in the layer - A Layer has it's own coordinate reference sysstem, i.e. it has it's own origin
Point(100, 100)
is different when defined in a layer and doesn't represent the location 100, 100 on the main canvas
width
, height
, position
and transparent
are optional and default to the video's width, height, origin and :opaque respectively. Layer declaration should take place before pushing objects to it if one is not using the macro
Example
function ground(args...)
background("white")
sethue("black")
end
function object(p = O, color = "black")
sethue(color)
circle(p, 50, :fill)
end
video = Video(500, 500)
Background(1:100, ground)
l1 = @JLayer 10:70 100 100 Point(150, 150) begin
red_ball = Object(20:60, (args...)->object(O, "red"), Point(50,0))
act!(red_ball, Action(anim_rotate_around(2π, O)))
end
render(video; pathname="test.gif")
Javis.@JShape
— Macro@JShape(body, args...)
Macro that creates a user-defined shape based on Luxor
instructions within its begin...end
block
Example
Object(@JShape begin
sethue(color)
poly(points, action, close = true)
end action = :stroke color = "red" radius = 8)
In this example, the arguments after the end
(i.e. action = :stroke color = "red" radius = 8
) can be used inside the begin...end
block and animated using the change
action.
Private functions
Javis.CURRENT_FETCHPATH_STATE
— ConstantCURRENT_FETCHPATH_STATE::Bool
If true all drawing functions convert the current path to a JPath and append them to the CURRENT_JPATHS (does not work on text
).
Javis.CURRENT_JPATHS
— ConstantAn array to accumulate the JPATHs as the obj.func is being executed to get the objects jpaths
Javis.CURRENT_LAYER
— ConstantCURRENT_LAYER
holds the current layer in an array to be declared as a constant The current layer can be accessed using CURRENT_LAYER[1]
Javis.CURRENT_OBJECT
— ConstantCURRENT_OBJECT
holds the current object in an array to be declared as a constant The current object can be accessed using CURRENT_OBJECT[1]
Javis.CURRENT_VIDEO
— ConstantCURRENT_VIDEO
holds the current video in an array to be declared as a constant The current video can be accessed using CURRENT_VIDEO[1]
Javis.DISABLE_LUXOR_DRAW
— ConstantDISABLE_LUXOR_DRAW :: Ref{Bool}
If true disables any drawing to the canvas by luxor , irresepective of what luxor functions are called and what actions are passed to them (:stroke/:fill/:strokepath/:fillpath) .
Javis.PUSH_TO_LAYER
— ConstantPUSHTOLAYER
A setinel to aid the creation of layers. If set to true, all the objects are pushed to the current layer. Can be accessed using PUSHTOLAYER[1]
Animations.Animation
— MethodAnimation(timestamps,funcs,easings)
returns an Animation
from an array of MorphFunctions.
Javis.Frames
— TypeFrames
Stores the actual computed frames and the user input which can be :same
or RFrames(10)
. The frames
are computed in render
.
Javis.JPath
— TypeJPath
a polygon representation of a path, every Object will have a list of JPaths under the field jpaths. Object JPaths are calculated and updated using getjpaths!
, Every call to stroke/fill in the objects obj.func
typically adds a JPath to the objects jpaths. a JPath can be drawn using drawjpath(jpath). Usually if one were to draw out the object.jpath
it would result in the exact same picture/drawing as running object.func
. JPaths are typically used for morphing and drawing partially.
Every JPath has the following fields.
polys
a list of polygons that makes up the pathclosed
a list of bools of same length aspolys
. closed[i]
states if polys[i] is a closed polygon or not
fill
a vector of 4 numbers , R, G ,B and A the color it
should be filled with. if the path was not filled its A is set to 0 (along with R,G,B) this way its an "invisible" fill.
stroke a vector of 4 numbers just like
fill` for the stroke color.- linewidth for stroke
- polylengths , length of every poly in
polys
, usually computed at rendertime
after polys are populated
Javis.Layer
— TypeLayer
Defines a new layer within the video.
Fields
frames::Frames
: A range of frames for which theLayer
existswidth::Int
: Width of the layerheight::Int
: hegiht of the layerposition::Point
: initial positon of the center of the layer on the main canvaslayer_objects::Vector{AbstractObject}
: Objects defined under the layeractions::Vector{AbstractAction}
: a list of actions applied to the entire layercurrent_setting::LayerSetting
: The current state of the layer seeLayerSetting
opts::Dict{Symbol,Any}
: can hold any options defined by the userimage_matrix::Vector
: Hold the Drwaing of the layer as a Luxor image matrix
Javis.LayerCache
— TypeLayerCache()
Holds image matrices of layer frames in case show_layer_frame
is called.
Arguments
frames::UnitRange
:The frame range for which layer's frames are to be viewedframe_counter::Int
: internal counter to keep count of the layer's frame being placedlayer_frames::Union{UnitRange,Int}
: The frame/frames of the layer to be viewedposition::Array{Point}
: The position of the layer at each frame that is to be viewedsettings_cache::Array{LayerSetting}
: Tha layer settings of each frame of the layer to be viewedmatrix_cache::Array
: a list that holds the image matrices of the layer frames to be viewed
Javis.LayerSetting
— TypeLayerSetting
The current settings of an Layer
which are saved in layer.current_setting
.
Fields
opacity::Float64
: the current opacitycurrent_scale::Tuple{Float64, Float64}
: the current scalerotation_angle::Float64
: the angle of rotation of a layer.misc::Dict{Symbol, Any}
: any other misc metadata
Javis.ObjectSetting
— TypeObjectSetting
The current settings of an Object
which are saved in object.current_setting
.
Fields
line_width::Float64
: the current line widthmul_line_width::Float64
: the current multiplier for line width. The actual line width is then:mul_line_width * line_width
opacity::Float64
: the current opacitymul_opacity::Float64
: the current multiplier for opacity. The actual opacity is then:mul_opacity * opacity
fontsize::Float64
the current font sizeshow_object::Bool
is set to false if scale would be 0.0 which is forbidden by Cairocurrent_scale::Tuple{Float64, Float64}
: the current scaledesired_scale::Tuple{Float64, Float64}
: the new desired scalemul_scale::Float64
: the multiplier for the new desired scale. The actual new scale is then:mul_scale * desired_scale
Javis.ReversedEasing
— TypeReversedEasing
Will be used to reverse an easing inside easing_to_animation
. Can be constructed from an easing function using rev
.
Javis.StreamConfig
— TypeStreamConfig
Holds the conguration for livestream, defaults to nothing
#Fields
livestreamto::Symbol
Livestream platform:local
or:twitch
protocol::String
The streaming protocol to be used. Defaults to UDPaddress::String
The IP address for the:local
stream(ignored in case of:twitch
)port::Int
The port for the:local
stream(ignored in case of:twitch
)twitch_key::String
Twitch stream key for your account
Animations.linear_interpolate
— MethodAnimations.linear_interpolate(
fraction::Real,
jpaths1::Vector{JPath},
jpaths2::Vector{Jpath}
)
A method so that Animations.jl can interpolate between Arrays of JPaths.
Note that the array of jpaths should be of the same size.
Javis._apply_and_reshape
— Method_apply_and_reshape(func, im, template, args...)
Applies function func
to imagematrix im
. Afterwards reshapes the output cropping it or padding it to the size of template
. All the args
are passed to func after im
as arguments.
Javis._betweenpoly_noresample
— Function_betweenpoly_noresample(loop1,loop2,k; easingfunction = easingflat)
Just like _betweenpoly from Luxor , but expects polygons loop1
and loop2
to be of same size , and therefore does not resample them to be of same size.
From Luxor Docs: Find a simple polygon between the two simple polygons loop1 and loop2 corresponding to k, where 0.0 < k < 1.0.
Arguments loop1: first polygon loop2: second polygon k: interpolation factor offset: a Tuple , first element is :former
or :latter
, second element is an Int. decides if loop1/loop2 is offset and by how much for matching points from loop1 to loop2 note that its not strictly an offset , it ranges from 1->N (no of points) and an offset of 1 means no offset , offset of 2 means offset by 1 and so on .. TODO change this name to startidx
Javis._convert_and_rescale_if_needed
— Method_rescale_if_needed(frame_image, rescale_factor)
Converts frame_image
values to RGB and if rescale_factor
in render
is different from 1.0 rescales the images matrix for faster rendering.
Javis._decrement
— Method_decrement(video::Video, widgets::Vector, objects::Vector, dims::Vector,
canvas::Gtk.Canvas, frames::Int, layers::Vector)
Decrements a given value and returns the associated frame.
Javis._draw_image
— Method_draw_image(video::Video, objects::Vector, frame::Int, canvas::Gtk.Canvas,
img_dims::Vector)
Internal function to create an image that is drawn on a Gtk Canvas.
Javis._drawpartial
— Method_drawpartial(video, action, object, rel_frame, fraction::Real)
Internal function that is used with showcreation
showdestruction
drawpartial
. makes an array of JPaths
called partialjpaths
that represents a partial drawing of the object. Then it replaces the object.func
with drawjpaths(partialjpaths)
Javis._get_range
— Method_get_range(sizemargin, sizefrom)
For even sizemargin
returns a range with values from sizemargin ÷ 2 + 1
to sizefrom - sizemargin ÷ 2
. For odd sizemargin
the left range value is increased by one.
Javis._increment
— Method_increment(video::Video, widgets::Vector, objects::Vector, dims::Vector,
canvas::Gtk.Canvas, frames::Int, layers=Vector)
Increments a given value and returns the associated frame.
Javis._javis_viewer
— Function _javis_viewer(video::Video, frames::Int, object_list::Vector, show::Bool)
Internal Javis Viewer built on Gtk that is called for live previewing.
Javis._livestream
— Method_livestream(streamconfig, framerate, width, height, pathname)
Internal method for livestreaming
Javis._morph_jpath
— Method_morph_jpath(jpath1::JPath, jpath2::JPath, k)
Returns an interpolated jpath between jpath1 and jpath2 with interpolation factor 0<k
<1.
Javis._morph_to
— Function_morph_to(video::Video, object::Object, action::Action, frame, to_func::Function, args::Array, samples=100)
Internal version of morph_to
but described there.
Javis._morph_to
— Method_morph_to(video::Video, object::Object, action::Action, frame, to_func::Function; do_action=:stroke)
Internal version of morph_to
but described there. older morph.
Javis._morph_to
— Method_morph_to( video::Video, object::Object, action::Action, frame, to_obj::Object, samples,)
Internal function used to morph one object
to another.
Javis._postprocess
— Method_postprocess(args...;kwargs...)
This function is used to perform the postprocessing inside the render function. It does mainly two things:
- Adds a memoization with checks for the frames to render. The keyword argument
framesmemory, stores those imagematrices associated to frames that will reappear later in the frames processing, so that when those will have to be rendered they can be taken from here instead, whereas those that do not reappear are discarded. (the check is performed after each frame on those predent in the framesmemory)
- Applies
postprocess_frame
as provided torender
on each frame.
Javis.add_points!
— Methodadd_points!(poly, missing_nodes)
Add #missing_nodes
to poly.
Javis.animate_text
— Methodanimate_text(
str,
pos::Point,
valign::Symbol,
halign::Symbol,
angle::Float64,
t::Float64,
)
This function is used as a subfunction of text
and animates the str
by clipping the textoutlines and creating a growing circle in the lower left corner to display the text from left to right in an animated fashion.
Javis.apply_layer_settings
— Methodapply_layer_settings(layer_settings, pos)
Applies the computed actions to the image matrix of the layer to it's image matrix Actions supported:
anim_translate
:translates the entire layer to a specified positionsetopacity
:changes the opacity of the entire layeranim_rotate
:rotates the layer by a given angleappear(:fade)
:fades in the layerdisappear(:fade)
:fades out the layer
It reads and applies the layer settings(computed by get_layer_frame
function))
Javis.apply_transform
— Methodapply_transform(transform::Vector{Float64} , poly::Vector{Point})
applies the transform , got by getmatrix() on every point in the poly and returns a new poly.
move this to luxoroverridesutil.jl later.
Javis.centered_point
— Methodcentered_point(pos::Point, width::Int, height::Int)
Returns pre-centered points to be used in the place image functions rather than using centered=true https://github.com/JuliaGraphics/Luxor.jl/issues/155
Returns
pt::Point
: the location of the center of a layer wrt global canvas
Javis.compute_frames!
— Methodcompute_frames!(elements::Vector{UA}; parent=nothing)
where UA<:Union{AbstractObject,AbstractAction}
Set elem.frames.frames to the computed frames for each elem in elements.
Javis.compute_shortest_morphing_dist
— Methodcompute_shortest_morphing_dist(from_poly::Vector{Point}, to_poly::Vector{Point})
Rotates from_poly
internally to check which mapping produces the smallest morphing distance. It returns the start index of the rotation of from_poly
as well as the smallest distance.
Javis.crop
— Methodcrop(im, heightto, widthto)
Crops an imagematrix to size (heightto, widthto)
around the center of the image.
Javis.default_postprocess
— Methoddefault_postprocess(frame_image, frame, frames)
Returns its first argument. Used as effectless default for keywords argument postprocess_frame
in render function.
Javis.draw_obj
— Methoddraw_obj(::Val{:g}, o, defs)
Draws a group by setting the attributes (like transformations) and then calls draw_obj
for all child elements.
Javis.draw_obj
— Methoddraw_obj(::Val{:path}, o, defs)
Calls the commands specified in the path data. Currently supports only a subset of possible SVG commands.
Javis.draw_obj
— Methoddraw_obj(::Val{:rect}, o, defs)
Draw the rectangle defined by the object o
.
Javis.draw_obj
— Methoddraw_obj(::Val{:use}, o, defs)
Calls the command specified in defs
.
Javis.draw_object
— Methoddraw_object(video, layer, frame, origin_matrix, layer_frames)
Is called inside the render
and does everything handled for an AbstractObject
. It is a 4-step process:
- translate to the start position
- call the relevant actions
- call the object function
- save the result of the object if wanted inside
video.defs
Javis.drawjpaths
— Methoddrawjpaths(jpaths::Array{JPath})
draws out the jpaths onto the current canvas
Javis.drawobj_jpaths
— Methoddrawobj_jpaths(obj::Object)
Draws JPaths of the object. (not typically used.)
Javis.easing_to_animation
— Methodeasing_to_animation(easing)
Converts an easing to an Animation with time goes from 0.0
to 1.0
and value from 0
to 1
.
Javis.easing_to_animation
— Methodeasing_to_animation(rev_easing::ReversedEasing)
Converts an easing to an Animation with time goes from 0.0
to 1.0
and value from 1
to 0
.
Javis.empty_CURRENT_constants
— Methodempty_CURRENT_constants()
empty all CURRENT_
constants like CURRENT_OBJECT
Javis.flatten
— Methodflatten(layers::Vector{AbstractObject})
Takes out all the objects from each layer and puts them into a single list. This makes things easier for the preprocess_frames!
method
Returns
objects::Vector{AbstractObject}
- list of all objects in each layer
Javis.float_attribute
— Methodfloat_attribute(o, name)
Get the attribute name
of the XMLElement and parse it as a Float64
Javis.get_current_setting
— Methodget_current_setting()
Return the current setting of the current object
Javis.get_frames
— Methodfunction get_frames(parent, elem, func_frames::Function, last_frames::UnitRange; is_first = false)
Return the frames based on a specified function. The function func_frames
is simply evaluated
Javis.get_frames
— Methodget_frames(parent, elem, glob::GFrames, last_frames::UnitRange)
Return the frames based on a global frames GFrames
object and the last_frames
. If is_action
is false this is the same as defining the frames as just a unit range. Inside an action it's now defined globally though.
Javis.get_frames
— Methodget_frames(parent, elem, relative::RFrames, last_frames::UnitRange; is_first=false)
Return the frames based on a relative frames RFrames
object and the last_frames
.
Javis.get_frames
— Methodget_frames(parent, elem, frames::Symbol, last_frames::UnitRange; is_first=false)
Get the frames based on a symbol defined in FRAMES_SYMBOL
and the last_frames
. Throw ArgumentError
if symbol is unknown
Javis.get_frames
— Methodget_frames(elem)
Return elem.frames.frames
which holds the computed frames for the AbstractObject or AbstractAction a
.
Javis.get_interpolation
— Methodget_interpolation(action::AbstractAction, frame)
Return the value of the action.anim
Animation based on the relative frame given by get_interpolation(get_frames(action), frame)
Javis.get_interpolation
— Methodget_interpolation(frames::UnitRange, frame)
Return a value between 0 and 1 which represents the relative frame
inside frames
.
Javis.get_javis_frame
— Methodget_javis_frame(video, objects, frame; layers = Layer[])
Is called inside the render
function. It is a 5-step process:
- for each layer fetch it's image matrix and store it into the layer's struct
- if the
show_layer_frame
method is defined for a layer, save the
position, image matrix and layer settings for that frame of the layer in a LayerCache
- place the layers on an empty drawing
- creates the main canvas and renders the independent objects
- places the drawing containing all the layers on the main drawing
Returens the final rendered frame
Javis.get_layer_frame
— Methodget_layer_frame(video, layer, frame)
Is called inside get_javis_frame
and does two things viz. - Creates a Luxor Drawing and renders the object of each layer - computes the actions applies on the layer and stores them
Returns the Drawing of the layer as an image matrix.
Javis.get_offsets
— Methodget_offsets(jpath1,jpath2)
returns an Array of Tuples , each Tuple is of the form (s::Symbol,offsetvalue::Int)
while interpolating polys inside the jpath. Javis tries to find a good offsetvalue if poly1 is being morphed into poly2 poly1[i]
goes to poly2[i + offsetvalue -1]
(modulo length(poly2) addition).
s
is either :former
or :latter
indicating if the offset should be applied on poly1 or poly2
morphing from closed to closed offsets the former. morphing from closed to open poly offsets the former. morphing from open to closed poly offsets the latter. morphing from open to open poly does no offsetting.
offset
of 1 means no offset . It should technically be called best starting indes.
Javis.getjpaths
— Functiongetjpaths(func::Function, args = [])
getjpaths runs the function func
. func
is usually a function with some calls to luxor functions inside to draw something onto a canvas. Although getjpaths
does call func
it does not draw on the canvas. getjpaths will return an array of JPaths that represent what would be drawn by the func
. Also see getjpath!(object,func)
Javis.getjpaths!
— Functiongetjpaths!(video::Video,obj::Object,frame::Int, func::Function , args=[])
This is called at rendertime . getjpaths!
updates obj.jpaths
with jpaths that are generated by drawing func
. Typically func
is obj.opts[:original_func]
Javis.getpartialjpaths
— Methodgetpartialjpaths(object,fraction)
returns an array of jpaths , that if drawn will look like partially drawn object
partially drawn upto fraction
Javis.interpolateable
— Methodinterpolateable(x::AbstractVector)
Return the vector in a datatype that is interpolateable. Currently only implemented is to change from <:Integer
to float
Javis.interpolation_to_transition_val
— Methodinterpolation_to_transition_val(interpolation_val, Transition)
Returns the transition value for the given interpolation_val
. If the interpolation value is already of the correct form it just gets returned. Otherwise the Transition function like get_position
is called and the interpolated value is calculated.
Javis.jpath_polylengths!
— Methodjpath_polylengths!(jpath::JPath)
updates the polylengths field in jpath with the lengths of the polys
Javis.len_jpath
— Methodlen_jpath(jpath::JPaht)
returns the sum of all the lengths of the polys that this jpath
contains
Javis.match_num_points
— Methodmatch_num_points(poly_1::Vector{Point}, poly_2::Vector{Point})
This is a helper function for morph_to
. Given two polygons poly_1
and poly_2
points are added to the polygon with less points until both polygons have the same number of points. The polygon with less points gets mutated during this process.
Arguments
poly_1::Vector{Point}
: The points which define the first polygonpoly_2::Vector{Point}
: The points which define the second polygon
Javis.morph_between
— Methodmorph_between(video::Video, action::Action, frame,
from_polys::Vector{Vector{Point}}, to_polys::Vector{Vector{Point}};
do_action=:stroke)
Internal version of morph_to
after the from poly is defined.
Javis.null_jpath
— Functiona very small jpath to appear from/disappear into has 1 poly of samples
points in the shape of an ngon black fill 0 alpha, black stroke opaque linewidth 2
Javis.path_move
— Methodpath_move(x,y)
Moving to the specified point
Javis.path_quadratic
— Methodpath_quadratic(c_pt::Point, x,y, xe, ye)
Drawing a quadratic bezier curve by computing a cubic one as that is supported by Luxor
Javis.pathsvg
— Methodpathsvg(svg)
Convert an svg to a path using Luxor. Normally called via the latex
command. It handles only a subset of the full power of svg.
Javis.place_layers
— Methodplace_layers(video, layers, frame)
Places the layers on an empty drawing It does 4 things:
- creates an empty Drawing of the same size as video
- calls the
apply_layer_settings
- places every layer's image matrix on the drawing
- Repeats the above two steps if the
show_layer_frame
is defined for that layer(and frame) But fetches image matrix, position and settings from the layer cache
Returns the Drawing containing all the layers as an image matrix.
Javis.polymorph_noresample
— Method polymorph_noresample(
pgon1::Array{Array{Point,1}},
pgon2::Array{Array{Point,1}},
k;
offsets::Array{Tuple{Symbol,Int}};
easingfunction = easingflat,
kludge = true,
)
like luxors polymorph
, but does not resample the polygon , therefore every polygon in pgon1
and pgon2
should have the same number of points. used by _morph_jpath
.
Also takes in an additional argument an array of offset
. Check _between_poly
for more detail on offset
From Luxor Docs:
"morph" is to gradually change from one thing to another. This function changes one polygon into another.
It returns an array of polygons, [p1, p2, p3, ... ], where each polygon pn is the intermediate shape between the corresponding shape in pgon1[1...n] and pgon2[1...n] at k, where 0.0 < k < 1.0. If k ≈ 0.0, the pgon1[1...n] is returned, and if `k ≈ 1.0, pgon2[1...n] is returned.
pgon1 and pgon2 can be either simple polygons or arrays of one or more polygonal shapes (eg as created by pathtopoly()). For example, pgon1 might consist of two polygonal shapes, a square and a triangular shaped hole inside; pgon2 might be a triangular shape with a square hole.
It makes sense for both arguments to have the same number of polygonal shapes. If one has more than another, some shapes would be lost when it morphs. But the suggestively-named kludge keyword argument, when set to (the default) true, tries to compensate for this.
By default, easingfunction = easingflat, so the intermediate steps are linear. If you use another easing function, intermediate steps are determined by the value of the easing function at k.
Javis.preprocess_frames!
— Methodpreprocess_frames!(objects::Vector{<:AbstractObject})
Computes the frames for each object(of both the main canvas and layers) and action based on the user defined frames that the user can provide like RFrames
, GFrames
and :same
.
This function needs to be called before calling get_javis_frame
as it computes the actual frames for objects and actions.
Returns
frames::Array{Int}
- list of all frames normally 1:...
Warning
Shows a warning if some frames don't have a background.
Javis.preprocess_frames!
— Methodpreprocess_frames!(video::Video)
Javis.remove_from_video
— Methodremove_from_video(object::Object)
Removes an object or a list of objects from the main video. This is a helper method for the to_layer!
method and is supposed to be used internally
Javis.render_objects
— Methodrender_objects(objects, video, frame; layer_frames=nothing)
Is called inside the get_javis_frame
function and renders objects(both individual and ones belonging to a layer).
Arguments
object::Object
: The object to be renderedvideo::Video
: The video which defines the dimensions of the outputframe::Int
: The frame number to be renderedlayer_frames::UnitRange
: The frames of the layer to which the object belongs(nothing
for independent objects)
Javis.reorder_match
— Methodreorder_match(from_shapes::Vector{Shape}, to_shapes::Vector{Shape})
Computes the similiarty of the shapes and finds the best mapping such that the sum of similiarty is maximized.
Additionally it creates empty shapes when needed such that reordered_from
and reordered_to
contain the same number of shapes.
Returns
reordered_from::Vector{Shape}
reordered_to::Vector{Shape}
Javis.save_morph_polygons!
— Methodsave_morph_polygons!(action::Action, from_func::Vector{Vector{Point}},
to_func::Vector{Vector{Point}})
Calls the functions to polygons and calls match_num_points
such that both polygons have the same number of points. This is done once inside _morph_to
. Saves the two polygons inside action.defs[:from_poly]
and action.defs[:to_poly]
.
Assumption: Both functions create the same number of polygons.
Javis.set_attr
— Methodset_attr(::Val{:transform}, transform_strs)
Call the corresponding set_transform
method i.e matrix
, scale
and translate
Javis.set_attrs
— Methodset_attrs(o)
Setting the attributes of the object o
by calling set_attr
methods.
Javis.set_current_action
— Methodset_current_action(action::Action)
Set the action
as CURRENT_ACTION
and update PREVIOUS_OBJECT
/PREVIOUS_ACTION
Javis.set_current_action_type
— Methodset_current_action_type(t)
Set CURRENT_OBJECT_ACTION_TYPE
to :Object
or :Action
depending on the type of t
.
Javis.set_current_object
— Methodset_current_object(object::Object)
Set the object
as CURRENT_OBJECT
and update PREVIOUS_OBJECT
/PREVIOUS_ACTION
Javis.set_frames!
— Methodset_frames!(parent, elem, last_frames::UnitRange; is_first=false)
Compute the frames based on a.frames and last_frames
. Save the result in a.frames.frames
which can be accessed via get_frames
.
Arguments
parent
is either nothing or the Object for the Actionelem
is the Object or Actionlast_frames
holds the frames of the previous object or action.is_first
defines whether this is the first child of the parent (for actions)
Javis.set_object_defaults!
— Methodset_object_defaults!(object)
Set the default object values
- line_width and calls
Luxor.setline
. - opacity and calls
Luxor.opacity
. - scale and calls
Luxor.scale
.
Javis.set_previous_action
— Methodset_previous_action(action::Action)
Set the action
as PREVIOUS_ACTION
Javis.set_previous_object
— Methodset_previous_object(object::Object)
Set the object
as PREVIOUS_OBJECT
Javis.set_transform
— Methodset_transform(::Val{:matrix}, args...)
Multiply the new matrix with the current matrix and set it.
Javis.show_layer_frame
— Methodshow_layer_frame(frames::UnitRange, layer_frame::Union{UnitRange,Int}, layer::Layer)
Repeat a layer's frame/frames for a given frame range.
Arguments
frames::UnitRange
: The frame range for which the layer should be repeatedlayer_frame::Union{UnitRange,Int}
: The layer frame range to repeatlayer::Layer
:the layer to be repeated
Javis.strip_eq
— Methodstrip_eq(text::LaTeXString)
Strips $$
from text.s
if present and returns the resulting string.
Arguments
text::LaTeXString
: a LaTeX string
Javis.svgwh
— Methodsvgwh(svg)
Return the width and height of svg displayed scaled to half the font size.
Javis.to_layer!
— Methodto_layer!(l::Layer, object::Object)
Pushes an object into the layer and out of the list of independent objects. This method is helpful in case one doesn't want to include an object in the begin...end
block of @JLayer
.
Javis.to_layer!
— Methodto_layer!(l::Layer, objects::Vector{Object})
Pushes a list of objects into the layer, This method is helpful in case one doesn't want to include an object in the begin...end
block of @JLayer
.
Javis.to_layer_m
— Methodto_layer_m( frames, body; width, height, position)
Helper method for the @JLayer
macro Returns an expression that creates a layer and pushes the objects defined withing the body to the layer :transparent is the default while the other :opaque copies the video's background
Javis.try_merge_polygons
— Methodtry_merge_polygons(polys)
Try to merge polygons together to match the number of polygons that get morphed. The only example I encountered is that the [
of a 3xY matrix consists of 3 parts which are merged together.
Javis.update_ObjectSetting!
— Methodupdate_ObjectSetting!(as::ObjectSetting, by::ObjectSetting)
Set the fields of as
to the same as by
. Basically copying them over.
Javis.update_currentjpath
— Methodupdate_currentjpath(action::Symbol)
Updates the CURRENTJPATHS This function is used inside the strokepath/strokepreserve/fillpath/fillpreserve. Converts the current Path and other drawing states into a JPath and appends to the CURRENTJPATHS global.
the argument is a symbol either :stroke
or :fill
, to change behaviour for stroke vs fill.
Javis.update_previous_object_or_action
— Methodupdate_previous_object_or_action()
Update the PREVIOUS_OBJECT
or PREVIOUS_ACTION
depending on whether the last element was an object or an action. This is still saved in CURRENT_OBJECT_ACTION_TYPE
.