I'm attempting to render a scrolling axis at 60 fps. It was nearly as simple as updating the scale's domain and calling axisGroupElement.call(axis) inside a loop. Unfortunately at different scales that produces some very smooth animations where the ticks and the text will jiggle.
http://jsfiddle.net/langdonx/fTcrU/11/
The jiggling probably depends on the width of the container and the length of the scale's domain... try changing the drop down for different results.
So, I thought I'd be creative and render the axis 3 times the size I needed and transform the entire group for a smoother scroll. That unfortunately produces nearly the same results.
I went a step further and moved the entire SVG element, which is a little smoother, but a huge hack.
There's also a problem where I can't get my own transform scrolling at the same rate the redraw scrolls at. It seems to fall behind over time. I thought I had it nailed down by calculating milliseconds per pixel, but that doesn't appear to be totally correct. It's interesting to see how it certain resolutions it'll tick along at 1px, store the remaining milliseconds, and then some ticks will adjust it 2px.
Is there anything I can do or is scrolling these irregular widths/time spans always going to produce animations that aren't smooth?
TIA!
The axis redraw example looks nicer because it sets the transform values more exactly as floating point numbers, whereas your calculation for transform produces integers.
I've amended your algorithm to produce floats, and now the "Redraw" and "Redraw and Transform" examples look identical.
http://jsfiddle.net/xJJHM/1/
The relevant change is
_left -= msPassed / _msPerPixel;
I tried to do the same with the left-positioning, but it turns out that you need integer values for that.
I found an article/video by Paul Irish which explains this in more detail: http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/
Related
Sorry for the vague title, but I'm not exactly sure what to call this. I'm making an assignment planner using HTML and JavaScript, and I've ran into a bit of a problem while trying to make a feature to snap your text to the nearest line.
The planner itself looks like this
The "Snap to Line" feature works by checking the Y coordinate of the note (which is an input element) and checking the nearest line. I know it's not good practice, but to make it easier everything is a fixed size, so I have an array of every line's Y coordinate it could snap to:
[58,80,102,124,146,168,190,212,234,257,279,301,323,345,367,389,411,434,458,480,502,524,546,568,590,612]
When the user creates a note or change's its position, this bit of code runs:
let height = parseInt(window.getComputedStyle(e.target).getPropertyValue('height'));
e.target.style.top = getClosest(yCoord+(height/2))-(height/2)
So it gets the element's height, then finds the Y coordinate of the closest line and subtracts half the height of the element to find the proper coordinates.
I arbitrarily used height/2 as opposed to height. I thought that since the coordinate is of the line, it would need to be exactly height higher up, which makes perfect sense, but in practice for whatever reason that didn't work, and height/2 was able to give me better, somewhat better results.
However, if I use the function, it doesn't exactly work. I've tried many different methods but I can't seem to figure it out. This is the result. As you can see, it works pretty well for smaller heights, but it's as if there's an offset relative to the height of the element that affects the position. Is the problem because my method is terribly wrong? (probably) Or is there just some factor that I've been forgetting?
There aren't any borders, no margins, the padding is only 1px, but that shouldn't matter anyway since I use getComputedStyle (which I believe takes everything into account) to find the height and not the font size.
The code surrounding this feature is only a small part in a decently sized project, but I'm posting the entire document so that it may be easier to fix this.
Thanks!
note: the window with the planner on it is a popup, so your browser might block it
The code (too many characters for this post so it's on pastebin)
EDIT: I think I found the problem, no surprise that I found it just as I posted this. First of all, I needed to use height and not height/2 (no surprise there, makes sense). I though I needed to use height/2 because I was testing with small heights and the snap points were a few pixels off (7, to be exact) which made it seem like height/2 was better. Two, the main problem, is that since I used height instead of font-size, the height was the height of the entire element which meant that the bottom of the P hit the line instead of going past it.
Currently, I'm doing a mini game which only has a box and a character.
The character can freely move around. I did so it moves 640px/second. The "formula" I use to get the pixels to move each frame is ((currentFrameTimeMs - lastFrameTimeMs) * pxPerSecond) / 1000. Actual values are ((currentFrameTimeMs - lastFrameTimeMs) * 640) / 1000. This effectively makes my character to move exactly 640px/s.
But the problem is that when moving, I see it as "fuzzy". I've checked out the FPS, and it's very far above 60, yet the image still looks fuzzy.
Is there any technique to remove that blurriness? I've played desktop games which have objects moving pretty fast, and they don't blur, so I suppose there's some trick for that.
Problem solved.
Problem was with FPS, they were under 60. I was using a wrong approach (with requestAnimationFrame, but wrong calculations).
Round the result so your image will always be at an exact pixel index, rather than "between" pixels. If you don't round, the pixels of your image will be "spread" between pixels and might appear blurry.
I've seen this "The Scale of the Universe 2" and I just want to know if this can be done with javascript or jQuery or with HTML5 Canvas.
If you click an item (example the "Human") , an info will pop out beside it.
I searched for 3 days here if someone has a similar question. But I only saw Google Map like behavior where you can zoom in on the map cursor position.
Actually I want to make a "Timeline" like effect or, like the "Time Machine" Recovery on Mac OS X.
Fixed position of zoom. Not like a google map zoom, that you can pan and zoom anywhere.
Can I put (example "The human") images and text on a div?
Are there available articles/tutorials about this?
Options:
Javascript
jQuery
HTML5 Canvas and CSS3 Transform and scrolling it to Z-axis so you can zoom in/out.
Flash/Flex (Well I don't want to use lots of resources on CPU because I need it in a large resolution or in full screen.
It is possible to implement an infinite zoom in HTML canvas, this is the source code of a proof of concept that I implemented and here you can test it live.
It is actually quite tricky to implement, and most probably you'll need to use big decimals.
The approach I followed uses the same coordinate space as d3-zoom. Basically, you have three coordinates, x, y and k. K is the zoom. If k is 2 it means that you have doubled everything.
Now, if you want to do infinite zoom, it is very easy to reach k = 64, but that is already outside of float64 precision and you'll have a lot of artifacts, where translating in the image is not smooth, or you don't zoom in where you want.
One way to avoid those artifacts is to use coordinates that have infinite length, for example BigIntegers. To make my implementation easy and compatible with d3-zoom, I used big decimals instead, but I had to implement my own library of BigDecimals, basically infinite precission on the integer part and 32bits of precision on the decimal part. Of course, you also need to adapt the zooming library to support BigDecimals. Moreover, in the case of d3-zoom, a lot of calculations where done in the initial coordinate space (k=1) but division of floats will always have an error and it is also perceivable once you are deep enough. To avoid that you need to do all computations locally.
It might sound like a lot of hassle to insist on using the d3-zoom library, but zooming UX is actually tricky, specially if you combine that at different k, you'll need to consider scrolling, zooming on the phone, double tapping...
In case you want to use SVG transformations, then you'll need to fake it. You'll introduce nodes when they are barely visible, allow to scale them. However, most probably you'll also need to fake it when they are too big to avoid artifacts there.
There is no infinite zoom. However you can zoom in/out of an SVG image in HTML5 canvas.
SVG supports affine tranformation. You can set the required zoom/pan in the affine transform and show the relavant areas. The behavior/listener can be implemented in Javascript and the SVG can be rendered on HTML5 canvas.
As a starting point you can look at this example: http://www.html5canvastutorials.com/labs/html5-canvas-scaling-a-drawing-with-plus-and-minus-buttons/
This is totally doable in HTML5. Actually, any system able to display and zoom images should be able to. It's not one big image being zoomed, it's a big amount of images being zoomed (for instance the initial human is an image, which is scaled and moved out when you zoom in or out). The idea is splendid, but I don't really see any technical performance in it. As long as you correctly limit the number of images being resized and bitmapped, it should keep a decent FPS rate.
I have a D3 setup using "Nodes" and "Lines". When the graph first appears, it bounces in with gravity until it settles in the middle. Does anyone know of a way to have it appear automatically in the middle without the "bounce" sort of effect?
P.S I am using force layout
Calling start resets the cooling parameter, alpha; alpha decays exponentially as the layout converges on its solution, and then stops so as to avoid wasting the cpu. There's no jittering on start (other than coincident nodes, which is necessary to avoid a divide by zero). However, anytime you have conflicting forces and geometric constraints (links), it's natural to expect the layout to adjust when starting.
If you want to avoid this bounce, you either need to keep the graph permanently hot (say by calling d3.timer(function() { force.resume(); })) or you'd need to do something else, like adjust the alpha parameter manually to reheat gradually instead of instantaneously.
Edit: In 2.8.x, you can avoid the first bounce entirely by running the force layout synchronously on startup. For example: http://bl.ocks.org/1667139
Another strategy I've used before is to gradually increase the radii of each node from zero over the first, say, 50 or 100 force ticks. You can see what that looks like (in Protovis, but it would behave the same way in d3) in the Dorling cartograms on the one.org data site.
I've put together some key frame animations in CSS which animate a div from one side of the screen to the other, applying a slight rotation along the way. I'm finding the key frame approach restrictive because I want to be able to have many variations that go into one big sequence. The variations could as an example be not just left to right, right to left but also up to down and so on. To add more complexity to the problem, I need to be able to shuffle up this sequence and retain continuity between each animation.
The sequence itself should be able to run in any order and reset.
For example if I want to move the div in 100px phases:
left (100px), up (100px), left (100px) and then down(100px)
the next time I might want the sequence as follows (again 100px):
left, down, right, up
My thinking is that this would be better achieved by using JavaScript to write the animations on the fly perhaps using something like the CSS3 Matrix. So far I've figured out the easy stuff like left and right but I can't figure out how to add in rotation. This seems like a really good starting point:
http://www.useragentman.com/blog/2011/01/07/css3-matrix-transform-for-the-mathematically-challenged/
http://www.eleqtriq.com/2010/05/css-3d-matrix-transformations/
Also been taking a look at this:
http://tweenjs.com/
My thoughts are, a) am I over-complicating this by taking the CSS Matrix approach? Is there something simpler? and b) How can I achieve rotation and movement at the same time using the CSS Matrix or any other approach?
Any help appreciated!
If you want to do dynamic animations, then you should be using JavaScript to animate.
As far as how to combine translation with rotation, the answer is right there in the useragentman post (which incidentally is a very good introduction to css matrixes.)
Take the angle of rotation (in radians) that you want to achieve and create the following matrix:
Cos(angle), -Sin(angle), 0
Sin(angle), Cos(angle), 0
0, 0, 1
then create the following matrix for your (presumably 2D) movement in x and y.
0,0,X
0,0,Y
0,0,1
Then multiply them together (or take the dot product in matrix terminology). Here is a handy matrix multiplier for you, the details of how to create a dot product are also in the same post.
Note that these are transforms (not position changes) and transforms don't affect affect page position.