Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

combine actions in a layer #75

Closed
Wikunia opened this issue Aug 12, 2020 · 11 comments · Fixed by #343
Closed

combine actions in a layer #75

Wikunia opened this issue Aug 12, 2020 · 11 comments · Fixed by #343
Assignees
Labels
enhancement New feature or request question Further information is requested
Milestone

Comments

@Wikunia
Copy link
Member

Wikunia commented Aug 12, 2020

I'm not sure whether this should be it's own issue it's somehow related to #64

Let's assume I draw this brain and then I want to rotate the brain. How can I do this?
This seems to be a big probably which is currently in my head.

A different example might make this clearer;
I want to draw a graph with nodes and edges and animate some stuff and then I want to scale it down and move it to a corner of the animation just to still show it and draw something else.
We somehow need to be able to combine actions into a layer than can be accessed later. I neither know a good interface for it nor how to implement it so this is just one idea:

Action(1:100, draw_node(1); subactions=[SubAction(1:20, appear(:fade)], layer=:graph)
Action(1:100, draw_node(2); subactions=[SubAction(1:20, appear(:fade)], layer=:graph)
Action(101:200, layer(:graph), Translate(200, 0)

And it would pick the latest version of that layer then which I think makes sense. Any other ideas just for the user interface @TheCedarPrince ?

@Wikunia Wikunia added enhancement New feature or request question Further information is requested labels Aug 12, 2020
@TheCedarPrince TheCedarPrince added this to the v0.2.0 milestone Aug 13, 2020
@TheCedarPrince
Copy link
Member

I was actually thinking something similar - especially in regards to scaling. As of right now, I put this under milestone v0.2.0 as I think this would take a bit of time to implement. I like the syntax you described. Here are some options that I can think of:

Example 1

graph = Layer([Action(1:100, draw_node(1); subactions=[SubAction(1:20, appear(:fade)], layer=:graph),
                        Action(1:100, draw_node(2); subactions=[SubAction(1:20, appear(:fade)], layer=:graph)])

javis(video, [
                    graph,
                    Action(101:200, graph, Translate(200, 0))
                    ])

With this idea, I could see defining a layer becoming very confusing within the general javis function. Therefore, perhaps a better user interface might be to create a Layer object that one could create outside the javis function wherever they want. This might enable a cleaner solution as one could easily read what all is happening in the Layer object. Inside javis, the Layer object would be seen and know it would be a set of Actions to be executed. This is not dissimilar to the SubAction that you implemented earlier. Could maybe make Layer be a subtype of AbstractAction perhaps?

Example 2

This takes place inside a Javis function

Collection(1:100, :graph)
Collection(:same, :graph, draw_node(1); subactions=[SubAction(1:20, appear(:fade)])
Collection(:same, :graph, draw_node(2); subactions=[SubAction(1:20, appear(:fade)])
CollectionAction(Rel(100), :graph, Translate(200, 0)

This is similar to your original idea that you had but rather than calling this system a "layer", I think the better syntax might be "Collection". The reason why I suggest this is that a layer to me suggests everything on that current frame. However, a collection refers to a subset of what is present in a frame. A Collection could be a subtype of AbstractAction which could "know" to identify specific actions as part of a subset of the present frame.

Example 3

graph = Collection([Action(1:100, draw_node(1); subactions=[SubAction(1:20, appear(:fade)], collection=:graph),
                        Action(1:100, draw_node(2); subactions=[SubAction(1:20, appear(:fade)], collection=:graph)])

javis(video, [
                    graph,
                    CollectionAction(Rel(100), graph, Translate(200, 0))
                    ])

I think this is my favorite syntax idea as it captures concepts from both prior examples. Here, again, I posit that the syntax should be Collection instead of Layer as Collection can refer to all objects in a given frame or some of the objects in a given frame. The collection kwarg also reflects this idea by saying that this is a collection of objects from the current frame. I think the CollectionAction can also provide additional utility as it allows special actions to be taken upon Collections.

Conclusion

These are just some thoughts, but let me know what you think. @Wikunia

@Wikunia
Copy link
Member Author

Wikunia commented Aug 13, 2020

Thanks for your thoughts! Some more 😉

I'm not sure I understand your confusion (okay I'm confused by your comment 😄 ) on Layer vs Collection.
In Photoshop as an example you have several layers for one "frame" (the image). And currently we have a Luxor @layer for each action.
I would like to add that in my way you can define it outside or inside javis i.e:

Action(1:100, draw_node(1); subactions=[SubAction(1:20, appear(:fade)], layer=:graph)
Action(1:100, draw_node(2); subactions=[SubAction(1:20, appear(:fade)], layer=:graph)
Action(101:200, layer(:graph), Translate(200, 0))

can be written as

graph = [Action(1:100, draw_node(1); subactions=[SubAction(1:20, appear(:fade)], layer=:graph),
              Action(1:100, draw_node(2); subactions=[SubAction(1:20, appear(:fade)], layer=:graph)]

inside javis:

graph...,
Action(101:200, layer(:graph), Translate(200, 0)

I was thinking about something like example 2 as well but I don't like the many symbols we already support in the first 2 positions.

About Example 1 and 3. We don't need the extra kwarg there, do we?

@TheCedarPrince TheCedarPrince removed this from the v0.2.0 milestone Aug 30, 2020
@Wikunia Wikunia added this to the v0.2.x milestone Sep 12, 2020
@Wikunia Wikunia self-assigned this Sep 28, 2020
@Wikunia
Copy link
Member Author

Wikunia commented Sep 30, 2020

A new idea:

video = Video(500, 500)
layer = Layer()
draw_circle = Action(1:10, (args...) -> circle())
appear_sub = SubAction(1:5, appear(:fade))
draw_circle += appear_sub
layer += draw_circle
render(video)

maybe it makes sense in general to only have some very small things in v0.2.x and release v0.3 with these breaking changes quite quickly without having a lot of v0.2.x changes. What do you think @TheCedarPrince

@TheCedarPrince
Copy link
Member

Hey @Wikunia , thanks for adding more thoughts.

So, after thinking about this syntax for a bit, I feel like some of it is obfuscating while other parts of it I very much like.

Parts I Think We Should Definitely Implement

  1. I really like the idea of how you defined Layer() similar to creating a Video object. And I really appreciated the syntax of layer += draw_circle. I think that makes sense for Layer syntax. Could you also stack layers on top of each other? Such that one Layer becomes an object in another Layer? The reason I ask for the conversion of a Layer into a generic object inside of another Layer is so that we could perform transformations on the "child" Layer hosted inside of the "parent" Layer. I'd love to have syntax like this:
layer1 = Layer()
layer2 = Layer()
...
layer_action = Action(1:10, layer1)
layer_action += SubAction(1:5, scale(1, 0.1))
layer2 += layer_action

Essentially, I am trying to figure out the best way to also handle the syntax of combining multiple layers together and mutating an entire layer at once.

  1. I think the idea of creating assignment for individual Action and SubAction objects is a great idea. I think to an extent we have already been doing this by storing lists of Action objects into a single variable (like Tutorial 6). I frankly could see the generic syntax of ideas like draw_circle = Action(1:10, (args...) -> circle()) and appear_sub = SubAction(1:5, appear(:fade)) being the foundation of solving the convenience function idea (Convenience Object Position Functions #130). I feel like we could build upon this generic syntax pretty easily for future functionality.

  2. How are you thinking about implementing a Layer object currently?

Parts I Think Could Be Problematic

  1. Building off of 2. in the first section, one issue that I see being problematic is how to handle function returns for Action objects such as draw_circle. With the above syntax, it is not clear to me how to reimplement Tutorial 1 using this syntax for example as I do not see how we could make id syntax work while also being confusing. If we stick with id syntax, I could see easily getting confused with having an Action stored into a variable, and having another id name represent the return of the function in the Action that was assigned to a variable. It feels like it could get messy very fast.

  2. Could we clear a Layer object? The reason I ask this is that I would like to be able to render more than one video per Julia script. The rationale for this is if someone wants to batch the creation of animations for various phenomena, I would not want to have them run the script, tweak variables, rerun the script ad nauseam.

Parts I Am Confused About

  1. What happened to the javis function? I miss the javis function! It's like our slogan. 😂

  2. Regarding render, I don't understand why we can't pass a layer directly to the function. I am not sure if I like this syntax very much if it is to replace the javis function as I do not like not having direct control about what goes into the render function.

  3. Was the lack of a BackgroundAction intentional or not considered for this example?

Conclusion

These were just some of my working thoughts on the proposed syntax. I really like the direction you are going with this! Especially the += operator syntax I think can be very powerful. Was that coined by @xiaodaigh in #179?

@xiaodaigh
Copy link

+= operator syntax

As mentioned elsewhere R's ggplot 2 uses + to compose layers. Seems like a good an intuitive way

@Wikunia
Copy link
Member Author

Wikunia commented Oct 1, 2020

Regarding the id problem: I would remove the symbol variant then and one can write:

red_ball = Action(1:10, (args...)->draw_circle("red"))
blue_ball =  Action(1:10, (args...)->draw_circle("blue"))
blue_ball += SubAction(1:10, Rotation(0, 2*pi, red_ball)

I'm not a fan of using layer_action = Action(1:10, layer1) why not layer1 += ?

If you want several videos in one julia script you just need to define a new Video this has nothing to do with Layers.

I forgot the BackgroundAction but also thinking that we might want to have a default one.

@Wikunia Wikunia modified the milestones: v0.2.x, v0.3.0 Oct 17, 2020
@Wikunia
Copy link
Member Author

Wikunia commented Oct 17, 2020

Just a small update. We decided against using + as we mutate the object which is normally not done with +.
For adding an action to an object we use act! now. We need something similar for adding an object to a layer.

@TheCedarPrince
Copy link
Member

The full discussion is freely viewable here if you want to check it out @xiaodaigh : https://julialang.zulipchat.com/#narrow/stream/253420-javis/topic/Taking.20Object.20Addition.20Seriously/near/213057763

Thanks for your thoughts as they were super valuable!

@xiaodaigh
Copy link

  • shouldn't mutate but crest a bew object with stuff added

@Wikunia
Copy link
Member Author

Wikunia commented Oct 18, 2020

If we create a ball in real life and move it we don't create a new one but instead move the old one.
Therefore the object should be mutated.

@xiaodaigh
Copy link

Good point

@TheCedarPrince TheCedarPrince modified the milestones: v0.3.0, v0.3.x Oct 26, 2020
@TheCedarPrince TheCedarPrince added error-handling Everything related to error and warnings thrown at the user and removed error-handling Everything related to error and warnings thrown at the user labels Oct 26, 2020
@TheCedarPrince TheCedarPrince modified the milestones: v0.3.x, v0.3.z Oct 26, 2020
This was referenced Jun 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants