Manim v0.2.0 self.play() method - manim

I cannot figure out how to create simple animations with the new Manim version (v0.2.0).
For example, I would like to move a circle to an edge and at the same time scale it.
In the previous versions I would have done as follows:
class CircleAnimations(Scene):
def construct(self):
circle = Circle()
self.add(circle)
self.play(
circle.scale, 0.2,
circle.to_edge, UP
)
self.wait()
But since in the new version, to animate in the self.play method we must use mobj.animate.method(parameters) , I tried to rewrite the self.play method as follows:
self.play(
circle.animate.scale(0.2),
circle.animate.to_edge(UP)
)
However this doesn't work: it seems to run only the first method, in this case, circle.animate.scale(0.2), and not both circle.animate.scale(0.2) and circle.animate.to_edge(UP)
Any solution?
Thanks in advance.

You can nest the animations like this:
self.play(
circle.animate.scale(0.2).to_edge(UP)
)
Another way would be to use the ApplyMethod class:
self.play(
ApplyMethod(circle.scale, 0.2),
ApplyMethod(circle.to_edge, UP)
)

Related

Is it a Manim bug or am I doing something wrong such that simple square fill_color fails?

Here is my code. I would expect both squares to be filled GREEN but only square1 is correct. Running Windows 10 and manim community v0.15.2. Is this a manim bug?
The comment for square2 shows how to circumvent the bug.
from manim import *
class MovingTriangle(Scene):
def construct(self):
square1 = Square(side_length=1,color=RED,fill_color=RED, fill_opacity=1)
square1.color = GREEN
square1.fill_color = GREEN
square1.fill_opacity = 1
square1.stroke_color = GREEN
square2 = Square(side_length=1) # if parms for any color added in this constructor then square2 would work (fill green)
square2.color = GREEN
square2.fill_color = GREEN
square2.fill_opacity = 1
square2.stroke_color = GREEN
square2.next_to(square1, RIGHT)
self.add(square1, square2)
self.wait()
I wouldn't really call it a bug, but I agree that the behavior is somewhat unexpected. Setting the color of a mobject just by setting the fill_color attribute is not supported; there is some additional stuff going on (see for example the implementation of VMobject.set_fill) before the color of the mobject is actually changed when rendering (most notably, the call to update_rgbas_array).
For now it is best to set the colors in the constructor, or to use the dedicated set_color, set_fill, set_stroke, or set_style methods.
Found a solution. You need to explicitly set opacity = 1.0 since by default most VMobjects have no fill opacity.

Kivy:Can't put 'BorderImage' at the specified position

(1) By using the following kv file version was able to place BorderImagewidget at the specified position..
<Screen>:
ProgressBar:
max: 100
pos_hint: {'top':0.86, 'x':0.01}
size_hint_x: 0.49
size_hint_y: 0.1
canvas:
BorderImage:
border: (10, 10, 10, 10)
pos: self.x, self.center_y
size: self.width, 8
source: '0.png'
(2) But, the following Pure Python code that should realize the same function as (1) doesn't work properly.BorderImagewidget is placed at the bottom of the screen.
pos_hint={'top':0.86,'x':0.01} doesn't work.
I think that how to specify pos=(bar.x, bar.center_y) is not good because bar.center_y value is different from the code of (1).
class BarWidget(FloatLayout):
def __init__(self, **kwargs):
super(BarWidget, self).__init__(**kwargs)
self.build()
def build(self):
bar = ProgressBar(pos_hint={'top':0.86,'x':0.01}, max=100, size_hint_x=0.49, size_hint_y=0.1)
with bar.canvas:
BorderImage(border=(10, 10, 10, 10), pos=(bar.x, bar.center_y), size=(self.width/2, 8), source='0.png')
self.add_widget(bar)
How should I modify bar.center_y?
(1):screen shot
(2):screen shot
In the kv language, when you set an attribute like size: self.size, this attribute is automatically updated whenever the 'self' widget changes size of shape. When things are loading up in a screen/layout, they start with funky positions and sizes then move to be correct. Since things automatically update upon changing sizes/positions if you work in kv, it works as you expect.
In python, you have to explicitly bind some function to update the canvas if the size or position of the widget it's inheriting its size and pos from changes. You can do that by using the bind function (available in most/all kivy widgets). Using bind, you can say bind(<attribute>=<function>) which means anytime the widget's <attribute>, aka size or pos, is changed, it calls the <function>
I didn't test this exactly with your code since not all of it is posted, but this is what I do for my projects. Let me know how it works. If it doesn't work, edit your answer to be a snippet of code that I can copy/paste to work with and I'll update my answer.
class BarWidget(FloatLayout):
def __init__(self, **kwargs):
super(BarWidget, self).__init__(**kwargs)
self.build()
def build(self):
# Make it so you can reference the bar and border image later
self.bar = ProgressBar(pos_hint={'top':0.86,'x':0.01}, max=100, size_hint_x=0.49, size_hint_y=0.1)
with self.bar.canvas:
# Make it so you can reference the border image
self.border_image = BorderImage(border=(10, 10, 10, 10), pos=(bar.x, bar.center_y), size=(self.width, 8), source='0.png')
self.add_widget(self.bar)
# Make it so whenever the widget's pos or size changes, we update the border image
self.bar.bind(pos=self.update_border_image, size=self.update_border_image)
# make a function to update border image
def update_border_image(self, *args):
self.border_image.size = (self.width, 8) # Should this 8 be 0.8 by the way?
self.border_image.pos = (self.bar.x, self.bar.center_y)

Applying animation on a circular chart

I have built a circular graph very similar to this example in paintcode:
http://www.paintcodeapp.com/news/animating-apple-watch-activity-rings-in-paintcode
I have successfully drawn out the control on my iOS view with ease, but now I would like to animate the graph so that it begins at 0 and eases towards the specified angle. Basically the animation should look like the first two seconds of the video in the URL above.
What is the best way to go about this type of animation?
FYI: I am working in C#/Xamarin but I am not fussy on syntax at all, so an Objective C or Swift example will do just fine.
I wrote a UIView subclass which does exactly what you're asking for. You just provide an array of rings along with a few other parameters, and it handles all of the setup and management for you.
https://github.com/lionheart/ConcentricProgressRingView
At the top of your UIViewController, import the module:
import ConcentricProgressRingView
Then, in your viewDidLoad:
let rings = [
ProgressRing(color: UIColor.redColor()),
ProgressRing(color: UIColor.blueColor()),
]
let margin: CGFloat = 2
let radius: CGFloat = 80
let progressRingView = ConcentricProgressRingView(center: view.center, radius: radius, margin: margin, rings: rings, defaultWidth: 20)
view.addSubview(progressRingView)
Once you've instantiated your ConcentricProgressRingView instance, animate a specific ring to a percentage with setProgress.
ring.arcs[1].setProgress(0.5, duration: 2)
Under the hood, this just uses CABasicAnimation and sets a few parameters which make it look "right". I know you're not using Swift, but if you want specific pointers, just check out the source code to see how I've solved it. Hope this helps!
You want to use CAShapeLayers, one for each arc, with a full-circle arc installed in each one, and the line cap style set to rounded.
Then you want to set the strokeEnd property to a small value (try .05). That will cause the shape to only draw 5% of it's arc.
Finally you want to submit CAAnimations to each shape layer that animate the strokeEnd value from the starting value to 1.0. That will animate the arcs drawing the full circle.
I don't have any ready-made sample code for you. I do have a sample project written in Objective-C that uses a very similar technique to create a "clock wipe" animation using a CAShapeLayer as a mask layer.
Take a look at the clock wipe animation in the project "iOS CAAnimationGroup demo" project on Github.

How to bring currentview of iCarousel to the top of other views in iCarouselTypeWheel

I want to create a wheel similar to "http://www.asianpaints.com/royale" in iOS, till now I have used iCarousel type: iCarouselTypeWheel. It almost works for me but main problem is the center view got overlapped by next elements. Please let me know how to fix.
Thanks in advance for any help.
Standard wheel set "first" element on most left or most right position, so if you want to carousel begins in top you need set carousel type to iCarouselTypeCustom and provide transform in carousel:itemTransformForOffset:baseTransform: you can take transform from iCarousel source as base
You will actually need to change the z transform value (that is returning) of CATransform3DTranslate function in transformForItemViewWithOffset method. This is kind of hacky though.
To do this,
Open your iCarousel.m file
Look for -(CATransform3D)transformForItemViewWithOffset:(CGFloat)offset method
Inside the switch case statement, go to iCarouselTypeWheel and in the else part, you will need to change the line
return CATransform3DTranslate(transform, 0.0f, -radius, offset * 0.01f);
to
return CATransform3DTranslate(transform, 0.0f, -radius, 0.0f);
Save the file and run the project to see if that gives you the desired result.

Corona SDK - How can i change color text with transition?

Can i change color of text field with transition?
I try with normal transition like this but did not work.
explainer = display.newText("my text", 100,100,"Hiragino Maru Gothic Pro",30)
transition.to(explainer, { time=100, color="rgba(255,0,0)" })
You really can't do this with transition.to. You would have to do it in an enterFrame listener and increment your R, G, B values during each step.
Here's a code that let's you make a blink effect. You can remove the part that changes the increment and it will work for you:
local min_r,min_g,min_b=100,100,255 -- Initial color
local max_r,max_g,max_b=255,255,255 -- End color
local color_steps=15 -- Adjust this to make it more fast/slow
local current_step=0
local increment=1
local step_r=(max_r-min_r)/color_steps
local step_g=(max_g-min_g)/color_steps
local step_b=(max_b-min_b)/color_steps
function blink()
if (rowPlayerName and rowPlayerName["text"] and rowScore and rowScore["text"]) then
rowPlayerName:setTextColor( min_r+current_step*step_r, min_g+current_step*step_g, min_b+current_step*step_b )
rowScore:setTextColor(min_r+current_step*step_r, min_g+current_step*step_g, min_b+current_step*step_b )
current_step=current_step+increment
if (current_step>=color_steps) then
current_step=color_steps-1
increment=-increment
elseif (current_step<0) then
current_step=0
increment=-increment
end
timer.performWithDelay(50, blink)
end
end
blink()
In this case, rowPlayerName and rowScore are 2 display.newText that need to be changed together.
What you could also do, is just put another object over it with different color and set its alpha to 0. Then using transition.to method change this objects alpha property to 1.

Resources