Greensock library morphSVG animation - animation

I am trying to make an animation that will fill a tube with liquid and then start moving the liquid inside. I am using an SVG with 3 main paths, the first one is liquid with short height, which then I morph to become the liquid with long height, then I want to "repeat" the morph between the other 2 paths to make it look like the liquid is moving, however when i move from one path to the other using morphSVG, I can't go back to the previous path, so my other morphSVG statement isn't executed.
Here's link to my code:
https://codepen.io/BrittanyR/pen/rJvOyX
As can be seen, I am able to move from one path to the other using:
TweenMax.to("#redSecondary", 2, {morphSVG: "#redPrimary", delay: 2})
But I can't then use this: TweenMax.to("#redPrimary", 2, {morphSVG: "#redSecondary"})
Any idea will be helpful.
Thanks.

It seems like it was just a logic issue in your code - your setTimeout() was alternating between animating #redPrimary and #redSecondary (targets), but you never changed what they were animating TO. So it worked the first time...and that's it. Every subsequent call was just duplicating the exact same movement (tweening to the current values...thus no motion).
I wonder if this is what you were looking for: https://codepen.io/GreenSock/pen/gvzMLG?editors=0010
Note: as a convenience, MorphSVGPlugin automatically records the original path data for the element so that if you ever want to animate back to it (like to("#redPrimary", 2, {morphSVG:"#redPrimary"}), it knows to grab that. It's all automatic :)
So if you want to repeatedly bounce between those morphs, a simple TimelineMax is probably the easiest way. Get rid of all that setTimeout() stuff and just do this:
var tl = new TimelineMax({repeat:-1, delay:2});
tl.to("#redPrimary", 2, {morphSVG:"#redSecondary", ease:Power1.easeInOut})
.to("#redPrimary", 2, {morphSVG:"#redPrimary", ease:Power1.easeInOut});
Does that help? I'm not entirely sure that I understood your goal properly with the animation, but hopefully this nudges you in the right direction.
Happy tweening!

Related

Can't get GSAP to return to initial state

... and I've scoured the web for answers.
I boiled down the problem as much as I could in this jsfiddle:
https://jsfiddle.net/tko8rk5j/14/
There are 2 button, you click Go then Boost.
I'm trying to get the whole svg back to its initial position after the end of the Boost animation, so you can play the same sequence again and again.
I attempted various solutions suggested in other posts:
// tl.pause(0);
// tl.restart();
// tl.remove();
I also tried using the repeating TimeLineMax, but that just repeats the first animation sequence after the first click on Go button.
I'm not quite sure about what you're ultimately trying to do (which could greatly influence how I'd recommend building this effect), but here's a fork that I believe delivers the result you were asking for:
https://jsfiddle.net/2q1qrvty/7/
Your code was jumping back to the beginning before your animation even had a chance to run at all. Plus it was re-using the same timeline and constantly adding to it which isn't very efficient.
To make it go back to the beginning and stop as soon as it's done, just use an onComplete callback, like:
tl.eventCallback("onComplete", function() {
tl.pause(0);
});
There are a bunch of other ways to do this, but I don't want to overwhelm you :)
You may have better luck asking your questions in the dedicated GSAP forums at https://greensock.com/forums/
Happy tweening!

Smooth animation of three shapes in SciLab

This answer provides a nice way to make smooth animations in SciLab. I now have to write a simulation of a body attached to two strings (and therefore its movement regarding some additional forces).
The code in the link works well to render movement of a single point and, unfortunately, I didn't manage to make an animation of a point + two lines using this method. If someone is curious, I tried this code to do it:
frametime=(tk-t0)/Nt//defining the waitnig time
plot(Y(1,1),Y(2,1),"o")//plotting the point
plot([0;Y(1,1)],[0;Y(2,1)],style=1)
plot([D;Y(1,1)],[0;Y(2,1)],style=1)//plotting the two initial lines
h1_compound = gce();
h_point=h1_compound.children
h_point.mark_size = 20;
h_point.mark_background = 2;
h_line1=h_compound.children
h_line2=h_compound.children
//h_axes = gca();
//h_axes.data_bounds = [0,-1;10,1];
realtimeinit(frametime);
for i=1:Nt//my vectors have Nt points
realtime(i);//wait "frametime" seconds before drawing the new position
h_point.data=[Y(1,i),Y(2,i)];
h_line1.data=[[0;Y(1,i)],[0;Y(2,i)]]
h_line2.data=[[D;Y(1,i)],[0;Y(2,i)]]
end
The question is: is there any way to make an animation of three shapes without making axes blink (as it is with the window refreshment) or other wierd stuff?
Since you didn't create a MCVE I can't reproduce your exact problem. But you may try to add drawlater(); before, and drawnow(); after your data modification to see if it does help with blinking or not.
Or you may get much better looking result by saving your plots in every round with xs2gif and assemble the animation with another gifmaker progam (there are free online sites to do this, however with some limitations). If you need to present your result, you should do this step anyway.

Inconsistent transparency, looking like render order issue

I am using r82.
I have a mesh with multiple materials. I can change their opacity just fine, but how they are rendered is what I would call "splotchy". I have been using ThreeJs for a while, and EDIT: was able to get the transparency working in a past version (r67) with the same model in a significantly more consistent way. So I was wondering if there is something that now I need to set that I didn't need to set before or if I am just overlooking something. Upon revisiting my older code and testing it again, I found that the same transparency issues were present. It was simply a matter of there not being as obvious "splotches" (and not testing enough, I'm sure). Here is a screenshot.
Here are a few more pictures I took that highlight the issue a bit better. I have the outside wall in a light grey and the floors a dark grey in the model and can toggle the outside walls to be visible or not. In these pictures I have one face of the outside wall purple and a face of the floor in the room on the other side of the wall green.
Based on the angle of the camera, it makes part of the green floor face invisible even though there is only one face between the camera and it.
The materials are all double sided already and there is no sign of this until the transparency is on. I found a similar question that suggested changing the mesh.setFaceCulling (or something similar) but that seemed to be from an older version and wasn't in r82.
Thanks for any help in advance!
EDIT:
I started looking into the old version of threeJS and the current version's source code to see what is done differently regarding transparency. I found transparentObjects, which is an array of the objects (I believe faces) that are going to be rendered and are in sorted based on "reversePainterSortStable". There is another list of objects (I believe for the materials objects, maybe?) called opaqueObjects that uses "painterSortStable". So to see if changing the sort order would change the outcome of how things are looking when transparent I changed it so that transparentObjects got sorted by "painterSortStable" and it did change how things showed up significantly (granted it didn't fix my problem since it just removed some problem spots and created new ones).
So the short version, it looks like it is an issue with the renderOrder of the faces.
That being said, I tried finding how the r67 version of the code handled the "renderOrder" of the faces since it wasn't something that (to my knowledge) could be set in that version and just did it automatically. But I have had no such luck tracking down how it was done as of yet.
So I see two possibilities. 1) find out how the past version correctly did transparency (at least for my purposes) and change the logic in the current version to use that. Or 2) find how to properly set the renderOrder of the faces based on the camera position in the scene. Will look into the second option first, but figured it would be good to document this for others looking to help answer or that have a similar problem.
EDIT 2:
So digging through the source code for threeJs and noticed something about the transparentObjects array I mentioned in the previous edit. The first, that I cannot for the life of me figure out how it gets populated since it doesn't seem like it is added to anywhere in the code. The second is that I think it is being populated with duplicates of the entire building object/mesh (see screenshot below).
The z indexes all seem to be the same. as well as the ids and the objects are all of type "mesh" (of the ones I looked through, granted, since there are a few thousand). So I was going to figure out why its adding what is being added to the array, but that is when I stumbled across the issue of not finding where in the code that the transparentObjects array actually get populated.
EDIT 3:
WestLangley, I tried setting the depth test for the outer wall material to false and got this. Like I said in my response comment, even if it did work it wouldn't fix the issues experienced with the camera inside the building, but wanted to follow up none the less (see snapshot below).

allowRotation in SceneKit?

How can I disallow rotation of a node in SceneKit?
For ex., I want a model (cone) to be dynamic, jumping and flying, but always vertically oriented?
I tried fix it like in apple's vehicle demo, it is bad solution. Also I tried below code, but model just slowly and glitchy falls down
- (void)renderer:(id<SCNSceneRenderer>)aRenderer didSimulatePhysicsAtTime:(NSTimeInterval)time{
_node.rotation = SCNVector4Make(0, 0, 0, 0);
//[_node.physicsBody resetTransform]; // - tried this too
}
...and finally I did not find any "allowRotation=NO" in scenekit manuals.
Instead of a Boolean allowsRotation flag like in SpriteKit, SceneKit lets you choose which directions a body is allowed to rotate in and by how much. See the angularVelocityFactor property.
This is probably a better idea than toggling the mass between different values — that approach looks like it could be unintended behavior, so you might not want to rely on it.
If you want to mix physics simulation and manual transforms, make sure to use a "kinematicBody" and not a "dynamicBody".
Ahaha, I found some bug solving this problem (but this is a bug, so it is weird)
create node
set mass=1
add node to scene
set mass=0 - this makes it static and unmovable, but...
set mass=1 - this makes it dynamic, jumping and falling but with fixed rotation!
iOS 8.0.2 iPad mini
Simple solution:
node.physicsBody?.allowsRotation = false

How to exit().transition rects under a col in d3

I have a stacked bar chart that shows values either for month or year.
It is composed of a series of columns (1 or 12), and rects within each column (9 individual values).
You can see it here: (Note - this is a valid web page, currently running on AWS.)
http://54.245.225.47/stackedbar_ex_good
When I go from months to year view, I want to move all the positions to the yearly value, then fade them out as the year values .enter().
The problem is that the rects (where I would normally do the .exit().transition().attr("y", new_val) never gets called since the column gets deleted (.exit()). And when I tried referencing the child .rects from the svg.selectAll(".col").exit().transition(), they seemed to disappear all at once. I'm guessing this is the wrong way.
Sorry this is so confusing! I'm sure this sort of thing is answered elsewhere, but I don't even know the language to describe it properly (and hence search for it). Any tips / pointers would be appreciated.
(There is a lot of code - I don't know how to simplify in order to even post it.)
Yeah, kinda hard to understand the problem... As I understand it, you want to animate the exiting rects to some position before they're removed from the SVG. But your problem is that the rects' parents –– col in your code –– are removed immediately, and so the nested rects never have a chance to animate. Right?
If so, one way around it is to delay the removal of the exiting col's in order to give the rects animation time to play. So, rather than doing:
col.exit().remove()
apply a the delay like so:
col.exit().transition().delay(2000).remove()
There's no actual, visible transition here; it's just a way to delay the call to remove().

Resources