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

Discussion: Syntax for SubAction #179

Closed
xiaodaigh opened this issue Sep 17, 2020 · 22 comments · Fixed by #226
Closed

Discussion: Syntax for SubAction #179

xiaodaigh opened this issue Sep 17, 2020 · 22 comments · Fixed by #226
Labels
Breaking This issue will break things enhancement New feature or request question Further information is requested
Milestone

Comments

@xiaodaigh
Copy link

I find the current syntax for subaction non-composable. I think of subactions as just actions on an object.

Describe the solution you'd like
So, we can we define subaction using the + e.g.

Action(....) + Action(....) so I am constantly doing more things to the object but I am just adding actions. Also, now actions are more composable, say if I wanna do the same subaction to two different objects I can just do [Action(...), Action(...)] .+ Action(....)

Describe alternatives you've considered*
Hmm. None.

Additional context
Libraries in R like ggplot2 adopts this addition syntax to modify a plot. So I think it makes for Javis.jl too.

@xiaodaigh xiaodaigh added the enhancement New feature or request label Sep 17, 2020
@Wikunia
Copy link
Member

Wikunia commented Sep 17, 2020

Thanks for trying out Javis!

I'm quite confused to be honest 😄
A SubAction is quite different to an Action. It basically defines the animated properties of the parental action.

The Action syntax doesn't allow to let an object appear it change color as an example. This can be only done using a SubAction. Examples can be found in tutorial no. 4

That being said I kind of like your idea of applying the same SubAction to two actions. It might be possible to have this in the syntax described in #100

I would additionally like to have a way to change the frame range then I think.

If you don't mind: can you send me some of your Javis code that you tried such that I can see the problem more clearly and might offer a way how I would express this in Javis?

@xiaodaigh
Copy link
Author

The Action syntax doesn't allow to let an object appear it change color as an example. This can be only done using a SubAction.

That's something I don't understand. Why is there such a distinction between the two? To me they are both just actions that can be applied to an object.

@Wikunia
Copy link
Member

Wikunia commented Sep 17, 2020

An Action creates the object and has very simple possibilities like Translation and Rotation but for complicated stuff SubAction is needed. One might rename Action to Object and SubAction to Action if that makes more sense.
Then one might want to remove those convenience functions like Translation and the action on the object needs to be defined inside what we currently call SubAction.

@xiaodaigh
Copy link
Author

One might rename Action to Object and SubAction to Action

That would make much more sense! And that is my mental model anyway. Strip away any "action" from Action and let subaction control all the movements colors etc with + syntax!

@Wikunia
Copy link
Member

Wikunia commented Sep 17, 2020

I'll leave this open such we don't loose track of it. I don't think we can do this in the next release. Unfortunately it's quite a breaking change. We should implement this quite soon as long as Javis is not used by many people.
Maybe it's possible to make this with a deprecation warning such that we can support both ways at the same time for one version and release v0.3.0 with this.

Another positive point is that this would make the code of Javis more readable and less complicated.
What do you think @TheCedarPrince ?

@Wikunia Wikunia reopened this Sep 17, 2020
@Wikunia Wikunia added the Breaking This issue will break things label Sep 17, 2020
@TheCedarPrince
Copy link
Member

Thanks for sharing your thoughts with us @xiaodaigh ! Appreciated as always. 😄

Yea I agree with you @Wikunia that this sort of change would certainly be breaking. Perhaps this could be in the v0.3.0 release or even in v0.4.0 as I think we already have a lot on the horizon for v0.3.0.

Furthermore, I do like the suggestion of changing Action syntax to Object syntax and having SubAction become Action as it frankly just makes more sense to me as a user and developer. As you said earlier,

It basically defines the animated properties of the parental action.

Could instead be said of the new Action syntax modifying an Object.

Perhaps tying this to issue #100, here are some ideas about syntax:

Idea 1

video = Video(600, 600)

@Background(1:60, ground)
@Object(id, func(my_args)) # If there is only one background, inherit frame range
@Object(1:10, func(id))

javis(video; pathname="test.gif")

Idea 2

video = Video(600, 600)

b = @Background(1:60, ground)
@Object(b.frames, id, func(my_args))
@Object(1:10, func(id))

javis(video; pathname="test.gif")

Idea 3

video = Video(600, 600)

@Background(1:180, ground)
a = @Object(1:180, id, draw_grid)
@Action(1:60, a, appear(:lr, :tb)) 

javis(video; pathname="test.gif")

Idea 4

video = Video(600, 600)

@Background(1:180, ground)
a = @Object(1:180, id, draw_grid)
@Action(1:60, appear(:lr, :tb)) # If an @Action follows an @Object, assume that @Action applies to the prior @Object

javis(video; pathname="test.gif")

One last comment, as I was writing this example, I somewhat felt that it might be more apt to instead call Object something like Drawing as syntax of sorts or maybe even @Render. The rationale is because calling an @Object that creates a star versus one @Object that creates a grid can be a bit hard to discuss as an @Object. Therefore, perhaps we could even use @Render as discussions about it could be more precise.

Just thoughts! Hope it helps!

@Wikunia
Copy link
Member

Wikunia commented Sep 17, 2020

Thanks for your thoughts @TheCedarPrince

Let me add some comments to your ideas first and address your last point. Afterwards I bring in my own ideas. 😄

Idea 1

I would agree on this one but wouldn't change the definition of default frames. It's currently the frame of the action above and I think that's okay. We can add more symbols on that like :all.

Idea 2

Yes b.frames can be added maybe

Idea 3

I think this is adding the Object at a weird point. It should in my opinion be in front of the frames

Idea 4

Yes I agree with the default

About your last comment: I do think that @Object is a reasonable name because it's kinda unspecific as it can be anything like a circle or a grid or a latex text.
I'm against @Drawing as in Luxor Drawing is an actual drawing so in our case one frame. @Render to me sounds like we do render this directly to something like a gif.

My ideas on including a whole concept with layers as discussed in #75:

appear_action = @Action(appear(:fade)) 
translate_action = @Action(translate_anim, translate()) 
translate_layer = @Action(translate_layer_anim, translate()) 

video = Video(600, 600)

@Background(1:250, ground)

acircle = @Object(1:180, id, circle(O, 50,:fill))
acircle += appear_action(1:60) # or if you only need it once `@Action(1:60, appear(:fade))` or `acircle += @Action(1:60, appear(:fade))` see **
acircle += translate_action(61:180)
astar = @Object(1:120, id, star(Point(100, 100), 50, 5, 0.5, 0, :fill))
astar += appear_action(1:30)
astar += translate_action(31:120)
layer_1 = Layer(acircle, astar)
layer_1 += translate_layer(181:250)

javis(video; pathname="test.gif")

**:
Or one can just write

@Object(1:180, id, circle(O, 50,:fill)) 
+ @Action(1:60, appear(:fade))

to not give it any name if one doesn't need the appear functionality again.

@Wikunia Wikunia added the question Further information is requested label Sep 17, 2020
@xiaodaigh
Copy link
Author

A breaking change with 50 users have less impact than one with 100. So if u decide a syntax change is in order then do it sooner rather than later would be better IMHO.

@xiaodaigh
Copy link
Author

Also |> works as well of u don't wanna overload +

@Wikunia
Copy link
Member

Wikunia commented Sep 18, 2020

Do you mind to comment on our ideas for the syntax @xiaodaigh and potentially add your own?

@TheCedarPrince
Copy link
Member

Perhaps similar to what I wrote up @xiaodaigh ? Thanks!

@xiaodaigh
Copy link
Author

About the Video syntax. Do we need it as a separate object? Cos

javis(objects; width=800, height=600) and the javis creates a video is more intuitive to me. I don't understand why I need to create a separate video object. Seems to be a distraction since I never make use of that video object anywhere else.

video = Video(600, 600)

@Background(1:60, ground)
@Object(id, func(my_args)) # If there is only one background, inherit frame range
@Object(1:10, func(id))

javis(video; pathname="test.gif")

how does background and object here related to the video? Some sort of implicit usage? Nah.

Idea 2

video = Video(600, 600)

b = @Background(1:60, ground)
@Object(b.frames, id, func(my_args))
@Object(1:10, func(id))

javis(video; pathname="test.gif")

Why does frames come from background? Should background be part of a frame? Also nah. Doesn't feel logical to me.

Idea 3

video = Video(600, 600)

@Background(1:180, ground)
a = @Object(1:180, id, draw_grid)
@Action(1:60, a, appear(:lr, :tb)) 

javis(video; pathname="test.gif")

Seems ok, but now clearly how video and background and object are linked.

How about something like this

@Background(1:180, color)
a = @Object(1:180, id, draw_grid)
@Action(a, 1:60, ...) 

javis([a]; outpath = "test.gif", video_width=600, video_height=600)

If you want to achieve # If an @Action follows an @Object, assume that @Action applies to the prior @Object, just let another package handle it. Like

using Lazy: @>

 a = @Object(1:180, id, draw_grid)

@> a begin
  @Action(1:60, ....)
  @Action(61:180, ....)
end

But make @Action explicit by default, so that you need @Action(object, ...)

@Wikunia
Copy link
Member

Wikunia commented Sep 22, 2020

Thanks for your comments @xiaodaigh . The Video is currently used to define global definitions and the last frames such that an Action (later Object) can be defined without explicitly defining its frames.
The workflow is similar to Luxor and JuMP whereas in JuMP one always needs to specify the video one is referring to I removed that as I expect nobody defines two videos at the same time. (Luxor does the same thing)

I think for small animations it is quite cumbersome to specify a name for every object to specify it inside an Action.

Do you mind to add some comments to my idea with using + ? @xiaodaigh

BTW:

  • Background is just an Action that leaks values to other actions so an action doesn't depend on a background action.
    As an example:
    If an Action defines sethue("red") it is only for this Action but if a BackgroundAction defines it is the default color for all actions which are specified on the same frame.

@Wikunia Wikunia added this to the v0.3.0 milestone Sep 22, 2020
@xiaodaigh
Copy link
Author

actually i don't understand the above now. But it's looking good!

@Wikunia
Copy link
Member

Wikunia commented Sep 23, 2020

You don't understand what and what is looking good even though you don't understand it?

@xiaodaigh
Copy link
Author

i trust u guys to make it awesome. I just make noise.

@Wikunia
Copy link
Member

Wikunia commented Sep 23, 2020

Can you please explain yourself! 😛

@xiaodaigh
Copy link
Author

The Video is currently used to define global definitions

I don't understand this.

the last frames such that an Action (later Object) can be defined without explicitly defining its frames.

What does this mean?

whereas in JuMP one always needs to specify the video one is referring to I removed that as I expect nobody defines two videos at the same time. (Luxor does the same thing)

So why not just not make the user create a video using Video() just leave it out and create a function for the user in the javis function? Like

function javis(objects_and_actions; width, height)
  video = Video(width, height)
  # apply actions to objects
   ....
end

I think for small animations it is quite cumbersome to specify a name for every object to specify it inside an Action.

Agree, so some kind of easy syntax.

Do you mind to add some comments to my idea with using + ?

+ is just an idea i got from ggplot2. As long as the actions are composable. Composability is my main point.

  • Background is just an Action that leaks values to other actions so an action doesn't depend on a background action.

Ok. Again. not sure what that means.

@Wikunia
Copy link
Member

Wikunia commented Sep 23, 2020

The Action function needs a video to save the last frames for example so Video needs to be defined before Action.
BackgroundAction is an action that is not in its own layer so everything you do in a BackgroundAction defines the "default" for all following actions like setting color or translating the canvas. But maybe you wanted to just relate them to a video and not an action to its background. I might have misunderstood you.

@xiaodaigh
Copy link
Author

The Action function needs a video to save the last frames for example so Video needs to be defined before Action

Why can't Action just "remember" what it needs to do to a video and only write to the video inside of javis(...)? If I don't use the video, except to pass it to javis then I don't see why I should have it outside. I think u r saying it's needed for technical reason right now, I am saying is there a logical reason for it to be outside?

BackgroundAction is an action that is not in its own layer so everything you do in a BackgroundAction defines the "default" for all following actions like setting color or translating the canvas.

I generally disagree with this design unless everything is inside a begin end block or inside a @macro block .e.g

@define_video begin
  BackgroundAction(dah, de, dah)
  .... something other stuff
end

In open code, it's generally a turn off for me.

But maybe you wanted to just relate them to a video and not an action to its background. I might have misunderstood you.

Maybe. Not sure I 100% follow.

@Wikunia
Copy link
Member

Wikunia commented Sep 24, 2020

This is an example in Luxor:

using Luxor
Drawing(1000, 1000, "hello-world.png")
origin()
background("black")
sethue("red")
fontsize(50)
text("hello world")
finish()
preview()

One needs to define a Drawing where everything is drawn into. I find it quite ugly to make it between a begin and end block as you don't gain clarity in my opinion. I think users will have an animation file and then everything in this file will be between a begin and end so I just remove that block.

There is always a way to define the Video afterwards inside the javis funcrion, so after defining the action but it's one line of code for the user and it gives quite some clarity.

Imagine you have two animations in one file so call javis twice if you don't define a video you only have the option to either start from scratch in the second animation or to continue with the last animation but you might wanted to have a gif for the start of the video as a teaser.

In the current version you could either define a new Video object or not.

Clearer would be to define an action with Action(video, ...
but I think it's similar to Luxor that one does not switch between videos so this is unnecessary.

@xiaodaigh
Copy link
Author

maybe u r right. For luxor and javis still project it's fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Breaking This issue will break things 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