When you are pretty far zoomed out on a google map, you can drag it enough so that the map ends and becomes a blank gray color. The map seems to repeat seemlessly on the horizontal axis, but not vertically.I'm wondering if there is a way to prevent the map from being dragged when it reaches that gray area. Any ideas?
Just for fun, another approach would be to tell the map to wrap vertically in the same way that it wraps horizontally, by overwriting GMercatorProjection.prototype.tileCheckRange before creating the map.
GMercatorProjection.prototype.tileCheckRange=function(a,b,c){
var d = 1<<b;
if (a.y<0||a.y>=d) {
a.y=a.y%d;
if(a.y<0){
a.y+=d;
}
}
if(a.x<0||a.x>=d){
a.x=a.x%d;
if(a.x<0){
a.x+=d;
}
}
return true
}
The downside is that the API doesn't contain any code for causing the markers and polylines to jump vertically to the copy of the map that's in view, they only jump horizontally. A complete solution would require writing own code to do the vertical jumps, and use unbounded GLatLngs throughout.
This is a good example of how to limit the range of a map. It's a bit of a hack, but it's probably your only real option.
Related
Using svg-pan-zoom utility, I want to register the zoom and pan values every time is changes (using onPan() and onZoom()) and use these saved values to pan and zoom my SVG to the same position (using pan() and zoom()).
I works fine if the zoom level is not changed, however, if zoom level is changed, I have a gap between the wanted position of the svg and the real one.
You can see this problem in that fiddle: first, zoom in, then press the Pan button.
I would like my svg to keep its current location.
I have read other posts on stackoverflow about similar situations (I guess I should use data from getSizes()) but I'm still unable to make it work.
Any advice?
OK, I got the solution, which is quite obvious.
While zooming, I need to apply a zoom factor to the saved pan.
onZoom: function(zoom) {
ratio = zoom/currentZoom;
currentZoom = zoom;
currentPan = {
x: currentPan.x*ratio,
y: currentPan.y*ratio
}
}
See full code here
I want to achieve the following: "Place an array of markers that may be distributed across a large range of lat, lng into a fitbounds method that places the fitbounds inside a custom rectangle."
The image below should clarify what I'm trying to achieve. Basically I have an array of markers that I want to make sure always fits within a small box on the right hand side of my page.
The white box contains some information pertaining to the markers, which will always be present, so I don't want any markers hidden behind the white box, and I'd love if I could define that they live within the black box. (Note the black box is just a visual reference for this question).
You can use the containsLocation to ensure a point is inside of a polygon. See here.
As you go through each coordinate pair in your array, verify the location is within the polygon area, then add to the map accordingly. You can also set an attribute to those points to "define" what extent they are in.
var latlng = new google.maps.latLng(array[n]);
if (google.maps.geometry.poly.containsLocation(latlng, polygon)){
marker = new google.maps.Marker({
position: latlng,
map: map
});
marker.dataset.box = 'blackbox';
} else {
alert('Not inside black box');
}
If you're using HTML5, you can add a dataset attribute to markers that are within the polygon.
marker.dataset.box = 'blackbox';
If not, you can use setAttribute.
marker.setAttribute('data-box', 'blackbox');
I'm answering my own question (hopefully for your benefit), but this is the issue:
I've created a world map with polylines (in Google maps API v3). Some of these lines span the IDL (international date line). I want to place directional arrows on some of my lines, one arrow in the center of each line. On lines that span the IDL, the arrow center calculated by averaging the 2 end points together:
(latlng1.lat()+latlng2.lat()/2), (latlng1.lng()+latlng2.lng()/2)
draws the line the opposite way around the world leaving a floating arrow on my map instead of in the center of the actual line.
I initially sought a formula for getting the reverse of the line and somehow determining which was used. But it's too dependent on the map display. I even went so far as to see if I could get the center from the end points of the line if I first converted them to pixels, but the data conversion had no effect on the outcome.
So I then thought to look for an intersect method on the polyline, passing a point to check - and if it wasn't, find the center point from the reverse line (which I believe would 180-center.lng()) but there is no intersection method on polylines. So I started looking into the bounds object, because there are some intersection/contains methods on bounds.
So here is a very simple solution for a relatively undocumented problem:
(credit for function to retrieve bounds goes to Ben Appleton, ty):
function getBoundsForPoly(poly) {
var bounds = new google.maps.LatLngBounds;
poly.getPath().forEach(function(latLng) {
bounds.extend(latLng);
});
return bounds;
}
var poly_bounds = MapAbstraction.get_poly_bounds(line);
var center_point =poly_bounds.getCenter();
and then I can pass my center_point to my marker creation tool to generate the arrow in the actual center of the line without worrying about which way it was drawn.
I have a canvas with the following size: 500x200. Inside this canvas i'm drawing some number of blocks (actually - table cells). Information about how much blocks i should draw i'm getting via AJAX, but size for every cell is fixed - 100x50. So, i can display inside my canvas only 5 blocks horizontally and 4 vertically. But what about other blocks? What if script return a table 30x30 cells. How can i side scroll (mouse preferred) my canvas so user can the rest of the cells (no zoom out, only scrolling).
If you need any more information, please, tell me and i will provide it.
Thank you.
The easiest way to accomplish this is to implement mouse-panning.
On the mouse down event, begin panning and save the mouse position
On the mouse move event, translate the context (ctx.translate(x,y)) by the difference between the current mouse position and the original position, then redraw the scene.
On the mouse up event, stop panning.
There are harder ways. You could implement scrollbars inside the canvas, as Mozilla Bespin has done (...which became Mozilla Skywriter which then merged with Ace and dropped all Canvas use). The code that they used was pretty good.
Or you could implement DOM scrollbars for use with your canvas, which isn't exactly easy to get right in all cases. This involves adding several dummy divs in order to give the appearance and function of real scrollbars. I have done this but the code remains unreleased for now. But thats no reason you can't give it a try if thats what you really want.
Check out a great tutorial at: http://www.brighthub.com/hubfolio/matthew-casperson/blog/archive/2009/06/29/game-development-with-javascript-and-the-canvas-element.aspx
It will give you an answer to your question and much much more...
I'm with Simon Sarris on this, but as an alternative, you could clone the canvas, and replace it with a blank canvas, and then render the original canvas as an image. I've some MooTools js that goes like this, which is fine for my use, by ymmv:
var destinationCanvas = this.canvas.clone()l
destinationCanvas.cloneEvents( this.canvas, 'mousemove');
var destCtx = destinationCanvas.getContext('2d');
destCtx.drawImage(
this.canvas,
(this.options.scrollPx)*-1,
0
);
destinationCanvas.replaces( this.canvas );
this.canvas.destroy();
this.canvas = destinationCanvas;
this.ctx = destCtx; // this.canvas.getContext('2d');
I'm using a flip mechanism to navigate through my site (flip file & demo). The problem is, once it's flipped the content been displayed good just like I want it, but there's some offset from the flipped (right) parts en the solid left part (visible when you look closely). Also the right part is now a little blurred (which is the disturbing part of my issue). This all caused by the flip (I think the rotationY is causing the problem).
When I click a button I do the following:
flip=new Flip(currentPage,nextPage,richting);
content.addChild(flip);
currentPage=nextPage;
nextPage = new MovieClip();
there is a fix for it, consider the following:
// store original matrix
var origMatrix:Matrix = box.transform.matrix;
// set initial position
box.rotationY = -180;
// start animation
TweenLite.to(box, 1, {rotationY:0, onComplete:cleanBlur})
// execute after animation complete
function cleanBlur():void {
box.transform.matrix = origMatrix;
}
maybe you can find better results using other 3d library.
EDIT: sorry the "box" object, I was testing in flash, but box would be any of your pages to flip. Just apply the same logic.
Matteo at Flash & Math has an excellent solution for this. He actually found that when you bring an object into native 3D space it expands the object by one pixel in both the width and height. This can be counteracted by scaling your object back and then setting it's z to 0 which will scale it back up. Now the object is ready to play with without the blur.
http://www.flashandmath.com/flashcs4/blursol/index.html
adding: This fixes the scale issue, but not the blurriness. You will still need to use the matrix transformation fix posted above.