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

Create Linear and Radial Gradients #605

Open
AshishS-1123 opened this issue Jun 11, 2021 · 9 comments
Open

Create Linear and Radial Gradients #605

AshishS-1123 opened this issue Jun 11, 2021 · 9 comments

Comments

@AshishS-1123
Copy link
Contributor

Expected Behavior

One of the features in the Beta Wishlist is Gradients. I would like to work on adding it. I have already gotten a simple gradient working and will discuss my approach here.
If there are any changes to be made, please comment. If not, could any of the maintainers create a branch- like WIP-gradients for this feature?

The following are some functionality this feature must have.

User Stories

  1. The user should be able to change the type of coloring used (simple, linear gradient, radial gradient).
  2. The user should be able to change the color shades of gradients using stop colors.
  3. The user should be able to change the direction in which the gradient flows using the direction line.
  4. If the user changes from either of the gradients to a simple color, their previous color should be used.

Possible Solution

UI Changes

In the ColorPicker popover, add a dropdown menu. This menu will be created using Gtk.ComboBoxText.
The dropdown menu will contain 3 items
1. Simple Color: this will represent a simple, plain color.
2. Linear Gradient: this will represent a linear gradient.
3. Radial Gradient: this will represent a radial gradient.

The user can select what kind of fill they want.

Other that the dropdown menu, a direction line will also be created. This line will determine the direction of gradients. This line will only be present if "Linear Gradient" or "Radial Gradient" Mode is chosen.

The user can then drag this line around to change the direction of gradient. This is similar to how most graphics software products use gradients.

This is what the popover looks like after adding the dropdown menu

dropdown menu

This is what the gradient looks like by default.

gradient_window

Code Changes

  • The dropdown menu will be created in Akira.Layouts.Partials.FillItem, inside the Gtk.Popover.
  • The widget used for this is Gtk.ComboBoxText.
  • To handle drawing gradients and the direction line, Akira.Lib.Components.Gradient will be used.
  • When a new item is selected from this menu, it triggers a signal changed.
  • The handler for this signal will change the color property in Akira.Models.FillsItemModel.
  • This in turn changes the color property in Akira.Lib.Components.Fill.
  • In Akira.Lib.Components.Fill, a Akira.Lib.Components.Gradient object is used to draw a linear or radial gradient Pattern using the Cairo library.

This approach looks a little too complicated to me, but when the user changes the color of a CanvasItem, these are the steps that happen, which is why I did the same.

I have implemented this, and can be found on my fork in the branch WIP-Gradient.

As of now, when the user selects the Linear Gradient or Radial Gradient mode, a static gradient of colors black and white and running diagonally appears. Its color or direction cannot be changed. The direction line also isn't created. But selecting another mode removes the gradient.

Future Work

Implement the remaining User Stories. There are also some bugs that cause the CanvasItem to draw Simple colors even when gradient mode is selected.

@ghost
Copy link

ghost commented Jun 11, 2021

We are dropping goocanvas library so working with anything related to goocanvas will be a waste of time

@AshishS-1123
Copy link
Contributor Author

@abdallah-moh The gradient is being drawn using Cairo.Pattern, and the only place where I am using GooCanvas is when dealing with the CanvasItem to be colored.

If you are thinking of dropping GooCanvas, does that mean you will be using Cairo instead? In which case changing a couple of lines in the code should do the trick.

Could you also point me to the branch where GooCanvas is being dropped so that I can start working off of that?

@ghost
Copy link

ghost commented Jun 11, 2021

@AshishS-1123 if the code doesn't depend on goocanvas to work you can open a pr on master

@ghost
Copy link

ghost commented Jun 11, 2021

And for the naming

  • Solid Colors
  • Linear gradient
  • Radial gradient

@Alecaddd
Copy link
Member

Alecaddd commented Jun 11, 2021

@AshishS-1123 Hi, thank you so much for your interest in Akira and the starting of this contribution.
I like the rationale behind the user journey and the possible approach in handling this feature, great starting work.

In the ColorPicker popover, add a dropdown menu. This menu will be created using Gtk.ComboBoxText.

I'm not sure about this.
I think it would be better to use colored icons at the top of the ColorPicker to show a sort of "Tabs" separation.
I really like how Sketch organizes these by offering clickable icons above the color picker.
sketch

If there are any changes to be made, please comment. If not, could any of the maintainers create a branch- like WIP-gradients for this feature?

We don't do that.
Every external contributor can manage their own fork of the app and then create a PR against the Akira repo's master branch once a new feature is ready for a review.

Could you also point me to the branch where GooCanvas is being dropped so that I can start working off of that?

Abdallah is misinformed.
We didn't start working on dropping GooCanvas yet, and it won't happen anytime soon as we're currently working on other refactoring and higher priority architectural changes.
Nonetheless, your assumption is correct as we will directly interact with the Cairo API for everything, so it should be easy to wire everything properly.

One important change that should land soon on master and will affect your code is PR #604.
In this, I reworked the Fills and Borders panel to use the same reusable UI widget, and simplify a lot the code.
This will be helpful because any change done to the ColorPicker will be automatically inherited by both fills and borders.

Another important change that should land soon, is in PR #587.
This is a more drastic architectural rework which will basically rewrite the whole Components and Canvas code, in order to improve performance and create a more solid and controlled update path when changing shapes' attributes.

As a suggestion, I'd say for now focus on the UI of that widget in order to implement the different views for the gradients in the ColorPicker, and take a look at how other apps handle the multiple colors in a gradient.
Take a look also at how Felipe handled a similar problem in his app: https://github.com/Philip-Scott/Spice-up
Ignore for now direct interactions with the CanvasItem as those APIs will change in the upcoming months.

And for the naming
Solid Colors
Linear gradient
Radial gradient

Indeed, "solid color" instead of "simple" sounds better, but you're using mixed of plural and singular nouns, and also a mix of uppercase and lowercase.
Maybe something like this works better:

  • Solid color
  • Linear gradient
  • Radial gradient

Great start on this!

@Alecaddd
Copy link
Member

Some examples of how various apps handle the control of the gradient's stop points (colors) in the UI.
Just to get some inspiration.

linear-gradient
gradient-affinity
Screenshot from 2021-06-11 11-36-10

@akiraux akiraux deleted a comment Jun 24, 2021
@AshishS-1123
Copy link
Contributor Author

Just a quick update, I have the gradient feature working. This is what it looks like.

akira_screenshot
You can add stop colors, delete stop colors, see the resultant shades on the CanvasItem and on the color picker widget, and change the colors of stop colors (for Linear and Radial Gradient).

Two things haven't been implemented yet.

  1. Direction and position of gradient cannot be changed. I am thinking of using Nobs from Lib.Selection.Nob along with Cairo to draw a direction line that the user can move around.
  2. When multiple Fill items are present, no blending occurs. I cant figure out how to do this. So if someone could give me some pointers...

@AshishS-1123
Copy link
Contributor Author

Right now, when choosing a color, a popover is used. While this may have worked for solid colors, it creates a maneuverability issue for gradients. After choosing a stop color, if the user wishes to change the position/direction of a stop color, they have to close the popover. Sometimes the popover might also hide a canvas item.
So instead of a popover, how about the following design.

Web 1920 – 1

When the user clicks on the color button, the Fill object will expand and the color picker will appear there. If the user clicks on another fill object, this picker will disappear and make space for the new one.
As a Popover is not used, the window won't lose focus and we can modify the color and gradient position simultaneously.

@Alecaddd
Copy link
Member

Mhh...that's an interesting proposal, but I'm not 100% sure about this.

The mock-up is a bit too simplified to make an educated decision as there are a lot of missing elements that are always part of the color picker.
How would this look with the Global colors grid? Also keep in mind that in the future we will most likely have more colors grid (Document, Custom libraries) that can be collapsed and expanded.
The color picker is missing the alpha and hue slider.

My main concern is that if the user is handling a shape with multiple fill (or border) colors, they will most likely be forced to scroll down the panel in order to select another color, and when they do, the UI will jump around moving the currently selected color all the way up, therefore changing the focal point.

I totally understand the points you're raising regarding Canvas focus, but I'm sure we can mitigate that by forcing the popup to stay open if the user selects the gradient controller that we will implement above the shape.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants