I've been working on a simulation that's pretty bloody huge, which meant it became necesary to zoom in and out.
I found a good working script but when the simulation got bigger I found it had a problem...
The more you zoom in, the smaller the steps became and the further you zoom out, the bigger.
This is a problem because I need the steps to be equal no matter what zoom level you are.
The script I'm using now is:
var total = 75,
delta = e.detail ? e.detail * -120 : e.wheelDelta; //e is mouse event
this.zoomValue += (delta > 0) ? 1 : -1;
this.zoomRatio = 1 + (this.zoomValue / total) * 2;
e.preventDefault();
You can see it in action here: http://clanpvp.com/sol (if it's not working, I'm either fiddling with it or you are using Internet Explorer)
I use the zoomRatio later to calculate the positions of various objects.
Who knows of a better way to zoom in?
The anwser is very simple actualy... yet I needed somebody to show me before I saw it myself.
The solution is to have it zoom exponentialy, so
this.zoomRatio = Math.exp(this.zoomValue);
Does the trick, you can do something like
this.zoomRatio = Math.exp(this.zoomValue / 10);
To make it scroll in smaller 'steps'.
Related
So I am trying to make a website in which I can place these NATO units on a map. It's all been going well so far until I started to work on the zoom function. The goal is to zoom the map canvas by a constant factor of either 2 or 0.5 and all of the units would retain their center position in relation to the map. However, these units will all remain the same size due to the inability to see small units.
I am currently having difficulties understanding why the zoom doesn't currently work. A quick run through the website reveals some major flaws. I suspect it has to do something with these two lines, lines 177 and 178 of the zoom(level) function in draw.js:
draggableElementsA[i].style.top = (draggableElementsA[i].getBoundingClientRect().top + (draggableElementsA[i].getBoundingClientRect().height / 2) - c1) * level - (draggableElementsA[i].getBoundingClientRect().height / 2) + canvas.getBoundingClientRect().top + "px";
draggableElementsA[i].style.left = (draggableElementsA[i].getBoundingClientRect().left + (draggableElementsA[i].getBoundingClientRect().width / 2) - c2) * level - (draggableElementsA[i].getBoundingClientRect().width / 2) + canvas.getBoundingClientRect().left + "px";
The context should be made clear on the actual file. This function performs an odd operation: it moves the units off the screen, far greater than any of the individual measurements. Any help is greatly appreciated!
I believe the issue arises when scrolling while in the zoomed state. Specifically, zooming in, moving an object, and unzooming results in the item being offset.
When recording the XY coordinates, specifically in these two lines:
pos3 = parseInt(e.clientX);
pos4 = parseInt(e.clientY);
record the position relative to the top of the game board, not simply the position of the mouse cursor on the screen.
I have figured out a nice effect from application that needs several UI elements but also requires as much screen space as possible.
Idea of the effect is, that the UI buttons almost dissapear as soon as you move the mouse too away from them.
I have made a jsFiddle in case you'd like to see it.
It's quite simple:
window.addEventListener("mousemove", function(e) {
var rect = element.getBoundingClientRect();
//Measuring distance from top-left corner of the div
var top = rect.top+(rect.bottom-rect.top)/2;
var left = rect.left+(rect.right-rect.left)/2;
//Mouse position
var x = e.clientX;
var y = e.clientY;
//Thank pythagoras for this
var distance = Math.sqrt(Math.pow(x-left, 2)+Math.pow(y-top, 2));
//Brightness in interval <1, 0.1>
var brightness = Math.min(1, Math.max(0.1, 100/distance));
element.style.opacity = brightness+"";
});
This jsFiddle was also supposed to demonstrate problem I have - but it runs unexpectedly smoothly.
The problem is, that the browsers seem to buffer the CSS changes if they are too frequent. This is a very smart performance strategy but in my case it quite breaks the effect.
I have also uploaded test script here. In Google Chrome, buffering appeared to be so strong (and unsynchronized), that the buttons sometimes flickered.
Should I implement some frame-skip so that the browser buffer is not initiated by the animation effect?
My buttons have their bottom border cut off. If you'd know why this happens, please let me know in comments
I implemented a simple draggable world map for a game but the performance differs when using different browsers - which is kinda obvious. I used 256x256 pixle tiles and the script dynamically renders the number to fill the whole window plus borders.
Prototype: http://mt111102.students.fhstp.ac.at/draggable/game.html
Currently I'm doing it simply by setting the top and left style attributes on mousemove. Heres a snippet:
mouseDown : function(e) {
Map.myPreventDefault(e);
dx = map.offsetLeft - e.clientX;
dy = map.offsetTop - e.clientY;
map.addEventListener('mousemove', Map.divMove, false);
},
divMove : function(e) {
Map.myPreventDefault(e);
map.style.position = "absolute";
map.style.cursor = "move";
map.style.left = e.clientX + dx + "px";
map.style.top = e.clientY + dy + "px";
}
Later when dragging to the borders I'm gonna load new tiles with XHR and delete old ones on the other end to retain performance so that the wrapper doesn't get to big.
My question is: Would it be more performant by using CSS translate instead of just setting the top and left attributes? And do you guys have any tips how to make it smoother?
In Firefox the prototype works almost perfectly smooth but in Webkit browsers like Chrome it doesn't look very good - it lags a bit. I just wonder how Google Maps managed it to work in every modern browser with the same smoothness.
A CSS transform, especially with a Z value (which will load the transform into the GPU), will almost always be faster and smoother - especially on devices like iPads, but elsewhere as well.
For more details you can check out this tutorial on GPU acceleration:
http://creativejs.com/2011/12/day-2-gpu-accelerate-your-dom-elements/
I'm trying to make the so called fine tune thing. Basically this looks like: http://jsfiddle.net/r9KQK/1/
Later I'll have some audio player and this thing will help to select seconds when we use it on a tablet.
The problem is when you try to move the red circle it strangely drops when it passes top and bottom of the green circle, but not at 0 or PI/2, something like at -260..-269 and 181..190 degrees
Just try to move it and you'll see the bug.
What's wrong in my code?
Thanks in advance
update
Last update: http://jsfiddle.net/r9KQK/17/
In this example I get degrees in 0..360 range. But instead I should get delta degrees between the point where I start dragging and where I end it, but I can't work out the maths. I should also take into account the direction of red circle, so that delta will be + or - =\
update
Finally: http://jsfiddle.net/r9KQK/18/
But the code is really awful. Though it's 2:46 AM and I'm kind of sleepy, so...
But anyway I think it could be much more simplified
That's happening because your parameter to Math.atan goes to infinity when DeltaX is zero. I recommend using atan2, which automatically handles this corner case:
function(dx, dy, x, y)
{
var deltaY = this.oy + dy - fineTuning.ring.attr('cy');
var deltaX = this.ox + dx - fineTuning.ring.attr('cx');
var angle = Math.atan2( deltaY, deltaX );
// etcetera, etcetera
Or check the fiddle.
I made a script that draws a series of lines on a canvas that makes it look like a sketch. There are two issues with the script. One, why is the y value twice as much as it should be? And two, why is the line several pixels wide and faded out?
I've tried it in both Google Chrome and Firefox and I get the same incorrect results. I realize that I can divide the y value by two to fix the first problem but that part of my question is why do I need to do that. I shouldn't have to.
I think you have two issues:
You need to be more careful in how you calculate the offset of where to draw. I have some code below that demonstrates how to handle this properly.
You aren't setting the width and height on the <canvas> element itself, which means it will scale your lines in funny ways depending how what you've set in your css.
An Example
I built a simple collaborative drawing app using <canvas> and socket.io that lets you draw to the screen like a pencil. You can check it out here:
http://xjamundx.no.de/
The source is also on github if that might help:
https://github.com/xjamundx/CollabPaintJS/ (main repo)
https://github.com/xjamundx/CollabPaintJS/blob/master/public/collabpaint.js (canvas drawing code)
In particular I do something like this to figure out where to draw things:
x = e.clientX + window.scrollX
y = e.clientY + window.scrollY
x -= $game.offsetLeft
y -= $game.offsetTop
Give a width and a height to your canvas; always !
http://jsfiddle.net/mz6hK/7/
fixed