How to create Drawer effect?

Hi.

I want to create an effect where if I click on a toggle button, it should expand and close like roughly shown in the image. :slight_smile:

Few points:
1) Obviously I can’t scale it in y direction because it’s not simple rectangle, it has radius and it should not distort.
2) Only possible way I can think is that on click of that button, I would make it show as progress bar and move it’s position because in Progress bar, start point is shown first and not end point. And in my case, end point is top part. Hence, I’ll have to start progress bar TOP-DOWN and simultaneously moveBy the position of that green bar. ButmoveBy and progress bar has to correctly in synch.

Any better way to achieve this effect?

Thanks :slight_smile:

you can use ccui panel support 9-slice cut

Hi jokerx86, can you elaborate it a bit!
I’ve never used ccui, so I’ve no idea how I can achieve with it.

EDIT: Ignore. I couldn’t thought of other way so, achieved that effect with the 2nd point I mentioned in initial post. And it wasn’t becoming possible with CCUI and LoadingBar so I ignored it.

This effect can also be achieved by using a Scale-9 Sprite, or Image, All you need to do is define scale points points in Cocos Studio(Use Image not Sprite) or in code look out for API, define your points in right hand panel from where you would want to scale the image(ideally from middle below the curvy edges), and then on touch of your button you can change the size of your Image by simply calling setSize() method of Image in code, remember you don’t wanna change in X direction for your specific requirements. To create a simple smooth drawer animation you can schedule the size change inside a Callback-function wrapped around a EaseOut Method when user click on button.

Regards
Ajay

1 Like

Hey @Lazy_Gamer :slight_smile:

What is Image in this?
For now, I am experimenting with ui::Scale9Sprite * popUp = ui::Scale9Sprite::create(file); to make it work for me.

You’ve any idea from where can I define points for my Scale-9-Sprite other than cocos Studio.

Thanks :slight_smile:

Hey @catch_up I used Image available in Cocos2d-x 3.4, it is available upto Cococs2d-X 3.5 as i can see. For Scale9Sprite you need to play with following methods as i am unsure myself as i haven’t did it with API, but this will surely give you much fine controls over your Drawer animation For starters look at the API here

void setPreferredSize(const Size & size)
Size getPreferredSize() cons
void setCapInsets(const Rect & rect)          
Rect getCapInsets() const
void setInsetRight(float rightInset)          
void setInsetLeft(float leftInset)
void setInsetTop(float topInset)          
void setInsetBottom(float bottomInset)

Do let me know if you stuck somewhere, Also you can also use Buttons for the same purpose(as Buttons also use scale9 renderer under the hood for rendering, and capInset for buttons also do get effected if setScale9Enabled(true) ), but it will be a overkill in my opinion if you use them for Drawer purpose only.

Regards
Ajay

@Lazy_Gamer
Thanks for the help. :slight_smile:
Yesterday, I achieved the effect with 9Slice also but after lot of effort since documentation clearly say what the functions are that you mentioned.
At the end of the day, concepts for 9slice w.r.t to functions are yet unclear…

Do I need to do setScale9Enabled(true) if I am using scaleTo action or manually scaling setScale? I thought it’s enabled by default.

Well that’s true, Can you help in improving it by putting your findings here or the Other thread you summoned regarding you Queries for Scale9Sprite. Atleast no info is better then some info.[quote=“catch_up, post:7, topic:32502”]
At the end of the day, concepts for 9slice w.r.t to functions are yet unclear…
[/quote]

True again, This is a simple yet difficult to get approach, specially for people who are not aware of its use or even don’t know what 9Scale is all about.

I think it will/should be called by default, i am unsure needs to test it to confirm it.

You mean, some info is better than no info? :smiley:
Truth, there were no findings…

Everything I found on cocos2d-x documentation related to 9Slice is given in my other thread,

Plus as I also mentioned in my above linked post that it is actually simply to write thing althogh concept is unclear.

This was the only thing that helped.


And code was simply 3 lines…

    ui::Scale9Sprite *drawer = ui::Scale9Sprite::create("drawer.png");
    drawer->setContentSize(Size(drawer->getContentSize().width, drawer->getContentSize().height*scaleY));
    drawer->setPosition(whateverPosition);

Only scaleY is there as I want to scale in vertical manner.

Although theoretically I know the concept of 9Slice but don’t know how to use insets and cap and other cocos2d-x functions, hence I used extremely simply implementation as above. Where it’s good that scaleY is >=1 and not less in my case as my image is rectangle and doing create() splice the image in equal parts. So, you won’t get desired effect is it’s <1 (Experiment with this factor for desired results).

Also, if anyone is using drawer->scale() or scaleTo or scaleBy then I htink you’ve to set to do setScale9Enabled(true) explicitly. Not sure about this. but without it, it surely doesn’t work.

@Lazy_Gamer
If you know below concepts, can you please share in this post wrt to implementation? And 1 diagram would help.

void setPreferredSize(const Size & size)

void setCapInsets(const Rect & rect)          
Rect getCapInsets() const

void setInsetRight(float rightInset)          
void setInsetLeft(float leftInset)
void setInsetTop(float topInset)          
void setInsetBottom(float bottomInset)

Thanks. :slight_smile:

1 Like

@Lazy_Gamer

So, I am trying to use 9 Slice sprite again but this time my sprite’s height is pretty less and it’s important for this one to have proper insets defined unlike last time where I didn’t define anything. :smiley: :stuck_out_tongue:

Can you please tell me the definition of below functions with a diagram as I can’t find it anywhere.

– I am not using cocos studio, so I’ll define the points myself –

void setPreferredSize(const Size & size)

void setCapInsets(const Rect & rect)          
Rect getCapInsets() const

void setInsetRight(float rightInset)          
void setInsetLeft(float leftInset)
void setInsetTop(float topInset)          
void setInsetBottom(float bottomInset)

This is exactly how my sprite looks:

Which I want to scale horizontally without distoring the circle which can be see in the center of the image…
Is it even possible anyhow with 9Slice… or by any other way in cocos?

Or else, I’ll try to put the white part of below as scaling and black part as the part which won’t distort through 9 slice sprite.

and cirlcle in the center of above image, I’ll put after 9 slice scaling of above image is done.

Thanks :slight_smile:

Hello @catch_up

I ran some quick tests and come to conclusion that setCapInsets(const Rect & rect) doesn’t allow you to define more then 4 points(Or Rect& ) for a single Sprite, and the way scale 9 sprite works is it scales texture inside the rect created by above rect not inversely. A easy solution would be to use three Image(available upto cocos2d-x 3.5) or Button leftBar, middleCircle, rightBar, apply scale 9 bounds to leftBar and rightBar, leaving middleCircle. Also make them child of a node just for ease of access and consistency. Now whenever you want to change size of your bars, get their reference from node and change their size as per your convenience,

myCustomBar->getChildByTag(TAGMANAGER::LEFTBAR)->setContentSize(Size & mycustomSize);
myCustomBar->getChildByTag(TAGMANAGER::RIGHTBAR)->setContentSize(Size & mycustomSize);

Best Regards

Hey @Lazy_Gamer
Thanks for the suggestion.

I have to 2 ways in mind which I wanted to experiment and see if they work.
In both the cases, I would anwyays, put the circle separately.

  1. If I export below image, I would make the points like this where the horizontal lines will overlap since the height is too small. And I’ll scale horizontally and the region in corners will not destort and so is my image.

  2. If above won’t work, then this case, which would be exactly as above but the splitting 9 slice horizontal lines won’t overlap and also I’ll scale down it vertically also since my packed sprite will look like below which is already veritically scaled up.

In this case, totaly sprites needed would be 2 and not 3.
I know, it’s not of an optimization but I just wanted to experiment and learn.
But for this, I needed to know how exactly the Insets in 9slice sprite work.

Meanwhile, I am trying out your solution of having 3 sprites.
Thanks

@catch_up I think keeping at-least 1px gap between two lines is a good idea, But i seriously doubt your methods will work as already mentioned by me earlier the closed inset rect created by four lines will be scaled only, so in your above tests only the center inset created by four lines will be stretched and would not give you desired effects.