I am trying to animate the change between layouts of a Cytoscape.js graph.
When switching from cose to grid, the change is animated. When switching from grid to cose, only the end position is shown without any animation.
I use a simple test scenario starting with a small graph in grid layout and this code to switch layouts:
...
function changeLayout(type){
var options = {
name: type,
animate: true
};
cy.layout(options);
}
...
<div onclick="changeLayout('cose')">to cose</div>
<div onclick="changeLayout('grid')">to grid</div>
I also tried the other options listed here:
http://js.cytoscape.org/#layouts/cose
but I am not able to animate from grid to cose.
What am I doing wrong?
A continuous layout like CoSE animates live. That is, it animates during the iterations of the calculations it does. If the layout runs very quickly -- as CoSE often does -- then you won't get much if any animation.
There is a proposal being discussed to have an option to animate continuous layouts like discrete ones (i.e. tweening between the start and end positions).
If you want this behaviour for now, you'll have to run the layout while batching. Now that you have saved the start and end positions for each node, you can just end batching and animate.
You can do this now using animate: 'end' in the layout definition. See https://github.com/cytoscape/cytoscape.js/blob/unstable/src/extensions/layout/cose.js#L31. This will animate the nodes from their initial starting position to their end position, in contrast with animate: true which will animate the changes in the layout, and only do so after a certain threshold of time (see animateThreshold).
Related
I am trying to play an animation when a scene is instanced. It is a simple animation that translates y from -5 to 5. The animation plays but it plays at x = 0 and z = 0. I understand this is because the translation values for the respective co-ordinates in the animation are set to 0. I have a spatial node on my player scene that can grab transform info and pass it on to my animated scene, but I do not know how to dynamically change the x and z values of the key frames in script.
This answer contains three solutions to the problem...
Target a sub-property
If I understand correctly you want to animate only the y coordinate, and leave the other coordinates unchanged. That is, you don't want to animate the translation vector. You want to animate the y or the translation, a sub-property. This is possible out of the box, but the UI won't offer it to you.
Start by creating a track from the animation editor. You click on "Add Track", select "Property Track", and then on the object you want, and select translation. Now, while the track is empty (no key frame inserted yet), modify the track name to :y at the end.
The track would have been create with a name such as SpatialNodeName:translation, you are going to change it to SpatialNodeName:translation:y.
Afterwards, when you add key frames, they will be for translation.y. Note: doing SpatialNodeName:transform:origin:y or even SpatialNodeName:global_transform:origin:y also works. Similarly, you can imagine how do it for only rotation or scaling, and so on.
Create custom properties and animate them
I'll also mention that another option is using a Tween node (which are easier to create from code).
And also that both Tween and AnimationPlayer can animate any property. Thus, if you need to animate something that is not available, consider adding a property (see setget).
For example:
export var y:float setget set_y, get_y
func set_y(new_value:float) -> void:
transform.origin.y = new_value
func get_y() -> float:
return transform.origin.y
Then you can add a track for the custom property, and animate it like any other.
By the way, also notice the AnimationPlayer can also have "Call Method" tracks.
Modify the animation
Manipulating an animation from code is also possible. I've seen an example elsewhere. You can call get_animation on the AnimationPlayer to get the animation. Then on the returned animation you can call track_get_key_value and track_set_key_value. However, this rarely what you want to do in practice (unless you are making a Godot addon that creates or modifies animations or something like that).
In my React Native application I have some tiles (wrapped in a View for the example) which are half of the full width wide. They act as buttons and slide to the opposite side to open a menu. When I perform a swipe gesture and release the finger before the slide reaches its final position, I want the slide to animate to its final 'opened' position. The animation should start with the last velocity of the touch gesture for a smooth impression.
I implemented different variations but did not find a good solution (You can find my test-component in my GitHub repository). My View has a PanResponder to manage the gesture and to get the velocity. I started to use the Animated library, but the provided methods do not solve my problem. The only method where I can pass a initial velocity for the animation is the decay, but I can't pass a parameter where the animation should stop. With a timing animation I can set a final value, but can not pass a initial velocity (so the animation starts with a velocity of 0 which looks very jumpy). I tried to combine these two methods, but that does not work properly.
On iOS I could use a horizontal ScrollView with pagingEnabled, which shows the desired effect - but then I do not have the feature on Android.
Any ideas how I can solve this problem and show a smooth animation, starting with an initial velocity and ending on a given position, after the touch gestures end?
Thanks for your help!
EDIT I added the link to my last test component...
You can get a close approximation of the velocity by setting the duration of the timing animation
const duration = Math.abs((this.props.MAXDISTANCE - Math.abs(distanceMoved)) / velocity);
MAXDISTANCE is your final position
distanceMoved is the current position (gestureState.dx)
velocity is the current velocity (gestureState.vx)
You can use Animated.decay or Animated.spring to achieve this effect.
I have an animation for humanoid models to simulate climbing. I have been looking for a way to stimulate this animation when the model comes next to the window. I used the triggers to determine where the model is and it worked. However, when I execute the animation, the position of the model is not being updated according to the animation. I am using offmesh links and nav mesh agent and I disable nav mesh agent when the model triggers. How can I use the animation and provide the update simultaneously?
Animation Properties
Thanks in advance.
I don't think the animation should take care of the movement. You should control that somewhere else. You could make the animation climb from y = 0 to 5 but then it won't work if your ladder is at y = 3.
You'd better have a method that is called from the animation using AnimationEvent so that when you trigger the animation, it also triggers a movement of the object upwards/downwards regardless of the current position of the object. It would simply use Translate and disabled input until the animation ends.
The new Unity 4.6 comes with a new GUI, when I change de resolution on Unity the UI Button scales perfectly but when I test on the Nexus 7 device the Button looks too small. Any idea how to solve this?
Unity's new GUI system uses "anchors" to control how gui elements (like buttons) scale in relation to their parent container.
Unity has a tutorial video on how to use the new "Rect Transform" component (where the anchors are configured) here: http://unity3d.com/learn/tutorials/modules/beginner/ui/rect-transform.
The last half of the tutorial is all about anchors. That page has links to the entire tutorial series. It's not too long. You should watch the whole thing.
Specific to your question:
The anchors are visible in your first screen shot. They are those 4 little arrows at the top left of your button.
Right now, your button is only anchored by it's top left corner.
The two right anchors need to be dragged to the right so that the right edge of your button is anchored to a space inside its parent container.
Depending on your situation, the two bottom arrows may need to be dragged down so that the bottom edge of your button is anchored as well.
The video I linked above covers all this in detail.
Lastly, for the font size to scale nicely on different resolutions, you will need to add and configure a reference resolution component to the base canvas of your UI, as Ash-Bash32 wrote earlier.
Update: The best way to add a Reference Resolution component is through the inspector window for the base canvas in your UI.
1) click the "Add Component Button" at the bottom of the inspector.
2) type the word "Reference" in the search filter field.
3) select the "Reference Resolution" component in the search results.
The Reference Resolution is now renamed as Canvas Scaler.. Along with the renaming they have added many more features for the dynamicity of the Canvas. You can go through the Unity Doc of Canvas Scaler and also take a look at this article for a practical example of how and why to use Canvas Scaler. Also make sure you use the Anchor Points to good effect to make this more robust...
To Scale UI added the ReferenceResolution Component to the Canvas you want to scale.
P.S. Theres no Documention for ReferenceResolution
If you want the button to be the same size for all screens and resolutions, you have to add the canvas scaler component to the canvas and the set the screen match mode to: match width or height, here is the link to the docs, this helps a lot if you want to aim to different sizes or resolutions:
http://docs.unity3d.com/Manual/HOWTO-UIMultiResolution.html
This becomes giant and convoluted once you start laying things out in code AND using a canvas scaler, so I wish to provide a thorough answer to save someone the hours I went through.
First, don't use anchoredPosition to position anything, unless you fully realize it is a 0.0 to 1.0 number. Use the RectTransform localPosition to do the actual laying out, and remember it's in relation to the parent anchor. (I had to lay out a grid from the center)
Second, put a canvas scaler on the parent layout object AND the inner ui pieces. One makes the layout in the right position, the other will resize your elements so they actually show up right. You can't rely on the the parent unless the children also have scalers (and Graphic Raycasters to touch them).
Third, if you have a scaler, DON'T use Screen.width and height, instead assume the screen is the same value you put for the scalers (hopefully you used the same, or know what you're doing). The screen width always returns the actual device pixels, retina devices too, but the canvas scalers DO NOT account for this. This probably gives unity the one remaining way to find actual screen dpi if your game wants it. Edit: This paragraph applies to any parent canvas connected to the code doing your laying out. Not stray canvases, you can probably mix it up. Just remember unity's guidelines on performance with canvases.
Fourth, the canvas is still a bit buggy. Even with the above working, some things don't render until you delete and recreate a canvas, if you re-open the scene or it crashes. Otherwise, the above is the general "rules" I've found.
To center a "grid of things" you can't just use half of the canvas scaler's width or height, you have to calculate the height of your grid and set the offset by half of it, otherwise it will always be slightly off. I just added this as an extra tip. This calculation works for all orientations.
If I add this style (.style("opacity", .2) to a rectangle the gridlines appear in front of the rectangle, in this example http://bl.ocks.org/bunkat/1962173. Is there a way to bring shape to front or send gridline back?
The elements in an SVG are displayed in the order in which they are added to the DOM. That is, anything you want displayed on top of everything else should be added last. In your case, you need to add the rectangle after adding the grid lines.
Here's a jsfiddle to play with dom order and opacity:
http://jsfiddle.net/laurieskelly/9jr65/
If you back the shapes with identical shapes of the background color, the grid lines will not show through.
Simpler solution: do the shapes really need to be transparent?