Most people mention that you must use the stagger behavior to animate opacity. How do you use the stagger function to have an object slowly fade into existence. The documentation doesn't say much but what the values mean.
Create the stagger function. Then animate the stagger function by going to certain frames and changing the maximum value to generate a keyframe. All the stagger function does is generate number values. So, hold the dot on the right side of the stagger function and drag it on to your object's opacity. This inputs the stagger function's value into the opacity value. Then it should work as intended.
The stagger function is a general value generator function, it's not just for opacity. Drag onto other values to animate them as well.
Related
I've got a scene where I'm drawing(to scale) the earth, moon, and some spacecraft. When the moon is occluded by the earth, instead of disappearing, it is still visible (through the earth).
From my research I found that part of the problem is that the near settings for my camera were much too small, as detailed in the article linked, small values of near cause rounding in z-sorting to get fuddled for very distant objects.
The complexity here is that I need to have fine grain z-indexes for when the camera is zoomed in, to look at a spacecraft (an object with a radius of 61 meters at most, in comparison to the earth, weighing in at r =~ 6.5e+06 meters). In order to make objects on the scale of the moon and earth to render in the correct order, the near has to be at least 100,000 m at which point I cannot look at close objects.
One solution would be to reduce the scale to use kilometers, but I cannot afford to lose that precision, and prefer to use meters.
Any ideas as to how to make very large, distant objects render at the correct z Indices, while retaining scale and ability to zoom into small objects?
My Ideas (which I don't know how to implement):
Change z-buffer to include more values, and higher resolution?
Add distant objects to a "farScene" which is rendered using a "farCamera" which is controlled by the same controls used on a close-up camera?
As per #WestLangley 's answer, the solution is simply to add the optionlogarithmicDepthBuffer: true to the renderer:
this.renderer = new THREE.WebGLRenderer({antialias: true, logarithmicDepthBuffer: true});
Probably that the problem is z-test and not z-precision. this mean: z-test not apply (perhaps because that you render transparent object with alpha blending) or z-test apply with non default testing (e.g. override far instead near).
Try to render the whole scene with simple shader with no transparency in-order to make sure that transparency is not the source of the bug.
to solve the z-order without z-test you should sort the object yourself each frame to determine the order of rendering (from far to close).
Is there a way to universally multiply physics2D calculations on the canvas?
I'm trying to make a set of canvas UI elements with 2D physic properties. The objects contain images and text, but need to respond to gravity, impacts, and overlapping collision boxes with other GUI elements.
I've added 2D RigidBody and boxCollider components to my objects. However, they move very slowly. If given a gravity, they fall slowly. If overlapped, they push each other apart slowly.
I've figured out that this is due to the canvas having a very large scale. My objects are effectively 'very big and very far away'.
I can't modify the canvas scale. It needs to be huge or I get render artifacts.
I can't just modify gravity because it doesn't provide a universal fix. Things fall faster, but they don't push apart or spring right.
I can't modify the timestep because it affects the whole world, not just the canvas.
My canvas objects have widths akin to 80, where unity physics expects widths akin to 1. How can I get them to behave like they have a width of 1?
Is there some universal scaling factor for canvas based physics, or am I simply mis-using the canvas for something it is not intended for?
if you are still having this problem, the answer to fixing the movement rates of your scaled-up objects is to scale up your movement forces as well as your gravity. If you can't get certain elements to work right, use a forcepush that you can set to any strength.
I'm trying to build a stock chart with zooming functionality using D3.js
I'm looking to start with this example here and attempt to make the zoom feel more natural for a stock chart. A perfect example is this. So the difference as far as I understand is that zoomng and panning are both locked on the Y-axis, and the only way the Y-axis moves is to autmatically fill the price range of the currently visible data.
Another noticeable difference is that zooming does not zoom into the current position of the mouse like it does in the first example.
How can the example be adjusted to work more closely as the other chart? What is the pertitent code, how should it be changed?
Setting the zoom behaviour to not affect the y-axis is simple: just don't attach your y-scale to the zoom behaviour.
In the sample code you linked to, the zoom functionality is added in this line:
this.plot.call(d3.behavior.zoom()
.x(this.x)
.y(this.y)
.on("zoom", this.redraw() )
);
That creates a zoom behaviour object/function, links it to the graphs x and y scales, and tells it to call the function returned by this.redraw() after every zoom event. The zoom behaviour automatically changes the domain of the scales on zoom, and then the redraw function uses the modified zoom. If you don't give it a y scale to modify, then zooming won't affect the y domain.
Getting the y scale to automatically adjust to the given extent of the data is a little trickier. However, remember that the zoom behaviour will have automatically adjusted the domain of the x scale to represent the extent of visible data horizontally. You'll then have to get the corresponding slice of your data array and figure out the extent of y values from it, set your y domain accordingly, and then call the redraw function (remembering that this.redraw() just returns the redraw function, to call it within another function you'll need to use this.redraw()() ).
To have the zoom be independent of the mouse position, set a center point for the zoom behaviour.
I have a large dataset in an array which translates into about a million 6-pixel wide bars,
Given that about 130 bars fit into 800 pixels of screen, I need to only display a portion of the data at a time. Then, when the user pans the chart, new data will be added and non-visible data will be removed. The user could pan right or left so data need to be able to enter and exit from both sides of the chart.
I feel like the solution involves D3's enter and exit, but I'm unsure how to implement it.
One idea I've had is to use Array.prototype.concat and redraw on pan. Another idea would be to use Array.prototype.slice. I hope those are fast enough.
Any examples?
There are no examples that I'm aware of. Roughly, you would need to do the following.
Draw the initial bar chart. Pass in only the data you'll display (i.e. the first 130 data points if your screen is 800px wide).
On pan, get the translation for the pan. The x translation corresponds to a certain number of bars. Take off this many data points from the beginning of your data array and add that many to the end.
Pass that new data array to D3 and redraw. This tutorial should give you some pointers. Remember to pass a key function to .data() so it knows how to match data to DOM elements.
Similar thing on subsequent pans. Figure out how many bars have been panned and modify the data array accordingly (e.g. using slice and concat -- doesn't matter that much). Redraw the bars.
The concept is very similar to what's done in the tutorial I've linked to, except that the redraw isn't triggered by a timer, but by the pan event.
There are fundamentally two ways to do this. One is that you draw all 1M bars using svg and rely on svg's built in panning. The other is that you draw 130 bars and redraw each time the user pans. enter() and exit() are useful for doing things to data elements in your set that are entering or exiting the scene since the last time it rendered. (d3 determines which elements are
"new" by calling a predicate function on each element. The function has a default but can be user supplied.) You don't actually have to use them here unless you want to be fancy. You can just selectAll the rects from last draw, and .data() them with your new data, and supply the usual calls for drawing rects.
I have a general question (I know I should present specific code with a problem, but in my case the problem is of a more general nature).
In Processing, let's say I make an ellipse:
ellipse(30, 30, 10, 10);
Now, is there a way to get the pixels where this ellipse is on the canvas? The reason would be to have a way of creating user interaction with the mouse (for instance). So when someone clicks the mouse over the ellipse, something happens.
I thought of turning everything into objects and use a constructor to somehow store the position of the shape, but this is easier said than done, particularly for more complex shapes. And that is what I am interested in. It's one thing to calculate the position of an ellipse, but what about more complex shapes? Are there any libraries?
Check out the geomerative library. It has a way to check whether the mouse is inside any SVG shape. I can't remember off the top of my head but it works something like you make a shape:
myShape = RG.loadShape("shape.svg");
and a point:
RPoint p = new RPoint(mouseX, mouseY);
and the boolean function contains() will tell you if the point is inside the shape:
myShape.contains(p);
It's better to use a mathematical formula than pixel-by-pixel checking of the mouse position (it's much faster, and involves less code).
For a perfect circle, you can calculate the Euclidean distance using Pythagoras' theorem. Assume your circle is centred at position (circleX,circleY), and has a radius (not diameter) of circleR. You can check if the mouse is over the circle like this:
if(sq(mouseX-circleX)+sq(mouseY-circleY) <= sq(circleR)) {
// mouse is over circle
} else {
// mouse is not over circle
}
This approach basically imagines a right-angled triangle, where the hypotenuse (the longest side) runs from the centre of the circle to the mouse position. It uses Pythagoras' theorem to calculate the length of that hypotenuse, and if it's less than the circle's radius then the mouse is inside the circle. (It includes a slight optimisation though -- it's comparing squares to avoid doing a square root, as that can be comparatively slow.)
An alternative to my original mathematical answer also occurred to me. If you can afford the memory and processing power of drawing all your UI elements twice then you can get good results by using a secondary buffer.
The principle involves having an off-screen graphics buffer (e.g. using PGraphics). It must be exactly the same size as the main display, and have anti-aliasing disabled. Draw all your interactive UI elements (buttons etc.) to this buffer. However, instead of drawing them the normal way, give each one a unique colour which it uses for fill and stroke (don't add any text or images... just solid colours). For example, one button might be entirely red, and another entirely green. Any other RGB value works, as long as each item has a unique colour. Make sure the background has a unique colour too.
The user never sees that buffer, so don't draw it to the screen (unless you're debugging or something). When you want to detect what item the mouse is over, just lookup the mouse position on that off-screen buffer. Get the pixel colour at that location, and match it to the UI element.
After you've done all that, just go ahead and draw everything to the main display as normal.
It's worth noting that you can cut-down the processing time of this approach a lot if your UI elements never (or rarely) move. You only need to redraw the secondary buffer when something appears/disappears, animates, or changes size/position.